mirror of
https://codeberg.org/forgejo/forgejo
synced 2024-11-25 11:16:11 +01:00
Compare commits
25 commits
f7d3fda9fc
...
2884de2094
Author | SHA1 | Date | |
---|---|---|---|
2884de2094 | |||
d0fcba5053 | |||
5a14575dda | |||
b2105876d8 | |||
2fcc4fb5ba | |||
0f1031425a | |||
90a65ebbc1 | |||
08e88b9189 | |||
aafcafed48 | |||
bc290dd932 | |||
8017fa486a | |||
c3a9e58dc9 | |||
4c66109ca2 | |||
2f81c0ec80 | |||
c190abc758 | |||
e463fa4543 | |||
4163402f5e | |||
e31090cf4b | |||
2cc3278791 | |||
693f7731f9 | |||
abec2442b7 | |||
64a89c8d33 | |||
76f172b080 | |||
9701e5e0ff | |||
e4eb82b738 |
|
@ -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: >
|
||||
|
|
11
models/issues/TestGetUIDsAndStopwatch/stopwatch.yml
Normal file
11
models/issues/TestGetUIDsAndStopwatch/stopwatch.yml
Normal 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
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
|
|
@ -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),
|
||||
})
|
||||
|
|
|
@ -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 cтежать
|
||||
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 = Cтежить
|
||||
followers.title.few = Cтежать
|
||||
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
110
package-lock.json
generated
|
@ -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": "*"
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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})
|
||||
})
|
||||
})
|
||||
}
|
||||
|
|
|
@ -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")
|
||||
|
|
Loading…
Reference in a new issue