diff options
56 files changed, 258 insertions, 195 deletions
diff --git a/.editorconfig b/.editorconfig index e23e4cd649..13aa8d50f0 100644 --- a/.editorconfig +++ b/.editorconfig @@ -12,6 +12,9 @@ insert_final_newline = true [*.{go,tmpl,html}] indent_style = tab +[go.*] +indent_style = tab + [templates/custom/*.tmpl] insert_final_newline = false diff --git a/CHANGELOG.md b/CHANGELOG.md index 7541bccb2a..ca2e67929c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,28 @@ This changelog goes through 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.com). +## [1.23.6](https://github.com/go-gitea/gitea/releases/tag/v1.23.6) - 2025-03-24 + +* SECURITY + * Fix LFS URL (#33840) (#33843) + * Update jwt and redis packages (#33984) (#33987) + * Update golang crypto and net (#33989) +* BUGFIXES + * Drop timeout for requests made to the internal hook api (#33947) (#33970) + * Fix maven panic when no package exists (#33888) (#33889) + * Fix markdown render (#33870) (#33875) + * Fix auto concurrency cancellation skips commit status updates (#33764) (#33849) + * Fix oauth2 auth (#33961) (#33962) + * Fix incorrect 1.23 translations (#33932) + * Try to figure out attribute checker problem (#33901) (#33902) + * Ignore trivial errors when updating push data (#33864) (#33887) + * Fix some UI problems for 1.23 (#33856) + * Removing unwanted ui container (#33833) (#33835) + * Support disable passkey auth (#33348) (#33819) + * Do not call "git diff" when listing PRs (#33817) + * Try to fix ACME (3rd) (#33807) (#33808) + * Fix incorrect code search indexer options (#33992) #33999 + ## [1.23.5](https://github.com/go-gitea/gitea/releases/tag/v1.23.5) - 2025-03-04 * SECURITY @@ -64,7 +64,7 @@ require ( github.com/gobwas/glob v0.2.3 github.com/gogs/chardet v0.0.0-20211120154057-b7413eaefb8f github.com/gogs/go-gogs-client v0.0.0-20210131175652-1d7215cd8d85 - github.com/golang-jwt/jwt/v5 v5.2.1 + github.com/golang-jwt/jwt/v5 v5.2.2 github.com/google/go-github/v61 v61.0.0 github.com/google/licenseclassifier/v2 v2.0.0 github.com/google/pprof v0.0.0-20250208200701-d0013a598941 @@ -99,7 +99,7 @@ require ( github.com/pquerna/otp v1.4.0 github.com/prometheus/client_golang v1.21.0 github.com/quasoft/websspi v1.1.2 - github.com/redis/go-redis/v9 v9.7.0 + github.com/redis/go-redis/v9 v9.7.3 github.com/robfig/cron/v3 v3.0.1 github.com/santhosh-tekuri/jsonschema/v5 v5.3.1 github.com/sassoftware/go-rpmutils v0.4.0 @@ -215,7 +215,7 @@ require ( github.com/go-openapi/validate v0.24.0 // indirect github.com/go-webauthn/x v0.1.16 // indirect github.com/goccy/go-json v0.10.5 // indirect - github.com/golang-jwt/jwt/v4 v4.5.1 // indirect + github.com/golang-jwt/jwt/v4 v4.5.2 // indirect github.com/golang-sql/civil v0.0.0-20220223132316-b832511892a9 // indirect github.com/golang-sql/sqlexp v0.1.0 // indirect github.com/golang/geo v0.0.0-20230421003525-6adc56603217 // indirect @@ -374,10 +374,11 @@ github.com/gogs/chardet v0.0.0-20211120154057-b7413eaefb8f h1:3BSP1Tbs2djlpprl7w github.com/gogs/chardet v0.0.0-20211120154057-b7413eaefb8f/go.mod h1:Pcatq5tYkCW2Q6yrR2VRHlbHpZ/R4/7qyL1TCF7vl14= github.com/gogs/go-gogs-client v0.0.0-20210131175652-1d7215cd8d85 h1:UjoPNDAQ5JPCjlxoJd6K8ALZqSDDhk2ymieAZOVaDg0= github.com/gogs/go-gogs-client v0.0.0-20210131175652-1d7215cd8d85/go.mod h1:fR6z1Ie6rtF7kl/vBYMfgD5/G5B1blui7z426/sj2DU= -github.com/golang-jwt/jwt/v4 v4.5.1 h1:JdqV9zKUdtaa9gdPlywC3aeoEsR681PlKC+4F5gQgeo= github.com/golang-jwt/jwt/v4 v4.5.1/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0= -github.com/golang-jwt/jwt/v5 v5.2.1 h1:OuVbFODueb089Lh128TAcimifWaLhJwVflnrgM17wHk= -github.com/golang-jwt/jwt/v5 v5.2.1/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk= +github.com/golang-jwt/jwt/v4 v4.5.2 h1:YtQM7lnr8iZ+j5q71MGKkNw9Mn7AjHM68uc9g5fXeUI= +github.com/golang-jwt/jwt/v4 v4.5.2/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0= +github.com/golang-jwt/jwt/v5 v5.2.2 h1:Rl4B7itRWVtYIHFrSNd7vhTiz9UpLdi6gZhZ3wEeDy8= +github.com/golang-jwt/jwt/v5 v5.2.2/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk= github.com/golang-sql/civil v0.0.0-20220223132316-b832511892a9 h1:au07oEsX2xN0ktxqI+Sida1w446QrXBRJ0nee3SNZlA= github.com/golang-sql/civil v0.0.0-20220223132316-b832511892a9/go.mod h1:8vg3r2VgvsThLBIFL93Qb5yWzgyZWhEmBwUJWevAkK0= github.com/golang-sql/sqlexp v0.1.0 h1:ZCD6MBpcuOVfGVqsEmY5/4FtYiKz6tSyUv9LPEDei6A= @@ -655,8 +656,8 @@ github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoG github.com/quasoft/websspi v1.1.2 h1:/mA4w0LxWlE3novvsoEL6BBA1WnjJATbjkh1kFrTidw= github.com/quasoft/websspi v1.1.2/go.mod h1:HmVdl939dQ0WIXZhyik+ARdI03M6bQzaSEKcgpFmewk= github.com/rcrowley/go-metrics v0.0.0-20190826022208-cac0b30c2563/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= -github.com/redis/go-redis/v9 v9.7.0 h1:HhLSs+B6O021gwzl+locl0zEDnyNkxMtf/Z3NNBMa9E= -github.com/redis/go-redis/v9 v9.7.0/go.mod h1:f6zhXITC7JUJIlPEiBOTXxJgPLdZcA93GewI7inzyWw= +github.com/redis/go-redis/v9 v9.7.3 h1:YpPyAayJV+XErNsatSElgRZZVCwXX9QzkKYNvO7x0wM= +github.com/redis/go-redis/v9 v9.7.3/go.mod h1:bGUrSggJ9X9GUmZpZNEOQKaANxSGgOEBRltRTZHSvrA= github.com/redis/rueidis v1.0.19 h1:s65oWtotzlIFN8eMPhyYwxlwLR1lUdhza2KtWprKYSo= github.com/redis/rueidis v1.0.19/go.mod h1:8B+r5wdnjwK3lTFml5VtxjzGOQAC+5UmujoD12pDrEo= github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0 h1:OdAsTTz6OkFY5QxjkYwrChwuRruF69c169dPK26NUlk= diff --git a/modules/indexer/code/bleve/bleve.go b/modules/indexer/code/bleve/bleve.go index 130ee78a4b..7037e47c93 100644 --- a/modules/indexer/code/bleve/bleve.go +++ b/modules/indexer/code/bleve/bleve.go @@ -30,7 +30,6 @@ import ( "github.com/blevesearch/bleve/v2" analyzer_custom "github.com/blevesearch/bleve/v2/analysis/analyzer/custom" analyzer_keyword "github.com/blevesearch/bleve/v2/analysis/analyzer/keyword" - "github.com/blevesearch/bleve/v2/analysis/token/camelcase" "github.com/blevesearch/bleve/v2/analysis/token/lowercase" "github.com/blevesearch/bleve/v2/analysis/token/unicodenorm" "github.com/blevesearch/bleve/v2/analysis/tokenizer/letter" @@ -72,7 +71,7 @@ const ( filenameIndexerAnalyzer = "filenameIndexerAnalyzer" filenameIndexerTokenizer = "filenameIndexerTokenizer" repoIndexerDocType = "repoIndexerDocType" - repoIndexerLatestVersion = 8 + repoIndexerLatestVersion = 9 ) // generateBleveIndexMapping generates a bleve index mapping for the repo indexer @@ -109,7 +108,7 @@ func generateBleveIndexMapping() (mapping.IndexMapping, error) { "type": analyzer_custom.Name, "char_filters": []string{}, "tokenizer": letter.Name, - "token_filters": []string{unicodeNormalizeName, camelcase.Name, lowercase.Name}, + "token_filters": []string{unicodeNormalizeName, lowercase.Name}, }); err != nil { return nil, err } diff --git a/modules/optional/option.go b/modules/optional/option.go index af9e5ac852..ccbad259c2 100644 --- a/modules/optional/option.go +++ b/modules/optional/option.go @@ -3,6 +3,8 @@ package optional +import "strconv" + type Option[T any] []T func None[T any]() Option[T] { @@ -43,3 +45,12 @@ func (o Option[T]) ValueOrDefault(v T) T { } return v } + +// ParseBool get the corresponding optional.Option[bool] of a string using strconv.ParseBool +func ParseBool(s string) Option[bool] { + v, e := strconv.ParseBool(s) + if e != nil { + return None[bool]() + } + return Some(v) +} diff --git a/modules/optional/option_test.go b/modules/optional/option_test.go index 203e9221e3..f600ff5a2c 100644 --- a/modules/optional/option_test.go +++ b/modules/optional/option_test.go @@ -57,3 +57,16 @@ func TestOption(t *testing.T) { assert.True(t, opt3.Has()) assert.Equal(t, int(1), opt3.Value()) } + +func Test_ParseBool(t *testing.T) { + assert.Equal(t, optional.None[bool](), optional.ParseBool("")) + assert.Equal(t, optional.None[bool](), optional.ParseBool("x")) + + assert.Equal(t, optional.Some(false), optional.ParseBool("0")) + assert.Equal(t, optional.Some(false), optional.ParseBool("f")) + assert.Equal(t, optional.Some(false), optional.ParseBool("False")) + + assert.Equal(t, optional.Some(true), optional.ParseBool("1")) + assert.Equal(t, optional.Some(true), optional.ParseBool("t")) + assert.Equal(t, optional.Some(true), optional.ParseBool("True")) +} diff --git a/modules/paginator/paginator.go b/modules/paginator/paginator.go index 8258d194c2..0f64e89d9a 100644 --- a/modules/paginator/paginator.go +++ b/modules/paginator/paginator.go @@ -4,6 +4,8 @@ package paginator +import "code.gitea.io/gitea/modules/util" + /* In template: @@ -32,25 +34,43 @@ Output: // Paginator represents a set of results of pagination calculations. type Paginator struct { - total int // total rows count + total int // total rows count, -1 means unknown + totalPages int // total pages count, -1 means unknown + current int // current page number + curRows int // current page rows count + pagingNum int // how many rows in one page - current int // current page number numPages int // how many pages to show on the UI } // New initialize a new pagination calculation and returns a Paginator as result. func New(total, pagingNum, current, numPages int) *Paginator { - if pagingNum <= 0 { - pagingNum = 1 + pagingNum = max(pagingNum, 1) + totalPages := util.Iif(total == -1, -1, (total+pagingNum-1)/pagingNum) + if total >= 0 { + current = min(current, totalPages) } - if current <= 0 { - current = 1 + current = max(current, 1) + return &Paginator{ + total: total, + totalPages: totalPages, + current: current, + pagingNum: pagingNum, + numPages: numPages, } - p := &Paginator{total, pagingNum, current, numPages} - if p.current > p.TotalPages() { - p.current = p.TotalPages() +} + +func (p *Paginator) SetCurRows(rows int) { + // For "unlimited paging", we need to know the rows of current page to determine if there is a next page. + // There is still an edge case: when curRows==pagingNum, then the "next page" will be an empty page. + // Ideally we should query one more row to determine if there is really a next page, but it's impossible in current framework. + p.curRows = rows + if p.total == -1 && p.current == 1 && !p.HasNext() { + // if there is only one page for the "unlimited paging", set total rows/pages count + // then the tmpl could decide to hide the nav bar. + p.total = rows + p.totalPages = util.Iif(p.total == 0, 0, 1) } - return p } // IsFirst returns true if current page is the first page. @@ -72,7 +92,10 @@ func (p *Paginator) Previous() int { // HasNext returns true if there is a next page relative to current page. func (p *Paginator) HasNext() bool { - return p.total > p.current*p.pagingNum + if p.total == -1 { + return p.curRows >= p.pagingNum + } + return p.current*p.pagingNum < p.total } func (p *Paginator) Next() int { @@ -84,10 +107,7 @@ func (p *Paginator) Next() int { // IsLast returns true if current page is the last page. func (p *Paginator) IsLast() bool { - if p.total == 0 { - return true - } - return p.total > (p.current-1)*p.pagingNum && !p.HasNext() + return !p.HasNext() } // Total returns number of total rows. @@ -97,10 +117,7 @@ func (p *Paginator) Total() int { // TotalPages returns number of total pages. func (p *Paginator) TotalPages() int { - if p.total == 0 { - return 1 - } - return (p.total + p.pagingNum - 1) / p.pagingNum + return p.totalPages } // Current returns current page number. @@ -135,10 +152,10 @@ func getMiddleIdx(numPages int) int { // If value is -1 means "..." that more pages are not showing. func (p *Paginator) Pages() []*Page { if p.numPages == 0 { - return []*Page{} - } else if p.numPages == 1 && p.TotalPages() == 1 { + return nil + } else if p.total == -1 || (p.numPages == 1 && p.TotalPages() == 1) { // Only show current page. - return []*Page{{1, true}} + return []*Page{{p.current, true}} } // Total page number is less or equal. diff --git a/modules/paginator/paginator_test.go b/modules/paginator/paginator_test.go index 8a56ee5121..ed46ecea94 100644 --- a/modules/paginator/paginator_test.go +++ b/modules/paginator/paginator_test.go @@ -76,9 +76,7 @@ func TestPaginator(t *testing.T) { t.Run("Only current page", func(t *testing.T) { p := New(0, 10, 1, 1) pages := p.Pages() - assert.Len(t, pages, 1) - assert.Equal(t, 1, pages[0].Num()) - assert.True(t, pages[0].IsCurrent()) + assert.Empty(t, pages) // no "total", so no pages p = New(1, 10, 1, 1) pages = p.Pages() diff --git a/modules/setting/setting.go b/modules/setting/setting.go index 20da796b58..e14997801f 100644 --- a/modules/setting/setting.go +++ b/modules/setting/setting.go @@ -12,8 +12,8 @@ import ( "time" "code.gitea.io/gitea/modules/log" + "code.gitea.io/gitea/modules/optional" "code.gitea.io/gitea/modules/user" - "code.gitea.io/gitea/modules/util" ) // settings @@ -159,7 +159,7 @@ func loadRunModeFrom(rootCfg ConfigProvider) { // The following is a purposefully undocumented option. Please do not run Gitea as root. It will only cause future headaches. // Please don't use root as a bandaid to "fix" something that is broken, instead the broken thing should instead be fixed properly. unsafeAllowRunAsRoot := ConfigSectionKeyBool(rootSec, "I_AM_BEING_UNSAFE_RUNNING_AS_ROOT") - unsafeAllowRunAsRoot = unsafeAllowRunAsRoot || util.OptionalBoolParse(os.Getenv("GITEA_I_AM_BEING_UNSAFE_RUNNING_AS_ROOT")).Value() + unsafeAllowRunAsRoot = unsafeAllowRunAsRoot || optional.ParseBool(os.Getenv("GITEA_I_AM_BEING_UNSAFE_RUNNING_AS_ROOT")).Value() RunMode = os.Getenv("GITEA_RUN_MODE") if RunMode == "" { RunMode = rootSec.Key("RUN_MODE").MustString("prod") diff --git a/modules/util/util.go b/modules/util/util.go index 1fb4cb21cb..72fcddbe13 100644 --- a/modules/util/util.go +++ b/modules/util/util.go @@ -11,21 +11,10 @@ import ( "strconv" "strings" - "code.gitea.io/gitea/modules/optional" - "golang.org/x/text/cases" "golang.org/x/text/language" ) -// OptionalBoolParse get the corresponding optional.Option[bool] of a string using strconv.ParseBool -func OptionalBoolParse(s string) optional.Option[bool] { - v, e := strconv.ParseBool(s) - if e != nil { - return optional.None[bool]() - } - return optional.Some(v) -} - // IsEmptyString checks if the provided string is empty func IsEmptyString(s string) bool { return len(strings.TrimSpace(s)) == 0 diff --git a/modules/util/util_test.go b/modules/util/util_test.go index effbc6da1e..fe4125cdb5 100644 --- a/modules/util/util_test.go +++ b/modules/util/util_test.go @@ -8,8 +8,6 @@ import ( "strings" "testing" - "code.gitea.io/gitea/modules/optional" - "github.com/stretchr/testify/assert" ) @@ -175,19 +173,6 @@ func Test_RandomBytes(t *testing.T) { assert.NotEqual(t, bytes3, bytes4) } -func TestOptionalBoolParse(t *testing.T) { - assert.Equal(t, optional.None[bool](), OptionalBoolParse("")) - assert.Equal(t, optional.None[bool](), OptionalBoolParse("x")) - - assert.Equal(t, optional.Some(false), OptionalBoolParse("0")) - assert.Equal(t, optional.Some(false), OptionalBoolParse("f")) - assert.Equal(t, optional.Some(false), OptionalBoolParse("False")) - - assert.Equal(t, optional.Some(true), OptionalBoolParse("1")) - assert.Equal(t, optional.Some(true), OptionalBoolParse("t")) - assert.Equal(t, optional.Some(true), OptionalBoolParse("True")) -} - // Test case for any function which accepts and returns a single string. type StringTest struct { in, out string diff --git a/options/locale/locale_cs-CZ.ini b/options/locale/locale_cs-CZ.ini index 41c770452f..57d7e8e076 100644 --- a/options/locale/locale_cs-CZ.ini +++ b/options/locale/locale_cs-CZ.ini @@ -446,7 +446,6 @@ oauth_signup_submit=Dokončit účet oauth_signin_tab=Propojit s existujícím účtem oauth_signin_title=Přihlaste se pro ověření propojeného účtu oauth_signin_submit=Propojit účet -oauth.signin.error=Došlo k chybě při zpracování žádosti o autorizaci. Pokud tato chyba přetrvává, obraťte se na správce webu. oauth.signin.error.access_denied=Žádost o autorizaci byla zamítnuta. oauth.signin.error.temporarily_unavailable=Autorizace se nezdařila, protože ověřovací server je dočasně nedostupný. Opakujte akci později. oauth_callback_unable_auto_reg=Automatická registrace je povolena, ale OAuth2 poskytovatel %[1]s vrátil chybějící pole: %[2]s, nelze vytvořit účet automaticky, vytvořte účet nebo se připojte k účtu, nebo kontaktujte správce webu. @@ -1530,7 +1529,6 @@ issues.filter_project=Projekt issues.filter_project_all=Všechny projekty issues.filter_project_none=Žádný projekt issues.filter_assignee=Zpracovatel -issues.filter_assginee_no_select=Všichni zpracovatelé issues.filter_assginee_no_assignee=Bez zpracovatele issues.filter_poster=Autor issues.filter_user_placeholder=Hledat uživatele diff --git a/options/locale/locale_de-DE.ini b/options/locale/locale_de-DE.ini index c9e7f5edab..0b0544b89c 100644 --- a/options/locale/locale_de-DE.ini +++ b/options/locale/locale_de-DE.ini @@ -452,7 +452,6 @@ oauth_signup_submit=Konto vervollständigen oauth_signin_tab=Mit existierendem Konto verbinden oauth_signin_title=Anmelden um verbundenes Konto zu autorisieren oauth_signin_submit=Konto verbinden -oauth.signin.error=Beim Verarbeiten der Autorisierungsanfrage ist ein Fehler aufgetreten. Wenn dieser Fehler weiterhin besteht, wende dich bitte an deinen Administrator. oauth.signin.error.access_denied=Die Autorisierungsanfrage wurde abgelehnt. oauth.signin.error.temporarily_unavailable=Autorisierung fehlgeschlagen, da der Authentifizierungsserver vorübergehend nicht verfügbar ist. Bitte versuch es später erneut. oauth_callback_unable_auto_reg=Automatische Registrierung ist aktiviert, aber der OAuth2-Provider %[1]s hat fehlende Felder zurückgegeben: %[2]s, kann den Account nicht automatisch erstellen. Bitte erstelle oder verbinde einen Account oder kontaktieren den Administrator. @@ -1531,7 +1530,6 @@ issues.filter_project=Projekt issues.filter_project_all=Alle Projekte issues.filter_project_none=Kein Projekt issues.filter_assignee=Zuständig -issues.filter_assginee_no_select=Alle Zuständigen issues.filter_assginee_no_assignee=Niemand zuständig issues.filter_poster=Autor issues.filter_user_placeholder=Benutzer suchen diff --git a/options/locale/locale_el-GR.ini b/options/locale/locale_el-GR.ini index 09ae6f5a87..f430c0506c 100644 --- a/options/locale/locale_el-GR.ini +++ b/options/locale/locale_el-GR.ini @@ -390,7 +390,6 @@ oauth_signup_submit=Ολοκληρωμένος Λογαριασμός oauth_signin_tab=Σύνδεση με υπάρχων λογαριασμό oauth_signin_title=Συνδεθείτε για να εγκρίνετε τον Συνδεδεμένο Λογαριασμό oauth_signin_submit=Σύνδεση Λογαριασμού -oauth.signin.error=Παρουσιάστηκε σφάλμα κατά την επεξεργασία του αιτήματος εξουσιοδότησης. Εάν αυτό το σφάλμα επιμένει, παρακαλούμε επικοινωνήστε με το διαχειριστή του ιστοτόπου. oauth.signin.error.access_denied=Η αίτηση εξουσιοδότησης απορρίφθηκε. oauth.signin.error.temporarily_unavailable=Η εξουσιοδότηση απέτυχε επειδή ο διακομιστής ταυτοποίησης δεν είναι διαθέσιμος προσωρινά. Παρακαλώ προσπαθήστε ξανά αργότερα. openid_connect_submit=Σύνδεση @@ -1378,7 +1377,6 @@ issues.filter_project=Έργο issues.filter_project_all=Όλα τα έργα issues.filter_project_none=Χωρίς έργα issues.filter_assignee=Αποδέκτης -issues.filter_assginee_no_select=Όλοι οι αποδέκτες issues.filter_assginee_no_assignee=Κανένας Αποδέκτης issues.filter_poster=Συγγραφέας issues.filter_type=Τύπος diff --git a/options/locale/locale_en-US.ini b/options/locale/locale_en-US.ini index 573c00eee6..b2e079c696 100644 --- a/options/locale/locale_en-US.ini +++ b/options/locale/locale_en-US.ini @@ -457,7 +457,7 @@ oauth_signup_submit = Complete Account oauth_signin_tab = Link to Existing Account oauth_signin_title = Sign In to Authorize Linked Account oauth_signin_submit = Link Account -oauth.signin.error = There was an error processing the authorization request. If this error persists, please contact the site administrator. +oauth.signin.error.general = There was an error processing the authorization request: %s. If this error persists, please contact the site administrator. oauth.signin.error.access_denied = The authorization request was denied. oauth.signin.error.temporarily_unavailable = Authorization failed because the authentication server is temporarily unavailable. Please try again later. oauth_callback_unable_auto_reg = Auto Registration is enabled, but OAuth2 Provider %[1]s returned missing fields: %[2]s, unable to create an account automatically, please create or link to an account, or contact the site administrator. diff --git a/options/locale/locale_es-ES.ini b/options/locale/locale_es-ES.ini index 1a0ee9be8e..debf9a6f5d 100644 --- a/options/locale/locale_es-ES.ini +++ b/options/locale/locale_es-ES.ini @@ -387,7 +387,6 @@ oauth_signup_submit=Completar Cuenta oauth_signin_tab=Vincular a una Cuenta Existente oauth_signin_title=Regístrese para autorizar cuenta vinculada oauth_signin_submit=Vincular Cuenta -oauth.signin.error=Hubo un error al procesar la solicitud de autorización. Si este error persiste, póngase en contacto con el administrador del sitio. oauth.signin.error.access_denied=La solicitud de autorización fue denegada. oauth.signin.error.temporarily_unavailable=La autorización falló porque el servidor de autenticación no está disponible temporalmente. Inténtalo de nuevo más tarde. openid_connect_submit=Conectar @@ -1368,7 +1367,6 @@ issues.filter_project=Proyecto issues.filter_project_all=Todos los proyectos issues.filter_project_none=Ningún proyecto issues.filter_assignee=Asignada a -issues.filter_assginee_no_select=Todos los asignados issues.filter_assginee_no_assignee=Sin asignado issues.filter_poster=Autor issues.filter_type=Tipo diff --git a/options/locale/locale_fa-IR.ini b/options/locale/locale_fa-IR.ini index 147c570ca0..5c96cea8f6 100644 --- a/options/locale/locale_fa-IR.ini +++ b/options/locale/locale_fa-IR.ini @@ -1059,7 +1059,6 @@ issues.filter_label_no_select=تمامی برچسبها issues.filter_milestone=نقطه عطف issues.filter_project_none=هیچ پروژه ثبت نشده issues.filter_assignee=مسئول رسیدگی -issues.filter_assginee_no_select=تمامی مسئولان رسیدگی issues.filter_assginee_no_assignee=بدون مسئول رسیدگی issues.filter_type=نوع issues.filter_type.all_issues=همه مسائل diff --git a/options/locale/locale_fr-FR.ini b/options/locale/locale_fr-FR.ini index 9964bcc077..c9b3345382 100644 --- a/options/locale/locale_fr-FR.ini +++ b/options/locale/locale_fr-FR.ini @@ -113,6 +113,7 @@ copy_type_unsupported=Ce type de fichier ne peut pas être copié write=Écrire preview=Aperçu loading=Chargement… +files=Fichiers error=Erreur error404=La page que vous essayez d'atteindre <strong>n'existe pas</strong> ou <strong>vous n'êtes pas autorisé</strong> à la voir. @@ -169,6 +170,10 @@ search=Rechercher… type_tooltip=Type de recherche fuzzy=Approximative fuzzy_tooltip=Inclure également les résultats proches de la recherche +words=Mots +words_tooltip=Inclure uniquement les résultats qui correspondent exactement aux mots recherchés +regexp=Regexp +regexp_tooltip=Inclure uniquement les résultats qui correspondent à l’expression régulière recherchée exact=Exact exact_tooltip=Inclure uniquement les résultats qui correspondent exactement au terme de recherche repo_kind=Chercher des dépôts… @@ -452,7 +457,6 @@ oauth_signup_submit=Finaliser la création du compte oauth_signin_tab=Lier à un compte existant oauth_signin_title=Connectez-vous pour autoriser le compte lié oauth_signin_submit=Lier un compte -oauth.signin.error=Une erreur s'est produite lors du traitement de la demande d'autorisation. Si cette erreur persiste, veuillez contacter l'administrateur du site. oauth.signin.error.access_denied=La demande d'autorisation a été refusée. oauth.signin.error.temporarily_unavailable=L'autorisation a échoué car le serveur d'authentification est temporairement indisponible. Veuillez réessayer plus tard. oauth_callback_unable_auto_reg=L’inscription automatique est activée, mais le fournisseur OAuth2 %[1]s a signalé des champs manquants : %[2]s, impossible de créer un compte automatiquement, veuillez créer ou lier un compte, ou bien contacter l’administrateur du site. @@ -1403,6 +1407,7 @@ commits.signed_by_untrusted_user_unmatched=Signature discordante de l'auteur de commits.gpg_key_id=ID de la clé GPG commits.ssh_key_fingerprint=Empreinte numérique de la clé SSH commits.view_path=Voir à ce point de l'historique +commits.view_file_diff=Voir les modifications du fichier dans cette révision commit.operations=Opérations commit.revert=Rétablir @@ -1540,8 +1545,6 @@ issues.filter_project=Projet issues.filter_project_all=Tous les projets issues.filter_project_none=Aucun projet issues.filter_assignee=Assigné -issues.filter_assginee_no_select=Tous les assignés -issues.filter_assginee_no_assignee=Aucun assigné issues.filter_poster=Auteur issues.filter_user_placeholder=Rechercher des utilisateurs issues.filter_user_no_select=Tous les utilisateurs @@ -3708,6 +3711,7 @@ creation=Ajouter un secret creation.description=Description creation.name_placeholder=Caractères alphanumériques ou tirets bas uniquement, insensibles à la casse, ne peut commencer par GITEA_ ou GITHUB_. creation.value_placeholder=Entrez n’importe quoi. Les blancs cernant seront taillés. +creation.description_placeholder=Décrire brièvement votre dépôt (optionnel). creation.success=Le secret "%s" a été ajouté. creation.failed=Impossible d'ajouter le secret. deletion=Supprimer le secret diff --git a/options/locale/locale_ga-IE.ini b/options/locale/locale_ga-IE.ini index aa79a03a3a..1245a8beed 100644 --- a/options/locale/locale_ga-IE.ini +++ b/options/locale/locale_ga-IE.ini @@ -113,6 +113,7 @@ copy_type_unsupported=Ní féidir an cineál comhaid seo a chóipeáil write=Scríobh preview=Réamhamharc loading=Á lódáil... +files=Comhaid error=Earráid error404=Níl an leathanach atá tú ag iarraidh a bhaint amach <strong>ann</strong> nó <strong>níl tú údaraithe</strong> chun é a fheiceáil. @@ -169,6 +170,10 @@ search=Cuardaigh... type_tooltip=Cineál cuardaigh fuzzy=Doiléir fuzzy_tooltip=Cuir san áireamh torthaí a mheaitseálann an téarma cuardaigh go dlúth freisin +words=Focail +words_tooltip=Ná cuir san áireamh ach torthaí a mheaitseálann na focail téarma cuardaigh +regexp=Nathanna Rialta +regexp_tooltip=Ná cuir ach torthaí a mheaitseálann an téarma cuardaigh nathanna rialta san áireamh exact=Beacht exact_tooltip=Ní chuir san áireamh ach torthaí a mheaitseálann leis an téarma repo_kind=Cuardaigh stórtha... @@ -452,7 +457,6 @@ oauth_signup_submit=Cuntas Comhlánaigh oauth_signin_tab=Nasc leis an gCuntas Reatha oauth_signin_title=Sínigh isteach chun Cuntas Nasctha a Údarú oauth_signin_submit=Cuntas Nasc -oauth.signin.error=Bhí earráid ann ag próiseáil an t-iarratas ar údarú. Má leanann an earráid seo, déan teagmháil le riarthóir an láithreáin. oauth.signin.error.access_denied=Diúltaíodh an t-iarratas ar údarú. oauth.signin.error.temporarily_unavailable=Theip ar údarú toisc nach bhfuil an fhreastalaí fíordheimhnithe ar fáil Bain triail as arís níos déanaí. oauth_callback_unable_auto_reg=Tá Clárú Uathoibríoch cumasaithe, ach sheol Soláthraí OAuth2 %[1]s réimsí in easnamh ar ais: %[2]s, ní raibh sé in ann cuntas a chruthú go huathoibríoch, cruthaigh nó nasc le cuntas, nó déan teagmháil le riarthóir an tsuímh. @@ -1403,6 +1407,7 @@ commits.signed_by_untrusted_user_unmatched=Sínithe ag úsáideoir neamhiontaofa commits.gpg_key_id=GPG Eochair ID commits.ssh_key_fingerprint=Méarloirg Eochair SSH commits.view_path=Féach ag an bpointe seo sa stair +commits.view_file_diff=Féach ar athruithe ar an gcomhad seo sa tiomantas seo commit.operations=Oibríochtaí commit.revert=Téigh ar ais @@ -1540,8 +1545,8 @@ issues.filter_project=Tionscadal issues.filter_project_all=Gach tionscadal issues.filter_project_none=Gan aon tionscadal issues.filter_assignee=Sannaitheoir -issues.filter_assginee_no_select=Gach sannaithe -issues.filter_assginee_no_assignee=Gan sannaitheoir +issues.filter_assginee_no_assignee=Sannta do dhuine ar bith +issues.filter_assignee_any_assignee=Sannta do dhuine ar bith issues.filter_poster=Údar issues.filter_user_placeholder=Cuardaigh úsáideoirí issues.filter_user_no_select=Gach úsáideoir @@ -3708,6 +3713,7 @@ creation=Cuir Rúnda leis creation.description=Cur síos creation.name_placeholder=carachtair alfanumair nó íoslaghda amháin nach féidir a thosú le GITEA_ nó GITHUB_ creation.value_placeholder=Ionchur ábhar ar bith. Fágfar spás bán ag tús agus ag deireadh ar lár. +creation.description_placeholder=Cuir isteach cur síos gairid (roghnach). creation.success=Tá an rún "%s" curtha leis. creation.failed=Theip ar an rún a chur leis. deletion=Bain rún diff --git a/options/locale/locale_hu-HU.ini b/options/locale/locale_hu-HU.ini index f4f0bed24c..a57d6960dd 100644 --- a/options/locale/locale_hu-HU.ini +++ b/options/locale/locale_hu-HU.ini @@ -774,8 +774,6 @@ issues.filter_label=Címke issues.filter_label_no_select=Minden címke issues.filter_milestone=Mérföldkő issues.filter_assignee=Megbízott -issues.filter_assginee_no_select=Minden megbízott -issues.filter_assginee_no_assignee=Nincs megbízott issues.filter_type=Típus issues.filter_type.all_issues=Minden hibajegy issues.filter_type.assigned_to_you=Hozzám rendelt diff --git a/options/locale/locale_id-ID.ini b/options/locale/locale_id-ID.ini index 10d8c43c5b..c54bfbb924 100644 --- a/options/locale/locale_id-ID.ini +++ b/options/locale/locale_id-ID.ini @@ -763,7 +763,6 @@ issues.delete_branch_at=`telah dihapus cabang <b>%s</b> %s` issues.filter_label=Label issues.filter_milestone=Tonggak issues.filter_assignee=Menerima -issues.filter_assginee_no_assignee=Tidak ada yang menerima issues.filter_type=Tipe issues.filter_type.all_issues=Semua masalah issues.filter_type.assigned_to_you=Ditugaskan kepada anda diff --git a/options/locale/locale_it-IT.ini b/options/locale/locale_it-IT.ini index b3564eb8f7..3ce5a6770f 100644 --- a/options/locale/locale_it-IT.ini +++ b/options/locale/locale_it-IT.ini @@ -323,7 +323,6 @@ oauth_signup_submit=Completa l'Account oauth_signin_tab=Collegamento ad un Account Esistente oauth_signin_title=Accedi per autorizzare l' Account collegato oauth_signin_submit=Collega Account -oauth.signin.error=Si è verificato un errore nell'elaborazione della richiesta di autorizzazione. Se questo errore persiste, si prega di contattare l'amministratore del sito. oauth.signin.error.access_denied=La richiesta di autorizzazione è stata negata. oauth.signin.error.temporarily_unavailable=Autorizzazione non riuscita perché il server di autenticazione non è temporaneamente disponibile. Riprova più tardi. openid_connect_submit=Connetti @@ -1144,7 +1143,6 @@ issues.filter_milestone=Traguardo issues.filter_project=Progetto issues.filter_project_none=Nessun progetto issues.filter_assignee=Assegnatario -issues.filter_assginee_no_select=Tutte le assegnazioni issues.filter_assginee_no_assignee=Nessun assegnatario issues.filter_poster=Autore issues.filter_type=Tipo diff --git a/options/locale/locale_ja-JP.ini b/options/locale/locale_ja-JP.ini index dd88f3eeaa..3a80e6e451 100644 --- a/options/locale/locale_ja-JP.ini +++ b/options/locale/locale_ja-JP.ini @@ -169,6 +169,10 @@ search=検索… type_tooltip=検索タイプ fuzzy=あいまい fuzzy_tooltip=検索語におおよそ一致する結果も含めます +words=単語 +words_tooltip=検索語と一致する結果だけを含めます +regexp=正規表現 +regexp_tooltip=正規表現検索パターンと一致する結果だけを含めます exact=完全一致 exact_tooltip=検索語と完全に一致する結果だけを含めます repo_kind=リポジトリを検索... @@ -452,7 +456,6 @@ oauth_signup_submit=アカウント登録完了 oauth_signin_tab=既存アカウントにリンク oauth_signin_title=リンク先アカウント認可のためサインイン oauth_signin_submit=アカウントにリンク -oauth.signin.error=認可リクエストの処理中にエラーが発生しました。このエラーが解決しない場合は、サイト管理者に問い合わせてください。 oauth.signin.error.access_denied=認可リクエストが拒否されました。 oauth.signin.error.temporarily_unavailable=認証サーバーが一時的に利用できないため、認可に失敗しました。後でもう一度やり直してください。 oauth_callback_unable_auto_reg=自動登録が有効になっていますが、OAuth2プロバイダー %[1]s の応答はフィールド %[2]s が不足しており、自動でアカウントを作成することができません。 アカウントを作成またはリンクするか、サイト管理者に問い合わせてください。 @@ -1463,6 +1466,8 @@ issues.filter_milestones=マイルストーンの絞り込み issues.filter_projects=プロジェクトの絞り込み issues.filter_labels=ラベルの絞り込み issues.filter_reviewers=レビューアの絞り込み +issues.filter_no_results=検索結果なし +issues.filter_no_results_placeholder=検索フィルターを変えてみて下さい。 issues.new=新しいイシュー issues.new.title_empty=タイトルは空にできません issues.new.labels=ラベル @@ -1538,8 +1543,8 @@ issues.filter_project=プロジェクト issues.filter_project_all=すべてのプロジェクト issues.filter_project_none=プロジェクトなし issues.filter_assignee=担当者 -issues.filter_assginee_no_select=すべての担当者 issues.filter_assginee_no_assignee=担当者なし +issues.filter_assignee_any_assignee=担当者あり issues.filter_poster=作成者 issues.filter_user_placeholder=ユーザーを検索 issues.filter_user_no_select=すべてのユーザー @@ -1935,6 +1940,7 @@ pulls.outdated_with_base_branch=このブランチはベースブランチに対 pulls.close=プルリクエストをクローズ pulls.closed_at=`がプルリクエストをクローズ <a id="%[1]s" href="#%[1]s">%[2]s</a>` pulls.reopened_at=`がプルリクエストを再オープン <a id="%[1]s" href="#%[1]s">%[2]s</a>` +pulls.cmd_instruction_hint=コマンドラインの手順を表示 pulls.cmd_instruction_checkout_title=チェックアウト pulls.cmd_instruction_checkout_desc=プロジェクトリポジトリから新しいブランチをチェックアウトし、変更内容をテストします。 pulls.cmd_instruction_merge_title=マージ @@ -2376,6 +2382,9 @@ settings.event_pull_request_review_request=プルリクエストのレビュー settings.event_pull_request_review_request_desc=プルリクエストのレビューが依頼されたとき、または依頼が削除されたとき。 settings.event_pull_request_approvals=プルリクエストの承認 settings.event_pull_request_merge=プルリクエストのマージ +settings.event_header_workflow=ワークフローイベント +settings.event_workflow_job=ワークフロージョブ +settings.event_workflow_job_desc=Gitea Actions のワークフロージョブが、キューに追加、待機中、実行中、完了になったとき。 settings.event_package=パッケージ settings.event_package_desc=リポジトリにパッケージが作成または削除されたとき。 settings.branch_filter=ブランチ フィルター @@ -3702,6 +3711,7 @@ creation=シークレットを追加 creation.description=説明 creation.name_placeholder=大文字小文字の区別なし、英数字とアンダースコアのみ、GITEA_ や GITHUB_ で始まるものは不可 creation.value_placeholder=内容を入力してください。前後の空白は除去されます。 +creation.description_placeholder=簡単な説明を入力してください。 (オプション) creation.success=シークレット "%s" を追加しました。 creation.failed=シークレットの追加に失敗しました。 deletion=シークレットの削除 diff --git a/options/locale/locale_ko-KR.ini b/options/locale/locale_ko-KR.ini index 601c203aba..697371c2c9 100644 --- a/options/locale/locale_ko-KR.ini +++ b/options/locale/locale_ko-KR.ini @@ -707,7 +707,6 @@ issues.filter_label=레이블 issues.filter_label_no_select=모든 레이블 issues.filter_milestone=마일스톤 issues.filter_assignee=담당자 -issues.filter_assginee_no_select=모든 담당자 issues.filter_assginee_no_assignee=담당자 없음 issues.filter_type=유형 issues.filter_type.all_issues=모든 이슈 diff --git a/options/locale/locale_lv-LV.ini b/options/locale/locale_lv-LV.ini index 975943ec91..4439537fd7 100644 --- a/options/locale/locale_lv-LV.ini +++ b/options/locale/locale_lv-LV.ini @@ -393,7 +393,6 @@ oauth_signup_submit=Pabeigt reģistrāciju oauth_signin_tab=Sasaistīt ar esošu kontu oauth_signin_title=Pieteikties, lai autorizētu saistīto kontu oauth_signin_submit=Sasaistīt kontu -oauth.signin.error=Radās kļūda apstrādājot pieteikšanās pieprasījumu. Ja šī kļūda atkārtojas, sazinieties ar lapas administratoru. oauth.signin.error.access_denied=Autorizācijas pieprasījums tika noraidīts. oauth.signin.error.temporarily_unavailable=Pieteikšanās neizdevās, jo autentifikācijas serveris ir īslaicīgi nepieejams. Mēģiniet autorizēties vēlāk. openid_connect_submit=Pievienoties @@ -1384,7 +1383,6 @@ issues.filter_project=Projekts issues.filter_project_all=Visi projekti issues.filter_project_none=Nav projekta issues.filter_assignee=Atbildīgais -issues.filter_assginee_no_select=Visi atbildīgie issues.filter_assginee_no_assignee=Nav atbildīgā issues.filter_poster=Autors issues.filter_type=Veids diff --git a/options/locale/locale_nl-NL.ini b/options/locale/locale_nl-NL.ini index efea6b82df..77bf2d2d59 100644 --- a/options/locale/locale_nl-NL.ini +++ b/options/locale/locale_nl-NL.ini @@ -322,7 +322,6 @@ oauth_signup_submit=Account voltooien oauth_signin_tab=Bestaand account koppelen oauth_signin_title=Inloggen om het gekoppelde account te machtigen oauth_signin_submit=Account koppelen -oauth.signin.error=Er is een fout opgetreden bij het verwerken van het autorisatieverzoek. Als deze fout zich blijft voordoen, neem dan contact op met de sitebeheerder. oauth.signin.error.access_denied=Het autorisatieverzoek is geweigerd. oauth.signin.error.temporarily_unavailable=Autorisatie mislukt omdat de verificatieserver tijdelijk niet beschikbaar is. Probeer het later opnieuw. openid_connect_submit=Verbinden @@ -1142,7 +1141,6 @@ issues.filter_milestone=Mijlpaal issues.filter_project=Project issues.filter_project_none=Geen project issues.filter_assignee=Aangewezene -issues.filter_assginee_no_select=Alle toegewezen personen issues.filter_assginee_no_assignee=Geen verantwoordelijke issues.filter_poster=Auteur issues.filter_type=Type diff --git a/options/locale/locale_pl-PL.ini b/options/locale/locale_pl-PL.ini index 1e6268e2be..f64b8771ac 100644 --- a/options/locale/locale_pl-PL.ini +++ b/options/locale/locale_pl-PL.ini @@ -1054,7 +1054,6 @@ issues.filter_label_no_select=Wszystkie etykiety issues.filter_milestone=Kamień milowy issues.filter_project_none=Brak projektu issues.filter_assignee=Przypisany -issues.filter_assginee_no_select=Wszyscy przypisani issues.filter_assginee_no_assignee=Brak przypisania issues.filter_type=Typ issues.filter_type.all_issues=Wszystkie zgłoszenia diff --git a/options/locale/locale_pt-BR.ini b/options/locale/locale_pt-BR.ini index b23e45088d..204fedc311 100644 --- a/options/locale/locale_pt-BR.ini +++ b/options/locale/locale_pt-BR.ini @@ -390,7 +390,6 @@ oauth_signup_submit=Completar conta oauth_signin_tab=Vincular à uma conta existente oauth_signin_title=Acesse com uma conta vinculada oauth_signin_submit=Vincular conta -oauth.signin.error=Ocorreu um erro durante o processamento do pedido de autorização. Se este erro persistir, contate o administrador. oauth.signin.error.access_denied=O pedido de autorização foi negado. oauth.signin.error.temporarily_unavailable=A autorização falhou porque o servidor de autenticação está temporariamente indisponível. Por favor, tente novamente mais tarde. openid_connect_submit=Conectar @@ -1379,8 +1378,6 @@ issues.filter_project=Projeto issues.filter_project_all=Todos os projetos issues.filter_project_none=Sem projeto issues.filter_assignee=Atribuído -issues.filter_assginee_no_select=Todos os responsáveis -issues.filter_assginee_no_assignee=Sem responsável issues.filter_poster=Autor issues.filter_type=Tipo issues.filter_type.all_issues=Todas as issues diff --git a/options/locale/locale_pt-PT.ini b/options/locale/locale_pt-PT.ini index 5b6672c266..8b4d66a718 100644 --- a/options/locale/locale_pt-PT.ini +++ b/options/locale/locale_pt-PT.ini @@ -457,7 +457,7 @@ oauth_signup_submit=Completar conta oauth_signin_tab=Vincular a uma conta existente oauth_signin_title=Inicie a sessão para autorizar a vinculação à conta oauth_signin_submit=Vincular conta -oauth.signin.error=Ocorreu um erro durante o processamento do pedido de autorização. Se este erro persistir, contacte o administrador. +oauth.signin.error.general=Ocorreu um erro durante o processamento do pedido de autorização: %s: Se este erro persistir, contacte o administrador. oauth.signin.error.access_denied=O pedido de autorização foi negado. oauth.signin.error.temporarily_unavailable=A autorização falhou porque o servidor de autenticação está temporariamente indisponível. Tente mais tarde. oauth_callback_unable_auto_reg=O registo automático está habilitado, mas o fornecedor OAuth2 %[1]s sinalizou campos em falta: %[2]s, por isso não foi possível criar uma conta automaticamente. Crie ou vincule uma conta ou contacte o administrador do sítio. @@ -1546,8 +1546,8 @@ issues.filter_project=Planeamento issues.filter_project_all=Todos os planeamentos issues.filter_project_none=Nenhum planeamento issues.filter_assignee=Encarregado -issues.filter_assginee_no_select=Todos os encarregados issues.filter_assginee_no_assignee=Sem encarregado +issues.filter_assignee_any_assignee=Atribuído a qualquer pessoa issues.filter_poster=Autor(a) issues.filter_user_placeholder=Procurar utilizadores issues.filter_user_no_select=Todos os utilizadores diff --git a/options/locale/locale_ru-RU.ini b/options/locale/locale_ru-RU.ini index 6b08ec9e5c..fe52165837 100644 --- a/options/locale/locale_ru-RU.ini +++ b/options/locale/locale_ru-RU.ini @@ -388,7 +388,6 @@ oauth_signup_submit=Полная учётная запись oauth_signin_tab=Ссылка на существующую учётную запись oauth_signin_title=Войдите, чтобы авторизовать связанную учётную запись oauth_signin_submit=Привязать учётную запись -oauth.signin.error=Произошла ошибка при обработке запроса авторизации. Если эта ошибка повторяется, обратитесь к администратору сайта. oauth.signin.error.access_denied=Запрос на авторизацию был отклонен. oauth.signin.error.temporarily_unavailable=Произошла ошибка авторизации, так как сервер аутентификации временно недоступен. Пожалуйста, повторите попытку позже. openid_connect_submit=Подключить @@ -1356,7 +1355,6 @@ issues.filter_project=Проект issues.filter_project_all=Все проекты issues.filter_project_none=Нет проекта issues.filter_assignee=Назначено -issues.filter_assginee_no_select=Все назначения issues.filter_assginee_no_assignee=Нет ответственного issues.filter_poster=Автор issues.filter_type=Тип diff --git a/options/locale/locale_si-LK.ini b/options/locale/locale_si-LK.ini index 0f5ae91e40..2cd7fb29b9 100644 --- a/options/locale/locale_si-LK.ini +++ b/options/locale/locale_si-LK.ini @@ -1025,7 +1025,6 @@ issues.filter_label_no_select=සියලු ලේබල issues.filter_milestone=සන්ධිස්ථානය issues.filter_project_none=ව්යාපෘති නැත issues.filter_assignee=අස්ගිනී -issues.filter_assginee_no_select=සියලුම ඇග්රි issues.filter_assginee_no_assignee=කිසිදු අස්වැද්දුමක් issues.filter_type=වර්ගය issues.filter_type.all_issues=සියලු ගැටළු diff --git a/options/locale/locale_sk-SK.ini b/options/locale/locale_sk-SK.ini index 53ea17b43e..20f26db801 100644 --- a/options/locale/locale_sk-SK.ini +++ b/options/locale/locale_sk-SK.ini @@ -377,7 +377,6 @@ oauth_signup_submit=Dokončiť účet oauth_signin_tab=Prepojiť s existujúcim účtom oauth_signin_title=Prihláste sa na overenie prepojeného účtu oauth_signin_submit=Prepojiť účet -oauth.signin.error=Vyskytla sa chyba počas spracovania vašej autorizačnej žiadosti. Ak chyba pretrváva, kontaktujte, prosím, správcu. oauth.signin.error.access_denied=Žiadosť o autorizáciu bola zamietnutá. oauth.signin.error.temporarily_unavailable=Autorizácia zlyhala, pretože overovací server je dočasne nedostupný. Skúste to prosím neskôr. openid_connect_submit=Pripojiť diff --git a/options/locale/locale_sv-SE.ini b/options/locale/locale_sv-SE.ini index d79d751ea3..dbe53aaadf 100644 --- a/options/locale/locale_sv-SE.ini +++ b/options/locale/locale_sv-SE.ini @@ -873,7 +873,6 @@ issues.filter_label_no_select=Alla etiketter issues.filter_milestone=Milsten issues.filter_project_none=Inget projekt issues.filter_assignee=Förvärvare -issues.filter_assginee_no_select=Alla tilldelade issues.filter_assginee_no_assignee=Ingen tilldelad issues.filter_type=Typ issues.filter_type.all_issues=Alla ärenden diff --git a/options/locale/locale_tr-TR.ini b/options/locale/locale_tr-TR.ini index d00cce5006..1a044fca83 100644 --- a/options/locale/locale_tr-TR.ini +++ b/options/locale/locale_tr-TR.ini @@ -441,7 +441,6 @@ oauth_signup_submit=Hesabı Tamamla oauth_signin_tab=Mevcut Hesaba Bağla oauth_signin_title=Bağlantılı Hesabı Yetkilendirmek için Giriş Yapın oauth_signin_submit=Hesabı Bağla -oauth.signin.error=Yetkilendirme isteğini işlerken bir hata oluştu. Eğer hata devam ederse lütfen site yöneticisiyle bağlantıya geçin. oauth.signin.error.access_denied=Yetkilendirme isteği reddedildi. oauth.signin.error.temporarily_unavailable=Yetkilendirme sunucusu geçici olarak erişilemez olduğu için yetkilendirme başarısız oldu. Lütfen daha sonra tekrar deneyin. oauth_callback_unable_auto_reg=Otomatik kayıt etkin ancak OAuth2 Sağlayıcı %[1] eksik sahalar döndürdü: %[2]s, otomatik olarak hesap oluşturulamıyor, lütfen bir hesap oluşturun veya bağlantı verin, veya site yöneticisiyle iletişim kurun. @@ -1485,7 +1484,6 @@ issues.filter_project=Proje issues.filter_project_all=Tüm projeler issues.filter_project_none=Proje yok issues.filter_assignee=Atanan -issues.filter_assginee_no_select=Tüm atananlar issues.filter_assginee_no_assignee=Atanan yok issues.filter_poster=Yazar issues.filter_type=Tür diff --git a/options/locale/locale_uk-UA.ini b/options/locale/locale_uk-UA.ini index 3b3017a127..8c8911ceb6 100644 --- a/options/locale/locale_uk-UA.ini +++ b/options/locale/locale_uk-UA.ini @@ -1071,7 +1071,6 @@ issues.filter_milestone=Етап issues.filter_project=Проєкт issues.filter_project_none=Проєкт відсутній issues.filter_assignee=Виконавець -issues.filter_assginee_no_select=Всі виконавці issues.filter_assginee_no_assignee=Немає виконавця issues.filter_type=Тип issues.filter_type.all_issues=Всі задачі diff --git a/options/locale/locale_zh-CN.ini b/options/locale/locale_zh-CN.ini index d6ef36dede..f36789921e 100644 --- a/options/locale/locale_zh-CN.ini +++ b/options/locale/locale_zh-CN.ini @@ -446,7 +446,6 @@ oauth_signup_submit=完成账号 oauth_signin_tab=绑定到现有帐号 oauth_signin_title=登录以授权绑定帐户 oauth_signin_submit=绑定账号 -oauth.signin.error=处理授权请求时出错。 如果此错误仍然存在,请联系站点管理员。 oauth.signin.error.access_denied=授权请求被拒绝。 oauth.signin.error.temporarily_unavailable=授权失败,因为认证服务器暂时不可用。请稍后再试。 oauth_callback_unable_auto_reg=自动注册已启用,但OAuth2 提供商 %[1]s 返回缺失的字段:%[2]s,无法自动创建帐户,请创建或链接到一个帐户,或联系站点管理员。 @@ -1525,8 +1524,6 @@ issues.filter_project=项目 issues.filter_project_all=所有项目 issues.filter_project_none=暂无项目 issues.filter_assignee=指派人筛选 -issues.filter_assginee_no_select=所有指派成员 -issues.filter_assginee_no_assignee=未指派 issues.filter_poster=作者 issues.filter_user_placeholder=搜索用户 issues.filter_user_no_select=所有用户 diff --git a/options/locale/locale_zh-TW.ini b/options/locale/locale_zh-TW.ini index 8b6dc3afcb..10d6676ac5 100644 --- a/options/locale/locale_zh-TW.ini +++ b/options/locale/locale_zh-TW.ini @@ -444,7 +444,6 @@ oauth_signup_submit=完成帳戶 oauth_signin_tab=連結到現有帳戶 oauth_signin_title=登入以授權連結帳戶 oauth_signin_submit=連結帳戶 -oauth.signin.error=處理授權請求時發生錯誤。如果這個問題持續發生,請聯絡網站管理員。 oauth.signin.error.access_denied=授權請求被拒絕。 oauth.signin.error.temporarily_unavailable=授權失敗,因為認證伺服器暫時無法使用。請稍後再試。 oauth_callback_unable_auto_reg=自助註冊已啟用,但是 OAuth2 提供者 %[1]s 回傳的結果缺少欄位:%[2]s,導致無法自動建立帳號。請建立新帳號或是連結至既存的帳號,或是聯絡網站管理者。 @@ -1518,8 +1517,6 @@ issues.filter_project=專案 issues.filter_project_all=所有專案 issues.filter_project_none=未選擇專案 issues.filter_assignee=負責人 -issues.filter_assginee_no_select=所有負責人 -issues.filter_assginee_no_assignee=沒有負責人 issues.filter_poster=作者 issues.filter_user_placeholder=搜尋使用者 issues.filter_user_no_select=所有使用者 diff --git a/routers/private/hook_post_receive.go b/routers/private/hook_post_receive.go index dba6aef9a3..442d0a76c9 100644 --- a/routers/private/hook_post_receive.go +++ b/routers/private/hook_post_receive.go @@ -303,14 +303,11 @@ func HookPostReceive(ctx *gitea_context.PrivateContext) { } if pr == nil { - if repo.IsFork { - branch = fmt.Sprintf("%s:%s", repo.OwnerName, branch) - } results = append(results, private.HookPostReceiveBranchResult{ Message: setting.Git.PullRequestPushMessage && baseRepo.AllowsPulls(ctx), Create: true, Branch: branch, - URL: fmt.Sprintf("%s/compare/%s...%s", baseRepo.HTMLURL(), util.PathEscapeSegments(baseRepo.DefaultBranch), util.PathEscapeSegments(branch)), + URL: fmt.Sprintf("%s/pulls/new/%s", repo.HTMLURL(), util.PathEscapeSegments(branch)), }) } else { results = append(results, private.HookPostReceiveBranchResult{ diff --git a/routers/web/admin/users.go b/routers/web/admin/users.go index f6a3af1c86..e42cbb316c 100644 --- a/routers/web/admin/users.go +++ b/routers/web/admin/users.go @@ -22,7 +22,6 @@ import ( "code.gitea.io/gitea/modules/optional" "code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/templates" - "code.gitea.io/gitea/modules/util" "code.gitea.io/gitea/modules/web" "code.gitea.io/gitea/routers/web/explore" user_setting "code.gitea.io/gitea/routers/web/user/setting" @@ -72,11 +71,11 @@ func Users(ctx *context.Context) { PageSize: setting.UI.Admin.UserPagingNum, }, SearchByEmail: true, - IsActive: util.OptionalBoolParse(statusFilterMap["is_active"]), - IsAdmin: util.OptionalBoolParse(statusFilterMap["is_admin"]), - IsRestricted: util.OptionalBoolParse(statusFilterMap["is_restricted"]), - IsTwoFactorEnabled: util.OptionalBoolParse(statusFilterMap["is_2fa_enabled"]), - IsProhibitLogin: util.OptionalBoolParse(statusFilterMap["is_prohibit_login"]), + IsActive: optional.ParseBool(statusFilterMap["is_active"]), + IsAdmin: optional.ParseBool(statusFilterMap["is_admin"]), + IsRestricted: optional.ParseBool(statusFilterMap["is_restricted"]), + IsTwoFactorEnabled: optional.ParseBool(statusFilterMap["is_2fa_enabled"]), + IsProhibitLogin: optional.ParseBool(statusFilterMap["is_prohibit_login"]), IncludeReserved: true, // administrator needs to list all accounts include reserved, bot, remote ones }, tplUsers) } diff --git a/routers/web/auth/auth_test.go b/routers/web/auth/auth_test.go index cbcb2a5222..e238125407 100644 --- a/routers/web/auth/auth_test.go +++ b/routers/web/auth/auth_test.go @@ -61,23 +61,35 @@ func TestUserLogin(t *testing.T) { assert.Equal(t, "/", test.RedirectURL(resp)) } -func TestSignUpOAuth2ButMissingFields(t *testing.T) { +func TestSignUpOAuth2Login(t *testing.T) { defer test.MockVariableValue(&setting.OAuth2Client.EnableAutoRegistration, true)() - defer test.MockVariableValue(&gothic.CompleteUserAuth, func(res http.ResponseWriter, req *http.Request) (goth.User, error) { - return goth.User{Provider: "dummy-auth-source", UserID: "dummy-user"}, nil - })() addOAuth2Source(t, "dummy-auth-source", oauth2.Source{}) - mockOpt := contexttest.MockContextOption{SessionStore: session.NewMockStore("dummy-sid")} - ctx, resp := contexttest.MockContext(t, "/user/oauth2/dummy-auth-source/callback?code=dummy-code", mockOpt) - ctx.SetPathParam("provider", "dummy-auth-source") - SignInOAuthCallback(ctx) - assert.Equal(t, http.StatusSeeOther, resp.Code) - assert.Equal(t, "/user/link_account", test.RedirectURL(resp)) + t.Run("OAuth2MissingField", func(t *testing.T) { + defer test.MockVariableValue(&gothic.CompleteUserAuth, func(res http.ResponseWriter, req *http.Request) (goth.User, error) { + return goth.User{Provider: "dummy-auth-source", UserID: "dummy-user"}, nil + })() + mockOpt := contexttest.MockContextOption{SessionStore: session.NewMockStore("dummy-sid")} + ctx, resp := contexttest.MockContext(t, "/user/oauth2/dummy-auth-source/callback?code=dummy-code", mockOpt) + ctx.SetPathParam("provider", "dummy-auth-source") + SignInOAuthCallback(ctx) + assert.Equal(t, http.StatusSeeOther, resp.Code) + assert.Equal(t, "/user/link_account", test.RedirectURL(resp)) + + // then the user will be redirected to the link account page, and see a message about the missing fields + ctx, _ = contexttest.MockContext(t, "/user/link_account", mockOpt) + LinkAccount(ctx) + assert.EqualValues(t, "auth.oauth_callback_unable_auto_reg:dummy-auth-source,email", ctx.Data["AutoRegistrationFailedPrompt"]) + }) - // then the user will be redirected to the link account page, and see a message about the missing fields - ctx, _ = contexttest.MockContext(t, "/user/link_account", mockOpt) - LinkAccount(ctx) - assert.EqualValues(t, "auth.oauth_callback_unable_auto_reg:dummy-auth-source,email", ctx.Data["AutoRegistrationFailedPrompt"]) + t.Run("OAuth2CallbackError", func(t *testing.T) { + mockOpt := contexttest.MockContextOption{SessionStore: session.NewMockStore("dummy-sid")} + ctx, resp := contexttest.MockContext(t, "/user/oauth2/dummy-auth-source/callback", mockOpt) + ctx.SetPathParam("provider", "dummy-auth-source") + SignInOAuthCallback(ctx) + assert.Equal(t, http.StatusSeeOther, resp.Code) + assert.Equal(t, "/user/login", test.RedirectURL(resp)) + assert.Contains(t, ctx.Flash.ErrorMsg, "auth.oauth.signin.error.general") + }) } diff --git a/routers/web/auth/oauth.go b/routers/web/auth/oauth.go index 7a9721cf56..277f8bed31 100644 --- a/routers/web/auth/oauth.go +++ b/routers/web/auth/oauth.go @@ -115,7 +115,7 @@ func SignInOAuthCallback(ctx *context.Context) { case "temporarily_unavailable": ctx.Flash.Error(ctx.Tr("auth.oauth.signin.error.temporarily_unavailable")) default: - ctx.Flash.Error(ctx.Tr("auth.oauth.signin.error")) + ctx.Flash.Error(ctx.Tr("auth.oauth.signin.error.general", callbackErr.Description)) } ctx.Redirect(setting.AppSubURL + "/user/login") return @@ -431,8 +431,10 @@ func oAuth2UserLoginCallback(ctx *context.Context, authSource *auth.Source, requ gothUser, err := oauth2Source.Callback(request, response) if err != nil { if err.Error() == "securecookie: the value is too long" || strings.Contains(err.Error(), "Data too long") { - log.Error("OAuth2 Provider %s returned too long a token. Current max: %d. Either increase the [OAuth2] MAX_TOKEN_LENGTH or reduce the information returned from the OAuth2 provider", authSource.Name, setting.OAuth2.MaxTokenLength) err = fmt.Errorf("OAuth2 Provider %s returned too long a token. Current max: %d. Either increase the [OAuth2] MAX_TOKEN_LENGTH or reduce the information returned from the OAuth2 provider", authSource.Name, setting.OAuth2.MaxTokenLength) + log.Error("oauth2Source.Callback failed: %v", err) + } else { + err = errCallback{Code: "internal", Description: err.Error()} } return nil, goth.User{}, err } diff --git a/routers/web/repo/compare.go b/routers/web/repo/compare.go index 3e9cdb5df8..4d4969fa87 100644 --- a/routers/web/repo/compare.go +++ b/routers/web/repo/compare.go @@ -569,19 +569,13 @@ func PrepareCompareDiff( ctx *context.Context, ci *common.CompareInfo, whitespaceBehavior git.TrustedCmdArgs, -) bool { - var ( - repo = ctx.Repo.Repository - err error - title string - ) - - // Get diff information. - ctx.Data["CommitRepoLink"] = ci.HeadRepo.Link() - +) (nothingToCompare bool) { + repo := ctx.Repo.Repository headCommitID := ci.CompareInfo.HeadCommitID + ctx.Data["CommitRepoLink"] = ci.HeadRepo.Link() ctx.Data["AfterCommitID"] = headCommitID + ctx.Data["ExpandNewPrForm"] = ctx.FormBool("expand") if (headCommitID == ci.CompareInfo.MergeBase && !ci.DirectComparison) || headCommitID == ci.CompareInfo.BaseCommitID { @@ -670,6 +664,7 @@ func PrepareCompareDiff( ctx.Data["Commits"] = commits ctx.Data["CommitCount"] = len(commits) + title := ci.HeadBranch if len(commits) == 1 { c := commits[0] title = strings.TrimSpace(c.UserCommit.Summary()) @@ -678,9 +673,8 @@ func PrepareCompareDiff( if len(body) > 1 { ctx.Data["content"] = strings.Join(body[1:], "\n") } - } else { - title = ci.HeadBranch } + if len(title) > 255 { var trailer string title, trailer = util.EllipsisDisplayStringX(title, 255) @@ -745,8 +739,7 @@ func CompareDiff(ctx *context.Context) { ctx.Data["OtherCompareSeparator"] = "..." } - nothingToCompare := PrepareCompareDiff(ctx, ci, - gitdiff.GetWhitespaceFlag(ctx.Data["WhitespaceBehavior"].(string))) + nothingToCompare := PrepareCompareDiff(ctx, ci, gitdiff.GetWhitespaceFlag(ctx.Data["WhitespaceBehavior"].(string))) if ctx.Written() { return } diff --git a/routers/web/repo/pull.go b/routers/web/repo/pull.go index e12798f93d..c72664f8e9 100644 --- a/routers/web/repo/pull.go +++ b/routers/web/repo/pull.go @@ -1269,6 +1269,21 @@ func stopTimerIfAvailable(ctx *context.Context, user *user_model.User, issue *is return nil } +func PullsNewRedirect(ctx *context.Context) { + branch := ctx.PathParam("*") + redirectRepo := ctx.Repo.Repository + repo := ctx.Repo.Repository + if repo.IsFork { + if err := repo.GetBaseRepo(ctx); err != nil { + ctx.ServerError("GetBaseRepo", err) + return + } + redirectRepo = repo.BaseRepo + branch = fmt.Sprintf("%s:%s", repo.OwnerName, branch) + } + ctx.Redirect(fmt.Sprintf("%s/compare/%s...%s?expand=1", redirectRepo.Link(), util.PathEscapeSegments(redirectRepo.DefaultBranch), util.PathEscapeSegments(branch))) +} + // CompareAndPullRequestPost response for creating pull request func CompareAndPullRequestPost(ctx *context.Context) { form := web.GetForm(ctx).(*forms.CreateIssueForm) diff --git a/routers/web/user/home.go b/routers/web/user/home.go index 864a2831d1..44e2a5ec71 100644 --- a/routers/web/user/home.go +++ b/routers/web/user/home.go @@ -137,11 +137,10 @@ func Dashboard(ctx *context.Context) { return } - ctx.Data["Feeds"] = feeds - - pager := context.NewPagination(int(count), setting.UI.FeedPagingNum, page, 5) + pager := context.NewPagination(count, setting.UI.FeedPagingNum, page, 5).WithCurRows(len(feeds)) pager.AddParamFromRequest(ctx.Req) ctx.Data["Page"] = pager + ctx.Data["Feeds"] = feeds ctx.HTML(http.StatusOK, tplDashboard) } diff --git a/routers/web/web.go b/routers/web/web.go index f4bd3ef4bc..463f486250 100644 --- a/routers/web/web.go +++ b/routers/web/web.go @@ -1185,6 +1185,7 @@ func registerRoutes(m *web.Router) { m.Combo("/compare/*", repo.MustBeNotEmpty, repo.SetEditorconfigIfExists). Get(repo.SetDiffViewStyle, repo.SetWhitespaceBehavior, repo.CompareDiff). Post(reqSignIn, context.RepoMustNotBeArchived(), reqUnitPullsReader, repo.MustAllowPulls, web.Bind(forms.CreateIssueForm{}), repo.SetWhitespaceBehavior, repo.CompareAndPullRequestPost) + m.Get("/pulls/new/*", repo.PullsNewRedirect) }, optSignIn, context.RepoAssignment, reqUnitCodeReader) // end "/{username}/{reponame}": repo code: find, compare, list diff --git a/services/context/pagination.go b/services/context/pagination.go index d33dd217d0..25a9298e01 100644 --- a/services/context/pagination.go +++ b/services/context/pagination.go @@ -21,12 +21,18 @@ type Pagination struct { // NewPagination creates a new instance of the Pagination struct. // "pagingNum" is "page size" or "limit", "current" is "page" +// total=-1 means only showing prev/next func NewPagination(total, pagingNum, current, numPages int) *Pagination { p := &Pagination{} p.Paginater = paginator.New(total, pagingNum, current, numPages) return p } +func (p *Pagination) WithCurRows(n int) *Pagination { + p.Paginater.SetCurRows(n) + return p +} + func (p *Pagination) AddParamFromRequest(req *http.Request) { for key, values := range req.URL.Query() { if key == "page" || len(values) == 0 || (len(values) == 1 && values[0] == "") { diff --git a/services/feed/feed.go b/services/feed/feed.go index 41a918f00e..214e9b5765 100644 --- a/services/feed/feed.go +++ b/services/feed/feed.go @@ -15,24 +15,17 @@ import ( user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/cache" "code.gitea.io/gitea/modules/setting" + "code.gitea.io/gitea/modules/util" ) func userFeedCacheKey(userID int64) string { return fmt.Sprintf("user_feed_%d", userID) } -func GetFeedsForDashboard(ctx context.Context, opts activities_model.GetFeedsOptions) (activities_model.ActionList, int64, error) { +func GetFeedsForDashboard(ctx context.Context, opts activities_model.GetFeedsOptions) (activities_model.ActionList, int, error) { opts.DontCount = opts.RequestedTeam == nil && opts.Date == "" results, cnt, err := activities_model.GetFeeds(ctx, opts) - if err != nil { - return nil, 0, err - } - if opts.DontCount { - cnt, err = cache.GetInt64(userFeedCacheKey(opts.Actor.ID), func() (int64, error) { - return activities_model.CountUserFeeds(ctx, opts.Actor.ID) - }) - } - return results, cnt, err + return results, util.Iif(opts.DontCount, -1, int(cnt)), err } // GetFeeds returns actions according to the provided options diff --git a/templates/base/paginate.tmpl b/templates/base/paginate.tmpl index 253892c009..f6c1785ccf 100644 --- a/templates/base/paginate.tmpl +++ b/templates/base/paginate.tmpl @@ -2,32 +2,42 @@ {{$paginationLink := $.Link}} {{if eq $paginationLink AppSubUrl}}{{$paginationLink = print $paginationLink "/"}}{{end}} {{with .Page.Paginater}} - {{if gt .TotalPages 1}} + {{if or (eq .TotalPages -1) (gt .TotalPages 1)}} + {{$showFirstLast := gt .TotalPages 1}} <div class="center page buttons"> <div class="ui borderless pagination menu"> + {{if $showFirstLast}} <a class="{{if .IsFirst}}disabled{{end}} item navigation" {{if not .IsFirst}}href="{{$paginationLink}}{{if $paginationParams}}?{{$paginationParams}}{{end}}"{{end}}> {{svg "gitea-double-chevron-left" 16 "tw-mr-1"}} <span class="navigation_label">{{ctx.Locale.Tr "admin.first_page"}}</span> </a> + {{end}} + <a class="{{if not .HasPrevious}}disabled{{end}} item navigation" {{if .HasPrevious}}href="{{$paginationLink}}?page={{.Previous}}{{if $paginationParams}}&{{$paginationParams}}{{end}}"{{end}}> {{svg "octicon-chevron-left" 16 "tw-mr-1"}} <span class="navigation_label">{{ctx.Locale.Tr "repo.issues.previous"}}</span> </a> - {{range .Pages}} + {{$pages := .Pages}} + {{$pagesLen := len $pages}} + {{range $pages}} {{if eq .Num -1}} <a class="disabled item">...</a> {{else}} - <a class="{{if .IsCurrent}}active {{end}}item" {{if not .IsCurrent}}href="{{$paginationLink}}?page={{.Num}}{{if $paginationParams}}&{{$paginationParams}}{{end}}"{{end}}>{{.Num}}</a> + {{/* do not highlight the current page if there is only one page */}} + <a class="{{if and .IsCurrent (gt $pagesLen 1)}}active {{end}}item" {{if not .IsCurrent}}href="{{$paginationLink}}?page={{.Num}}{{if $paginationParams}}&{{$paginationParams}}{{end}}"{{end}}>{{.Num}}</a> {{end}} {{end}} <a class="{{if not .HasNext}}disabled{{end}} item navigation" {{if .HasNext}}href="{{$paginationLink}}?page={{.Next}}{{if $paginationParams}}&{{$paginationParams}}{{end}}"{{end}}> <span class="navigation_label">{{ctx.Locale.Tr "repo.issues.next"}}</span> {{svg "octicon-chevron-right" 16 "tw-ml-1"}} </a> + + {{if $showFirstLast}} <a class="{{if .IsLast}}disabled{{end}} item navigation" {{if not .IsLast}}href="{{$paginationLink}}?page={{.TotalPages}}{{if $paginationParams}}&{{$paginationParams}}{{end}}"{{end}}> <span class="navigation_label">{{ctx.Locale.Tr "admin.last_page"}}</span> {{svg "gitea-double-chevron-right" 16 "tw-ml-1"}} </a> + {{end}} </div> </div> {{end}} diff --git a/templates/repo/branch/list.tmpl b/templates/repo/branch/list.tmpl index f4f3c2e5c5..c0accf16fa 100644 --- a/templates/repo/branch/list.tmpl +++ b/templates/repo/branch/list.tmpl @@ -128,13 +128,13 @@ {{svg "octicon-git-pull-request"}} {{ctx.Locale.Tr "repo.branch.included"}} </span> {{else if and (not .DBBranch.IsDeleted) $.AllowsPulls (gt .CommitsAhead 0)}} - <a href="{{$.RepoLink}}/compare/{{PathEscapeSegments $.DefaultBranchBranch.DBBranch.Name}}...{{if ne $.Repository.Owner.Name $.Owner.Name}}{{PathEscape $.Owner.Name}}:{{end}}{{PathEscapeSegments .DBBranch.Name}}"> + <a href="{{$.RepoLink}}/compare/{{PathEscapeSegments $.DefaultBranchBranch.DBBranch.Name}}...{{if ne $.Repository.Owner.Name $.Owner.Name}}{{PathEscape $.Owner.Name}}:{{end}}{{PathEscapeSegments .DBBranch.Name}}?expand=1"> <button id="new-pull-request" class="ui compact basic button tw-mr-0">{{if $.CanPull}}{{ctx.Locale.Tr "repo.pulls.compare_changes"}}{{else}}{{ctx.Locale.Tr "action.compare_branch"}}{{end}}</button> </a> {{end}} {{else if and .LatestPullRequest.HasMerged .MergeMovedOn}} {{if and (not .DBBranch.IsDeleted) $.AllowsPulls (gt .CommitsAhead 0)}} - <a href="{{$.RepoLink}}/compare/{{PathEscapeSegments $.DefaultBranchBranch.DBBranch.Name}}...{{if ne $.Repository.Owner.Name $.Owner.Name}}{{PathEscape $.Owner.Name}}:{{end}}{{PathEscapeSegments .DBBranch.Name}}"> + <a href="{{$.RepoLink}}/compare/{{PathEscapeSegments $.DefaultBranchBranch.DBBranch.Name}}...{{if ne $.Repository.Owner.Name $.Owner.Name}}{{PathEscape $.Owner.Name}}:{{end}}{{PathEscapeSegments .DBBranch.Name}}?expand=1"> <button id="new-pull-request" class="ui compact basic button tw-mr-0">{{if $.CanPull}}{{ctx.Locale.Tr "repo.pulls.compare_changes"}}{{else}}{{ctx.Locale.Tr "action.compare_branch"}}{{end}}</button> </a> {{end}} diff --git a/templates/repo/code/recently_pushed_new_branches.tmpl b/templates/repo/code/recently_pushed_new_branches.tmpl index f0edf6065b..4a864ba756 100644 --- a/templates/repo/code/recently_pushed_new_branches.tmpl +++ b/templates/repo/code/recently_pushed_new_branches.tmpl @@ -5,7 +5,7 @@ {{$branchLink := HTMLFormat `<a href="%s">%s</a>` .BranchLink .BranchDisplayName}} {{ctx.Locale.Tr "repo.pulls.recently_pushed_new_branches" $branchLink $timeSince}} </div> - <a role="button" class="ui compact green button tw-m-0" href="{{.BranchCompareURL}}"> + <a role="button" class="ui compact green button tw-m-0" href="{{QueryBuild .BranchCompareURL "expand" 1}}"> {{ctx.Locale.Tr "repo.pulls.compare_changes"}} </a> </div> diff --git a/templates/repo/diff/compare.tmpl b/templates/repo/diff/compare.tmpl index 9a7a04a328..05cfffd2b7 100644 --- a/templates/repo/diff/compare.tmpl +++ b/templates/repo/diff/compare.tmpl @@ -205,10 +205,10 @@ {{end}} </div> {{else if $allowCreatePR}} - <div class="ui info message pullrequest-form-toggle {{if .Flash}}tw-hidden{{end}}"> + <div class="ui info message pullrequest-form-toggle {{if .ExpandNewPrForm}}tw-hidden{{end}}"> <button class="ui button primary show-panel toggle" data-panel=".pullrequest-form-toggle, .pullrequest-form">{{ctx.Locale.Tr "repo.pulls.new"}}</button> </div> - <div class="pullrequest-form {{if not .Flash}}tw-hidden{{end}}"> + <div class="pullrequest-form {{if not .ExpandNewPrForm}}tw-hidden{{end}}"> {{template "repo/issue/new_form" .}} </div> {{end}} diff --git a/templates/repo/view_content.tmpl b/templates/repo/view_content.tmpl index 06e9f8515c..292a2f878c 100644 --- a/templates/repo/view_content.tmpl +++ b/templates/repo/view_content.tmpl @@ -30,7 +30,7 @@ {{end}} {{$cmpBranch = print $cmpBranch (.BranchName|PathEscapeSegments)}} {{$compareLink := printf "%s/compare/%s...%s" .BaseRepo.Link (.BaseRepo.DefaultBranch|PathEscapeSegments) $cmpBranch}} - <a id="new-pull-request" role="button" class="ui compact basic button" href="{{$compareLink}}" + <a id="new-pull-request" role="button" class="ui compact basic button" href="{{QueryBuild $compareLink "expand" 1}}" data-tooltip-content="{{if .PullRequestCtx.Allowed}}{{ctx.Locale.Tr "repo.pulls.compare_changes"}}{{else}}{{ctx.Locale.Tr "action.compare_branch"}}{{end}}"> {{svg "octicon-git-pull-request"}} </a> diff --git a/templates/user/dashboard/dashboard.tmpl b/templates/user/dashboard/dashboard.tmpl index 3ce3c1eb73..666dd78073 100644 --- a/templates/user/dashboard/dashboard.tmpl +++ b/templates/user/dashboard/dashboard.tmpl @@ -5,7 +5,7 @@ <div class="flex-container-main"> {{template "base/alert" .}} {{template "user/heatmap" .}} - {{if .Feeds}} + {{if .Page.Paginater.TotalPages}} {{template "user/dashboard/feeds" .}} {{else}} {{template "user/dashboard/guide" .}} diff --git a/tests/integration/oauth_test.go b/tests/integration/oauth_test.go index d7ef103506..d2228bae79 100644 --- a/tests/integration/oauth_test.go +++ b/tests/integration/oauth_test.go @@ -19,7 +19,7 @@ import ( "code.gitea.io/gitea/modules/json" "code.gitea.io/gitea/modules/setting" api "code.gitea.io/gitea/modules/structs" - oauth2_provider "code.gitea.io/gitea/services/oauth2_provider" + "code.gitea.io/gitea/services/oauth2_provider" "code.gitea.io/gitea/tests" "github.com/stretchr/testify/assert" diff --git a/tests/integration/pull_compare_test.go b/tests/integration/pull_compare_test.go index 106774aa54..4ac5be18be 100644 --- a/tests/integration/pull_compare_test.go +++ b/tests/integration/pull_compare_test.go @@ -24,23 +24,38 @@ import ( func TestPullCompare(t *testing.T) { defer tests.PrepareTestEnv(t)() - session := loginUser(t, "user2") - req := NewRequest(t, "GET", "/user2/repo1/pulls") - resp := session.MakeRequest(t, req, http.StatusOK) - htmlDoc := NewHTMLParser(t, resp.Body) - link, exists := htmlDoc.doc.Find(".new-pr-button").Attr("href") - assert.True(t, exists, "The template has changed") - - req = NewRequest(t, "GET", link) - resp = session.MakeRequest(t, req, http.StatusOK) - assert.EqualValues(t, http.StatusOK, resp.Code) - - // test the edit button in the PR diff view - req = NewRequest(t, "GET", "/user2/repo1/pulls/3/files") - resp = session.MakeRequest(t, req, http.StatusOK) - doc := NewHTMLParser(t, resp.Body) - editButtonCount := doc.doc.Find(".diff-file-header-actions a[href*='/_edit/']").Length() - assert.Positive(t, editButtonCount, "Expected to find a button to edit a file in the PR diff view but there were none") + t.Run("PullsNewRedirect", func(t *testing.T) { + req := NewRequest(t, "GET", "/user2/repo1/pulls/new/foo") + resp := MakeRequest(t, req, http.StatusSeeOther) + redirect := test.RedirectURL(resp) + assert.Equal(t, "/user2/repo1/compare/master...foo?expand=1", redirect) + + req = NewRequest(t, "GET", "/user13/repo11/pulls/new/foo") + resp = MakeRequest(t, req, http.StatusSeeOther) + redirect = test.RedirectURL(resp) + assert.Equal(t, "/user12/repo10/compare/master...user13:foo?expand=1", redirect) + }) + + t.Run("ButtonsExist", func(t *testing.T) { + session := loginUser(t, "user2") + + // test the "New PR" button + req := NewRequest(t, "GET", "/user2/repo1/pulls") + resp := session.MakeRequest(t, req, http.StatusOK) + htmlDoc := NewHTMLParser(t, resp.Body) + link, exists := htmlDoc.doc.Find(".new-pr-button").Attr("href") + assert.True(t, exists, "The template has changed") + req = NewRequest(t, "GET", link) + resp = session.MakeRequest(t, req, http.StatusOK) + assert.EqualValues(t, http.StatusOK, resp.Code) + + // test the edit button in the PR diff view + req = NewRequest(t, "GET", "/user2/repo1/pulls/3/files") + resp = session.MakeRequest(t, req, http.StatusOK) + doc := NewHTMLParser(t, resp.Body) + editButtonCount := doc.doc.Find(".diff-file-header-actions a[href*='/_edit/']").Length() + assert.Positive(t, editButtonCount, "Expected to find a button to edit a file in the PR diff view but there were none") + }) onGiteaRun(t, func(t *testing.T, u *url.URL) { defer tests.PrepareTestEnv(t)() @@ -54,8 +69,8 @@ func TestPullCompare(t *testing.T) { repo1 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{OwnerName: "user2", Name: "repo1"}) issueIndex := unittest.AssertExistsAndLoadBean(t, &issues_model.IssueIndex{GroupID: repo1.ID}, unittest.OrderBy("group_id ASC")) prFilesURL := fmt.Sprintf("/user2/repo1/pulls/%d/files", issueIndex.MaxIndex) - req = NewRequest(t, "GET", prFilesURL) - resp = session.MakeRequest(t, req, http.StatusOK) + req := NewRequest(t, "GET", prFilesURL) + resp := session.MakeRequest(t, req, http.StatusOK) doc := NewHTMLParser(t, resp.Body) editButtonCount := doc.doc.Find(".diff-file-header-actions a[href*='/_edit/']").Length() assert.Positive(t, editButtonCount, "Expected to find a button to edit a file in the PR diff view but there were none") |