Merge branch 'main' into lunny/glob_protected_branch_rule
This commit is contained in:
commit
6f39f75985
15 changed files with 197 additions and 18 deletions
|
@ -171,3 +171,7 @@ issues:
|
||||||
- path: models/user/openid.go
|
- path: models/user/openid.go
|
||||||
linters:
|
linters:
|
||||||
- golint
|
- golint
|
||||||
|
- path: models/user/badge.go
|
||||||
|
linters:
|
||||||
|
- revive
|
||||||
|
text: "exported: type name will be used as user.UserBadge by other packages, and that stutters; consider calling this Badge"
|
||||||
|
|
|
@ -23,7 +23,7 @@ Gitea 在其 Docker Hub 组织内提供自动更新的 Docker 镜像。可以始
|
||||||
|
|
||||||
## 基本
|
## 基本
|
||||||
|
|
||||||
最简单的设置只是创建一个卷和一个网络,然后将 `gitea/gitea:latest` 镜像作为服务启动。由于没有可用的数据库,因此可以使用 SQLite3 初始化数据库。创建一个类似 `gitea` 的目录,并将以下内容粘贴到名为 `docker-compose.yml` 的文件中。请注意,该卷应由配置文件中指定的 UID/GID 的用户/组拥有。如果您不授予卷正确的权限,则容器可能无法启动。另请注意,标签 `:latest` 将安装当前的开发版本。对于稳定的发行版,您可以使用 `:1` 或指定某个发行版,例如 `:1.13.0`。
|
最简单的设置只是创建一个卷和一个网络,然后将 `gitea/gitea:latest` 镜像作为服务启动。由于没有可用的数据库,因此可以使用 SQLite3 初始化数据库。创建一个类似 `gitea` 的目录,并将以下内容粘贴到名为 `docker-compose.yml` 的文件中。请注意,该卷应由配置文件中指定的 UID/GID 的用户/组拥有。如果您不授予卷正确的权限,则容器可能无法启动。另请注意,标签 `:latest` 将安装当前的开发版本。对于稳定的发行版,您可以使用 `:1` 或指定某个发行版,例如 `{{< version >}}`。
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
version: "3"
|
version: "3"
|
||||||
|
@ -103,11 +103,11 @@ services:
|
||||||
environment:
|
environment:
|
||||||
- USER_UID=1000
|
- USER_UID=1000
|
||||||
- USER_GID=1000
|
- USER_GID=1000
|
||||||
+ - DB_TYPE=mysql
|
+ - GITEA__database__DB_TYPE=mysql
|
||||||
+ - DB_HOST=db:3306
|
+ - GITEA__database__HOST=db:3306
|
||||||
+ - DB_NAME=gitea
|
+ - GITEA__database__NAME=gitea
|
||||||
+ - DB_USER=gitea
|
+ - GITEA__database__USER=gitea
|
||||||
+ - DB_PASSWD=gitea
|
+ - GITEA__database__PASSWD=gitea
|
||||||
restart: always
|
restart: always
|
||||||
networks:
|
networks:
|
||||||
- gitea
|
- gitea
|
||||||
|
@ -153,11 +153,11 @@ services:
|
||||||
environment:
|
environment:
|
||||||
- USER_UID=1000
|
- USER_UID=1000
|
||||||
- USER_GID=1000
|
- USER_GID=1000
|
||||||
+ - DB_TYPE=postgres
|
+ - GITEA__database__DB_TYPE=postgres
|
||||||
+ - DB_HOST=db:5432
|
+ - GITEA__database__HOST=db:5432
|
||||||
+ - DB_NAME=gitea
|
+ - GITEA__database__NAME=gitea
|
||||||
+ - DB_USER=gitea
|
+ - GITEA__database__USER=gitea
|
||||||
+ - DB_PASSWD=gitea
|
+ - GITEA__database__PASSWD=gitea
|
||||||
restart: always
|
restart: always
|
||||||
networks:
|
networks:
|
||||||
- gitea
|
- gitea
|
||||||
|
@ -276,6 +276,42 @@ docker-compose pull
|
||||||
docker-compose up -d
|
docker-compose up -d
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## 使用环境变量管理部署
|
||||||
|
|
||||||
|
除了上面的环境变量之外,`app.ini` 中的任何设置都可以使用以下形式的环境变量进行设置或覆盖:`GITEA__SECTION_NAME__KEY_NAME`。 每次 docker 容器启动时都会应用这些设置。 完整信息在[这里](https://github.com/go-gitea/gitea/tree/master/contrib/environment-to-ini)。
|
||||||
|
|
||||||
|
```bash
|
||||||
|
...
|
||||||
|
services:
|
||||||
|
server:
|
||||||
|
environment:
|
||||||
|
- GITEA__mailer__ENABLED=true
|
||||||
|
- GITEA__mailer__FROM=${GITEA__mailer__FROM:?GITEA__mailer__FROM not set}
|
||||||
|
- GITEA__mailer__MAILER_TYPE=smtp
|
||||||
|
- GITEA__mailer__HOST=${GITEA__mailer__HOST:?GITEA__mailer__HOST not set}
|
||||||
|
- GITEA__mailer__IS_TLS_ENABLED=true
|
||||||
|
- GITEA__mailer__USER=${GITEA__mailer__USER:-apikey}
|
||||||
|
- GITEA__mailer__PASSWD="""${GITEA__mailer__PASSWD:?GITEA__mailer__PASSWD not set}"""
|
||||||
|
```
|
||||||
|
|
||||||
|
Gitea 将为每次新安装自动生成新的 `SECRET_KEY` 并将它们写入 `app.ini`。 如果您想手动设置 `SECRET_KEY`,您可以使用以下 docker 命令来使用 Gitea 内置的[方法](https://docs.gitea.io/en-us/command-line/#generate)生成 `SECRET_KEY`。 安装后请妥善保管您的 `SECRET_KEY`,如若丢失则无法解密已加密的数据。
|
||||||
|
|
||||||
|
以下命令将向 `stdout` 输出一个新的 `SECRET_KEY` 和 `INTERNAL_TOKEN`,然后您可以将其放入环境变量中。
|
||||||
|
|
||||||
|
```bash
|
||||||
|
docker run -it --rm gitea/gitea:1 gitea generate secret SECRET_KEY
|
||||||
|
docker run -it --rm gitea/gitea:1 gitea generate secret INTERNAL_TOKEN
|
||||||
|
```
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
...
|
||||||
|
services:
|
||||||
|
server:
|
||||||
|
environment:
|
||||||
|
- GITEA__security__SECRET_KEY=[value returned by generate secret SECRET_KEY]
|
||||||
|
- GITEA__security__INTERNAL_TOKEN=[value returned by generate secret INTERNAL_TOKEN]
|
||||||
|
```
|
||||||
|
|
||||||
## SSH 容器直通
|
## SSH 容器直通
|
||||||
|
|
||||||
由于 SSH 在容器内运行,因此,如果需要 SSH 支持,则需要将 SSH 从主机传递到容器。一种选择是在非标准端口上运行容器 SSH(或将主机端口移至非标准端口)。另一个可能更直接的选择是将 SSH 连接从主机转发到容器。下面将说明此设置。
|
由于 SSH 在容器内运行,因此,如果需要 SSH 支持,则需要将 SSH 从主机传递到容器。一种选择是在非标准端口上运行容器 SSH(或将主机端口移至非标准端口)。另一个可能更直接的选择是将 SSH 连接从主机转发到容器。下面将说明此设置。
|
||||||
|
|
|
@ -512,10 +512,14 @@ func GetActiveOAuth2ProviderSources() ([]*Source, error) {
|
||||||
func GetActiveOAuth2SourceByName(name string) (*Source, error) {
|
func GetActiveOAuth2SourceByName(name string) (*Source, error) {
|
||||||
authSource := new(Source)
|
authSource := new(Source)
|
||||||
has, err := db.GetEngine(db.DefaultContext).Where("name = ? and type = ? and is_active = ?", name, OAuth2, true).Get(authSource)
|
has, err := db.GetEngine(db.DefaultContext).Where("name = ? and type = ? and is_active = ?", name, OAuth2, true).Get(authSource)
|
||||||
if !has || err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if !has {
|
||||||
|
return nil, fmt.Errorf("oauth2 source not found, name: %q", name)
|
||||||
|
}
|
||||||
|
|
||||||
return authSource, nil
|
return authSource, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -406,6 +406,9 @@ var migrations = []Migration{
|
||||||
NewMigration("Drop old CredentialID column", dropOldCredentialIDColumn),
|
NewMigration("Drop old CredentialID column", dropOldCredentialIDColumn),
|
||||||
// v223 -> v224
|
// v223 -> v224
|
||||||
NewMigration("Rename CredentialIDBytes column to CredentialID", renameCredentialIDBytes),
|
NewMigration("Rename CredentialIDBytes column to CredentialID", renameCredentialIDBytes),
|
||||||
|
|
||||||
|
// v999
|
||||||
|
NewMigration("Add badges to users", creatUserBadgesTable),
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetCurrentDBVersion returns the current db version
|
// GetCurrentDBVersion returns the current db version
|
||||||
|
|
28
models/migrations/v999.go
Normal file
28
models/migrations/v999.go
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
// Copyright 2022 The Gitea Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a MIT-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package migrations
|
||||||
|
|
||||||
|
import (
|
||||||
|
"xorm.io/xorm"
|
||||||
|
)
|
||||||
|
|
||||||
|
func creatUserBadgesTable(x *xorm.Engine) error {
|
||||||
|
type Badge struct {
|
||||||
|
ID int64 `xorm:"pk autoincr"`
|
||||||
|
Description string
|
||||||
|
ImageURL string
|
||||||
|
}
|
||||||
|
|
||||||
|
type userBadge struct {
|
||||||
|
ID int64 `xorm:"pk autoincr"`
|
||||||
|
BadgeID int64
|
||||||
|
UserID int64 `xorm:"INDEX"`
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := x.Sync2(new(Badge)); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return x.Sync2(new(userBadge))
|
||||||
|
}
|
|
@ -153,8 +153,10 @@ func (repos MirrorRepositoryList) loadAttributes(ctx context.Context) error {
|
||||||
}
|
}
|
||||||
for i := range repos {
|
for i := range repos {
|
||||||
repos[i].Mirror = set[repos[i].ID]
|
repos[i].Mirror = set[repos[i].ID]
|
||||||
|
if repos[i].Mirror != nil {
|
||||||
repos[i].Mirror.Repo = repos[i]
|
repos[i].Mirror.Repo = repos[i]
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -85,6 +85,7 @@ func DeleteUser(ctx context.Context, u *user_model.User, purge bool) (err error)
|
||||||
&organization.TeamUser{UID: u.ID},
|
&organization.TeamUser{UID: u.ID},
|
||||||
&issues_model.Stopwatch{UserID: u.ID},
|
&issues_model.Stopwatch{UserID: u.ID},
|
||||||
&user_model.Setting{UserID: u.ID},
|
&user_model.Setting{UserID: u.ID},
|
||||||
|
&user_model.UserBadge{UserID: u.ID},
|
||||||
&pull_model.AutoMerge{DoerID: u.ID},
|
&pull_model.AutoMerge{DoerID: u.ID},
|
||||||
&pull_model.ReviewState{UserID: u.ID},
|
&pull_model.ReviewState{UserID: u.ID},
|
||||||
); err != nil {
|
); err != nil {
|
||||||
|
|
42
models/user/badge.go
Normal file
42
models/user/badge.go
Normal file
|
@ -0,0 +1,42 @@
|
||||||
|
// Copyright 2022 The Gitea Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a MIT-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package user
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
|
"code.gitea.io/gitea/models/db"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Badge represents a user badge
|
||||||
|
type Badge struct {
|
||||||
|
ID int64 `xorm:"pk autoincr"`
|
||||||
|
Description string
|
||||||
|
ImageURL string
|
||||||
|
}
|
||||||
|
|
||||||
|
// UserBadge represents a user badge
|
||||||
|
type UserBadge struct {
|
||||||
|
ID int64 `xorm:"pk autoincr"`
|
||||||
|
BadgeID int64
|
||||||
|
UserID int64 `xorm:"INDEX"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
db.RegisterModel(new(Badge))
|
||||||
|
db.RegisterModel(new(UserBadge))
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetUserBadges returns the user's badges.
|
||||||
|
func GetUserBadges(ctx context.Context, u *User) ([]*Badge, int64, error) {
|
||||||
|
sess := db.GetEngine(ctx).
|
||||||
|
Select("`badge`.*").
|
||||||
|
Join("INNER", "user_badge", "`user_badge`.badge_id=badge.id").
|
||||||
|
Where("user_badge.user_id=?", u.ID)
|
||||||
|
|
||||||
|
badges := make([]*Badge, 0, 8)
|
||||||
|
count, err := sess.FindAndCount(&badges)
|
||||||
|
return badges, count, err
|
||||||
|
}
|
|
@ -1031,6 +1031,7 @@ file_view_rendered=Ansicht rendern
|
||||||
file_view_raw=Originalformat anzeigen
|
file_view_raw=Originalformat anzeigen
|
||||||
file_permalink=Permalink
|
file_permalink=Permalink
|
||||||
file_too_large=Die Datei ist zu groß zum Anzeigen.
|
file_too_large=Die Datei ist zu groß zum Anzeigen.
|
||||||
|
ambiguous_character=`%[1]c [U+%04[1]X] kann mit %[2]c [U+%04[2]X] verwechselt werden`
|
||||||
|
|
||||||
escape_control_characters=Escapen
|
escape_control_characters=Escapen
|
||||||
unescape_control_characters=Unescapen
|
unescape_control_characters=Unescapen
|
||||||
|
@ -1051,6 +1052,7 @@ normal_view=Normale Ansicht
|
||||||
line=zeile
|
line=zeile
|
||||||
lines=Zeilen
|
lines=Zeilen
|
||||||
|
|
||||||
|
editor.add_file=Datei hinzufügen
|
||||||
editor.new_file=Neue Datei
|
editor.new_file=Neue Datei
|
||||||
editor.upload_file=Datei hochladen
|
editor.upload_file=Datei hochladen
|
||||||
editor.edit_file=Datei bearbeiten
|
editor.edit_file=Datei bearbeiten
|
||||||
|
@ -1256,6 +1258,8 @@ issues.filter_milestone=Meilenstein
|
||||||
issues.filter_milestone_no_select=Alle Meilensteine
|
issues.filter_milestone_no_select=Alle Meilensteine
|
||||||
issues.filter_assignee=Zuständig
|
issues.filter_assignee=Zuständig
|
||||||
issues.filter_assginee_no_select=Alle Zuständigen
|
issues.filter_assginee_no_select=Alle Zuständigen
|
||||||
|
issues.filter_poster=Autor
|
||||||
|
issues.filter_poster_no_select=Alle Autoren
|
||||||
issues.filter_type=Typ
|
issues.filter_type=Typ
|
||||||
issues.filter_type.all_issues=Alle Issues
|
issues.filter_type.all_issues=Alle Issues
|
||||||
issues.filter_type.assigned_to_you=Dir zugewiesen
|
issues.filter_type.assigned_to_you=Dir zugewiesen
|
||||||
|
@ -2782,7 +2786,9 @@ config.deliver_timeout=Zeitlimit für Zustellung
|
||||||
config.skip_tls_verify=TLS-Verifikation überspringen
|
config.skip_tls_verify=TLS-Verifikation überspringen
|
||||||
|
|
||||||
config.mailer_enabled=Aktiviert
|
config.mailer_enabled=Aktiviert
|
||||||
|
config.mailer_enable_helo=HELO aktivieren
|
||||||
config.mailer_name=Name
|
config.mailer_name=Name
|
||||||
|
config.mailer_protocol=Protokoll
|
||||||
config.mailer_user=Benutzer
|
config.mailer_user=Benutzer
|
||||||
config.mailer_use_sendmail=Sendmail benutzen
|
config.mailer_use_sendmail=Sendmail benutzen
|
||||||
config.mailer_sendmail_path=Sendmail-Pfad
|
config.mailer_sendmail_path=Sendmail-Pfad
|
||||||
|
@ -3089,6 +3095,7 @@ npm.dependencies.development=Entwicklungsabhängigkeiten
|
||||||
npm.dependencies.peer=Peer Abhängigkeiten
|
npm.dependencies.peer=Peer Abhängigkeiten
|
||||||
npm.dependencies.optional=Optionale Abhängigkeiten
|
npm.dependencies.optional=Optionale Abhängigkeiten
|
||||||
npm.details.tag=Tag
|
npm.details.tag=Tag
|
||||||
|
pub.install=Um das Paket mit Dart zu installieren, führe den folgenden Befehl aus:
|
||||||
pypi.requires=Erfordert Python
|
pypi.requires=Erfordert Python
|
||||||
pypi.install=Nutze folgenden Befehl, um das Paket mit pip zu installieren:
|
pypi.install=Nutze folgenden Befehl, um das Paket mit pip zu installieren:
|
||||||
pypi.documentation=Weitere Informationen zur PyPI-Paketverwaltung findest du in der <a target="_blank" rel="noopener noreferrer" href="https://docs.gitea.io/en-us/packages/pypi/">Dokumentation</a>.
|
pypi.documentation=Weitere Informationen zur PyPI-Paketverwaltung findest du in der <a target="_blank" rel="noopener noreferrer" href="https://docs.gitea.io/en-us/packages/pypi/">Dokumentation</a>.
|
||||||
|
|
|
@ -372,6 +372,7 @@ reset_password.text=Veuillez cliquer sur le lien suivant pour récupérer votre
|
||||||
|
|
||||||
register_success=Inscription réussie
|
register_success=Inscription réussie
|
||||||
|
|
||||||
|
issue_assigned.pull=@%[1]s vous a assigné à la demande d’ajout %[2]s dans le dépôt %[3]s.
|
||||||
issue_assigned.issue=@%[1]s vous a assigné le ticket %[2]s dans le dépôt %[3]s.
|
issue_assigned.issue=@%[1]s vous a assigné le ticket %[2]s dans le dépôt %[3]s.
|
||||||
|
|
||||||
issue.x_mentioned_you=<b>@%s</b> vous a mentionné:
|
issue.x_mentioned_you=<b>@%s</b> vous a mentionné:
|
||||||
|
@ -1418,6 +1419,7 @@ compare.compare_head=comparer
|
||||||
|
|
||||||
pulls.desc=Activer les demandes de fusion et la revue de code.
|
pulls.desc=Activer les demandes de fusion et la revue de code.
|
||||||
pulls.new=Nouvelle demande d'ajout
|
pulls.new=Nouvelle demande d'ajout
|
||||||
|
pulls.view=Voir la demande d'ajout
|
||||||
pulls.compare_changes=Nouvelle demande de fusion
|
pulls.compare_changes=Nouvelle demande de fusion
|
||||||
pulls.compare_changes_desc=Sélectionnez la branche dans laquelle fusionner et la branche depuis laquelle tirer les modifications.
|
pulls.compare_changes_desc=Sélectionnez la branche dans laquelle fusionner et la branche depuis laquelle tirer les modifications.
|
||||||
pulls.compare_base=fusionner dans
|
pulls.compare_base=fusionner dans
|
||||||
|
@ -1427,6 +1429,7 @@ pulls.filter_branch=Filtre de branche
|
||||||
pulls.no_results=Aucun résultat trouvé.
|
pulls.no_results=Aucun résultat trouvé.
|
||||||
pulls.nothing_to_compare=Ces branches sont identiques. Il n'y a pas besoin de créer une demande de fusion.
|
pulls.nothing_to_compare=Ces branches sont identiques. Il n'y a pas besoin de créer une demande de fusion.
|
||||||
pulls.nothing_to_compare_and_allow_empty_pr=Ces branches sont égales. Cette demande d'ajout sera vide.
|
pulls.nothing_to_compare_and_allow_empty_pr=Ces branches sont égales. Cette demande d'ajout sera vide.
|
||||||
|
pulls.has_pull_request='Il existe déjà une demande d'ajout entre ces deux branches : <a href="%[1]s">%[2]s#%[3]d</a>'
|
||||||
pulls.create=Créer une demande d'ajout
|
pulls.create=Créer une demande d'ajout
|
||||||
pulls.title_desc=veut fusionner %[1]d révision(s) depuis <code>%[2]s</code> vers <code id="branch_target">%[3]s</code>
|
pulls.title_desc=veut fusionner %[1]d révision(s) depuis <code>%[2]s</code> vers <code id="branch_target">%[3]s</code>
|
||||||
pulls.merged_title_desc=a fusionné %[1]d révision(s) à partir de <code>%[2]s</code> vers <code>%[3]s</code> %[4]s
|
pulls.merged_title_desc=a fusionné %[1]d révision(s) à partir de <code>%[2]s</code> vers <code>%[3]s</code> %[4]s
|
||||||
|
@ -1455,7 +1458,6 @@ pulls.required_status_check_missing=Certains contrôles requis sont manquants.
|
||||||
pulls.required_status_check_administrator=En tant qu'administrateur, vous pouvez toujours fusionner cette requête de pull.
|
pulls.required_status_check_administrator=En tant qu'administrateur, vous pouvez toujours fusionner cette requête de pull.
|
||||||
pulls.blocked_by_approvals=Cette demande d'ajout n'a pas assez d'approbation. %d sur %d approbations accordées.
|
pulls.blocked_by_approvals=Cette demande d'ajout n'a pas assez d'approbation. %d sur %d approbations accordées.
|
||||||
pulls.blocked_by_rejection=Cette demande de fusion a des modifications demandées par un réviseur officiel.
|
pulls.blocked_by_rejection=Cette demande de fusion a des modifications demandées par un réviseur officiel.
|
||||||
pulls.blocked_by_official_review_requests=Cette demande d'ajout a des demandes de revue officielles.
|
|
||||||
pulls.blocked_by_outdated_branch=Cette demande d'ajout est bloquée car elle est obsolète.
|
pulls.blocked_by_outdated_branch=Cette demande d'ajout est bloquée car elle est obsolète.
|
||||||
pulls.blocked_by_changed_protected_files_1=Cette demande d'ajout est bloquée car elle modifie un fichier protégé :
|
pulls.blocked_by_changed_protected_files_1=Cette demande d'ajout est bloquée car elle modifie un fichier protégé :
|
||||||
pulls.blocked_by_changed_protected_files_n=Cette Pull Request est bloquée car elle modifie les fichiers protégés :
|
pulls.blocked_by_changed_protected_files_n=Cette Pull Request est bloquée car elle modifie les fichiers protégés :
|
||||||
|
@ -1477,6 +1479,10 @@ pulls.no_merge_helper=Activez des options de fusion dans les paramètres du dép
|
||||||
pulls.no_merge_wip=Cette demande d'ajout ne peut pas être fusionnée car elle est marquée comme en cours de chantier.
|
pulls.no_merge_wip=Cette demande d'ajout ne peut pas être fusionnée car elle est marquée comme en cours de chantier.
|
||||||
pulls.no_merge_not_ready=Cette demande d'ajout n'est pas prête à être fusionnée, vérifiez l'état de la revue et les vérifications.
|
pulls.no_merge_not_ready=Cette demande d'ajout n'est pas prête à être fusionnée, vérifiez l'état de la revue et les vérifications.
|
||||||
pulls.no_merge_access=Vous n'êtes pas autorisé⋅e à fusionner cette demande d'ajout.
|
pulls.no_merge_access=Vous n'êtes pas autorisé⋅e à fusionner cette demande d'ajout.
|
||||||
|
pulls.merge_pull_request=Créer une révision de fusion
|
||||||
|
pulls.rebase_merge_pull_request=Rebaser puis avancer rapidement
|
||||||
|
pulls.rebase_merge_commit_pull_request=Rebaser puis créer une révision de fusion
|
||||||
|
pulls.squash_merge_pull_request=Créer une révision de concaténation
|
||||||
pulls.merge_manually=Fusionné manuellement
|
pulls.merge_manually=Fusionné manuellement
|
||||||
pulls.merge_commit_id=L'ID de la révision de fusion
|
pulls.merge_commit_id=L'ID de la révision de fusion
|
||||||
pulls.require_signed_wont_sign=La branche nécessite des révisions signées mais cette fusion ne sera pas signée
|
pulls.require_signed_wont_sign=La branche nécessite des révisions signées mais cette fusion ne sera pas signée
|
||||||
|
@ -1507,9 +1513,17 @@ pulls.merge_instruction_hint=`Vous pouvez également voir <a class="show-instruc
|
||||||
pulls.merge_instruction_step1_desc=Depuis le dépôt de votre projet, sélectionnez une nouvelle branche et testez les modifications.
|
pulls.merge_instruction_step1_desc=Depuis le dépôt de votre projet, sélectionnez une nouvelle branche et testez les modifications.
|
||||||
pulls.merge_instruction_step2_desc=Fusionner les modifications et mettre à jour sur Gitea.
|
pulls.merge_instruction_step2_desc=Fusionner les modifications et mettre à jour sur Gitea.
|
||||||
|
|
||||||
|
pulls.auto_merge_newly_scheduled=La demande d'ajout était programmée pour fusionner lorsque toutes les vérifications aurait réussi.
|
||||||
|
pulls.auto_merge_has_pending_schedule=%[1]s Ont planifié cette demande d'ajout pour fusionner automatiquement lorsque toutes les vérifications réussissent %[2]s.
|
||||||
|
|
||||||
|
pulls.auto_merge_not_scheduled=Cette demande d'ajout n'est pas planifiée pour fusionner automatiquement.
|
||||||
|
pulls.auto_merge_canceled_schedule=La fusion automatique a été annulée pour cette demande d'ajout.
|
||||||
|
|
||||||
|
pulls.auto_merge_newly_scheduled_comment=`a programmé cette demande de fusion automatique lorsque toutes les vérifications réussissent %[1]s`
|
||||||
|
pulls.auto_merge_canceled_schedule_comment=`a annulé la fusion automatique de cette demande d'ajout lorsque toutes les vérifications réussissent %[1]s`
|
||||||
|
|
||||||
|
pulls.delete.title=Supprimer cette demande d'ajout ?
|
||||||
|
pulls.delete.text=Voulez-vous vraiment supprimer cet demande d'ajout ? (Cela supprimera définitivement tout le contenu. Envisagez de le fermer à la place, si vous avez l'intention de le garder archivé)
|
||||||
|
|
||||||
milestones.new=Nouveau jalon
|
milestones.new=Nouveau jalon
|
||||||
milestones.closed=%s fermé
|
milestones.closed=%s fermé
|
||||||
|
@ -1704,6 +1718,7 @@ settings.pulls.allow_rebase_merge_commit=Activer le rebasage avec un commit de f
|
||||||
settings.pulls.allow_squash_commits=Activer la concaténation de révisions
|
settings.pulls.allow_squash_commits=Activer la concaténation de révisions
|
||||||
settings.pulls.allow_manual_merge=Activer le marquage des demandes d'ajout comme fusionnées manuellement
|
settings.pulls.allow_manual_merge=Activer le marquage des demandes d'ajout comme fusionnées manuellement
|
||||||
settings.pulls.enable_autodetect_manual_merge=Activer la détection automatique de la fusion manuelle (Remarque : dans certains cas particuliers, des erreurs de détection peuvent se produire)
|
settings.pulls.enable_autodetect_manual_merge=Activer la détection automatique de la fusion manuelle (Remarque : dans certains cas particuliers, des erreurs de détection peuvent se produire)
|
||||||
|
settings.pulls.allow_rebase_update=Activer la mise à jour de demande d'ajout par rebase
|
||||||
settings.pulls.default_delete_branch_after_merge=Supprimer la branche après la fusion par default
|
settings.pulls.default_delete_branch_after_merge=Supprimer la branche après la fusion par default
|
||||||
settings.projects_desc=Activer les projets de dépôt
|
settings.projects_desc=Activer les projets de dépôt
|
||||||
settings.admin_settings=Paramètres administrateur
|
settings.admin_settings=Paramètres administrateur
|
||||||
|
@ -2671,6 +2686,11 @@ notices.delete_success=Les informations systèmes ont été supprimées.
|
||||||
[action]
|
[action]
|
||||||
create_repo=a créé le dépôt <a href="%s">%s</a>
|
create_repo=a créé le dépôt <a href="%s">%s</a>
|
||||||
rename_repo=a rebaptisé le dépôt de <code>%[1]s</code> vers <a href="%[2]s">%[3]s</a>
|
rename_repo=a rebaptisé le dépôt de <code>%[1]s</code> vers <a href="%[2]s">%[3]s</a>
|
||||||
|
create_pull_request=`a créé la demande d'ajout <a href="%[1]s">%[3]s#%[2]s</a>`
|
||||||
|
close_pull_request=`a fermé la demande d'ajout <a href="%[1]s">%[3]s#%[2]s</a>`
|
||||||
|
reopen_pull_request=`a réouvert la demande d'ajout <a href="%[1]s">%[3]s#%[2]s</a>`
|
||||||
|
comment_pull=`a commenté la demande d'ajout <a href="%[1]s">%[3]s#%[2]s</a>`
|
||||||
|
merge_pull_request=`a fusionné la demande d'ajout <a href="%[1]s">%[3]s#%[2]s</a>`
|
||||||
transfer_repo=a transféré le dépôt <code>%s</code> à <a href="%s">%s</a>
|
transfer_repo=a transféré le dépôt <code>%s</code> à <a href="%s">%s</a>
|
||||||
delete_tag=étiquette supprimée %[2]s de <a href="%[1]s">%[3]s</a>
|
delete_tag=étiquette supprimée %[2]s de <a href="%[1]s">%[3]s</a>
|
||||||
delete_branch=branche %[2]s supprimée de <a href="%[1]s">%[3]s</a>
|
delete_branch=branche %[2]s supprimée de <a href="%[1]s">%[3]s</a>
|
||||||
|
@ -2678,6 +2698,8 @@ compare_branch=Comparer
|
||||||
compare_commits=Comparer %d révisions
|
compare_commits=Comparer %d révisions
|
||||||
compare_commits_general=Comparer les révisions
|
compare_commits_general=Comparer les révisions
|
||||||
mirror_sync_delete=a synchronisé puis supprimé la nouvelle référence <code>%[2]s</code> vers <a href="%[1]s">%[3]s</a> depuis le miroir
|
mirror_sync_delete=a synchronisé puis supprimé la nouvelle référence <code>%[2]s</code> vers <a href="%[1]s">%[3]s</a> depuis le miroir
|
||||||
|
approve_pull_request=`a approuvé <a href="%[1]s">%[3]s#%[2]s</a>`
|
||||||
|
reject_pull_request=`a suggérés des changements pour <a href="%[1]s">%[3]s#%[2]s</a>`
|
||||||
review_dismissed_reason=Raison :
|
review_dismissed_reason=Raison :
|
||||||
|
|
||||||
[tool]
|
[tool]
|
||||||
|
|
|
@ -1038,6 +1038,7 @@ file_too_large=Bu dosya görüntülemek için çok büyük.
|
||||||
invisible_runes_header=`Bu dosya görünmez Evrensel Kodlu karakter içeriyor!`
|
invisible_runes_header=`Bu dosya görünmez Evrensel Kodlu karakter içeriyor!`
|
||||||
invisible_runes_description=`Bu dosya, aşağıda görünenden farklı bir şekilde işlenebilecek görünmez Evrensel Kodlu karakter içeriyor. Eğer bunu kasıtlı ve meşru olarak yaptıysanız bu uyarıyı yok sayabilirsiniz. Gizli karakterleri göstermek için Kaçış düğmesine tıklayın.`
|
invisible_runes_description=`Bu dosya, aşağıda görünenden farklı bir şekilde işlenebilecek görünmez Evrensel Kodlu karakter içeriyor. Eğer bunu kasıtlı ve meşru olarak yaptıysanız bu uyarıyı yok sayabilirsiniz. Gizli karakterleri göstermek için Kaçış düğmesine tıklayın.`
|
||||||
ambiguous_runes_header=`Bu dosya muğlak Evrensel Kodlu karakter içeriyor!`
|
ambiguous_runes_header=`Bu dosya muğlak Evrensel Kodlu karakter içeriyor!`
|
||||||
|
ambiguous_runes_description=`Bu dosya, aşağıda görünenden farklı bir şekilde işlenebilecek muğlak Evrensel Kodlu karakter içeriyor. Eğer bunu kasıtlı ve meşru olarak yaptıysanız bu uyarıyı yok sayabilirsiniz. Bu karakterleri göstermek için Kaçış düğmesine tıklayın.`
|
||||||
invisible_runes_line=`Bu satırda görünmez evrensel kodlu karakter var`
|
invisible_runes_line=`Bu satırda görünmez evrensel kodlu karakter var`
|
||||||
ambiguous_runes_line=`Bu satırda muğlak evrensel kodlu karakter var`
|
ambiguous_runes_line=`Bu satırda muğlak evrensel kodlu karakter var`
|
||||||
ambiguous_character=`%[1]c [U+%04[1]X], %[2]c [U+%04[2]X] ile karıştırılabilir`
|
ambiguous_character=`%[1]c [U+%04[1]X], %[2]c [U+%04[2]X] ile karıştırılabilir`
|
||||||
|
@ -2894,6 +2895,7 @@ monitor.queue.nopool.title=Çalışan Havuzu Yok
|
||||||
monitor.queue.nopool.desc=Bu kuyruk diğer kuyrukları sarar ve kendisinin bir işçi havuzu yoktur.
|
monitor.queue.nopool.desc=Bu kuyruk diğer kuyrukları sarar ve kendisinin bir işçi havuzu yoktur.
|
||||||
monitor.queue.wrapped.desc=Sarılmış bir kuyruk, yavaş bir başlangıç kuyruğunu sararak kanaldaki kuyruk isteklerini arabelleğe alır. Bir işçi havuzu yoktur.
|
monitor.queue.wrapped.desc=Sarılmış bir kuyruk, yavaş bir başlangıç kuyruğunu sararak kanaldaki kuyruk isteklerini arabelleğe alır. Bir işçi havuzu yoktur.
|
||||||
monitor.queue.persistable-channel.desc=Kesintisiz bir kanal, kendi alt havuzuna sahip bir kanal kuyruğu ve önceki kapanmalardan gelen kalıcı istekler için bir seviye kuyruğu olan iki kuyruğu sarar. Bir işçi havuzu yoktur.
|
monitor.queue.persistable-channel.desc=Kesintisiz bir kanal, kendi alt havuzuna sahip bir kanal kuyruğu ve önceki kapanmalardan gelen kalıcı istekler için bir seviye kuyruğu olan iki kuyruğu sarar. Bir işçi havuzu yoktur.
|
||||||
|
monitor.queue.flush=Çalışanı boşalt
|
||||||
monitor.queue.pool.timeout=Zaman aşımı
|
monitor.queue.pool.timeout=Zaman aşımı
|
||||||
monitor.queue.pool.addworkers.title=Çalışan Ekle
|
monitor.queue.pool.addworkers.title=Çalışan Ekle
|
||||||
monitor.queue.pool.addworkers.submit=Çalışan Ekle
|
monitor.queue.pool.addworkers.submit=Çalışan Ekle
|
||||||
|
|
|
@ -105,6 +105,13 @@ func Profile(ctx *context.Context) {
|
||||||
ctx.Data["Orgs"] = orgs
|
ctx.Data["Orgs"] = orgs
|
||||||
ctx.Data["HasOrgsVisible"] = organization.HasOrgsVisible(orgs, ctx.Doer)
|
ctx.Data["HasOrgsVisible"] = organization.HasOrgsVisible(orgs, ctx.Doer)
|
||||||
|
|
||||||
|
badges, _, err := user_model.GetUserBadges(ctx, ctx.ContextUser)
|
||||||
|
if err != nil {
|
||||||
|
ctx.ServerError("GetUserBadges", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
ctx.Data["Badges"] = badges
|
||||||
|
|
||||||
tab := ctx.FormString("tab")
|
tab := ctx.FormString("tab")
|
||||||
ctx.Data["TabName"] = tab
|
ctx.Data["TabName"] = tab
|
||||||
|
|
||||||
|
|
|
@ -69,6 +69,17 @@
|
||||||
</ul>
|
</ul>
|
||||||
</li>
|
</li>
|
||||||
{{end}}
|
{{end}}
|
||||||
|
{{if .Badges}}
|
||||||
|
<li>
|
||||||
|
<ul class="user-badges">
|
||||||
|
{{range .Badges}}
|
||||||
|
<li>
|
||||||
|
<img width="64" height="64" src="{{.ImageURL}}" alt="{{.Description}}" data-content="{{.Description}}" class="tooltip"/>
|
||||||
|
</li>
|
||||||
|
{{end}}
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
{{end}}
|
||||||
{{if and .IsSigned (ne .SignedUserName .Owner.Name)}}
|
{{if and .IsSigned (ne .SignedUserName .Owner.Name)}}
|
||||||
<li class="follow">
|
<li class="follow">
|
||||||
{{if $.IsFollowing}}
|
{{if $.IsFollowing}}
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
import {emojiKeys, emojiHTML, emojiString} from './emoji.js';
|
import {emojiKeys, emojiHTML, emojiString} from './emoji.js';
|
||||||
import {uniq} from '../utils.js';
|
import {uniq} from '../utils.js';
|
||||||
|
import {htmlEscape} from 'escape-goat';
|
||||||
|
|
||||||
function makeCollections({mentions, emoji}) {
|
function makeCollections({mentions, emoji}) {
|
||||||
const collections = [];
|
const collections = [];
|
||||||
|
@ -24,7 +25,7 @@ function makeCollections({mentions, emoji}) {
|
||||||
return emojiString(item.original);
|
return emojiString(item.original);
|
||||||
},
|
},
|
||||||
menuItemTemplate: (item) => {
|
menuItemTemplate: (item) => {
|
||||||
return `<div class="tribute-item">${emojiHTML(item.original)}<span>${item.original}</span></div>`;
|
return `<div class="tribute-item">${emojiHTML(item.original)}<span>${htmlEscape(item.original)}</span></div>`;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -36,9 +37,9 @@ function makeCollections({mentions, emoji}) {
|
||||||
menuItemTemplate: (item) => {
|
menuItemTemplate: (item) => {
|
||||||
return `
|
return `
|
||||||
<div class="tribute-item">
|
<div class="tribute-item">
|
||||||
<img src="${item.original.avatar}"/>
|
<img src="${htmlEscape(item.original.avatar)}"/>
|
||||||
<span class="name">${item.original.name}</span>
|
<span class="name">${htmlEscape(item.original.name)}</span>
|
||||||
${item.original.fullname && item.original.fullname !== '' ? `<span class="fullname">${item.original.fullname}</span>` : ''}
|
${item.original.fullname && item.original.fullname !== '' ? `<span class="fullname">${htmlEscape(item.original.fullname)}</span>` : ''}
|
||||||
</div>
|
</div>
|
||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
|
|
|
@ -169,6 +169,15 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.user-badges {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(auto-fill, 64px);
|
||||||
|
gap: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.user-badges img {
|
||||||
|
object-fit: contain;
|
||||||
|
}
|
||||||
#notification_div .tab.segment {
|
#notification_div .tab.segment {
|
||||||
overflow-x: auto;
|
overflow-x: auto;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue