Compare commits

...

7 Commits

Author SHA1 Message Date
CaiCandong
b937adc54d
Update index doc (#26455)
In the previous feature description, numerous functionalities of Gitea
were listed, which appeared redundant and failed to highlight the unique
characteristics of Gitea. Therefore, I have rewritten this section based
on the description provided on the official Gitea website
2023-08-12 00:49:23 +00:00
GiteaBot
e17e43f1db [skip ci] Updated translations via Crowdin 2023-08-12 00:20:47 +00:00
Denys Konovalov
46660f1614
remove unnecessary explore org template (#26459) 2023-08-11 16:07:04 -04:00
Panagiotis "Ivory" Vasilopoulos
73f6535406
Fix URL of padlock icon in profile (#26446) 2023-08-11 17:40:38 +00:00
JakobDev
f3fbb7c67d
Count only visible repos on profile (#25928)
Fixes #25914
2023-08-11 13:08:05 -04:00
Lunny Xiao
7e382a5555
Update upgrade documentation to add a check for deprecated configurations (#26451)
fix
https://github.com/go-gitea/gitea/issues/25995#issuecomment-1674096710

---------

Co-authored-by: silverwind <me@silverwind.io>
2023-08-11 13:53:23 +08:00
silverwind
a838901a06
Fall back to esbuild for css minify (#26445)
Fixes https://github.com/go-gitea/gitea/issues/26439.

The minification result is not ideal with esbuild, but it's better than
failing competely.

Co-authored-by: Giteabot <teabot@gitea.io>
2023-08-11 06:13:25 +02:00
18 changed files with 321 additions and 606 deletions

View File

@ -25,244 +25,27 @@ You can try it out using [the online demo](https://try.gitea.io/).
## Features
- User Dashboard
- Context switcher (organization or current user)
- Activity timeline
- Commits
- Issues
- Pull requests
- Repository creation
- Searchable repository list
- List of organizations
- A list of mirror repositories
- Issues dashboard
- Context switcher (organization or current user)
- Filter by
- Open
- Closed
- Your repositories
- Assigned issues
- Your issues
- Repository
- Sort by
- Oldest
- Last updated
- Number of comments
- Pull request dashboard
- Same as issue dashboard
- Repository types
- Mirror
- Normal
- Migrated
- Notifications (email and web)
- Read
- Unread
- Pin
- Explore page
- Users
- Repos
- Organizations
- Search
- Custom templates
- Override public files (logo, css, etc)
- CSRF and XSS protection
- HTTPS support
- Set allowed upload sizes and types
- Logging
- Configuration
- Databases
- MySQL (>=5.7)
- PostgreSQL (>=10)
- SQLite3
- MSSQL (>=2008R2 SP3)
- TiDB (MySQL protocol)
- Configuration file
- [app.ini](https://github.com/go-gitea/gitea/blob/main/custom/conf/app.example.ini)
- Admin panel
- Statistics
- Actions
- Delete inactive accounts
- Delete cached repository archives
- Delete repositories records which are missing their files
- Run garbage collection on repositories
- Rewrite SSH keys
- Resync hooks
- Recreate repositories which are missing
- Server status
- Uptime
- Memory
- Current # of goroutines
- And more
- User management
- Search
- Sort
- Last login
- Authentication source
- Maximum repositories
- Disable account
- Admin permissions
- Permission to create Git Hooks
- Permission to create organizations
- Permission to import repositories
- Organization management
- Members
- Teams
- Avatar
- Hooks
- Repository management
- See all repository information and manage repositories
- Authentication sources
- OAuth
- PAM
- LDAP
- SMTP
- Configuration viewer
- Everything in config file
- System notices
- When something unexpected happens
- Monitoring
- Current processes
- Cron jobs
- Update mirrors
- Repository health check
- Check repository statistics
- Clean up old archives
- Environment variables
- Command line options
- Multi-language support ([21 languages](https://github.com/go-gitea/gitea/tree/main/options/locale))
- [Mermaid](https://mermaidjs.github.io/) diagrams in Markdown
- Math syntax in Markdown
- Mail service
- Notifications
- Registration confirmation
- Password reset
- Reverse proxy support
- Includes subpaths
- Users
- Profile
- Name
- Username
- Email
- Website
- Join date
- Followers and following
- Organizations
- Repositories
- Activity
- Starred repositories
- Settings
- Same as profile and more below
- Keep email private
- Avatar
- Gravatar
- Libravatar
- Custom
- Password
- Multiple email addresses
- SSH Keys
- Connected applications
- Two factor authentication
- Linked OAuth2 sources
- Delete account
- Repositories
- Clone with SSH/HTTP/HTTPS
- Git LFS
- Watch, Star, Fork
- View watchers, stars, and forks
- Code
- Branch browser
- Web based file upload and creation
- Clone urls
- Download
- ZIP
- TAR.GZ
- Web based editor
- Markdown editor
- Plain text editor
- Syntax highlighting
- Diff preview
- Preview
- Choose where to commit to
- View file history
- Delete file
- View raw
- Issues
- Issue templates
- Milestones
- Labels
- Assign issues
- Track time
- Reactions
- Filter
- Open
- Closed
- Assigned person
- Created by you
- Mentioning you
- Sort
- Oldest
- Last updated
- Number of comments
- Search
- Comments
- Attachments
- Pull requests
- Same features as issues
- Commits
- Commit graph
- Commits by branch
- Search
- Search in all branches
- View diff
- View SHA
- View author
- Browse files in commit
- Releases
- Attachments
- Title
- Content
- Delete
- Mark as pre-release
- Choose branch
- Wiki
- Import
- Markdown editor
- Settings
- Options
- Name
- Description
- Private/Public
- Website
- Wiki
- Enabled/disabled
- Internal/external
- Issues
- Enabled/disabled
- Internal/external
- External supports url rewriting for better integration
- Enable/disable pull requests
- Transfer repository
- Delete wiki
- Delete repository
- Collaboration
- Read/write/admin
- Branches
- Default branch
- Branch protection
- Webhooks
- Git Hooks
- Deploy keys
- Package Registries
- Composer
- Conan
- Container
- Generic
- Helm
- Maven
- NPM
- Nuget
- PyPI
- RubyGems
- Code Hosting: Gitea supports creating and managing repositories, browsing commit history and code files, reviewing and merging code submissions, managing collaborators, handling branches, and more. It also supports many common Git features such as tags, Cherry-pick, hooks, integrated collaboration tools, and more.
- Lightweight and Fast: One of Gitea's design goals is to be lightweight and fast in response. Unlike some large code hosting platforms, it remains lean, performing well in terms of speed, and is suitable for resource-limited server environments. Due to its lightweight design, Gitea has relatively low resource consumption and performs well in resource-constrained environments.
- Easy Deployment and Maintenance: It can be easily deployed on various servers without complex configurations or dependencies. This makes it convenient for individual developers or small teams to set up and manage their own Git services.
- Security: Gitea places a strong emphasis on security, offering features such as user permission management, access control lists, and more to ensure the security of code and data.
- Code Review: Code review supports both the Pull Request workflow and AGit workflow. Reviewers can browse code online and provide review comments or feedback. Submitters can receive review comments and respond or modify code online. Code reviews can help individuals and organizations enhance code quality.
- CI/CD: Gitea Actions supports CI/CD functionality, compatible with GitHub Actions. Users can write workflows in familiar YAML format and reuse a variety of existing Actions plugins. Actions plugins support downloading from any Git website.
- Project Management: Gitea tracks project requirements, features, and bugs through boards and issues. Issues support features like branches, tags, milestones, assignments, time tracking, due dates, dependencies, and more.
- Artifact Repository: Gitea supports over 20 different types of public or private software package management, including Cargo, Chef, Composer, Conan, Conda, Container, Helm, Maven, npm, NuGet, Pub, PyPI, RubyGems, Vagrant, and more.
- Open Source Community Support: Gitea is an open-source project based on the MIT license. It has an active open-source community that continuously develops and improves the platform. The project also actively welcomes community contributions, ensuring updates and innovation.
- Multilingual Support: Gitea provides interfaces in multiple languages, catering to users globally and promoting internationalization and localization.
Additional Features: For more detailed information, please refer to: https://docs.gitea.com/installation/comparison#general-features
## System Requirements

View File

@ -18,234 +18,27 @@ Gitea 是從 [Gogs](http://gogs.io) Fork 出來的,請閱讀部落格文章 [G
## 功能
- 使用者面板
- 內容切換(組織或目前使用者)
- 動態時間軸
- 提交
- 問題
- 合併請求
- 儲存庫的建立
- 可搜尋的儲存庫清單
- 組織清單
- 鏡像儲存庫清單
- 問題面板
- 內容切換(組織或目前使用者)
- 篩選器
- 開放中
- 已關閉
- 您的儲存庫
- 被指派的問題
- 您的問題
- 儲存庫
- 排序
- 最舊
- 最近更新
- 留言數量
- 合併請求面板
- 和問題面板相同
- 儲存庫類型
- 鏡像
- 一般
- 已遷移
- 通知email 和網頁)
- 已讀
- 未讀
- 釘選
- 探索頁面
- 使用者
- 儲存庫
- 組織
- 搜尋
- 自訂範本
- 複寫 public 檔案logo, css 等)
- CSRF 與 XSS 保護
- 支援 HTTPS
- 設定允許上傳的檔案大小和類型
- 日誌
- 組態
- 資料庫
- MySQL
- PostgreSQL
- SQLite3
- MSSQL
- TiDBMySQL 協議)
- 設定檔
- [app.ini](https://github.com/go-gitea/gitea/blob/main/custom/conf/app.example.ini)
- 管理員面板
- 系統摘要
- 維護操作
- 刪除未啟用帳戶
- 刪除快取的儲存庫存檔
- 刪除遺失 Git 檔案的儲存庫
- 對儲存庫進行垃圾回收
- 重寫 SSH 金鑰
- 重新同步 hooks
- 重新建立遺失的儲存庫
- 伺服器狀態
- 執行時間
- 記憶體
- 目前的 Goroutines 數量
- 還有更多……
- 使用者管理
- 搜尋
- 排序
- 最後登入時間
- 認證來源
- 儲存庫上限
- 停用帳戶
- 管理員權限
- 建立 Git Hook 的權限
- 建立組織的權限
- 匯入儲存庫的權限
- 組織管理
- 成員
- 團隊
- 大頭貼
- Hook
- 儲存庫管理
- 查看所有儲存庫資訊和管理儲存庫
- 認證來源
- OAuth
- PAM
- LDAP
- SMTP
- 組態檢視器
- 所有設定檔中的值
- 系統提示
- 當有未預期的事情發生時
- 應用監控面板
- 目前的處理程序
- Cron 任務
- 更新鏡像
- 儲存庫健康檢查
- 檢查儲存庫的統計資料
- 刪除舊的儲存庫存檔
- 環境變數
- 命令列選項
- 支援多國語言 ([21 種語言](https://github.com/go-gitea/gitea/tree/master/options/locale))
- 支援 [Mermaid](https://mermaidjs.github.io/) 圖表
- 郵件服務
- 通知
- 確認註冊
- 重設密碼
- 支援反向代理Reverse Proxy
- 包含子路徑
- 使用者
- 代碼託管Gitea 支援建立和管理存儲庫、瀏覽提交歷史和程式碼檔案、審查和合併程式碼提交、管理協作者、處理分支等。它還支援許多常見的 Git 功能如標籤、Cherry-pick、鉤子、集成協作工具等。
- 個人資料
- 姓名
- 帳號
- 電子信箱
- 網站
- 加入日期
- 追蹤者和追蹤中
- 組織
- 儲存庫
- 動態
- 已加星號的儲存庫
- 設定
- 和個人資料相同並包含下列功能
- 隱藏電子信箱
- 大頭貼
- Gravatar
- Libravatar
- 自訂
- 密碼
- 多個電子信箱
- SSH 金鑰
- 已連結的應用程式
- 兩步驟驗證
- 已連結 OAuth2 來源
- 刪除帳戶
- 輕量級和快速Gitea 的設計目標之一就是輕量級和快速響應。與某些大型代碼託管平台不同它保持了精簡在速度方面表現出色適用於資源有限的伺服器環境。由於其輕量級設計Gitea 的資源消耗相對較低,在資源受限的環境中表現出色。
- 儲存庫
- 以 SSH/HTTP/HTTPS Clone
- Git LFS
- 關注、星號、Fork
- 檢視關注、已加星號、Fork 的使用者
- 程式碼
- 瀏覽分支
- 從網頁上傳和建立檔案
- Clone url
- 下載
- ZIP
- TAR.GZ
- 網頁程式碼編輯器
- Markdown 編輯器
- 文本編輯器
- 語法高亮
- 預覽差異
- 預覽
- 選擇提交目標分支
- 檢視檔案歷史
- 刪除檔案
- 檢視 raw
- 問題
- 問題範本
- 里程碑
- 標籤
- 指派問題
- 時間追蹤
- 表情反應
- 篩選器
- 開放中
- 已關閉
- 被指派的人
- 您的問題
- 提及您
- 排序
- 最舊
- 最近更新
- 留言數量
- 搜尋
- 留言
- 附件
- 合併請求
- 功能和問題相同
- 提交
- 提交線圖
- 不同分支的提交
- 搜尋
- 在所有分支中搜尋
- 檢視差異diff
- 檢視 SHA
- 檢視作者author
- 瀏覽提交中的檔案
- 版本發佈
- 附件
- 標題
- 內容
- 刪除
- 標記為 pre-release
- 選擇分支
- Wiki
- 匯入
- Markdown 編輯器
- 設定
- 選項
- 名稱
- 描述
- 私有/公開
- 網站
- Wiki
- 開啟/關閉
- 內部/外部
- 問題
- 開啟/關閉
- 內部/外部
- 外部問題追蹤器支援 URL 重寫URL Rewrite以獲得更好的整合性
- 開啟/關閉合併請求
- 轉移儲存庫所有權
- 刪除 wiki
- 刪除儲存庫
- 協作者
- 讀取/寫入/管理員
- 分支
- 預設分支
- 分支保護
- Webhook
- Git hook
- 部署金鑰
- 易於部署和維護:它可以輕鬆地部署在各種伺服器上,無需複雜的配置或依賴。這使得個人開發者或小團隊可以方便地設置和管理自己的 Git 服務。
- 安全性Gitea 強調安全性,提供用戶權限管理、訪問控制列表等功能,確保程式碼和數據的安全性。
- 代碼審查:代碼審查同時支援拉取請求工作流和 AGit 工作流。審查者可以在線瀏覽程式碼並提供審查意見或反饋。提交者可以接收審查意見並在線回覆或修改程式碼。代碼審查可以幫助個人和組織提升程式碼質量。
- CI/CDGitea Actions 支援 CI/CD 功能,與 GitHub Actions 相容。用戶可以使用熟悉的 YAML 格式編寫工作流程,並重複使用各種現有的 Actions 插件。Actions 插件支援從任何 Git 網站下載。
- 專案管理Gitea 通過看板和工單來追蹤一個專案的需求、功能和錯誤。工單支援分支、標籤、里程碑、指派、時間追蹤、到期日期、依賴關係等功能。
- 制品庫Gitea 支援超過 20 種不同類型的公有或私有軟體包管理包括Cargo、Chef、Composer、Conan、Conda、Container、Helm、Maven、npm、NuGet、Pub、PyPI、RubyGems、Vagrant 等。
- 開源社區支援Gitea 是一個基於 MIT 許可證的開源專案,擁有活躍的開源社區,能夠持續進行開發和改進,同時也積極接受社區貢獻,保持了平台的更新和創新。
- 多語言支援Gitea 提供多種語言界面,適應全球範圍內的用戶,促進了國際化和本地化。
更多功能特性詳見https://docs.gitea.com/installation/comparison#general-features
## 系統需求

View File

@ -17,16 +17,20 @@ menu:
# Upgrade from an old Gitea
To update Gitea, download a newer version, stop the old one, perform a backup, and run the new one.
Every time a Gitea instance starts up, it checks whether a database migration should be run.
If a database migration is required, Gitea will take some time to complete the upgrade and then serve.
Follow below steps to ensure a smooth upgrade to a new Gitea version.
## Check the Changelog for breaking changes
To make Gitea better, some breaking changes are unavoidable, especially for big milestone releases.
Before upgrade, please read the [Changelog on Gitea blog](https://blog.gitea.io/)
Before upgrading, please read the [Changelog on Gitea blog](https://blog.gitea.com/)
and check whether the breaking changes affect your Gitea instance.
## Verify there are no deprecated configuration options
New versions of Gitea often come with changed configuration syntax or options which are usually displayed for
at least one release cycle inside at the top of the Site Administration panel. If these warnings are not
resolved, Gitea may refuse to start in the following version.
## Backup for downgrade
Gitea keeps compatibility for patch versions whose first two fields are the same (`a.b.x` -> `a.b.y`),
@ -60,6 +64,11 @@ Backup steps:
If you are using cloud services or filesystems with snapshot feature,
a snapshot for the Gitea data volume and related object storage is more convenient.
After all of steps have been prepared, download the new version, stop the application, perform a backup and
then start the new application. On each startup, Gitea verifies that the database is up to date and will automtically
perform any necessary migrations. Depending on the size of the database, this can take some additional time on the
first launch during which the application will be unavailable.
## Upgrade with Docker
* `docker pull` the latest Gitea release.

View File

@ -15,16 +15,20 @@ menu:
# 从旧版 Gitea 升级
想要升级 Gitea只需要下载新版停止运行旧版进行数据备份然后运行新版就好。
每次 Gitea 实例启动时,它都会检查是否要进行数据库迁移。
如果需要进行数据库迁移Gitea 会花一些时间完成升级然后继续服务。
在升级之前,您需要做如下的准备工作。
## 为重大变更检查更新日志
为了让 Gitea 变得更好,进行重大变更是不可避免的,尤其是一些里程碑更新的发布。
在更新前,请 [在 Gitea 博客上阅读更新日志](https://blog.gitea.io/)
在更新前,请 [在 Gitea 博客上阅读更新日志](https://blog.gitea.com/)
并检查重大变更是否会影响你的 Gitea 实例。
## 在控制面板中检查过期的配置项
一些配置项可能会在后续版本中过期,你需要在控制面板中检查他们。如果不解决过期的配置项,
Gitea也许会在升级后无法重启。你可以访问 https://docs.gitea.com 获得要升级的版本
对应的文档来修改你的配置文件。
## 降级前的备份
Gitea 会保留首二位版本号相同的版本的兼容性 (`a.b.x` -> `a.b.y`)
@ -56,6 +60,10 @@ Gitea 会保留首二位版本号相同的版本的兼容性 (`a.b.x` -> `a.b.y`
如果你在使用云服务或拥有快照功能的文件系统,
最好对 Gitea 的数据盘及相关资料存储进行一次快照。
在所有上述步骤准备妥当之后,要升级 Gitea只需要下载新版停止运行旧版进行数据备份然后运行新版就好。
每次 Gitea 实例启动时,它都会检查是否要进行数据库迁移。
如果需要进行数据库迁移Gitea 会花一些时间完成升级然后继续服务。
## 从 Docker 升级
* `docker pull` 拉取 Gitea 的最新发布版。

View File

@ -522,6 +522,11 @@ func SearchRepository(ctx context.Context, opts *SearchRepoOptions) (RepositoryL
return SearchRepositoryByCondition(ctx, opts, cond, true)
}
// CountRepository counts repositories based on search options,
func CountRepository(ctx context.Context, opts *SearchRepoOptions) (int64, error) {
return db.GetEngine(ctx).Where(SearchRepositoryCondition(opts)).Count(new(Repository))
}
// SearchRepositoryByCondition search repositories by condition
func SearchRepositoryByCondition(ctx context.Context, opts *SearchRepoOptions, cond builder.Cond, loadAttributes bool) (RepositoryList, int64, error) {
sess, count, err := searchRepositoryByCondition(ctx, opts, cond)

View File

@ -15,108 +15,11 @@ import (
"github.com/stretchr/testify/assert"
)
func TestSearchRepository(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
// test search public repository on explore page
repos, count, err := repo_model.SearchRepositoryByName(db.DefaultContext, &repo_model.SearchRepoOptions{
ListOptions: db.ListOptions{
Page: 1,
PageSize: 10,
},
Keyword: "repo_12",
Collaborate: util.OptionalBoolFalse,
})
assert.NoError(t, err)
if assert.Len(t, repos, 1) {
assert.Equal(t, "test_repo_12", repos[0].Name)
}
assert.Equal(t, int64(1), count)
repos, count, err = repo_model.SearchRepositoryByName(db.DefaultContext, &repo_model.SearchRepoOptions{
ListOptions: db.ListOptions{
Page: 1,
PageSize: 10,
},
Keyword: "test_repo",
Collaborate: util.OptionalBoolFalse,
})
assert.NoError(t, err)
assert.Equal(t, int64(2), count)
assert.Len(t, repos, 2)
// test search private repository on explore page
repos, count, err = repo_model.SearchRepositoryByName(db.DefaultContext, &repo_model.SearchRepoOptions{
ListOptions: db.ListOptions{
Page: 1,
PageSize: 10,
},
Keyword: "repo_13",
Private: true,
Collaborate: util.OptionalBoolFalse,
})
assert.NoError(t, err)
if assert.Len(t, repos, 1) {
assert.Equal(t, "test_repo_13", repos[0].Name)
}
assert.Equal(t, int64(1), count)
repos, count, err = repo_model.SearchRepositoryByName(db.DefaultContext, &repo_model.SearchRepoOptions{
ListOptions: db.ListOptions{
Page: 1,
PageSize: 10,
},
Keyword: "test_repo",
Private: true,
Collaborate: util.OptionalBoolFalse,
})
assert.NoError(t, err)
assert.Equal(t, int64(3), count)
assert.Len(t, repos, 3)
// Test non existing owner
repos, count, err = repo_model.SearchRepositoryByName(db.DefaultContext, &repo_model.SearchRepoOptions{OwnerID: unittest.NonexistentID})
assert.NoError(t, err)
assert.Empty(t, repos)
assert.Equal(t, int64(0), count)
// Test search within description
repos, count, err = repo_model.SearchRepository(db.DefaultContext, &repo_model.SearchRepoOptions{
ListOptions: db.ListOptions{
Page: 1,
PageSize: 10,
},
Keyword: "description_14",
Collaborate: util.OptionalBoolFalse,
IncludeDescription: true,
})
assert.NoError(t, err)
if assert.Len(t, repos, 1) {
assert.Equal(t, "test_repo_14", repos[0].Name)
}
assert.Equal(t, int64(1), count)
// Test NOT search within description
repos, count, err = repo_model.SearchRepository(db.DefaultContext, &repo_model.SearchRepoOptions{
ListOptions: db.ListOptions{
Page: 1,
PageSize: 10,
},
Keyword: "description_14",
Collaborate: util.OptionalBoolFalse,
IncludeDescription: false,
})
assert.NoError(t, err)
assert.Empty(t, repos)
assert.Equal(t, int64(0), count)
func getTestCases() []struct {
name string
opts *repo_model.SearchRepoOptions
count int
} {
testCases := []struct {
name string
opts *repo_model.SearchRepoOptions
@ -274,6 +177,113 @@ func TestSearchRepository(t *testing.T) {
},
}
return testCases
}
func TestSearchRepository(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
// test search public repository on explore page
repos, count, err := repo_model.SearchRepositoryByName(db.DefaultContext, &repo_model.SearchRepoOptions{
ListOptions: db.ListOptions{
Page: 1,
PageSize: 10,
},
Keyword: "repo_12",
Collaborate: util.OptionalBoolFalse,
})
assert.NoError(t, err)
if assert.Len(t, repos, 1) {
assert.Equal(t, "test_repo_12", repos[0].Name)
}
assert.Equal(t, int64(1), count)
repos, count, err = repo_model.SearchRepositoryByName(db.DefaultContext, &repo_model.SearchRepoOptions{
ListOptions: db.ListOptions{
Page: 1,
PageSize: 10,
},
Keyword: "test_repo",
Collaborate: util.OptionalBoolFalse,
})
assert.NoError(t, err)
assert.Equal(t, int64(2), count)
assert.Len(t, repos, 2)
// test search private repository on explore page
repos, count, err = repo_model.SearchRepositoryByName(db.DefaultContext, &repo_model.SearchRepoOptions{
ListOptions: db.ListOptions{
Page: 1,
PageSize: 10,
},
Keyword: "repo_13",
Private: true,
Collaborate: util.OptionalBoolFalse,
})
assert.NoError(t, err)
if assert.Len(t, repos, 1) {
assert.Equal(t, "test_repo_13", repos[0].Name)
}
assert.Equal(t, int64(1), count)
repos, count, err = repo_model.SearchRepositoryByName(db.DefaultContext, &repo_model.SearchRepoOptions{
ListOptions: db.ListOptions{
Page: 1,
PageSize: 10,
},
Keyword: "test_repo",
Private: true,
Collaborate: util.OptionalBoolFalse,
})
assert.NoError(t, err)
assert.Equal(t, int64(3), count)
assert.Len(t, repos, 3)
// Test non existing owner
repos, count, err = repo_model.SearchRepositoryByName(db.DefaultContext, &repo_model.SearchRepoOptions{OwnerID: unittest.NonexistentID})
assert.NoError(t, err)
assert.Empty(t, repos)
assert.Equal(t, int64(0), count)
// Test search within description
repos, count, err = repo_model.SearchRepository(db.DefaultContext, &repo_model.SearchRepoOptions{
ListOptions: db.ListOptions{
Page: 1,
PageSize: 10,
},
Keyword: "description_14",
Collaborate: util.OptionalBoolFalse,
IncludeDescription: true,
})
assert.NoError(t, err)
if assert.Len(t, repos, 1) {
assert.Equal(t, "test_repo_14", repos[0].Name)
}
assert.Equal(t, int64(1), count)
// Test NOT search within description
repos, count, err = repo_model.SearchRepository(db.DefaultContext, &repo_model.SearchRepoOptions{
ListOptions: db.ListOptions{
Page: 1,
PageSize: 10,
},
Keyword: "description_14",
Collaborate: util.OptionalBoolFalse,
IncludeDescription: false,
})
assert.NoError(t, err)
assert.Empty(t, repos)
assert.Equal(t, int64(0), count)
testCases := getTestCases()
for _, testCase := range testCases {
t.Run(testCase.name, func(t *testing.T) {
repos, count, err := repo_model.SearchRepositoryByName(db.DefaultContext, testCase.opts)
@ -349,6 +359,21 @@ func TestSearchRepository(t *testing.T) {
}
}
func TestCountRepository(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
testCases := getTestCases()
for _, testCase := range testCases {
t.Run(testCase.name, func(t *testing.T) {
count, err := repo_model.CountRepository(db.DefaultContext, testCase.opts)
assert.NoError(t, err)
assert.Equal(t, int64(testCase.count), count)
})
}
}
func TestSearchRepositoryByTopicName(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())

View File

@ -1126,6 +1126,7 @@ release=Versão
releases=Versões
tag=Tag
released_this=lançou isto
tagged_this=criou essa tag
file.title=%s em %s
file_raw=Original
file_history=Histórico
@ -1339,6 +1340,7 @@ issues.label_templates.title=Carregue um conjunto de etiquetas pré-definidas
issues.label_templates.info=Ainda não existem etiquetas. Crie uma etiqueta em 'Nova etiqueta' ou use um conjunto de etiquetas predefinida:
issues.label_templates.helper=Selecione um conjunto de etiquetas
issues.label_templates.use=Use o conjunto de etiquetas
issues.label_templates.fail_to_load_file=Falha ao carregar o modelo de etiquetas "%s": %v
issues.add_label=adicionou o rótulo %s %s
issues.add_labels=adicionou os rótulos %s %s
issues.remove_label=removeu o rótulo %s %s
@ -1429,6 +1431,8 @@ issues.context.edit=Editar
issues.context.delete=Excluir
issues.no_content=Ainda não há conteúdo.
issues.close=Fechar issue
issues.comment_pull_merged_at=aplicou o merge do commit %[1]s em %[2]s %[3]s
issues.comment_manually_pull_merged_at=aplicou o merge manual do commit %[1]s em %[2]s %[3]s
issues.close_comment_issue=Comentar e fechar
issues.reopen_issue=Reabrir
issues.reopen_comment_issue=Comentar e reabrir
@ -1645,6 +1649,8 @@ pulls.tab_files=Arquivos alterados
pulls.reopen_to_merge=Por favor reabra este pull request para aplicar o merge.
pulls.cant_reopen_deleted_branch=Este pull request não pode ser reaberto porque o branch foi excluído.
pulls.merged=Merge aplicado
pulls.merged_success=Pull request aplicado e fechado com sucesso
pulls.closed=Pull Request Fechado
pulls.manually_merged=Merge aplicado manualmente
pulls.merged_info_text=O branch %s pode ser excluído.
pulls.is_closed=O pull request foi fechado.
@ -1807,10 +1813,13 @@ wiki.file_revision=Revisão de página
wiki.wiki_page_revisions=Revisões de página Wiki
wiki.back_to_wiki=Voltar para página Wiki
wiki.delete_page_button=Excluir página
wiki.delete_page_notice_1=A exclusão da página de wiki "%s" não pode ser desfeita. Continuar?
wiki.page_already_exists=Uma página de wiki com o mesmo nome já existe.
wiki.reserved_page=O nome da página da wiki "%s" está reservado.
wiki.pages=Páginas
wiki.last_updated=Última atualização %s
wiki.page_name_desc=Digite um nome para esta página Wiki. Alguns nomes especiais são: 'Home', '_Sidebar' e '_Footer'.
wiki.original_git_entry_tooltip=Ver o arquivo Git original em vez de usar o link amigável.
activity=Atividade
activity.period.filter_label=Período:
@ -2201,6 +2210,7 @@ settings.require_signed_commits_desc=Rejeitar pushes para este branch se não es
settings.protect_branch_name_pattern=Padrão de Nome de Branch Protegida
settings.protect_patterns=Padrões
settings.protect_protected_file_patterns=Padrões de arquivos protegidos (separados usando ponto e vírgula ';'):
settings.protect_protected_file_patterns_desc=Arquivos protegidos não podem ser alterados diretamente, mesmo que o usuário tenha direitos para adicionar, editar ou excluir arquivos neste branch. Vários padrões podem ser separados usando ponto e vírgula (';'). Consulte a documentação <a href='https://pkg.go.dev/github.com/gobwas/glob#Compile'>github.com/gobwas/glob</a> para a sintaxe padrão. Exemplos: <code>.drone.yml</code>, <code>/docs/**/*.txt</code>.
settings.protect_unprotected_file_patterns=Padrões de arquivos desprotegidos (separados usando ponto e vírgula ';'):
settings.protect_unprotected_file_patterns_desc=Arquivos não protegidos que podem ser alterados diretamente se o usuário tiver acesso de gravação, ignorando as restrições de push. Vários padrões podem ser separados usando ponto e vírgula (\;'). Veja <a href='https://pkg.go.dev/github.com/gobwas/glob#Compile'>github.com/gobwas/glob</a> documentação para sintaxe de padrões. Exemplos: <code>.drone.yml</code>, <code>/docs/**/*.txt</code>.
settings.add_protected_branch=Habilitar proteção
@ -2399,6 +2409,7 @@ branch.delete_html=Excluir Branch
branch.delete_desc=A exclusão de um branch é permanente. Isto <strong>NÃO PODERÁ</strong> ser desfeito. Continuar?
branch.deletion_success=Branch "%s" excluído.
branch.deletion_failed=Falha ao excluir o branch "%s".
branch.delete_branch_has_new_commits=O branch "%s" não pode ser excluído porque novos commits foram feitos após o merge.
branch.create_branch=Criar branch <strong>%s</strong>
branch.create_from=`a partir de "%s"`
branch.create_success=Branch "%s" criado.
@ -3012,6 +3023,7 @@ config.git_pull_timeout=Tempo limite para operação de pull
config.git_gc_timeout=Tempo limite para execução do GC
config.log_config=Configuração de log
config.logger_name_fmt=Logger: %s
config.disabled_logger=Desabilitado
config.access_log_mode=Modo log Access
config.access_log_template=Modelo do registro de acesso
@ -3193,80 +3205,87 @@ versions=Versões
versions.view_all=Ver todas
dependency.id=ID
dependency.version=Versão
alpine.registry=Configure este registro adicionando o URL no arquivo <code>/etc/apk/repositories</code>:
alpine.registry.key=Baixe a chave RSA pública do registro para a pasta <code>/etc/apk/keys/</code> para verificar a assinatura do índice:
alpine.registry.info=Escolha o $branch e $repository da lista abaixo.
alpine.install=Para instalar o pacote, execute o seguinte comando:
alpine.documentation=Para obter mais informações sobre o registro do Alpine Linux, consulte <a target="_blank" rel="noopener noreferrer" href="%s">a documentação</a>.
alpine.repository=Informações do repositório
alpine.repository.branches=Branches
alpine.repository.repositories=Repositórios
alpine.repository.architectures=Arquiteturas
cargo.registry=Configurar este registro no arquivo de configuração de Cargo (por exemplo <code>~/.cargo/config.toml</code>):
cargo.install=Para instalar o pacote usando Cargo, execute o seguinte comando:
cargo.documentation=Para obter mais informações sobre o registro Cargo, consulte <a target="_blank" rel="noopener noreferrer" href="https://docs.gitea.io/en-us/packages/cargo/">a documentação</a>.
cargo.documentation=Para obter mais informações sobre o registro Cargo, consulte <a target="_blank" rel="noopener noreferrer" href="%s">a documentação</a>.
cargo.details.repository_site=Site do Repositório
cargo.details.documentation_site=Site da Documentação
chef.registry=Configure este registro em seu arquivo <code>~/.chef/config.rb</code>:
chef.install=Para instalar o pacote, execute o seguinte comando:
chef.documentation=Para obter mais informações sobre o registro Chef, consulte <a target="_blank" rel="noopener noreferrer" href="https://docs.gitea.io/en-us/packages/chef/">a documentação</a>.
chef.documentation=Para obter mais informações sobre o registro Chef, consulte <a target="_blank" rel="noopener noreferrer" href="%s">a documentação</a>.
composer.registry=Configure este registro em seu arquivo <code>~/.composer/config.json</code>:
composer.install=Para instalar o pacote usando o Composer, execute o seguinte comando:
composer.documentation=Para obter mais informações sobre o registro do Composer, consulte <a target="_blank" rel="noopener noreferrer" href="https://docs.gitea.io/en-us/packages/composer/">a documentação</a>.
composer.documentation=Para obter mais informações sobre o registro do Composer, consulte <a target="_blank" rel="noopener noreferrer" href="%s">a documentação</a>.
composer.dependencies=Dependências
composer.dependencies.development=Dependências de Desenvolvimento
conan.details.repository=Repositório
conan.registry=Configure este registro pela linha de comando:
conan.install=Para instalar o pacote usando o Conan, execute o seguinte comando:
conan.documentation=Para obter mais informações sobre o registro Conan, consulte <a target="_blank" rel="noopener noreferrer" href="https://docs.gitea.io/en-us/packages/conan/">a documentação</a>.
conan.documentation=Para obter mais informações sobre o registro Conan, consulte <a target="_blank" rel="noopener noreferrer" href="%s">a documentação</a>.
conda.registry=Configure este registro como um repositório Conda no arquivo <code>.condarc</code>:
conda.install=Para instalar o pacote usando o Conda, execute o seguinte comando:
conda.documentation=Para obter mais informações sobre o registro Conda, consulte <a target="_blank" rel="noopener noreferrer" href="https://docs.gitea.io/en-us/packages/conda/">a documentação</a>.
conda.documentation=Para obter mais informações sobre o registro Conda, consulte <a target="_blank" rel="noopener noreferrer" href="%s">a documentação</a>.
conda.details.repository_site=Site do Repositório
conda.details.documentation_site=Site da Documentação
container.details.type=Tipo de Imagem
container.details.platform=Plataforma
container.pull=Puxe a imagem pela linha de comando:
container.digest=Digest:
container.documentation=Para obter mais informações sobre o registro de Container, consulte <a target="_blank" rel="noopener noreferrer" href="https://docs.gitea.io/en-us/packages/container/">a documentação</a>.
container.documentation=Para obter mais informações sobre o registro de Container, consulte <a target="_blank" rel="noopener noreferrer" href="%s">a documentação</a>.
container.multi_arch=S.O. / Arquitetura
container.layers=Camadas da Imagem
container.labels=Rótulos
container.labels.key=Chave
container.labels.value=Valor
cran.registry=Configure este registro no arquivo <code>Rprofile.site</code>:
cran.install=Para instalar o pacote, execute o seguinte comando:
debian.registry=Configure este registro pela linha de comando:
debian.registry.info=Escolha uma $distribution e um $component da lista abaixo:
debian.install=Para instalar o pacote, execute o seguinte comando:
debian.documentation=Para obter mais informações sobre o registro do Debian, consulte <a target="_blank" rel="noopener noreferrer" href="%s">a documentação</a>.
debian.repository=Informações do repositório
debian.repository.distributions=Distribuições
debian.repository.components=Componentes
debian.repository.architectures=Arquiteturas
generic.download=Baixar pacote pela linha de comando:
generic.documentation=Para obter mais informações sobre o registro genérico, consulte <a target="_blank" rel="noopener noreferrer" href="https://docs.gitea.io/en-us/packages/generic">a documentação</a>.
generic.documentation=Para obter mais informações sobre o registro genérico, consulte <a target="_blank" rel="noopener noreferrer" href="%s">a documentação</a>.
go.install=Instale o pacote usando o comando:
go.documentation=Para obter mais informações sobre o registro Go, consulte <a target="_blank" rel="noopener noreferrer" href="%s">a documentação</a>.
helm.registry=Configurar este registro pela linha de comando:
helm.install=Para instalar o pacote, execute o seguinte comando:
helm.documentation=Para obter mais informações sobre o registro Helm, consulte <a target="_blank" rel="noopener noreferrer" href="https://docs.gitea.io/en-us/packages/helm/">a documentação</a>.
helm.documentation=Para obter mais informações sobre o registro Helm, consulte <a target="_blank" rel="noopener noreferrer" href="%s">a documentação</a>.
maven.registry=Configure este registro no arquivo <code>pom.xml</code> do seu projeto:
maven.install=Para usar o pacote inclua o seguinte no bloco de <code>dependencies</code> no arquivo <code>pom.xml</code>:
maven.install2=Executar via linha de comando:
maven.download=Para baixar a dependência, execute via linha de comando:
maven.documentation=Para obter mais informações sobre o registro Maven, consulte <a target="_blank" rel="noopener noreferrer" href="https://docs.gitea.io/en-us/packages/maven/">a documentação</a>.
maven.documentation=Para obter mais informações sobre o registro Maven, consulte <a target="_blank" rel="noopener noreferrer" href="%s">a documentação</a>.
nuget.registry=Configurar este registro pela linha de comando:
nuget.install=Para instalar o pacote usando NuGet, execute o seguinte comando:
nuget.documentation=Para obter mais informações sobre o registro Nuget, consulte <a target="_blank" rel="noopener noreferrer" href="https://docs.gitea.io/en-us/packages/nuget/">a documentação</a>.
nuget.documentation=Para obter mais informações sobre o registro Nuget, consulte <a target="_blank" rel="noopener noreferrer" href="%s">a documentação</a>.
nuget.dependency.framework=Estrutura Alvo
npm.registry=Configure este registro no arquivo <code>.npmrc</code> do seu projeto:
npm.install=Para instalar o pacote usando o npm, execute o seguinte comando:
npm.install2=ou adicione-o ao arquivo package.json:
npm.documentation=Para obter mais informações sobre o registro npm, consulte <a target="_blank" rel="noopener noreferrer" href="https://docs.gitea.io/en-us/packages/npm/">a documentação</a>.
npm.documentation=Para obter mais informações sobre o registro npm, consulte <a target="_blank" rel="noopener noreferrer" href="%s">a documentação</a>.
npm.dependencies=Dependências
npm.dependencies.development=Dependências de Desenvolvimento
npm.dependencies.peer=Dependências Peer
npm.dependencies.optional=Dependências Opcionais
npm.details.tag=Tag
pub.install=Para instalar o pacote usando Dart, execute o seguinte comando:
pub.documentation=Para obter mais informações sobre o registro Pub, consulte <a target="_blank" rel="noopener noreferrer" href="https://docs.gitea.io/en-us/packages/pub/">a documentação</a>.
pub.documentation=Para obter mais informações sobre o registro Pub, consulte <a target="_blank" rel="noopener noreferrer" href="%s">a documentação</a>.
pypi.requires=Requer Python
pypi.install=Para instalar o pacote usando pip, execute o seguinte comando:
pypi.documentation=Para obter mais informações sobre o registro PyPI, consulte <a target="_blank" rel="noopener noreferrer" href="https://docs.gitea.io/en-us/packages/pypi/">a documentação</a>.
pypi.documentation=Para obter mais informações sobre o registro PyPI, consulte <a target="_blank" rel="noopener noreferrer" href="%s">a documentação</a>.
rpm.registry=Configure este registro pela linha de comando:
rpm.install=Para instalar o pacote, execute o seguinte comando:
rpm.documentation=Para obter mais informações sobre o registro RPM, consulte <a target="_blank" rel="noopener noreferrer" href="%s">a documentação</a>.
@ -3276,13 +3295,13 @@ rubygems.dependencies.runtime=Dependências de Execução
rubygems.dependencies.development=Dependências de Desenvolvimento
rubygems.required.ruby=Requer o Ruby versão
rubygems.required.rubygems=Requer o RubyGem versão
rubygems.documentation=Para obter mais informações sobre o registro do RubyGems, consulte <a target="_blank" rel="noopener noreferrer" href="https://docs.gitea.io/en-us/packages/rubygems/">a documentação</a>.
rubygems.documentation=Para obter mais informações sobre o registro do RubyGems, consulte <a target="_blank" rel="noopener noreferrer" href="%s">a documentação</a>.
swift.registry=Configure este registro pela linha de comando:
swift.install=Adicione o pacote em seu arquivo <code>Package.swift</code>:
swift.install2=e execute o seguinte comando:
swift.documentation=Para obter mais informações sobre o registro Swift, consulte <a target="_blank" rel="noopener noreferrer" href="https://docs.gitea.io/en-us/packages/swift/">a documentação</a>.
swift.documentation=Para obter mais informações sobre o registro Swift, consulte <a target="_blank" rel="noopener noreferrer" href="%s">a documentação</a>.
vagrant.install=Para adicionar uma Vagrant box, execute o seguinte comando:
vagrant.documentation=Para obter mais informações sobre o registro do Vagrant, consulte <a target="_blank" rel="noopener noreferrer" href="https://docs.gitea.io/en-us/packages/vagrant/">a documentação</a>.
vagrant.documentation=Para obter mais informações sobre o registro do Vagrant, consulte <a target="_blank" rel="noopener noreferrer" href="%s">a documentação</a>.
settings.link=Vincular este pacote a um repositório
settings.link.description=Se você vincular um pacote a um repositório, o pacote será listado na lista de pacotes do repositório.
settings.link.select=Selecionar Repositório

View File

@ -6,17 +6,11 @@ package explore
import (
"code.gitea.io/gitea/models/db"
user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/modules/base"
"code.gitea.io/gitea/modules/context"
"code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/modules/structs"
)
const (
// tplExploreOrganizations explore organizations page template
tplExploreOrganizations base.TplName = "explore/organizations"
)
// Organizations render explore organizations page
func Organizations(ctx *context.Context) {
ctx.Data["UsersIsDisabled"] = setting.Service.Explore.DisableUsersPage
@ -39,5 +33,5 @@ func Organizations(ctx *context.Context) {
Type: user_model.UserTypeOrganization,
ListOptions: db.ListOptions{PageSize: setting.UI.ExplorePagingNum},
Visible: visibleTypes,
}, tplExploreOrganizations)
}, tplExploreUsers)
}

View File

@ -16,6 +16,7 @@ import (
"code.gitea.io/gitea/modules/markup"
"code.gitea.io/gitea/modules/markup/markdown"
"code.gitea.io/gitea/modules/setting"
shared_user "code.gitea.io/gitea/routers/web/shared/user"
)
const (
@ -158,6 +159,12 @@ func Home(ctx *context.Context) {
ctx.Data["PageIsViewRepositories"] = true
ctx.Data["IsFollowing"] = isFollowing
err = shared_user.LoadHeaderCount(ctx)
if err != nil {
ctx.ServerError("LoadHeaderCount", err)
return
}
pager := context.NewPagination(int(count), setting.UI.User.RepoPagingNum, page, 5)
pager.SetDefaultParams(ctx)
pager.AddParam(ctx, "language", "Language")

View File

@ -101,6 +101,12 @@ func Projects(ctx *context.Context) {
project.RenderedContent = project.Description
}
err = shared_user.LoadHeaderCount(ctx)
if err != nil {
ctx.ServerError("LoadHeaderCount", err)
return
}
numPages := 0
if total > 0 {
numPages = (int(total) - 1/setting.UI.IssuePagingNum)
@ -135,6 +141,13 @@ func RenderNewProject(ctx *context.Context) {
ctx.Data["HomeLink"] = ctx.ContextUser.HomeLink()
ctx.Data["CancelLink"] = ctx.ContextUser.HomeLink() + "/-/projects"
shared_user.RenderUserHeader(ctx)
err := shared_user.LoadHeaderCount(ctx)
if err != nil {
ctx.ServerError("LoadHeaderCount", err)
return
}
ctx.HTML(http.StatusOK, tplProjectsNew)
}
@ -270,6 +283,12 @@ func EditProjectPost(ctx *context.Context) {
shared_user.RenderUserHeader(ctx)
err := shared_user.LoadHeaderCount(ctx)
if err != nil {
ctx.ServerError("LoadHeaderCount", err)
return
}
if ctx.HasError() {
ctx.HTML(http.StatusOK, tplProjectsNew)
return
@ -379,6 +398,12 @@ func ViewProject(ctx *context.Context) {
ctx.Data["Boards"] = boards
shared_user.RenderUserHeader(ctx)
err = shared_user.LoadHeaderCount(ctx)
if err != nil {
ctx.ServerError("LoadHeaderCount", err)
return
}
ctx.HTML(http.StatusOK, tplProjectsView)
}

View File

@ -14,6 +14,7 @@ import (
"code.gitea.io/gitea/modules/markup"
"code.gitea.io/gitea/modules/markup/markdown"
"code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/modules/util"
)
// prepareContextForCommonProfile store some common data into context data for user's profile related pages (including the nav menu)
@ -110,3 +111,21 @@ func RenderUserHeader(ctx *context.Context) {
defer profileClose()
ctx.Data["HasProfileReadme"] = profileReadmeBlob != nil
}
func LoadHeaderCount(ctx *context.Context) error {
prepareContextForCommonProfile(ctx)
repoCount, err := repo_model.CountRepository(ctx, &repo_model.SearchRepoOptions{
Actor: ctx.Doer,
OwnerID: ctx.ContextUser.ID,
Private: ctx.IsSigned,
Collaborate: util.OptionalBoolFalse,
IncludeDescription: setting.UI.SearchRepoDescription,
})
if err != nil {
return err
}
ctx.Data["RepoCount"] = repoCount
return nil
}

View File

@ -101,6 +101,12 @@ func ListPackages(ctx *context.Context) {
ctx.Data["Total"] = total
ctx.Data["RepositoryAccessMap"] = repositoryAccessMap
err = shared_user.LoadHeaderCount(ctx)
if err != nil {
ctx.ServerError("LoadHeaderCount", err)
return
}
// TODO: context/org -> HandleOrgAssignment() can not be used
if ctx.ContextUser.IsOrganization() {
org := org_model.OrgFromUser(ctx.ContextUser)
@ -255,6 +261,12 @@ func ViewPackageVersion(ctx *context.Context) {
}
ctx.Data["HasRepositoryAccess"] = hasRepositoryAccess
err = shared_user.LoadHeaderCount(ctx)
if err != nil {
ctx.ServerError("LoadHeaderCount", err)
return
}
ctx.HTML(http.StatusOK, tplPackagesView)
}
@ -346,6 +358,12 @@ func ListPackageVersions(ctx *context.Context) {
ctx.Data["Total"] = total
err = shared_user.LoadHeaderCount(ctx)
if err != nil {
ctx.ServerError("LoadHeaderCount", err)
return
}
pager := context.NewPagination(int(total), setting.UI.PackagesPagingNum, page, 5)
for k, v := range pagerParams {
pager.AddParamString(k, v)

View File

@ -269,6 +269,12 @@ func prepareUserProfileTabData(ctx *context.Context, showPrivate bool, profileGi
ctx.Data["Repos"] = repos
ctx.Data["Total"] = total
err = shared_user.LoadHeaderCount(ctx)
if err != nil {
ctx.ServerError("LoadHeaderCount", err)
return
}
pager := context.NewPagination(total, pagingNum, page, 5)
pager.SetDefaultParams(ctx)
pager.AddParam(ctx, "tab", "TabName")

View File

@ -1 +0,0 @@
{{template "explore/users" .}}

View File

@ -2,8 +2,8 @@
<div class="ui secondary stackable pointing menu">
<a class="{{if .PageIsViewRepositories}}active {{end}}item" href="{{$.Org.HomeLink}}">
{{svg "octicon-repo"}} {{.locale.Tr "user.repositories"}}
{{if .ContextUser.NumRepos}}
<div class="ui small label">{{.ContextUser.NumRepos}}</div>
{{if .RepoCount}}
<div class="ui small label">{{.RepoCount}}</div>
{{end}}
</a>
{{if .CanReadProjects}}

View File

@ -39,7 +39,7 @@
<li>
{{svg "octicon-mail"}}
<a class="gt-f1" href="mailto:{{.ContextUser.Email}}" rel="nofollow">{{.ContextUser.Email}}</a>
<a href="{{AppSubUrl}}/user/settings#keep-email-private">
<a href="{{AppSubUrl}}/user/settings#privacy-user-settings">
{{if .ShowUserEmail}}
<i data-tooltip-content="{{.locale.Tr "user.email_visibility.limited"}}">
{{svg "octicon-unlock"}}

View File

@ -6,8 +6,8 @@
{{end}}
<a class="{{if eq .TabName "repositories"}}active {{end}} item" href="{{.ContextUser.HomeLink}}?tab=repositories">
{{svg "octicon-repo"}} {{.locale.Tr "user.repositories"}}
{{if .ContextUser.NumRepos}}
<div class="ui small label">{{.ContextUser.NumRepos}}</div>
{{if .RepoCount}}
<div class="ui small label">{{.RepoCount}}</div>
{{end}}
</a>
{{if or .ContextUser.IsIndividual (and .ContextUser.IsOrganization .CanReadProjects)}}

View File

@ -11,7 +11,6 @@ import webpack from 'webpack';
import {fileURLToPath} from 'node:url';
import {readFileSync} from 'node:fs';
import {env} from 'node:process';
import {LightningCssMinifyPlugin} from 'lightningcss-loader';
const {EsbuildPlugin} = EsBuildLoader;
const {SourceMapDevToolPlugin, DefinePlugin} = webpack;
@ -52,6 +51,12 @@ const filterCssImport = (url, ...args) => {
return true;
};
// in case lightningcss fails to load, fall back to esbuild for css minify
let LightningCssMinifyPlugin;
try {
({LightningCssMinifyPlugin} = await import('lightningcss-loader'));
} catch {}
/** @type {import("webpack").Configuration} */
export default {
mode: isProduction ? 'production' : 'development',
@ -97,10 +102,10 @@ export default {
new EsbuildPlugin({
target: 'es2015',
minify: true,
css: false,
css: !LightningCssMinifyPlugin,
legalComments: 'none',
}),
new LightningCssMinifyPlugin(),
LightningCssMinifyPlugin && new LightningCssMinifyPlugin(),
],
splitChunks: {
chunks: 'async',