Merge branch 'go-gitea:main' into main

pull/33830/head
jerryyummy 2025-06-16 10:26:43 +08:00 committed by GitHub
commit ba8b90698d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
20 changed files with 526 additions and 513 deletions

View File

@ -4,7 +4,7 @@
"features": { "features": {
// installs nodejs into container // installs nodejs into container
"ghcr.io/devcontainers/features/node:1": { "ghcr.io/devcontainers/features/node:1": {
"version": "20" "version": "lts"
}, },
"ghcr.io/devcontainers/features/git-lfs:1.2.2": {}, "ghcr.io/devcontainers/features/git-lfs:1.2.2": {},
"ghcr.io/devcontainers-contrib/features/poetry:2": {}, "ghcr.io/devcontainers-contrib/features/poetry:2": {},

View File

@ -37,7 +37,7 @@ jobs:
python-version: "3.12" python-version: "3.12"
- uses: actions/setup-node@v4 - uses: actions/setup-node@v4
with: with:
node-version: 22 node-version: 24
cache: npm cache: npm
cache-dependency-path: package-lock.json cache-dependency-path: package-lock.json
- run: pip install poetry - run: pip install poetry
@ -66,7 +66,7 @@ jobs:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
- uses: actions/setup-node@v4 - uses: actions/setup-node@v4
with: with:
node-version: 22 node-version: 24
cache: npm cache: npm
cache-dependency-path: package-lock.json cache-dependency-path: package-lock.json
- run: make deps-frontend - run: make deps-frontend
@ -137,7 +137,7 @@ jobs:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
- uses: actions/setup-node@v4 - uses: actions/setup-node@v4
with: with:
node-version: 22 node-version: 24
cache: npm cache: npm
cache-dependency-path: package-lock.json cache-dependency-path: package-lock.json
- run: make deps-frontend - run: make deps-frontend
@ -186,7 +186,7 @@ jobs:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
- uses: actions/setup-node@v4 - uses: actions/setup-node@v4
with: with:
node-version: 22 node-version: 24
cache: npm cache: npm
cache-dependency-path: package-lock.json cache-dependency-path: package-lock.json
- run: make deps-frontend - run: make deps-frontend

View File

@ -25,7 +25,7 @@ jobs:
check-latest: true check-latest: true
- uses: actions/setup-node@v4 - uses: actions/setup-node@v4
with: with:
node-version: 22 node-version: 24
cache: npm cache: npm
cache-dependency-path: package-lock.json cache-dependency-path: package-lock.json
- run: make deps-frontend frontend deps-backend - run: make deps-frontend frontend deps-backend

View File

@ -22,7 +22,7 @@ jobs:
check-latest: true check-latest: true
- uses: actions/setup-node@v4 - uses: actions/setup-node@v4
with: with:
node-version: 22 node-version: 24
cache: npm cache: npm
cache-dependency-path: package-lock.json cache-dependency-path: package-lock.json
- run: make deps-frontend deps-backend - run: make deps-frontend deps-backend

View File

@ -23,7 +23,7 @@ jobs:
check-latest: true check-latest: true
- uses: actions/setup-node@v4 - uses: actions/setup-node@v4
with: with:
node-version: 22 node-version: 24
cache: npm cache: npm
cache-dependency-path: package-lock.json cache-dependency-path: package-lock.json
- run: make deps-frontend deps-backend - run: make deps-frontend deps-backend

View File

@ -27,7 +27,7 @@ jobs:
check-latest: true check-latest: true
- uses: actions/setup-node@v4 - uses: actions/setup-node@v4
with: with:
node-version: 22 node-version: 24
cache: npm cache: npm
cache-dependency-path: package-lock.json cache-dependency-path: package-lock.json
- run: make deps-frontend deps-backend - run: make deps-frontend deps-backend

View File

@ -212,7 +212,7 @@ func runServ(ctx context.Context, c *cli.Command) error {
if git.DefaultFeatures().SupportProcReceive { if git.DefaultFeatures().SupportProcReceive {
// for AGit Flow // for AGit Flow
if cmd == "ssh_info" { if cmd == "ssh_info" {
fmt.Print(`{"type":"gitea","version":1}`) fmt.Print(`{"type":"agit","version":1}`)
return nil return nil
} }
} }

View File

@ -1652,6 +1652,7 @@ issues.save=Sábháil
issues.label_title=Ainm issues.label_title=Ainm
issues.label_description=Cur síos issues.label_description=Cur síos
issues.label_color=Dath issues.label_color=Dath
issues.label_color_invalid=Dath neamhbhailí
issues.label_exclusive=Eisiach issues.label_exclusive=Eisiach
issues.label_archive=Lipéad Cartlann issues.label_archive=Lipéad Cartlann
issues.label_archived_filter=Taispeáin lipéid cartlainne issues.label_archived_filter=Taispeáin lipéid cartlainne

File diff suppressed because it is too large Load Diff

View File

@ -262,7 +262,7 @@ host=数据库主机
user=用户名 user=用户名
password=数据库用户密码 password=数据库用户密码
db_name=数据库名称 db_name=数据库名称
db_schema=Schema db_schema=架构
db_schema_helper=留空则数据库中默认值为("public")。 db_schema_helper=留空则数据库中默认值为("public")。
ssl_mode=SSL ssl_mode=SSL
path=数据库文件路径 path=数据库文件路径
@ -752,7 +752,7 @@ cancel=取消操作
language=界面语言 language=界面语言
ui=主题 ui=主题
hidden_comment_types=隐藏的评论类型 hidden_comment_types=隐藏的评论类型
hidden_comment_types_description=此处选中的注释类型不会显示在工单页面中。比如,勾选「标」删除所有「{user} 添加/删除的 {label}」注释。 hidden_comment_types_description=此处选中的注释类型不会显示在工单页面中。比如,勾选「标」删除所有「{user} 添加/删除的 {label}」注释。
hidden_comment_types.ref_tooltip=注释此问题在何处被提及过,如另一个问题、代码提交等 hidden_comment_types.ref_tooltip=注释此问题在何处被提及过,如另一个问题、代码提交等
hidden_comment_types.issue_ref_tooltip=注释用户在何处更改了与此问题相关联的分支/标签 hidden_comment_types.issue_ref_tooltip=注释用户在何处更改了与此问题相关联的分支/标签
comment_type_group_reference=引用 comment_type_group_reference=引用
@ -1066,10 +1066,10 @@ download_tar=下载 TAR.GZ
download_bundle=下载 BUNDLE download_bundle=下载 BUNDLE
generate_repo=生成仓库 generate_repo=生成仓库
generate_from=生成自 generate_from=生成自
repo_desc=仓库描述 repo_desc=描述
repo_desc_helper=输入简要描述 (可选) repo_desc_helper=输入简要描述 (可选)
repo_no_desc=无详细信息 repo_no_desc=无详细信息
repo_lang=编程语言 repo_lang=语言
repo_gitignore_helper=选择 .gitignore 模板。 repo_gitignore_helper=选择 .gitignore 模板。
repo_gitignore_helper_desc=从常见语言的模板列表中选择忽略跟踪的文件。默认情况下,由开发或构建工具生成的特殊文件都包含在 .gitignore 中。 repo_gitignore_helper_desc=从常见语言的模板列表中选择忽略跟踪的文件。默认情况下,由开发或构建工具生成的特殊文件都包含在 .gitignore 中。
issue_labels=工单标签 issue_labels=工单标签
@ -1161,15 +1161,15 @@ template.issue_labels=工单标签
template.one_item=必须至少选择一个模板项 template.one_item=必须至少选择一个模板项
template.invalid=必须选择一个模板仓库 template.invalid=必须选择一个模板仓库
archive.title=该仓库已被归档。您可以查看文件和克隆它,但不能推送、创建工单或合并请求。 archive.title=该仓库已被归档。您可以查看文件和克隆它,但不能推送、打开工单或合并请求。
archive.title_date=该仓库已于 %s 归档。您可以查看文件或克隆它,但不能推送、创建工单或合并请求。 archive.title_date=该仓库已于 %s 归档。您可以查看文件或克隆它,但不能推送、打开工单或合并请求。
archive.issue.nocomment=此仓库已存档,您不能在此工单添加评论。 archive.issue.nocomment=此仓库已存档,您不能在此工单添加评论。
archive.pull.nocomment=此仓库已存档,您不能在此合并请求添加评论。 archive.pull.nocomment=此仓库已存档,您不能在此合并请求添加评论。
form.reach_limit_of_creation_1=您已经达到了 %d 仓库的上限。 form.reach_limit_of_creation_1=您已经达到了 %d 仓库的上限。
form.reach_limit_of_creation_n=您已经达到了 %d 个仓库的上限。 form.reach_limit_of_creation_n=您已经达到了 %d 个仓库的上限。
form.name_reserved=仓库名称 %s 是保留的。 form.name_reserved=仓库名称 %s 是保留的。
form.name_pattern_not_allowed=仓库名称中不允许使用 %s 格式。 form.name_pattern_not_allowed=仓库名中不允许使用「%s」格式。
need_auth=授权 need_auth=授权
migrate_options=迁移选项 migrate_options=迁移选项
@ -1261,7 +1261,7 @@ branch=分支
tree=目录树 tree=目录树
clear_ref=`清除当前引用` clear_ref=`清除当前引用`
filter_branch_and_tag=过滤分支或标签 filter_branch_and_tag=过滤分支或标签
find_tag=查找 Git 标签 find_tag=查找标签
branches=分支列表 branches=分支列表
tags=标签列表 tags=标签列表
issues=工单 issues=工单
@ -1279,7 +1279,7 @@ commits=提交
commit=提交 commit=提交
release=发布 release=发布
releases=发布 releases=发布
tag=Git 标签 tag=标签
released_this=发布 released_this=发布
tagged_this=已标记 tagged_this=已标记
file.title=%s 位于 %s file.title=%s 位于 %s
@ -1336,7 +1336,7 @@ editor.cannot_edit_non_text_files=网页不能编辑二进制文件。
editor.edit_this_file=编辑文件 editor.edit_this_file=编辑文件
editor.this_file_locked=文件已锁定 editor.this_file_locked=文件已锁定
editor.must_be_on_a_branch=您必须在某个分支上才能对此文件进行修改操作。 editor.must_be_on_a_branch=您必须在某个分支上才能对此文件进行修改操作。
editor.fork_before_edit=您必须派生这个仓库才能对此文件进行修改操作 editor.fork_before_edit=您必须派生这个仓库才能对此文件进行修改操作
editor.delete_this_file=删除文件 editor.delete_this_file=删除文件
editor.must_have_write_access=您必须具有写权限才能对此文件进行修改操作。 editor.must_have_write_access=您必须具有写权限才能对此文件进行修改操作。
editor.file_delete_success=文件「%s」已删除。 editor.file_delete_success=文件「%s」已删除。
@ -1359,7 +1359,7 @@ editor.signoff_desc=在提交日志消息末尾添加签署人信息。
editor.commit_directly_to_this_branch=直接提交至 <strong class="branch-name">%s</strong> 分支。 editor.commit_directly_to_this_branch=直接提交至 <strong class="branch-name">%s</strong> 分支。
editor.create_new_branch=为此提交创建一个 <strong>新的分支</strong> 并发起合并请求。 editor.create_new_branch=为此提交创建一个 <strong>新的分支</strong> 并发起合并请求。
editor.create_new_branch_np=为此提交创建 <strong>新分支</strong>。 editor.create_new_branch_np=为此提交创建 <strong>新分支</strong>。
editor.propose_file_change=议文件更改 editor.propose_file_change=议文件更改
editor.new_branch_name=为这次提交的新分支命名 editor.new_branch_name=为这次提交的新分支命名
editor.new_branch_name_desc=新的分支名称... editor.new_branch_name_desc=新的分支名称...
editor.cancel=取消 editor.cancel=取消
@ -1613,8 +1613,8 @@ issues.close=关闭工单
issues.comment_pull_merged_at=已合并提交 %[1]s 到 %[2]s %[3]s issues.comment_pull_merged_at=已合并提交 %[1]s 到 %[2]s %[3]s
issues.comment_manually_pull_merged_at=手动合并提交 %[1]s 到 %[2]s %[3]s issues.comment_manually_pull_merged_at=手动合并提交 %[1]s 到 %[2]s %[3]s
issues.close_comment_issue=评论并关闭 issues.close_comment_issue=评论并关闭
issues.reopen_issue=重新 issues.reopen_issue=重新
issues.reopen_comment_issue=评论并重新 issues.reopen_comment_issue=评论并重新
issues.create_comment=评论 issues.create_comment=评论
issues.comment.blocked_user=无法创建或编辑评论,因为您已被仓库所有者或工单创建者屏蔽。 issues.comment.blocked_user=无法创建或编辑评论,因为您已被仓库所有者或工单创建者屏蔽。
issues.closed_at=`于 <a id="%[1]s" href="#%[1]s">%[2]s</a> 关闭此工单` issues.closed_at=`于 <a id="%[1]s" href="#%[1]s">%[2]s</a> 关闭此工单`
@ -1650,19 +1650,19 @@ issues.edit=编辑
issues.cancel=取消 issues.cancel=取消
issues.save=保存 issues.save=保存
issues.label_title=标签名称 issues.label_title=标签名称
issues.label_description=标签描述 issues.label_description=描述
issues.label_color=标签颜色 issues.label_color=颜色
issues.label_color_invalid=无效的颜色 issues.label_color_invalid=无效的颜色
issues.label_exclusive=互斥标签 issues.label_exclusive=互斥
issues.label_archive=归档标签 issues.label_archive=归档标签
issues.label_archived_filter=显示档标签 issues.label_archived_filter=显示已归档标签
issues.label_archive_tooltip=在标签搜索时,默认情况下档标签将被排除在外。 issues.label_archive_tooltip=在标签搜索时,默认情况下已归档标签将被排除在外。
issues.label_exclusive_desc=命名标签为 <code>scope/item</code> 以使其与其他以 <code>scope/</code> 开头的标签互斥。 issues.label_exclusive_desc=命名标签为 <code>scope/item</code> 以使其与其他以 <code>scope/</code> 开头的标签互斥。
issues.label_exclusive_warning=在编辑工单或合并请求的标签时,任何冲突的范围标签都将被删除。 issues.label_exclusive_warning=在编辑工单或合并请求的标签时,任何冲突的范围标签都将被删除。
issues.label_exclusive_order=排序顺序 issues.label_exclusive_order=排序顺序
issues.label_exclusive_order_tooltip=在同一个范围内的互斥标签将按照这个数字进行排序 issues.label_exclusive_order_tooltip=在同一个范围内的互斥标签将按照这个数字进行排序
issues.label_count=%d 个标签 issues.label_count=%d 个标签
issues.label_open_issues=%d 个启的工单 issues.label_open_issues=%d 个已打开工单/合并请求
issues.label_edit=编辑 issues.label_edit=编辑
issues.label_delete=删除 issues.label_delete=删除
issues.label_modify=编辑标签 issues.label_modify=编辑标签
@ -1993,7 +1993,7 @@ milestones.new=新的里程碑
milestones.closed=于 %s关闭 milestones.closed=于 %s关闭
milestones.update_ago=已更新 %s milestones.update_ago=已更新 %s
milestones.no_due_date=暂无截止日期 milestones.no_due_date=暂无截止日期
milestones.open= milestones.open=
milestones.close=关闭 milestones.close=关闭
milestones.new_subheader=里程碑可以帮助您组织工单并跟踪其进度。 milestones.new_subheader=里程碑可以帮助您组织工单并跟踪其进度。
milestones.completeness=<strong>%d%%</strong> 已完成 milestones.completeness=<strong>%d%%</strong> 已完成
@ -2068,22 +2068,22 @@ activity=活动
activity.navbar.pulse=活动 activity.navbar.pulse=活动
activity.navbar.code_frequency=代码频率 activity.navbar.code_frequency=代码频率
activity.navbar.contributors=贡献者 activity.navbar.contributors=贡献者
activity.navbar.recent_commits=最近提交 activity.navbar.recent_commits=最近提交
activity.period.filter_label=周期: activity.period.filter_label=周期:
activity.period.daily=1 天 activity.period.daily=1 天
activity.period.halfweekly=3 天 activity.period.halfweekly=3 天
activity.period.weekly=1 activity.period.weekly=1
activity.period.monthly=1 activity.period.monthly=1
activity.period.quarterly=3 activity.period.quarterly=3
activity.period.semiyearly=6 activity.period.semiyearly=6
activity.period.yearly=1 activity.period.yearly=1
activity.overview=概览 activity.overview=概览
activity.active_prs_count_1=<strong>%d</strong> 个合并请求 activity.active_prs_count_1=<strong>%d</strong> 个合并请求
activity.active_prs_count_n=<strong>%d</strong> 个合并请求 activity.active_prs_count_n=<strong>%d</strong> 个合并请求
activity.merged_prs_count_1=合并请求 activity.merged_prs_count_1=已合并的合并请求
activity.merged_prs_count_n=合并请求 activity.merged_prs_count_n=已合并的合并请求
activity.opened_prs_count_1=合并请求 activity.opened_prs_count_1=创建的合并请求
activity.opened_prs_count_n=合并请求 activity.opened_prs_count_n=创建的合并请求
activity.title.user_1=%d 位用户 activity.title.user_1=%d 位用户
activity.title.user_n=%d 位用户 activity.title.user_n=%d 位用户
activity.title.prs_1=%d 个合并请求 activity.title.prs_1=%d 个合并请求
@ -2101,8 +2101,8 @@ activity.title.issues_n=%d 张工单
activity.title.issues_closed_from=%s 从 %s 关闭 activity.title.issues_closed_from=%s 从 %s 关闭
activity.title.issues_created_by=%[2]s 创建了 %[1]s activity.title.issues_created_by=%[2]s 创建了 %[1]s
activity.closed_issue_label=已关闭 activity.closed_issue_label=已关闭
activity.new_issues_count_1=创建工单 activity.new_issues_count_1=已打开的工单
activity.new_issues_count_n=创建工单 activity.new_issues_count_n=已打开的工单
activity.new_issue_label=打开的 activity.new_issue_label=打开的
activity.title.unresolved_conv_1=%d 未解决的会话 activity.title.unresolved_conv_1=%d 未解决的会话
activity.title.unresolved_conv_n=%d 未解决的会话 activity.title.unresolved_conv_n=%d 未解决的会话
@ -2113,11 +2113,11 @@ activity.title.releases_n=%d 个发布
activity.title.releases_published_by=%[2]s 发布了 %[1]s activity.title.releases_published_by=%[2]s 发布了 %[1]s
activity.published_release_label=已发布 activity.published_release_label=已发布
activity.no_git_activity=在此期间没有任何提交活动。 activity.no_git_activity=在此期间没有任何提交活动。
activity.git_stats_exclude_merges=排除合并 activity.git_stats_exclude_merges=排除合并
activity.git_stats_author_1=%d 位作者 activity.git_stats_author_1=%d 位作者
activity.git_stats_author_n=%d 位作者 activity.git_stats_author_n=%d 位作者
activity.git_stats_pushed_1=推送 activity.git_stats_pushed_1=推送
activity.git_stats_pushed_n=推送 activity.git_stats_pushed_n=推送
activity.git_stats_commit_1=%d 次提交 activity.git_stats_commit_1=%d 次提交
activity.git_stats_commit_n=%d 次提交 activity.git_stats_commit_n=%d 次提交
activity.git_stats_push_to_branch=到 %s 和 activity.git_stats_push_to_branch=到 %s 和
@ -2125,14 +2125,14 @@ activity.git_stats_push_to_all_branches=到所有分支。
activity.git_stats_on_default_branch=在 %s 上, activity.git_stats_on_default_branch=在 %s 上,
activity.git_stats_file_1=%d 个文件 activity.git_stats_file_1=%d 个文件
activity.git_stats_file_n=%d 个文件 activity.git_stats_file_n=%d 个文件
activity.git_stats_files_changed_1=经改变 activity.git_stats_files_changed_1=修改
activity.git_stats_files_changed_n=经改变 activity.git_stats_files_changed_n=修改
activity.git_stats_additions=而且 activity.git_stats_additions=并且已有
activity.git_stats_addition_1=新增 %d 行 activity.git_stats_addition_1=%d 行新增
activity.git_stats_addition_n=新增 %d 行 activity.git_stats_addition_n=%d 行新增
activity.git_stats_and_deletions= activity.git_stats_and_deletions=
activity.git_stats_deletion_1=删除 %d 行 activity.git_stats_deletion_1=%d 行删除
activity.git_stats_deletion_n=删除 %d 行 activity.git_stats_deletion_n=%d 行删除
contributors.contribution_type.filter_label=贡献类型: contributors.contribution_type.filter_label=贡献类型:
contributors.contribution_type.commits=提交 contributors.contribution_type.commits=提交
@ -2211,7 +2211,7 @@ settings.tracker_issue_style=外部工单管理系统的编号格式
settings.tracker_issue_style.numeric=纯数字形式 settings.tracker_issue_style.numeric=纯数字形式
settings.tracker_issue_style.alphanumeric=英文字母数字组合形式 settings.tracker_issue_style.alphanumeric=英文字母数字组合形式
settings.tracker_issue_style.regexp=正则表达式 settings.tracker_issue_style.regexp=正则表达式
settings.tracker_issue_style.regexp_pattern=正则表达式模式 settings.tracker_issue_style.regexp_pattern=正则表达式
settings.tracker_issue_style.regexp_pattern_desc=第一个被捕获的组将取代 <code>{index}</code>。 settings.tracker_issue_style.regexp_pattern_desc=第一个被捕获的组将取代 <code>{index}</code>。
settings.tracker_url_format_desc=使用占位符 <code>{user}</code>, <code>{repo}</code> 和 <code>{index}</code> 作为用户名、仓库名和工单索引。 settings.tracker_url_format_desc=使用占位符 <code>{user}</code>, <code>{repo}</code> 和 <code>{index}</code> 作为用户名、仓库名和工单索引。
settings.enable_timetracker=启用时间跟踪 settings.enable_timetracker=启用时间跟踪
@ -2221,7 +2221,7 @@ settings.pulls.ignore_whitespace=忽略空白冲突
settings.pulls.enable_autodetect_manual_merge=启用自动检测手动合并 (注意:在某些特殊情况下可能发生错误判断) settings.pulls.enable_autodetect_manual_merge=启用自动检测手动合并 (注意:在某些特殊情况下可能发生错误判断)
settings.pulls.allow_rebase_update=允许通过变基更新合并请求分支 settings.pulls.allow_rebase_update=允许通过变基更新合并请求分支
settings.pulls.default_delete_branch_after_merge=默认合并后删除合并请求分支 settings.pulls.default_delete_branch_after_merge=默认合并后删除合并请求分支
settings.pulls.default_allow_edits_from_maintainers=默认开启允许维护者编辑 settings.pulls.default_allow_edits_from_maintainers=默认允许维护者编辑
settings.releases_desc=启用仓库发布 settings.releases_desc=启用仓库发布
settings.packages_desc=启用仓库软件包注册中心 settings.packages_desc=启用仓库软件包注册中心
settings.projects_desc=启用项目 settings.projects_desc=启用项目
@ -2386,7 +2386,7 @@ settings.event_pull_request=合并请求
settings.event_pull_request_desc=合并请求已打开、关闭、重新打开或编辑。 settings.event_pull_request_desc=合并请求已打开、关闭、重新打开或编辑。
settings.event_pull_request_assign=合并请求已指派 settings.event_pull_request_assign=合并请求已指派
settings.event_pull_request_assign_desc=合并请求已指派或取消指派。 settings.event_pull_request_assign_desc=合并请求已指派或取消指派。
settings.event_pull_request_label=合并请求已贴上标签 settings.event_pull_request_label=合并请求增删标签
settings.event_pull_request_label_desc=合并请求的标签已更新或清除。 settings.event_pull_request_label_desc=合并请求的标签已更新或清除。
settings.event_pull_request_milestone=合并请求已记录于里程碑中 settings.event_pull_request_milestone=合并请求已记录于里程碑中
settings.event_pull_request_milestone_desc=合并请求已记录或取消记录于里程碑中。 settings.event_pull_request_milestone_desc=合并请求已记录或取消记录于里程碑中。
@ -2406,7 +2406,7 @@ settings.event_workflow_job_desc=Gitea 工作流队列中、等待中、正在
settings.event_package=软件包 settings.event_package=软件包
settings.event_package_desc=软件包在仓库中已创建或删除。 settings.event_package_desc=软件包在仓库中已创建或删除。
settings.branch_filter=分支过滤 settings.branch_filter=分支过滤
settings.branch_filter_desc=推送、创建,删除分支事件的分支白名单,使用 glob 模式匹配指定。若为空或 <code>*</code>,则将报告所有分支的事件。语法文档见 <a href="%[1]s">%[2]s</a>。示例:<code>master</code>,<code>{master,release*}</code>。 settings.branch_filter_desc=推送、创建,删除分支事件的分支白名单,使用 glob 表达式匹配指定。若为空或 <code>*</code>,则会报告所有分支的事件。语法文档见 <a href="%[1]s">%[2]s</a>。示例:<code>master</code>,<code>{master,release*}</code>。
settings.authorization_header=授权标头 settings.authorization_header=授权标头
settings.authorization_header_desc=当存在时将被作为授权标头包含在内。例如: %s。 settings.authorization_header_desc=当存在时将被作为授权标头包含在内。例如: %s。
settings.active=激活 settings.active=激活
@ -2486,13 +2486,13 @@ settings.protect_merge_whitelist_committers_desc=仅允许白名单用户或团
settings.protect_merge_whitelist_users=合并白名单用户: settings.protect_merge_whitelist_users=合并白名单用户:
settings.protect_merge_whitelist_teams=合并白名单团队: settings.protect_merge_whitelist_teams=合并白名单团队:
settings.protect_check_status_contexts=启用状态检查 settings.protect_check_status_contexts=启用状态检查
settings.protect_status_check_patterns=状态检查式: settings.protect_status_check_patterns=状态检查表达式:
settings.protect_status_check_patterns_desc=输入模式,指定哪些状态检查必须通过,才能将分支合并到符合此规则的分支中去。每一行指定一个模式,模式不能为空。 settings.protect_status_check_patterns_desc=输入表达式以指定在分支合并到匹配此规则的分支之前必须通过哪些状态检查。每一行指定一个表达式且表达式不能为空。
settings.protect_check_status_contexts_desc=要求状态检查通过才能合并。如果启用,提交必须先推送到另一个分支,然后再合并或推送到匹配这些保护规则的分支。如果没有选择具体的状态检查上下文,则所有的状态检查都通过才能合并。 settings.protect_check_status_contexts_desc=要求状态检查通过才能合并。如果启用,提交必须先推送到另一个分支,然后再合并或推送到匹配这些保护规则的分支。如果没有选择具体的状态检查上下文,则所有的状态检查都通过才能合并。
settings.protect_check_status_contexts_list=此仓库上周进行过的状态检查 settings.protect_check_status_contexts_list=此仓库上周进行过的状态检查
settings.protect_status_check_matched=匹配 settings.protect_status_check_matched=匹配
settings.protect_invalid_status_check_pattern=无效的状态检查规则:「%s」。 settings.protect_invalid_status_check_pattern=无效的状态检查表达式:「%s」。
settings.protect_no_valid_status_check_patterns=没有有效的状态检查规则 settings.protect_no_valid_status_check_patterns=没有有效的状态检查表达式
settings.protect_required_approvals=所需的批准: settings.protect_required_approvals=所需的批准:
settings.protect_required_approvals_desc=只允许合并有足够审核的合并请求。要求的审核必须来自白名单或者有权限的用户或团队。 settings.protect_required_approvals_desc=只允许合并有足够审核的合并请求。要求的审核必须来自白名单或者有权限的用户或团队。
settings.protect_approvals_whitelist_enabled=仅列入白名单的用户或团队才可批准 settings.protect_approvals_whitelist_enabled=仅列入白名单的用户或团队才可批准
@ -2505,13 +2505,13 @@ settings.ignore_stale_approvals=忽略过期批准
settings.ignore_stale_approvals_desc=对旧提交(过期审核)的批准将不计入 PR 的批准数。如果过期审查已被驳回,则与此无关。 settings.ignore_stale_approvals_desc=对旧提交(过期审核)的批准将不计入 PR 的批准数。如果过期审查已被驳回,则与此无关。
settings.require_signed_commits=需要签名提交 settings.require_signed_commits=需要签名提交
settings.require_signed_commits_desc=拒绝推送未签名或无法验证的提交到分支 settings.require_signed_commits_desc=拒绝推送未签名或无法验证的提交到分支
settings.protect_branch_name_pattern=受保护的分支名称 settings.protect_branch_name_pattern=受保护的分支名称表达
settings.protect_branch_name_pattern_desc=分支保护的名称匹配规则。语法请参阅 <a href="%s">文档</a> 。如main, release/** settings.protect_branch_name_pattern_desc=分支保护的名称匹配表达式。语法请参阅 <a href="%s">文档</a> 。如main, release/**
settings.protect_patterns=规则 settings.protect_patterns=表达式
settings.protect_protected_file_patterns=受保护的文件模式(使用分号 ';' 分隔) settings.protect_protected_file_patterns=受保护的文件表达式(使用分号「;」分隔)
settings.protect_protected_file_patterns_desc=即使用户有权添加、编辑或删除此分支中的文件,也不允许直接更改受保护的文件。 可以使用分号 (';') 分隔多个模式。 见<a href='%[1]s'>%[2]s</a>文档了解模式语法。例如: <code>.drone.yml</code>, <code>/docs/**/*.txt</code> settings.protect_protected_file_patterns_desc=即使用户有权添加、编辑或删除此分支中的文件,也不允许直接更改受保护的文件。 可以使用分号「;」分隔多个表达式。 见<a href='%[1]s'>%[2]s</a>文档了解表达式语法。例如: <code>.drone.yml</code>, <code>/docs/**/*.txt</code>
settings.protect_unprotected_file_patterns=不受保护的文件模式(使用分号 ';' 分隔) settings.protect_unprotected_file_patterns=不受保护的文件表达式(使用分号「;」分隔)
settings.protect_unprotected_file_patterns_desc=如果用户有写权限,则允许直接更改的不受保护的文件,以绕过推送限制。可以使用分号分隔多个模式 (';')。 见 <a href='%[1]s'>%[2]s</a> 文档了解模式语法。例如: <code>.drone.yml</code>, <code>/docs/**/*.txt</code> settings.protect_unprotected_file_patterns_desc=如果用户有写权限,则允许直接更改的不受保护的文件,以绕过推送限制。可以使用分号分隔多个表达式「;」。 见 <a href='%[1]s'>%[2]s</a> 文档了解表达式语法。例如: <code>.drone.yml</code>, <code>/docs/**/*.txt</code>
settings.add_protected_branch=启用保护 settings.add_protected_branch=启用保护
settings.delete_protected_branch=禁用保护 settings.delete_protected_branch=禁用保护
settings.update_protect_branch_success=分支保护规则「%s」更新成功。 settings.update_protect_branch_success=分支保护规则「%s」更新成功。
@ -2537,15 +2537,15 @@ settings.protected_branch_required_rule_name=必须填写规则名称
settings.protected_branch_duplicate_rule_name=规则名称已存在 settings.protected_branch_duplicate_rule_name=规则名称已存在
settings.protected_branch_required_approvals_min=所需的审批数不能为负数。 settings.protected_branch_required_approvals_min=所需的审批数不能为负数。
settings.tags=标签 settings.tags=标签
settings.tags.protection=Git 标签保护 settings.tags.protection=标签保护
settings.tags.protection.pattern=Git 标签表达式 settings.tags.protection.pattern=标签表达式
settings.tags.protection.allowed=允许列表 settings.tags.protection.allowed=允许列表
settings.tags.protection.allowed.users=允许的账号 settings.tags.protection.allowed.users=允许的账号
settings.tags.protection.allowed.teams=允许的团队 settings.tags.protection.allowed.teams=允许的团队
settings.tags.protection.allowed.noone= settings.tags.protection.allowed.noone=
settings.tags.protection.create=保护 Git 标签 settings.tags.protection.create=保护标签
settings.tags.protection.none=没有受保护的 Git 标签。 settings.tags.protection.none=没有受保护的标签。
settings.tags.protection.pattern.description=您可以使用单个名称或 glob 式匹配或正则表达式来匹配多个标签。了解详情请访问 <a target="_blank" rel="noopener" href="%s">保护 Git 标签指南</a>。 settings.tags.protection.pattern.description=您可以使用单个名称或 glob 表达式匹配或正则表达式来匹配多个标签。了解详情请访问 <a target="_blank" rel="noopener" href="%s">保护标签指南</a>。
settings.bot_token=Bot 令牌 settings.bot_token=Bot 令牌
settings.chat_id=聊天 ID settings.chat_id=聊天 ID
settings.thread_id=线程 ID settings.thread_id=线程 ID
@ -2571,7 +2571,7 @@ settings.archive.success=仓库已成功归档。
settings.archive.error=仓库在归档时出现异常。请通过日志获取详细信息。 settings.archive.error=仓库在归档时出现异常。请通过日志获取详细信息。
settings.archive.error_ismirror=请不要对镜像仓库归档,谢谢! settings.archive.error_ismirror=请不要对镜像仓库归档,谢谢!
settings.archive.branchsettings_unavailable=已归档仓库无法进行分支设置。 settings.archive.branchsettings_unavailable=已归档仓库无法进行分支设置。
settings.archive.tagsettings_unavailable=已归档仓库的 Git 标签设置不可用。 settings.archive.tagsettings_unavailable=已归档仓库的标签设置不可用。
settings.archive.mirrors_unavailable=如果仓库已归档,镜像将不可用。 settings.archive.mirrors_unavailable=如果仓库已归档,镜像将不可用。
settings.unarchive.button=撤销仓库归档 settings.unarchive.button=撤销仓库归档
settings.unarchive.header=撤销此仓库归档 settings.unarchive.header=撤销此仓库归档
@ -2672,7 +2672,7 @@ diff.submodule_updated=子模块 %[1]s 已更新:%[2]s
releases.desc=跟踪项目版本和下载。 releases.desc=跟踪项目版本和下载。
release.releases=发布 release.releases=发布
release.detail=发布详情 release.detail=发布详情
release.tags=Git 标签 release.tags=标签
release.new_release=发布新版 release.new_release=发布新版
release.draft=草稿 release.draft=草稿
release.prerelease=预发布 release.prerelease=预发布
@ -2701,16 +2701,16 @@ release.publish=发布版本
release.save_draft=保存草稿 release.save_draft=保存草稿
release.edit_release=保存此次发布 release.edit_release=保存此次发布
release.delete_release=删除发布 release.delete_release=删除发布
release.delete_tag=删除 Git 标签 release.delete_tag=删除标签
release.deletion=删除发布 release.deletion=删除发布
release.deletion_desc=删除版本发布只会从 Gitea 中移除。这不会影响 Git 的标签以及您仓库的内容和历史。是否继续? release.deletion_desc=删除发布只会从 Gitea 中移除发布。这不会影响 Git 的标签以及您仓库的内容和历史。是否继续?
release.deletion_success=该发布已删除。 release.deletion_success=该发布已删除。
release.deletion_tag_desc=将从仓库中删除此 Git 标签。仓库内容和历史记录保持不变。继续吗? release.deletion_tag_desc=将从仓库中删除此标签。仓库内容和历史记录保持不变。继续吗?
release.deletion_tag_success= Git 标签已删除。 release.deletion_tag_success=标签已删除。
release.tag_name_already_exist=使用此标签名称的发布已经存在。 release.tag_name_already_exist=使用此标签名称的发布已经存在。
release.tag_name_invalid=标签名称无效。 release.tag_name_invalid=标签名称无效。
release.tag_name_protected=Git 标签名已受保护。 release.tag_name_protected=标签名已受保护。
release.tag_already_exist= Git 标签名已存在。 release.tag_already_exist=标签名已存在。
release.downloads=下载附件 release.downloads=下载附件
release.download_count=下载:%s release.download_count=下载:%s
release.add_tag_msg=使用发布的标题和内容作为标签消息。 release.add_tag_msg=使用发布的标题和内容作为标签消息。
@ -2809,7 +2809,7 @@ team_unit_desc=允许访问仓库单元
team_unit_disabled=(已禁用) team_unit_disabled=(已禁用)
form.name_reserved=组织名称「%s」是保留的。 form.name_reserved=组织名称「%s」是保留的。
form.name_pattern_not_allowed=仓库名称中不允许使用「%s」 form.name_pattern_not_allowed=组织名中不允许使用「%s」格式
form.create_org_not_allowed=此账号禁止创建组织 form.create_org_not_allowed=此账号禁止创建组织
settings=组织设置 settings=组织设置
@ -3305,7 +3305,7 @@ config.db_type=类型
config.db_host=主机 config.db_host=主机
config.db_name=数据库名称 config.db_name=数据库名称
config.db_user=用户名 config.db_user=用户名
config.db_schema=架构模式 config.db_schema=架构
config.db_ssl_mode=SSL config.db_ssl_mode=SSL
config.db_path=数据库路径 config.db_path=数据库路径
@ -3476,10 +3476,10 @@ rename_repo=重命名仓库 <code>%[1]s</code> 为 <a href="%[2]s">%[3]s</a>
commit_repo=推送到了仓库 <a href="%[1]s">%[4]s</a> 的 <a href="%[2]s">%[3]s</a> 分支 commit_repo=推送到了仓库 <a href="%[1]s">%[4]s</a> 的 <a href="%[2]s">%[3]s</a> 分支
create_issue=`创建了工单 <a href="%[1]s">%[3]s#%[2]s</a>` create_issue=`创建了工单 <a href="%[1]s">%[3]s#%[2]s</a>`
close_issue=`关闭了工单 <a href="%[1]s">%[3]s#%[2]s</a>` close_issue=`关闭了工单 <a href="%[1]s">%[3]s#%[2]s</a>`
reopen_issue=`重新了工单 <a href="%[1]s">%[3]s#%[2]s</a>` reopen_issue=`重新开了工单 <a href="%[1]s">%[3]s#%[2]s</a>`
create_pull_request=`创建了合并请求 <a href="%[1]s">%[3]s#%[2]s</a>` create_pull_request=`创建了合并请求 <a href="%[1]s">%[3]s#%[2]s</a>`
close_pull_request=`关闭了合并请求 <a href="%[1]s">%[3]s#%[2]s</a>` close_pull_request=`关闭了合并请求 <a href="%[1]s">%[3]s#%[2]s</a>`
reopen_pull_request=`重新了合并请求 <a href="%[1]s">%[3]s#%[2]s</a>` reopen_pull_request=`重新开了合并请求 <a href="%[1]s">%[3]s#%[2]s</a>`
comment_issue=`评论了工单 <a href="%[1]s">%[3]s#%[2]s</a>` comment_issue=`评论了工单 <a href="%[1]s">%[3]s#%[2]s</a>`
comment_pull=`评论了合并请求 <a href="%[1]s">%[3]s#%[2]s</a>` comment_pull=`评论了合并请求 <a href="%[1]s">%[3]s#%[2]s</a>`
merge_pull_request=`合并了合并请求 <a href="%[1]s">%[3]s#%[2]s</a>` merge_pull_request=`合并了合并请求 <a href="%[1]s">%[3]s#%[2]s</a>`
@ -3704,7 +3704,7 @@ owner.settings.cleanuprules.preview=清理规则预览
owner.settings.cleanuprules.preview.overview=%d 个软件包计划被删除。 owner.settings.cleanuprules.preview.overview=%d 个软件包计划被删除。
owner.settings.cleanuprules.preview.none=清理规则与任何软件包都不匹配。 owner.settings.cleanuprules.preview.none=清理规则与任何软件包都不匹配。
owner.settings.cleanuprules.enabled=启用 owner.settings.cleanuprules.enabled=启用
owner.settings.cleanuprules.pattern_full_match=应用规则到完整软件包名称 owner.settings.cleanuprules.pattern_full_match=应用表达式到完整软件包名称
owner.settings.cleanuprules.keep.title=与这些规则相匹配的版本即使与下面的删除规则相匹配,也将予以保留。 owner.settings.cleanuprules.keep.title=与这些规则相匹配的版本即使与下面的删除规则相匹配,也将予以保留。
owner.settings.cleanuprules.keep.count=保留最新的 owner.settings.cleanuprules.keep.count=保留最新的
owner.settings.cleanuprules.keep.count.1=每个软件包1个版本 owner.settings.cleanuprules.keep.count.1=每个软件包1个版本

2
package-lock.json generated
View File

@ -117,7 +117,7 @@
"vue-tsc": "2.2.10" "vue-tsc": "2.2.10"
}, },
"engines": { "engines": {
"node": ">= 18.0.0" "node": ">= 20.0.0"
} }
}, },
"node_modules/@alloc/quick-lru": { "node_modules/@alloc/quick-lru": {

View File

@ -1,7 +1,7 @@
{ {
"type": "module", "type": "module",
"engines": { "engines": {
"node": ">= 18.0.0" "node": ">= 20.0.0"
}, },
"dependencies": { "dependencies": {
"@citation-js/core": "0.7.18", "@citation-js/core": "0.7.18",

View File

@ -313,13 +313,12 @@ func InitiateUploadBlob(ctx *context.Context) {
setResponseHeaders(ctx.Resp, &containerHeaders{ setResponseHeaders(ctx.Resp, &containerHeaders{
Location: fmt.Sprintf("/v2/%s/%s/blobs/uploads/%s", ctx.Package.Owner.LowerName, image, upload.ID), Location: fmt.Sprintf("/v2/%s/%s/blobs/uploads/%s", ctx.Package.Owner.LowerName, image, upload.ID),
Range: "0-0",
UploadUUID: upload.ID, UploadUUID: upload.ID,
Status: http.StatusAccepted, Status: http.StatusAccepted,
}) })
} }
// https://docs.docker.com/registry/spec/api/#get-blob-upload // https://github.com/opencontainers/distribution-spec/blob/main/spec.md#pushing-a-blob-in-chunks
func GetUploadBlob(ctx *context.Context) { func GetUploadBlob(ctx *context.Context) {
uuid := ctx.PathParam("uuid") uuid := ctx.PathParam("uuid")
@ -333,13 +332,18 @@ func GetUploadBlob(ctx *context.Context) {
return return
} }
setResponseHeaders(ctx.Resp, &containerHeaders{ // FIXME: undefined behavior when the uploaded content is empty: https://github.com/opencontainers/distribution-spec/issues/578
Range: fmt.Sprintf("0-%d", upload.BytesReceived), respHeaders := &containerHeaders{
UploadUUID: upload.ID, UploadUUID: upload.ID,
Status: http.StatusNoContent, Status: http.StatusNoContent,
}) }
if upload.BytesReceived > 0 {
respHeaders.Range = fmt.Sprintf("0-%d", upload.BytesReceived-1)
}
setResponseHeaders(ctx.Resp, respHeaders)
} }
// https://github.com/opencontainers/distribution-spec/blob/main/spec.md#single-post
// https://github.com/opencontainers/distribution-spec/blob/main/spec.md#pushing-a-blob-in-chunks // https://github.com/opencontainers/distribution-spec/blob/main/spec.md#pushing-a-blob-in-chunks
func UploadBlob(ctx *context.Context) { func UploadBlob(ctx *context.Context) {
image := ctx.PathParam("image") image := ctx.PathParam("image")
@ -377,12 +381,15 @@ func UploadBlob(ctx *context.Context) {
return return
} }
setResponseHeaders(ctx.Resp, &containerHeaders{ respHeaders := &containerHeaders{
Location: fmt.Sprintf("/v2/%s/%s/blobs/uploads/%s", ctx.Package.Owner.LowerName, image, uploader.ID), Location: fmt.Sprintf("/v2/%s/%s/blobs/uploads/%s", ctx.Package.Owner.LowerName, image, uploader.ID),
Range: fmt.Sprintf("0-%d", uploader.Size()-1),
UploadUUID: uploader.ID, UploadUUID: uploader.ID,
Status: http.StatusAccepted, Status: http.StatusAccepted,
}) }
if contentRange != "" {
respHeaders.Range = fmt.Sprintf("0-%d", uploader.Size()-1)
}
setResponseHeaders(ctx.Resp, respHeaders)
} }
// https://github.com/opencontainers/distribution-spec/blob/main/spec.md#pushing-a-blob-in-chunks // https://github.com/opencontainers/distribution-spec/blob/main/spec.md#pushing-a-blob-in-chunks

View File

@ -20,7 +20,7 @@ func SSHInfo(rw http.ResponseWriter, req *http.Request) {
return return
} }
rw.Header().Set("content-type", "text/json;charset=UTF-8") rw.Header().Set("content-type", "text/json;charset=UTF-8")
_, err := rw.Write([]byte(`{"type":"gitea","version":1}`)) _, err := rw.Write([]byte(`{"type":"agit","version":1}`))
if err != nil { if err != nil {
log.Error("fail to write result: err: %v", err) log.Error("fail to write result: err: %v", err)
rw.WriteHeader(http.StatusInternalServerError) rw.WriteHeader(http.StatusInternalServerError)

View File

@ -140,13 +140,6 @@ func prepareToRenderFile(ctx *context.Context, entry *git.TreeEntry) {
ctx.Data["LFSLockHint"] = ctx.Tr("repo.editor.this_file_locked") ctx.Data["LFSLockHint"] = ctx.Tr("repo.editor.this_file_locked")
} }
// Assume file is not editable first.
if fInfo.isLFSFile {
ctx.Data["EditFileTooltip"] = ctx.Tr("repo.editor.cannot_edit_lfs_files")
} else if !isRepresentableAsText {
ctx.Data["EditFileTooltip"] = ctx.Tr("repo.editor.cannot_edit_non_text_files")
}
// read all needed attributes which will be used later // read all needed attributes which will be used later
// there should be no performance different between reading 2 or 4 here // there should be no performance different between reading 2 or 4 here
attrsMap, err := attribute.CheckAttributes(ctx, ctx.Repo.GitRepo, ctx.Repo.CommitID, attribute.CheckAttributeOpts{ attrsMap, err := attribute.CheckAttributes(ctx, ctx.Repo.GitRepo, ctx.Repo.CommitID, attribute.CheckAttributeOpts{
@ -243,21 +236,6 @@ func prepareToRenderFile(ctx *context.Context, entry *git.TreeEntry) {
ctx.Data["FileContent"] = fileContent ctx.Data["FileContent"] = fileContent
ctx.Data["LineEscapeStatus"] = statuses ctx.Data["LineEscapeStatus"] = statuses
} }
if !fInfo.isLFSFile {
if ctx.Repo.CanEnableEditor(ctx, ctx.Doer) {
if lfsLock != nil && lfsLock.OwnerID != ctx.Doer.ID {
ctx.Data["CanEditFile"] = false
ctx.Data["EditFileTooltip"] = ctx.Tr("repo.editor.this_file_locked")
} else {
ctx.Data["CanEditFile"] = true
ctx.Data["EditFileTooltip"] = ctx.Tr("repo.editor.edit_this_file")
}
} else if !ctx.Repo.RefFullName.IsBranch() {
ctx.Data["EditFileTooltip"] = ctx.Tr("repo.editor.must_be_on_a_branch")
} else if !ctx.Repo.CanWriteToBranch(ctx, ctx.Doer, ctx.Repo.BranchName) {
ctx.Data["EditFileTooltip"] = ctx.Tr("repo.editor.fork_before_edit")
}
}
case fInfo.st.IsPDF(): case fInfo.st.IsPDF():
ctx.Data["IsPDFFile"] = true ctx.Data["IsPDFFile"] = true
@ -307,17 +285,49 @@ func prepareToRenderFile(ctx *context.Context, entry *git.TreeEntry) {
} }
} }
if ctx.Repo.CanEnableEditor(ctx, ctx.Doer) { prepareToRenderButtons(ctx, fInfo.isLFSFile, isRepresentableAsText, lfsLock)
if lfsLock != nil && lfsLock.OwnerID != ctx.Doer.ID { }
ctx.Data["CanDeleteFile"] = false
ctx.Data["DeleteFileTooltip"] = ctx.Tr("repo.editor.this_file_locked") func prepareToRenderButtons(ctx *context.Context, isLFSFile, isRepresentableAsText bool, lfsLock *git_model.LFSLock) {
} else { // archived or mirror repository, the buttons should not be shown
ctx.Data["CanDeleteFile"] = true if ctx.Repo.Repository.IsArchived || !ctx.Repo.Repository.CanEnableEditor() {
ctx.Data["DeleteFileTooltip"] = ctx.Tr("repo.editor.delete_this_file") return
} }
} else if !ctx.Repo.RefFullName.IsBranch() {
ctx.Data["DeleteFileTooltip"] = ctx.Tr("repo.editor.must_be_on_a_branch") // The buttons should not be shown if it's not a branch
} else if !ctx.Repo.CanWriteToBranch(ctx, ctx.Doer, ctx.Repo.BranchName) { if !ctx.Repo.RefFullName.IsBranch() {
ctx.Data["DeleteFileTooltip"] = ctx.Tr("repo.editor.must_have_write_access") ctx.Data["EditFileTooltip"] = ctx.Tr("repo.editor.must_be_on_a_branch")
} ctx.Data["DeleteFileTooltip"] = ctx.Tr("repo.editor.must_be_on_a_branch")
return
}
if isLFSFile {
ctx.Data["EditFileTooltip"] = ctx.Tr("repo.editor.cannot_edit_lfs_files")
} else if !isRepresentableAsText {
ctx.Data["EditFileTooltip"] = ctx.Tr("repo.editor.cannot_edit_non_text_files")
}
if !ctx.Repo.CanWriteToBranch(ctx, ctx.Doer, ctx.Repo.BranchName) {
if !isLFSFile { // lfs file cannot be edited after fork
ctx.Data["EditFileTooltip"] = ctx.Tr("repo.editor.fork_before_edit")
}
ctx.Data["DeleteFileTooltip"] = ctx.Tr("repo.editor.must_have_write_access")
return
}
// it's a lfs file and the user is not the owner of the lock
if lfsLock != nil && lfsLock.OwnerID != ctx.Doer.ID {
ctx.Data["CanEditFile"] = false
ctx.Data["EditFileTooltip"] = ctx.Tr("repo.editor.this_file_locked")
ctx.Data["CanDeleteFile"] = false
ctx.Data["DeleteFileTooltip"] = ctx.Tr("repo.editor.this_file_locked")
return
}
if !isLFSFile { // lfs file cannot be edited
ctx.Data["CanEditFile"] = true
ctx.Data["EditFileTooltip"] = ctx.Tr("repo.editor.edit_this_file")
}
ctx.Data["CanDeleteFile"] = true
ctx.Data["DeleteFileTooltip"] = ctx.Tr("repo.editor.delete_this_file")
} }

View File

@ -123,7 +123,8 @@ func (r *Repository) CanCommitToBranch(ctx context.Context, doer *user_model.Use
sign, keyID, _, err := asymkey_service.SignCRUDAction(ctx, r.Repository.RepoPath(), doer, r.Repository.RepoPath(), git.BranchPrefix+r.BranchName) sign, keyID, _, err := asymkey_service.SignCRUDAction(ctx, r.Repository.RepoPath(), doer, r.Repository.RepoPath(), git.BranchPrefix+r.BranchName)
canCommit := r.CanEnableEditor(ctx, doer) && userCanPush canEnableEditor := r.CanEnableEditor(ctx, doer)
canCommit := canEnableEditor && userCanPush
if requireSigned { if requireSigned {
canCommit = canCommit && sign canCommit = canCommit && sign
} }
@ -139,7 +140,7 @@ func (r *Repository) CanCommitToBranch(ctx context.Context, doer *user_model.Use
return CanCommitToBranchResults{ return CanCommitToBranchResults{
CanCommitToBranch: canCommit, CanCommitToBranch: canCommit,
EditorEnabled: r.CanEnableEditor(ctx, doer), EditorEnabled: canEnableEditor,
UserCanPush: userCanPush, UserCanPush: userCanPush,
RequireSigned: requireSigned, RequireSigned: requireSigned,
WillSign: sign, WillSign: sign,

View File

@ -311,7 +311,7 @@ func TestPackageContainer(t *testing.T) {
resp = MakeRequest(t, req, http.StatusNoContent) resp = MakeRequest(t, req, http.StatusNoContent)
assert.Equal(t, uuid, resp.Header().Get("Docker-Upload-Uuid")) assert.Equal(t, uuid, resp.Header().Get("Docker-Upload-Uuid"))
assert.Equal(t, fmt.Sprintf("0-%d", len(blobContent)), resp.Header().Get("Range")) assert.Equal(t, contentRange, resp.Header().Get("Range"))
pbu, err = packages_model.GetBlobUploadByID(db.DefaultContext, uuid) pbu, err = packages_model.GetBlobUploadByID(db.DefaultContext, uuid)
assert.NoError(t, err) assert.NoError(t, err)
@ -342,7 +342,8 @@ func TestPackageContainer(t *testing.T) {
resp = MakeRequest(t, req, http.StatusNoContent) resp = MakeRequest(t, req, http.StatusNoContent)
assert.Equal(t, uuid, resp.Header().Get("Docker-Upload-Uuid")) assert.Equal(t, uuid, resp.Header().Get("Docker-Upload-Uuid"))
assert.Equal(t, "0-0", resp.Header().Get("Range")) // FIXME: undefined behavior when the uploaded content is empty: https://github.com/opencontainers/distribution-spec/issues/578
assert.Nil(t, resp.Header().Values("Range"))
req = NewRequest(t, "DELETE", setting.AppURL+uploadURL[1:]). req = NewRequest(t, "DELETE", setting.AppURL+uploadURL[1:]).
AddTokenAuth(userToken) AddTokenAuth(userToken)

View File

@ -525,6 +525,7 @@ $.fn.dropdown = function(parameters) {
return true; return true;
} }
if(settings.onShow.call(element) !== false) { if(settings.onShow.call(element) !== false) {
settings.onAfterFiltered.call(element); // GITEA-PATCH: callback to correctly handle the filtered items
module.animate.show(function() { module.animate.show(function() {
if( module.can.click() ) { if( module.can.click() ) {
module.bind.intent(); module.bind.intent();

View File

@ -56,8 +56,12 @@ async function fetchActionDoRequest(actionElem: HTMLElement, url: string, opt: R
actionElem.classList.remove('is-loading', 'loading-icon-2px'); actionElem.classList.remove('is-loading', 'loading-icon-2px');
} }
async function formFetchAction(formEl: HTMLFormElement, e: SubmitEvent) { async function onFormFetchActionSubmit(formEl: HTMLFormElement, e: SubmitEvent) {
e.preventDefault(); e.preventDefault();
await submitFormFetchAction(formEl, submitEventSubmitter(e));
}
export async function submitFormFetchAction(formEl: HTMLFormElement, formSubmitter?: HTMLElement) {
if (formEl.classList.contains('is-loading')) return; if (formEl.classList.contains('is-loading')) return;
formEl.classList.add('is-loading'); formEl.classList.add('is-loading');
@ -68,7 +72,6 @@ async function formFetchAction(formEl: HTMLFormElement, e: SubmitEvent) {
const formMethod = formEl.getAttribute('method') || 'get'; const formMethod = formEl.getAttribute('method') || 'get';
const formActionUrl = formEl.getAttribute('action'); const formActionUrl = formEl.getAttribute('action');
const formData = new FormData(formEl); const formData = new FormData(formEl);
const formSubmitter = submitEventSubmitter(e);
const [submitterName, submitterValue] = [formSubmitter?.getAttribute('name'), formSubmitter?.getAttribute('value')]; const [submitterName, submitterValue] = [formSubmitter?.getAttribute('name'), formSubmitter?.getAttribute('value')];
if (submitterName) { if (submitterName) {
formData.append(submitterName, submitterValue || ''); formData.append(submitterName, submitterValue || '');
@ -96,7 +99,7 @@ async function formFetchAction(formEl: HTMLFormElement, e: SubmitEvent) {
await fetchActionDoRequest(formEl, reqUrl, reqOpt); await fetchActionDoRequest(formEl, reqUrl, reqOpt);
} }
async function linkAction(el: HTMLElement, e: Event) { async function onLinkActionClick(el: HTMLElement, e: Event) {
// A "link-action" can post AJAX request to its "data-url" // A "link-action" can post AJAX request to its "data-url"
// Then the browser is redirected to: the "redirect" in response, or "data-redirect" attribute, or current URL by reloading. // Then the browser is redirected to: the "redirect" in response, or "data-redirect" attribute, or current URL by reloading.
// If the "link-action" has "data-modal-confirm" attribute, a confirm modal dialog will be shown before taking action. // If the "link-action" has "data-modal-confirm" attribute, a confirm modal dialog will be shown before taking action.
@ -126,6 +129,6 @@ async function linkAction(el: HTMLElement, e: Event) {
} }
export function initGlobalFetchAction() { export function initGlobalFetchAction() {
addDelegatedEventListener(document, 'submit', '.form-fetch-action', formFetchAction); addDelegatedEventListener(document, 'submit', '.form-fetch-action', onFormFetchActionSubmit);
addDelegatedEventListener(document, 'click', '.link-action', linkAction); addDelegatedEventListener(document, 'click', '.link-action', onLinkActionClick);
} }

View File

@ -1,5 +1,6 @@
import {toggleElem} from '../../utils/dom.ts'; import {toggleElem} from '../../utils/dom.ts';
import {fomanticQuery} from '../../modules/fomantic/base.ts'; import {fomanticQuery} from '../../modules/fomantic/base.ts';
import {submitFormFetchAction} from '../common-fetch-action.ts';
function nameHasScope(name: string): boolean { function nameHasScope(name: string): boolean {
return /.*[^/]\/[^/].*/.test(name); return /.*[^/]\/[^/].*/.test(name);
@ -70,7 +71,7 @@ export function initCompLabelEdit(pageSelector: string) {
form.reportValidity(); form.reportValidity();
return false; return false;
} }
form.dispatchEvent(new Event('submit', {bubbles: true})); submitFormFetchAction(form);
}, },
}).modal('show'); }).modal('show');
}; };