Template
1
0
Fork 0
mirror of https://codeberg.org/forgejo/forgejo synced 2024-11-22 09:54:24 +01:00

Compare commits

..

25 commits

Author SHA1 Message Date
SomeTr 2884de2094
i18n: translated using Weblate (Ukrainian)
Currently translated at 74.2% (2715 of 3655 strings)

Translation: Forgejo/forgejo
Translate-URL: https://translate.codeberg.org/projects/forgejo/forgejo/uk/
2024-11-17 21:23:32 +00:00
SomeTr d0fcba5053
i18n: translated using Weblate (Ukrainian)
Currently translated at 73.4% (2684 of 3655 strings)

Translation: Forgejo/forgejo
Translate-URL: https://translate.codeberg.org/projects/forgejo/forgejo/uk/
2024-11-17 21:23:32 +00:00
SomeTr 5a14575dda
i18n: translated using Weblate (Ukrainian)
Currently translated at 73.3% (2680 of 3655 strings)

Translation: Forgejo/forgejo
Translate-URL: https://translate.codeberg.org/projects/forgejo/forgejo/uk/
2024-11-17 21:23:32 +00:00
artnay b2105876d8
i18n: translated using Weblate (Finnish)
Currently translated at 57.2% (2094 of 3655 strings)

Translation: Forgejo/forgejo
Translate-URL: https://translate.codeberg.org/projects/forgejo/forgejo/fi/
2024-11-17 21:23:32 +00:00
xtex 2fcc4fb5ba
i18n: translated using Weblate (Chinese (Simplified Han script))
Currently translated at 100.0% (3655 of 3655 strings)

Translation: Forgejo/forgejo
Translate-URL: https://translate.codeberg.org/projects/forgejo/forgejo/zh_Hans/
2024-11-17 21:23:32 +00:00
SomeTr 0f1031425a
i18n: translated using Weblate (Ukrainian)
Currently translated at 73.2% (2676 of 3655 strings)

Translation: Forgejo/forgejo
Translate-URL: https://translate.codeberg.org/projects/forgejo/forgejo/uk/
2024-11-17 21:23:32 +00:00
artnay 90a65ebbc1
i18n: translated using Weblate (Finnish)
Currently translated at 56.3% (2059 of 3655 strings)

Translation: Forgejo/forgejo
Translate-URL: https://translate.codeberg.org/projects/forgejo/forgejo/fi/
2024-11-17 21:23:32 +00:00
SomeTr 08e88b9189
i18n: translated using Weblate (Ukrainian)
Currently translated at 73.1% (2675 of 3655 strings)

Translation: Forgejo/forgejo
Translate-URL: https://translate.codeberg.org/projects/forgejo/forgejo/uk/
2024-11-17 21:23:32 +00:00
artnay aafcafed48
i18n: translated using Weblate (Finnish)
Currently translated at 55.8% (2040 of 3655 strings)

Translation: Forgejo/forgejo
Translate-URL: https://translate.codeberg.org/projects/forgejo/forgejo/fi/
2024-11-17 21:23:32 +00:00
SomeTr bc290dd932
i18n: translated using Weblate (Ukrainian)
Currently translated at 72.8% (2661 of 3655 strings)

Translation: Forgejo/forgejo
Translate-URL: https://translate.codeberg.org/projects/forgejo/forgejo/uk/
2024-11-17 21:23:31 +00:00
xtex 8017fa486a
i18n: translated using Weblate (Chinese (Simplified Han script))
Currently translated at 100.0% (3655 of 3655 strings)

Translation: Forgejo/forgejo
Translate-URL: https://translate.codeberg.org/projects/forgejo/forgejo/zh_Hans/
2024-11-17 21:23:31 +00:00
xtex c3a9e58dc9
i18n: translated using Weblate (Chinese (Simplified Han script))
Currently translated at 100.0% (3655 of 3655 strings)

Translation: Forgejo/forgejo
Translate-URL: https://translate.codeberg.org/projects/forgejo/forgejo/zh_Hans/
2024-11-17 21:23:31 +00:00
Edgarsons 4c66109ca2
i18n: translated using Weblate (Latvian)
Currently translated at 72.3% (2644 of 3655 strings)

Translation: Forgejo/forgejo
Translate-URL: https://translate.codeberg.org/projects/forgejo/forgejo/lv/
2024-11-17 21:23:31 +00:00
xtex 2f81c0ec80
i18n: translated using Weblate (Chinese (Simplified Han script))
Currently translated at 100.0% (3655 of 3655 strings)

Translation: Forgejo/forgejo
Translate-URL: https://translate.codeberg.org/projects/forgejo/forgejo/zh_Hans/
2024-11-17 21:23:31 +00:00
Edgarsons c190abc758
i18n: translated using Weblate (Latvian)
Currently translated at 71.9% (2628 of 3655 strings)

Translation: Forgejo/forgejo
Translate-URL: https://translate.codeberg.org/projects/forgejo/forgejo/lv/
2024-11-17 21:23:31 +00:00
yumechi e463fa4543
i18n: translated using Weblate (Japanese)
Currently translated at 91.7% (3353 of 3655 strings)

Translation: Forgejo/forgejo
Translate-URL: https://translate.codeberg.org/projects/forgejo/forgejo/ja/
2024-11-17 21:23:31 +00:00
Renovate Bot 4163402f5e Update dependency vue to v3.5.13 (forgejo) (#5981)
Co-authored-by: Renovate Bot <forgejo-renovate-action@forgejo.org>
Co-committed-by: Renovate Bot <forgejo-renovate-action@forgejo.org>
2024-11-17 21:23:23 +00:00
Gusted e31090cf4b Merge pull request 'fix: check read permissions for code owner review requests' (#5996) from gusted/forgejo-codeowners into forgejo
Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/5996
Reviewed-by: Earl Warren <earl-warren@noreply.codeberg.org>
2024-11-17 19:13:46 +00:00
Gusted 2cc3278791 Merge pull request 'fix: use better code to group UID and stopwatches' (#5989) from gusted/improve-uid-stopwatches into forgejo
Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/5989
Reviewed-by: Earl Warren <earl-warren@noreply.codeberg.org>
2024-11-17 19:13:30 +00:00
Gusted 693f7731f9
fix: check read permissions for code owner review requests
- Only send a review request based on the code owner file if the code
owner user has read permissions to the pull requests of that repository.
- This avoids leaking title of PRs from private repository when a
CODEOWNER file is present which contains users that do not have access
to the private repository.
- Found by @oliverpool.
- Integration test added.
2024-11-17 20:12:59 +01:00
Earl Warren abec2442b7 Merge pull request 'chore(ci): make merge-conditions job copy/pastable' (#6001) from earl-warren/forgejo:wip-ci-labels into forgejo
Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/6001
Reviewed-by: Michael Kriese <michael.kriese@gmx.de>
2024-11-17 18:13:16 +00:00
Earl Warren 64a89c8d33
chore(ci): make merge-conditions job copy/pastable
Refs: forgejo/forgejo#5999
2024-11-17 17:57:40 +01:00
Gusted 76f172b080 Merge pull request 'fix: remember fuzzy for open/close state' (#5995) from gusted/forgejo-remember-fuzzy into forgejo
Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/5995
Reviewed-by: Earl Warren <earl-warren@noreply.codeberg.org>
Reviewed-by: Shiny Nematoda <snematoda@noreply.codeberg.org>
2024-11-17 15:27:48 +00:00
Gusted 9701e5e0ff
fix: remember fuzzy for open/close state
- Remember if fuzzy was set or not for the open/close/all states.
- Use `fuzzy=false` for test, as `fuzzy=true` is the default (this is
the opposite of all the other values).
- Remove `ctx.Link` prefix for open/close states, this makes them
suspectible to the existing tests (the other filter links are also in
the format of simply having `?xx=xx&yy=yy`).
- Fix typo in test name.
2024-11-17 02:06:51 +01:00
Gusted e4eb82b738
fix: use better code to group UID and stopwatches
- Instead of having code that relied on the result being sorted (which
wasn't specified in the query and therefore not safe to assume so). Use
a map where it doesn't care if the result that we get from the database
is sorted or not.
- Added unit test.
2024-11-16 15:59:02 +01:00
12 changed files with 223 additions and 108 deletions

View file

@ -1,7 +1,7 @@
# Copyright 2024 The Forgejo Authors
# SPDX-License-Identifier: MIT
name: requirements
name: issue-labels
on:
pull_request:
@ -9,19 +9,26 @@ on:
- labeled
- edited
- opened
- synchronize
jobs:
merge-conditions:
if: vars.ROLE == 'forgejo-coding'
if: >
vars.ROLE == 'forgejo-coding' &&
github.event_name == 'pull_request' &&
(
github.event.action == 'label_updated' ||
github.event.action == 'edited' ||
github.event.action == 'opened'
)
runs-on: docker
container:
image: 'code.forgejo.org/oci/node:20-bookworm'
steps:
- name: Debug output
- name: Debug info
run: |
cat <<'EOF'
${{ toJSON(github.event) }}
${{ toJSON(github) }}
EOF
- name: Missing test label
if: >

View file

@ -0,0 +1,11 @@
-
id: 3
user_id: 1
issue_id: 2
created_unix: 1500988004
-
id: 4
user_id: 3
issue_id: 0
created_unix: 1500988003

View file

@ -60,34 +60,19 @@ func getStopwatch(ctx context.Context, userID, issueID int64) (sw *Stopwatch, ex
return sw, exists, err
}
// UserIDCount is a simple coalition of UserID and Count
type UserStopwatch struct {
UserID int64
StopWatches []*Stopwatch
}
// GetUIDsAndNotificationCounts between the two provided times
func GetUIDsAndStopwatch(ctx context.Context) ([]*UserStopwatch, error) {
func GetUIDsAndStopwatch(ctx context.Context) (map[int64][]*Stopwatch, error) {
sws := []*Stopwatch{}
if err := db.GetEngine(ctx).Where("issue_id != 0").Find(&sws); err != nil {
return nil, err
}
res := map[int64][]*Stopwatch{}
if len(sws) == 0 {
return []*UserStopwatch{}, nil
return res, nil
}
lastUserID := int64(-1)
res := []*UserStopwatch{}
for _, sw := range sws {
if lastUserID == sw.UserID {
lastUserStopwatch := res[len(res)-1]
lastUserStopwatch.StopWatches = append(lastUserStopwatch.StopWatches, sw)
} else {
res = append(res, &UserStopwatch{
UserID: sw.UserID,
StopWatches: []*Stopwatch{sw},
})
}
res[sw.UserID] = append(res[sw.UserID], sw)
}
return res, nil
}

View file

@ -4,12 +4,14 @@
package issues_test
import (
"path/filepath"
"testing"
"code.gitea.io/gitea/models/db"
issues_model "code.gitea.io/gitea/models/issues"
"code.gitea.io/gitea/models/unittest"
user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/modules/timeutil"
"github.com/stretchr/testify/assert"
@ -77,3 +79,41 @@ func TestCreateOrStopIssueStopwatch(t *testing.T) {
unittest.AssertNotExistsBean(t, &issues_model.Stopwatch{UserID: 2, IssueID: 2})
unittest.AssertExistsAndLoadBean(t, &issues_model.TrackedTime{UserID: 2, IssueID: 2})
}
func TestGetUIDsAndStopwatch(t *testing.T) {
defer unittest.OverrideFixtures(
unittest.FixturesOptions{
Dir: filepath.Join(setting.AppWorkPath, "models/fixtures/"),
Base: setting.AppWorkPath,
Dirs: []string{"models/issues/TestGetUIDsAndStopwatch/"},
},
)()
require.NoError(t, unittest.PrepareTestDatabase())
uidStopwatches, err := issues_model.GetUIDsAndStopwatch(db.DefaultContext)
require.NoError(t, err)
assert.EqualValues(t, map[int64][]*issues_model.Stopwatch{
1: {
{
ID: 1,
UserID: 1,
IssueID: 1,
CreatedUnix: timeutil.TimeStamp(1500988001),
},
{
ID: 3,
UserID: 1,
IssueID: 2,
CreatedUnix: timeutil.TimeStamp(1500988004),
},
},
2: {
{
ID: 2,
UserID: 2,
IssueID: 2,
CreatedUnix: timeutil.TimeStamp(1500988002),
},
},
}, uidStopwatches)
}

View file

@ -90,8 +90,8 @@ loop:
return
}
for _, userStopwatches := range usersStopwatches {
apiSWs, err := convert.ToStopWatches(ctx, userStopwatches.StopWatches)
for uid, stopwatches := range usersStopwatches {
apiSWs, err := convert.ToStopWatches(ctx, stopwatches)
if err != nil {
if !issues_model.IsErrIssueNotExist(err) {
log.Error("Unable to APIFormat stopwatches: %v", err)
@ -103,7 +103,7 @@ loop:
log.Error("Unable to marshal stopwatches: %v", err)
continue
}
m.SendMessage(userStopwatches.UserID, &Event{
m.SendMessage(uid, &Event{
Name: "stopwatches",
Data: string(dataBs),
})

View file

@ -234,7 +234,7 @@ install=Встановлення
title=Початкова конфігурація
docker_helper=Якщо ви запускаєте Forgejo всередині Docker, будь ласка уважно прочитайте <a target="_blank" rel="noopener" href="%s">документацію</a> перед тим, як щось змінити на цій сторінці.
db_title=Налаштування бази даних
db_type=Вид бази даних
db_type=Тип бази даних
host=Хост
user=Ім'я кристувача
password=Пароль
@ -258,8 +258,8 @@ err_admin_name_pattern_not_allowed=Ім'я адміністратора неді
err_admin_name_is_invalid=Неправильне ім'я користувача-адміністратора
general_title=Загальні налаштування
app_name=Назва екземпляру
app_name_helper=Тут ви можете ввести назву свого екземпляру.
app_name=Назва екземпляра
app_name_helper=Уведіть тут назву свого екземпляра. Вона відображатиметься на кожній сторінці.
repo_path=Коренева тека репозиторію
repo_path_helper=Всі вилучені Git репозиторії будуть збережені в цей каталог.
lfs_path=Кореневий шлях Git LFS
@ -339,8 +339,8 @@ require_db_desc = Forgejo вимагає MySQL, PostgreSQL, SQLite3 чи TiDB (
allow_only_external_registration = Дозволити реєстрацію тільки через зовнішні сервіси
require_sign_in_view.description = Обмежити доступ до контенту лише користувачам, що увійшли. Гості зможуть лише відвідувати сторінки автентифікації.
password_algorithm_helper = Встановити алгоритм хешування паролів. Алгоритми мають різні вимоги та силу. Алгоритм argon2 є досить безпечним, проте споживає багато памʼяті та є недоречним для малих систем.
app_slogan = Гасло екземпляру
app_slogan_helper = Уведіть гасло вашого екземпляру тут. Залиште порожнім, аби вимкнути.
app_slogan = Гасло екземпляра
app_slogan_helper = Уведіть гасло вашого екземпляра тут. Залиште порожнім, аби вимкнути.
run_user_helper = Імʼя користувача операційної системи, від якого запущено Forgejo. Зауважте, що цей користувач повинен мати доступ до кореневої теки репозиторію.
smtp_from_invalid = Адреса з «Відправляти email від імені» недійсна
allow_dots_in_usernames = Дозволити користувачам використовувати крапки у своїх іменах. Не впливає на облікові записи, що вже існують.
@ -540,6 +540,10 @@ admin.new_user.text = Будь ласка, <a href="%s">натисніть ту
admin.new_user.subject = Новий користувач %s щойно ввійшов
removed_security_key.text_1 = Ключ безпеки «%[1]s» було щойно видалено з вашого облікового запису.
removed_security_key.subject = Ключ безпеки видалено
team_invite.text_2 = Щоб приєднатися до команди, будь ласка, перейдіть за посиланням:
team_invite.subject = %[1]s запрошує Вас приєднатися до організації %[2]s
team_invite.text_3 = Примітка: Це запрошення призначене для %[1]s. Якщо Ви не очікували цього запрошення, можете проігнорувати цей лист.
team_invite.text_1 = %[1]s запрошує Вас приєднатися до команди %[2]s в організації %[3]s.
[modal]
@ -626,18 +630,23 @@ still_own_packages = Ваш обліковий запис володіє одн
org_still_own_packages = Організація все ще володіє одним чи більше пакунками, спочатку видаліть їх.
username_error_no_dots = ` може містити тільки літерно-цифрові символи («0-9», «a-z», «A-Z»), дефіс («-») та підкреслення («_»). Не може починатися або закінчуватися нелітерними символами; нелітерні символи підряд також заборонені.`
username_error = ` може містити тільки літерно-цифрові символи («0-9», «a-z», «A-Z»), дефіс («-»), підкреслення («_») та крапки («.»). Не може починатися або закінчуватися нелітерними символами; нелітерні символи підряд також заборонені.`
Description = Опис
Pronouns = Займенники
Biography = Про себе
FullName = Повне ім'я
Website = Вебсайт
[user]
change_avatar=Змінити свій аватар…
repositories=Репозиторії
activity=Публічна активність
followers_few=%d читачі
followers_few=%d ежать
starred=Обрані репозиторії
watched=Відстежувані репозиторії
projects=Проєкт
overview=Огляд
following_few=%d читає
following_few=%d відстежуваних
follow=Підписатися
unfollow=Відписатися
user_bio=Біографія
@ -655,7 +664,13 @@ unblock = Розблокувати
code = Код
block_user = Заблокувати користувача
block_user.detail = Зверніть увагу, що блокування користувача має такі наслідки:
follow_blocked_user = Ви не можете підписатися на цього користувача, тому що ви його заблокували або він заблокував вас.
follow_blocked_user = Ви не можете стежити за цим користувачем, тому що ви його заблокували або він заблокував вас.
following_one = %d відстежуваний
followers_one = %d cтежить
followers.title.one = ежить
followers.title.few = ежать
following.title.one = Відстежуваний
following.title.few = Відстежувані
[settings]
@ -1166,7 +1181,7 @@ editor.fork_before_edit=Необхідно зробити форк цього р
editor.delete_this_file=Видалити файл
editor.must_have_write_access=Ви повинні мати доступ на запис щоб запропонувати зміни до цього файлу.
editor.name_your_file=Дайте назву файлу…
editor.filename_help=Щоб додати каталог, наберіть його назву, а потім - косу риску ('/'). Щоб видалити каталог, перейдіть до початку поля і натисніть backspace.
editor.filename_help=Щоб додати каталог, наберіть його назву, а потім — косу риску «/». Щоб видалити каталог, перейдіть до початку поля і натисніть Backspace.
editor.or=або
editor.cancel_lower=Скасувати
editor.commit_signed_changes=Внести підписані зміни
@ -1564,7 +1579,7 @@ pulls.reject_count_1=%d запит на зміну
pulls.reject_count_n=%d запити на зміну
pulls.waiting_count_1=очікується %d рецензія
pulls.waiting_count_n=очікується %d рецензії(й)
pulls.wrong_commit_id=id коміту повинен бути id коміту в цільовій гілці
pulls.wrong_commit_id=ID коміта повинен бути ID коміта в цільовій гілці
pulls.no_merge_desc=Цей запити на злиття неможливо злити, оскільки всі параметри об'єднання репозиторія вимкнено.
pulls.no_merge_helper=Увімкніть параметри злиття в налаштуваннях репозиторія або злийте запити на злиття вручну.
@ -2192,7 +2207,7 @@ find_file.go_to_file = Знайти файл
visibility_helper = Зробити репозиторій приватним
projects.card_type.desc = Попередній вигляд карток
projects.card_type.text_only = Лише текст
projects.card_type.images_and_text = Світлини та текст
projects.card_type.images_and_text = Зображення і текст
issues.filter_poster = Автор
issues.author = Автор
issues.author_helper = Цей користувач - автор.
@ -2363,6 +2378,14 @@ signing.wont_sign.not_signed_in = Ви не ввійшли в систему.
settings.wiki_globally_editable = Дозволити всім користувачам редагувати вікі
settings.reindex_button = Додати в чергу на переіндексацію
settings.reindex_requested = Потрібна переіндексація
editor.file_delete_success = Файл «%s» видалено.
file_follow = Слідувати за символьним посиланням
projects.column.set_default = Установити за замовчуванням
settings.federation_following_repos = URL-адреси відстежуваних репозиторіїв. Через «;», без пробілів.
settings.federation_not_enabled = Федерацію вимкнено у вашому екземплярі.
settings.federation_settings = Налаштування федерації
signing.wont_sign.nokey = Цей екземпляр не має ключа для підписання цього коміта.
settings.federation_apapiurl = URL федерації цього репозиторію. Скопіюйте її та вставте в налаштування федерації іншого репозиторію як URL-адресу відстежуваного репозиторію.
[graphs]
contributors.what = внески
@ -2480,6 +2503,9 @@ teams.all_repositories_write_permission_desc=Ця команда надає до
teams.all_repositories_admin_permission_desc=Ця команда надає дозвіл <strong>Адміністрування</strong> для <strong>всіх репозиторіїв</strong>: учасники можуть переглядати, виконувати push та додавати співробітників.
code = Код
open_dashboard = Відкрити панель управління
follow_blocked_user = Ви не можете стежити за цією організацією, тому що вас у ній заблокували.
teams.invite.description = Щоб приєднатися до команди, натисніть кнопку нижче.
teams.invite.title = Вас запрошено приєднатися до команди <strong>%s</strong> в організації <strong>%s</strong>.
[admin]
dashboard=Панель управління
@ -2957,6 +2983,7 @@ monitor.queue.numberinqueue = Номер у черзі
monitor.queue.settings.desc = Пули динамічно зростають у відповідь на блокування їхніх черг обробників.
monitor.queue.settings.remove_all_items_done = Усі елементи в черзі видалено.
monitor.queue.settings.remove_all_items = Видалити всі
config.app_slogan = Гасло екземпляра
[action]
@ -3075,7 +3102,7 @@ installation = Установлення
details.license = Ліцензія
filter.type.all = Усі
conan.install = Аби встановити пакунок, використовуючи Conan, запустіть команду:
container.layers = Шари світлини
container.layers = Шари образу
details.project_site = Вебсторінка проєкту
details.documentation_site = Вебсторінка документації
desc = Керувати пакунками репозиторію.
@ -3100,8 +3127,8 @@ arch.version.properties = Властивості версії
arch.version.description = Опис
chef.install = Аби встановити пакунок, запустіть команду:
container.details.platform = Платформа
container.details.type = Вид світлини
container.pull = Завантажити світлину з командного рядка:
container.details.type = Тип образу
container.pull = Завантажити образ із командного рядка:
details.repository_site = Вебсторінка репозиторію
composer.dependencies = Залежності
debian.install = Аби встановити пакунок, запустіть команду:
@ -3138,6 +3165,7 @@ creation = Додати секрет
none = Секретів ще немає.
creation.name_placeholder = без урахування регістру, тільки літерно-цифрові символи або підкреслення, не може починатися з GITEA_ або GITHUB_
secrets = Секрети
creation.value_placeholder = Уведіть довільний вміст. Пробіли на початку та в кінці будуть пропущені.
[actions]

110
package-lock.json generated
View file

@ -51,7 +51,7 @@
"tributejs": "5.1.3",
"uint8-to-base64": "0.2.0",
"vanilla-colorful": "0.7.2",
"vue": "3.5.12",
"vue": "3.5.13",
"vue-chartjs": "5.3.1",
"vue-loader": "17.4.2",
"vue3-calendar-heatmap": "2.0.5",
@ -5326,42 +5326,42 @@
}
},
"node_modules/@vue/compiler-core": {
"version": "3.5.12",
"resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.5.12.tgz",
"integrity": "sha512-ISyBTRMmMYagUxhcpyEH0hpXRd/KqDU4ymofPgl2XAkY9ZhQ+h0ovEZJIiPop13UmR/54oA2cgMDjgroRelaEw==",
"version": "3.5.13",
"resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.5.13.tgz",
"integrity": "sha512-oOdAkwqUfW1WqpwSYJce06wvt6HljgY3fGeM9NcVA1HaYOij3mZG9Rkysn0OHuyUAGMbEbARIpsG+LPVlBJ5/Q==",
"license": "MIT",
"dependencies": {
"@babel/parser": "^7.25.3",
"@vue/shared": "3.5.12",
"@vue/shared": "3.5.13",
"entities": "^4.5.0",
"estree-walker": "^2.0.2",
"source-map-js": "^1.2.0"
}
},
"node_modules/@vue/compiler-dom": {
"version": "3.5.12",
"resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.5.12.tgz",
"integrity": "sha512-9G6PbJ03uwxLHKQ3P42cMTi85lDRvGLB2rSGOiQqtXELat6uI4n8cNz9yjfVHRPIu+MsK6TE418Giruvgptckg==",
"version": "3.5.13",
"resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.5.13.tgz",
"integrity": "sha512-ZOJ46sMOKUjO3e94wPdCzQ6P1Lx/vhp2RSvfaab88Ajexs0AHeV0uasYhi99WPaogmBlRHNRuly8xV75cNTMDA==",
"license": "MIT",
"dependencies": {
"@vue/compiler-core": "3.5.12",
"@vue/shared": "3.5.12"
"@vue/compiler-core": "3.5.13",
"@vue/shared": "3.5.13"
}
},
"node_modules/@vue/compiler-sfc": {
"version": "3.5.12",
"resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.5.12.tgz",
"integrity": "sha512-2k973OGo2JuAa5+ZlekuQJtitI5CgLMOwgl94BzMCsKZCX/xiqzJYzapl4opFogKHqwJk34vfsaKpfEhd1k5nw==",
"version": "3.5.13",
"resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.5.13.tgz",
"integrity": "sha512-6VdaljMpD82w6c2749Zhf5T9u5uLBWKnVue6XWxprDobftnletJ8+oel7sexFfM3qIxNmVE7LSFGTpv6obNyaQ==",
"license": "MIT",
"dependencies": {
"@babel/parser": "^7.25.3",
"@vue/compiler-core": "3.5.12",
"@vue/compiler-dom": "3.5.12",
"@vue/compiler-ssr": "3.5.12",
"@vue/shared": "3.5.12",
"@vue/compiler-core": "3.5.13",
"@vue/compiler-dom": "3.5.13",
"@vue/compiler-ssr": "3.5.13",
"@vue/shared": "3.5.13",
"estree-walker": "^2.0.2",
"magic-string": "^0.30.11",
"postcss": "^8.4.47",
"postcss": "^8.4.48",
"source-map-js": "^1.2.0"
}
},
@ -5375,63 +5375,63 @@
}
},
"node_modules/@vue/compiler-ssr": {
"version": "3.5.12",
"resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.5.12.tgz",
"integrity": "sha512-eLwc7v6bfGBSM7wZOGPmRavSWzNFF6+PdRhE+VFJhNCgHiF8AM7ccoqcv5kBXA2eWUfigD7byekvf/JsOfKvPA==",
"version": "3.5.13",
"resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.5.13.tgz",
"integrity": "sha512-wMH6vrYHxQl/IybKJagqbquvxpWCuVYpoUJfCqFZwa/JY1GdATAQ+TgVtgrwwMZ0D07QhA99rs/EAAWfvG6KpA==",
"license": "MIT",
"dependencies": {
"@vue/compiler-dom": "3.5.12",
"@vue/shared": "3.5.12"
"@vue/compiler-dom": "3.5.13",
"@vue/shared": "3.5.13"
}
},
"node_modules/@vue/reactivity": {
"version": "3.5.12",
"resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.5.12.tgz",
"integrity": "sha512-UzaN3Da7xnJXdz4Okb/BGbAaomRHc3RdoWqTzlvd9+WBR5m3J39J1fGcHes7U3za0ruYn/iYy/a1euhMEHvTAg==",
"version": "3.5.13",
"resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.5.13.tgz",
"integrity": "sha512-NaCwtw8o48B9I6L1zl2p41OHo/2Z4wqYGGIK1Khu5T7yxrn+ATOixn/Udn2m+6kZKB/J7cuT9DbWWhRxqixACg==",
"license": "MIT",
"dependencies": {
"@vue/shared": "3.5.12"
"@vue/shared": "3.5.13"
}
},
"node_modules/@vue/runtime-core": {
"version": "3.5.12",
"resolved": "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.5.12.tgz",
"integrity": "sha512-hrMUYV6tpocr3TL3Ad8DqxOdpDe4zuQY4HPY3X/VRh+L2myQO8MFXPAMarIOSGNu0bFAjh1yBkMPXZBqCk62Uw==",
"version": "3.5.13",
"resolved": "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.5.13.tgz",
"integrity": "sha512-Fj4YRQ3Az0WTZw1sFe+QDb0aXCerigEpw418pw1HBUKFtnQHWzwojaukAs2X/c9DQz4MQ4bsXTGlcpGxU/RCIw==",
"license": "MIT",
"dependencies": {
"@vue/reactivity": "3.5.12",
"@vue/shared": "3.5.12"
"@vue/reactivity": "3.5.13",
"@vue/shared": "3.5.13"
}
},
"node_modules/@vue/runtime-dom": {
"version": "3.5.12",
"resolved": "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.5.12.tgz",
"integrity": "sha512-q8VFxR9A2MRfBr6/55Q3umyoN7ya836FzRXajPB6/Vvuv0zOPL+qltd9rIMzG/DbRLAIlREmnLsplEF/kotXKA==",
"version": "3.5.13",
"resolved": "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.5.13.tgz",
"integrity": "sha512-dLaj94s93NYLqjLiyFzVs9X6dWhTdAlEAciC3Moq7gzAc13VJUdCnjjRurNM6uTLFATRHexHCTu/Xp3eW6yoog==",
"license": "MIT",
"dependencies": {
"@vue/reactivity": "3.5.12",
"@vue/runtime-core": "3.5.12",
"@vue/shared": "3.5.12",
"@vue/reactivity": "3.5.13",
"@vue/runtime-core": "3.5.13",
"@vue/shared": "3.5.13",
"csstype": "^3.1.3"
}
},
"node_modules/@vue/server-renderer": {
"version": "3.5.12",
"resolved": "https://registry.npmjs.org/@vue/server-renderer/-/server-renderer-3.5.12.tgz",
"integrity": "sha512-I3QoeDDeEPZm8yR28JtY+rk880Oqmj43hreIBVTicisFTx/Dl7JpG72g/X7YF8hnQD3IFhkky5i2bPonwrTVPg==",
"version": "3.5.13",
"resolved": "https://registry.npmjs.org/@vue/server-renderer/-/server-renderer-3.5.13.tgz",
"integrity": "sha512-wAi4IRJV/2SAW3htkTlB+dHeRmpTiVIK1OGLWV1yeStVSebSQQOwGwIq0D3ZIoBj2C2qpgz5+vX9iEBkTdk5YA==",
"license": "MIT",
"dependencies": {
"@vue/compiler-ssr": "3.5.12",
"@vue/shared": "3.5.12"
"@vue/compiler-ssr": "3.5.13",
"@vue/shared": "3.5.13"
},
"peerDependencies": {
"vue": "3.5.12"
"vue": "3.5.13"
}
},
"node_modules/@vue/shared": {
"version": "3.5.12",
"resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.5.12.tgz",
"integrity": "sha512-L2RPSAwUFbgZH20etwrXyVyCBu9OxRSi8T/38QsvnkJyvq2LufW2lDCOzm7t/U9C1mkhJGWYfCuFBCmIuNivrg==",
"version": "3.5.13",
"resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.5.13.tgz",
"integrity": "sha512-/hnE/qP5ZoGpol0a5mDi45bOd7t3tjYJBjsgCsivow7D48cJeV5l05RD82lPqi7gRiphZM37rnhW1l6ZoCNNnQ==",
"license": "MIT"
},
"node_modules/@vue/test-utils": {
@ -16405,16 +16405,16 @@
"license": "MIT"
},
"node_modules/vue": {
"version": "3.5.12",
"resolved": "https://registry.npmjs.org/vue/-/vue-3.5.12.tgz",
"integrity": "sha512-CLVZtXtn2ItBIi/zHZ0Sg1Xkb7+PU32bJJ8Bmy7ts3jxXTcbfsEfBivFYYWz1Hur+lalqGAh65Coin0r+HRUfg==",
"version": "3.5.13",
"resolved": "https://registry.npmjs.org/vue/-/vue-3.5.13.tgz",
"integrity": "sha512-wmeiSMxkZCSc+PM2w2VRsOYAZC8GdipNFRTsLSfodVqI9mbejKeXEGr8SckuLnrQPGe3oJN5c3K0vpoU9q/wCQ==",
"license": "MIT",
"dependencies": {
"@vue/compiler-dom": "3.5.12",
"@vue/compiler-sfc": "3.5.12",
"@vue/runtime-dom": "3.5.12",
"@vue/server-renderer": "3.5.12",
"@vue/shared": "3.5.12"
"@vue/compiler-dom": "3.5.13",
"@vue/compiler-sfc": "3.5.13",
"@vue/runtime-dom": "3.5.13",
"@vue/server-renderer": "3.5.13",
"@vue/shared": "3.5.13"
},
"peerDependencies": {
"typescript": "*"

View file

@ -50,7 +50,7 @@
"tributejs": "5.1.3",
"uint8-to-base64": "0.2.0",
"vanilla-colorful": "0.7.2",
"vue": "3.5.12",
"vue": "3.5.13",
"vue-chartjs": "5.3.1",
"vue-loader": "17.4.2",
"vue3-calendar-heatmap": "2.0.5",

View file

@ -457,16 +457,16 @@ func issues(ctx *context.Context, milestoneID, projectID int64, isPullOption opt
ctx.Data["OpenCount"] = issueStats.OpenCount
ctx.Data["ClosedCount"] = issueStats.ClosedCount
ctx.Data["AllCount"] = issueStats.AllCount
linkStr := "%s?q=%s&type=%s&sort=%s&state=%s&labels=%s&milestone=%d&project=%d&assignee=%d&poster=%d&archived=%t"
ctx.Data["AllStatesLink"] = fmt.Sprintf(linkStr, ctx.Link,
linkStr := "?q=%s&type=%s&sort=%s&state=%s&labels=%s&milestone=%d&project=%d&assignee=%d&poster=%d&fuzzy=%t&archived=%t"
ctx.Data["AllStatesLink"] = fmt.Sprintf(linkStr,
url.QueryEscape(keyword), url.QueryEscape(viewType), url.QueryEscape(sortType), "all", url.QueryEscape(selectLabels),
milestoneID, projectID, assigneeID, posterID, archived)
ctx.Data["OpenLink"] = fmt.Sprintf(linkStr, ctx.Link,
milestoneID, projectID, assigneeID, posterID, isFuzzy, archived)
ctx.Data["OpenLink"] = fmt.Sprintf(linkStr,
url.QueryEscape(keyword), url.QueryEscape(viewType), url.QueryEscape(sortType), "open", url.QueryEscape(selectLabels),
milestoneID, projectID, assigneeID, posterID, archived)
ctx.Data["ClosedLink"] = fmt.Sprintf(linkStr, ctx.Link,
milestoneID, projectID, assigneeID, posterID, isFuzzy, archived)
ctx.Data["ClosedLink"] = fmt.Sprintf(linkStr,
url.QueryEscape(keyword), url.QueryEscape(viewType), url.QueryEscape(sortType), "closed", url.QueryEscape(selectLabels),
milestoneID, projectID, assigneeID, posterID, archived)
milestoneID, projectID, assigneeID, posterID, isFuzzy, archived)
ctx.Data["SelLabelIDs"] = labelIDs
ctx.Data["SelectLabels"] = selectLabels
ctx.Data["ViewType"] = viewType

View file

@ -10,6 +10,8 @@ import (
issues_model "code.gitea.io/gitea/models/issues"
org_model "code.gitea.io/gitea/models/organization"
access_model "code.gitea.io/gitea/models/perm/access"
"code.gitea.io/gitea/models/unit"
user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/modules/git"
"code.gitea.io/gitea/modules/gitrepo"
@ -117,7 +119,11 @@ func PullRequestCodeOwnersReview(ctx context.Context, issue *issues_model.Issue,
}
for _, u := range uniqUsers {
if u.ID != issue.Poster.ID {
permission, err := access_model.GetUserRepoPermission(ctx, issue.Repo, u)
if err != nil {
return nil, fmt.Errorf("GetUserRepoPermission: %w", err)
}
if u.ID != issue.Poster.ID && permission.CanRead(unit.TypePullRequests) {
comment, err := issues_model.AddReviewRequest(ctx, issue, u, issue.Poster)
if err != nil {
log.Warn("Failed add assignee user: %s to PR review: %s#%d, error: %s", u.Name, pr.BaseRepo.Name, pr.ID, err)

View file

@ -14,6 +14,7 @@ import (
"testing"
"time"
"code.gitea.io/gitea/models/db"
issues_model "code.gitea.io/gitea/models/issues"
repo_model "code.gitea.io/gitea/models/repo"
unit_model "code.gitea.io/gitea/models/unit"
@ -159,5 +160,42 @@ func TestCodeOwner(t *testing.T) {
pr := unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{BaseRepoID: repo.ID, HeadBranch: "branch"})
unittest.AssertExistsIf(t, true, &issues_model.Review{IssueID: pr.IssueID, Type: issues_model.ReviewTypeRequest, ReviewerID: 4})
})
t.Run("Codeowner user with no permission", func(t *testing.T) {
defer tests.PrintCurrentTest(t)()
// Make repository private, only user2 (owner of repository) has now access to this repository.
repo.IsPrivate = true
_, err := db.GetEngine(db.DefaultContext).Cols("is_private").Update(repo)
require.NoError(t, err)
err = os.WriteFile(path.Join(dstPath, "README.md"), []byte("## very senstive info"), 0o666)
require.NoError(t, err)
err = git.AddChanges(dstPath, true)
require.NoError(t, err)
err = git.CommitChanges(dstPath, git.CommitChangesOptions{
Committer: &git.Signature{
Email: "user2@example.com",
Name: "user2",
When: time.Now(),
},
Author: &git.Signature{
Email: "user2@example.com",
Name: "user2",
When: time.Now(),
},
Message: "Add secrets to the README.",
})
require.NoError(t, err)
err = git.NewCommand(git.DefaultContext, "push", "origin", "HEAD:refs/for/main", "-o", "topic=codeowner-private").Run(&git.RunOpts{Dir: dstPath})
require.NoError(t, err)
// In CODEOWNERS file the codeowner for README.md is user5, but does not have access to this private repository.
pr := unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{BaseRepoID: repo.ID, HeadBranch: "user2/codeowner-private"})
unittest.AssertExistsIf(t, false, &issues_model.Review{IssueID: pr.IssueID, Type: issues_model.ReviewTypeRequest, ReviewerID: 5})
})
})
}

View file

@ -1140,7 +1140,7 @@ func TestRepoIssueFilterLinks(t *testing.T) {
t.Run("Fuzzy", func(t *testing.T) {
defer tests.PrintCurrentTest(t)()
req := NewRequest(t, "GET", "/user2/repo1/issues?fuzzy=true")
req := NewRequest(t, "GET", "/user2/repo1/issues?fuzzy=false")
resp := MakeRequest(t, req, http.StatusOK)
htmlDoc := NewHTMLParser(t, resp.Body)
@ -1157,7 +1157,7 @@ func TestRepoIssueFilterLinks(t *testing.T) {
assert.Contains(t, href, "&project=")
assert.Contains(t, href, "&assignee=")
assert.Contains(t, href, "&poster=")
assert.Contains(t, href, "&fuzzy=true")
assert.Contains(t, href, "&fuzzy=false")
})
assert.True(t, called)
})
@ -1237,7 +1237,7 @@ func TestRepoIssueFilterLinks(t *testing.T) {
assert.True(t, called)
})
t.Run("Miilestone", func(t *testing.T) {
t.Run("Milestone", func(t *testing.T) {
defer tests.PrintCurrentTest(t)()
req := NewRequest(t, "GET", "/user2/repo1/issues?milestone=1")