-
-
- - +
+ +
diff --git a/web_src/css/modules/switch.css b/web_src/css/modules/switch.css index 5250274d05..265c2ed45a 100644 --- a/web_src/css/modules/switch.css +++ b/web_src/css/modules/switch.css @@ -22,3 +22,11 @@ background: var(--color-active); outline: 1px solid var(--color-input-border); } + +.switch .item svg { + vertical-align: sub; +} + +.switch button.item { + background: transparent; +} From 30c7a0b94787123afc80906b4040f2c73a44d6e9 Mon Sep 17 00:00:00 2001 From: 0ko <0ko@noreply.codeberg.org> Date: Mon, 13 Jan 2025 17:28:36 +0000 Subject: [PATCH 143/198] Make switch larger on touchscreen devices (#6546) Followup to https://codeberg.org/forgejo/forgejo/pulls/6459. Usually it's quite hard to have inputs with balanced size that works for both desktop and mobile: it's either too large or too small for one of them. I think this can be a solution for this new element. I tried it locally, it feels good on a phone. There's likely one downside which is that the switch will still be larger on touch devices even when they're wide, like on tablets. I think it can be resolved separately at some point. It isn't a problem on small devices because usually these elements go on separate rows. ## Preview This change only affects touch devices. |Before|After| |-|-| |![](/attachments/75311c3f-2e19-4b03-9596-7f78c78f0a70)|![](/attachments/74f987af-57c1-417d-89ed-f96666cb9bad)| Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/6546 Reviewed-by: Michael Kriese Reviewed-by: Otto Co-authored-by: 0ko <0ko@noreply.codeberg.org> Co-committed-by: 0ko <0ko@noreply.codeberg.org> --- web_src/css/modules/switch.css | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/web_src/css/modules/switch.css b/web_src/css/modules/switch.css index 265c2ed45a..a9499a84aa 100644 --- a/web_src/css/modules/switch.css +++ b/web_src/css/modules/switch.css @@ -23,8 +23,10 @@ outline: 1px solid var(--color-input-border); } -.switch .item svg { - vertical-align: sub; +@media (pointer: coarse) { + .switch .item { + padding: .75em 1.125em; + } } .switch button.item { From a87d07f4d260d6a85c4ee0d20190655f242adc04 Mon Sep 17 00:00:00 2001 From: Renovate Bot Date: Mon, 13 Jan 2025 22:10:43 +0000 Subject: [PATCH 144/198] Update dependency katex to v0.16.20 (forgejo) (#6548) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This PR contains the following updates: | Package | Type | Update | Change | |---|---|---|---| | [katex](https://katex.org) ([source](https://github.com/KaTeX/KaTeX)) | dependencies | patch | [`0.16.18` -> `0.16.20`](https://renovatebot.com/diffs/npm/katex/0.16.18/0.16.20) | --- ### Release Notes
KaTeX/KaTeX (katex) ### [`v0.16.20`](https://github.com/KaTeX/KaTeX/blob/HEAD/CHANGELOG.md#01620-2025-01-12) [Compare Source](https://github.com/KaTeX/KaTeX/compare/v0.16.19...v0.16.20) ##### Bug Fixes - \providecommand does not overwrite existing macro ([#​4000](https://github.com/KaTeX/KaTeX/issues/4000)) ([6d30fe4](https://github.com/KaTeX/KaTeX/commit/6d30fe47b06f9da9b836fe518d5cbbecf6a6a3a1)), closes [#​3928](https://github.com/KaTeX/KaTeX/issues/3928) ### [`v0.16.19`](https://github.com/KaTeX/KaTeX/blob/HEAD/CHANGELOG.md#01619-2024-12-29) [Compare Source](https://github.com/KaTeX/KaTeX/compare/v0.16.18...v0.16.19) ##### Bug Fixes - **types:** improve `strict` function type ([#​4009](https://github.com/KaTeX/KaTeX/issues/4009)) ([4228b4e](https://github.com/KaTeX/KaTeX/commit/4228b4eb529b8e35def66cc6e4fa467383b98c86))
--- ### Configuration 📅 **Schedule**: Branch creation - "* 0-3 * * *" (UTC), Automerge - "* 0-3 * * *" (UTC). 🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied. ♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] If you want to rebase/retry this PR, check this box --- This PR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate). Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/6548 Reviewed-by: Michael Kriese Co-authored-by: Renovate Bot Co-committed-by: Renovate Bot --- package-lock.json | 8 ++++---- package.json | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package-lock.json b/package-lock.json index 576d395dad..223dfbd310 100644 --- a/package-lock.json +++ b/package-lock.json @@ -30,7 +30,7 @@ "htmx.org": "1.9.12", "idiomorph": "0.3.0", "jquery": "3.7.1", - "katex": "0.16.18", + "katex": "0.16.20", "mermaid": "11.4.1", "mini-css-extract-plugin": "2.9.2", "minimatch": "10.0.1", @@ -10402,9 +10402,9 @@ "license": "MIT" }, "node_modules/katex": { - "version": "0.16.18", - "resolved": "https://registry.npmjs.org/katex/-/katex-0.16.18.tgz", - "integrity": "sha512-LRuk0rPdXrecAFwQucYjMiIs0JFefk6N1q/04mlw14aVIVgxq1FO0MA9RiIIGVaKOB5GIP5GH4aBBNraZERmaQ==", + "version": "0.16.20", + "resolved": "https://registry.npmjs.org/katex/-/katex-0.16.20.tgz", + "integrity": "sha512-jjuLaMGD/7P8jUTpdKhA9IoqnH+yMFB3sdAFtq5QdAqeP2PjiSbnC3EaguKPNtv6dXXanHxp1ckwvF4a86LBig==", "funding": [ "https://opencollective.com/katex", "https://github.com/sponsors/katex" diff --git a/package.json b/package.json index 508c9af45d..86b1b17029 100644 --- a/package.json +++ b/package.json @@ -29,7 +29,7 @@ "htmx.org": "1.9.12", "idiomorph": "0.3.0", "jquery": "3.7.1", - "katex": "0.16.18", + "katex": "0.16.20", "mermaid": "11.4.1", "mini-css-extract-plugin": "2.9.2", "minimatch": "10.0.1", From d717c78ea08c17c8e38b5ba75ebc09e88f546d19 Mon Sep 17 00:00:00 2001 From: Codeberg Translate Date: Tue, 14 Jan 2025 06:49:06 +0000 Subject: [PATCH 145/198] i18n: update of translations from Codeberg Translate (#6515) Co-authored-by: 0ko <0ko@users.noreply.translate.codeberg.org> Co-authored-by: Edgarsons Co-authored-by: div72 Co-authored-by: tkbremnes Co-authored-by: artnay Co-authored-by: Outbreak2096 Co-authored-by: Protestant Co-authored-by: micash Co-authored-by: Ikuyo Mita Co-authored-by: tacaly Co-authored-by: burakozaydin Co-authored-by: kdh8219 Co-authored-by: Juno Takano Co-authored-by: earl-warren Co-authored-by: justbispo Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/6515 Reviewed-by: 0ko <0ko@noreply.codeberg.org> Co-authored-by: Codeberg Translate Co-committed-by: Codeberg Translate --- options/locale/locale_da.ini | 19 +++++ options/locale/locale_fi-FI.ini | 22 ++++- options/locale/locale_fil.ini | 2 + options/locale/locale_fr-FR.ini | 33 ++++++-- options/locale/locale_ko-KR.ini | 143 +++++++++++++++++++++++--------- options/locale/locale_lv-LV.ini | 96 ++++++++++----------- options/locale/locale_nb_NO.ini | 15 +++- options/locale/locale_pl-PL.ini | 4 +- options/locale/locale_pt-BR.ini | 2 + options/locale/locale_pt-PT.ini | 1 + options/locale/locale_ru-RU.ini | 13 +-- options/locale/locale_tr-TR.ini | 89 ++++++++++---------- options/locale/locale_zh-CN.ini | 42 +++++----- 13 files changed, 313 insertions(+), 168 deletions(-) diff --git a/options/locale/locale_da.ini b/options/locale/locale_da.ini index eb62ac012b..27b53b4604 100644 --- a/options/locale/locale_da.ini +++ b/options/locale/locale_da.ini @@ -1608,6 +1608,25 @@ issues.label_count = %d etiketter issues.label_open_issues = %d åben problemer/pull-anmodninger issues.label_edit = Redigere issues.label_delete = Slet +issues.archived_label_description = (Arkiveret) %s +issues.label.filter_sort.alphabetically = Alfabetisk +issues.label.filter_sort.reverse_alphabetically = Omvendt alfabetisk +issues.label.filter_sort.by_size = Mindste størrelse +issues.label.filter_sort.reverse_by_size = Største størrelse +issues.num_participants_one = %d deltager +issues.num_participants_few = %d deltagere +issues.attachment.open_tab = `Klik for at se "%s" i en ny fane` +issues.attachment.download = `Klik for at downloade "%s"` +issues.subscribe = Abonner +issues.unsubscribe = Afmeld +issues.lock_duplicate = Et problem kan ikke låses to gange. +issues.unlock_error = Kan ikke låse et problem op, der ikke er låst. +issues.lock_with_reason = låst som %s og begrænset samtale til samarbejdspartnere %s +issues.lock_confirm = Lås +issues.unlock_confirm = Lås op +issues.lock.notice_1 = - Andre brugere kan ikke tilføje nye kommentarer til dette problem. +issues.lock_no_reason = låst og begrænset samtale til samarbejdspartnere %s +issues.unlock_comment = låste denne samtale %s op [notification] watching = Overvåger diff --git a/options/locale/locale_fi-FI.ini b/options/locale/locale_fi-FI.ini index 70bd6413cc..2e7362b448 100644 --- a/options/locale/locale_fi-FI.ini +++ b/options/locale/locale_fi-FI.ini @@ -119,7 +119,7 @@ new_project_column = Uusi sarake retry = Yritä uudelleen copy_type_unsupported = Tätä tiedostotyyppiä ei voi kopioida locked = Lukittu -filter = Suodatin +filter = Suodata filter.is_archived = Arkistoitu filter.not_archived = Ei arkistoitu filter.public = Julkinen @@ -468,6 +468,13 @@ reset_password_wrong_user = Olet kirjautuneena tilillä %s, mutta tilin palautus last_admin = Et voi poistaa viimeistä ylläpitäjää. Ylläpitäjiä tulee olla vähintään yksi. password_pwned = Valitsemasi salasana on varastettujen salasanojen listalla, eli se on paljastanut jossain julkisessa tietovuodossa. Kokeile asettaa eri salasana, ja jos käytät samaa salasanaa muissa palveluissa, vaihda kyseinen salasana. use_onetime_code = Käytä kertakäyttöiskoodia +unauthorized_credentials = Kirjautumistiedot ovat virheelliset tai vanhentuneet. Yritä suorittaa komento uudelleen tai katso %s saadaksesi lisätietoja +oauth.signin.error.temporarily_unavailable = Valtuus epäonnistui, koska todennuspalvelin ei ole tällä hetkellä käytettävissä. Yritä uudelleen myöhemmin. +disable_forgot_password_mail = Tilin palautus ei ole käytössä, koska sähköpostia ei ole määritetty. Ota yhteys sivuston ylläpitoon. +password_pwned_err = Pyyntöä HaveIBeenPwned-palveluun ei voitu suorittaa +authorization_failed_desc = Valtuus epäonnistui, koska havaitsimme virheellisen pyynnön. Ota yhteys sen sovelluksen ylläpitäjään, jota yritit valtuuttaa. +oauth.signin.error = Valtuuspyynnön käsittelyssä tapahtui virhe. Jos virhe toistuu, ota yhteys sivuston ylläpitoon. +disable_forgot_password_mail_admin = Tilin palautus on käytössä vain, jos sähköposti on määritetty. Aseta sähköposti, jotta tilin palauttaminen on mahdollista ottaa käyttöön. [mail] view_it_on=Näytä %s @@ -526,6 +533,8 @@ issue.action.close = @%[1]s sulki ongelman #%[2]d. issue.action.reopen = @%[1]s avasi uudelleen ongelman #%[2]d. admin.new_user.text = Napsauta tästä hallitaksesi tätä käyttäjää ylläpitonäkymästä. repo.collaborator.added.text = Sinut on lisätty avustajaksi repoon: +primary_mail_change.text_1 = Tilisi ensisijaiseksi sähköpostiosoitteeksi asetettiin %[1]s. Se tarkoittaa, että tämä sähköpostiosoite ei enää vastaanota tilisi ilmoituksia sähköpostitse. +team_invite.text_1 = %[1]s on kutsunut sinut liittymään tiimiin %[2]s organisaatiossa %[3]s. @@ -643,6 +652,8 @@ show_on_map = Näytä paikka kartalla form.name_chars_not_allowed = Käyttäjätunnus "%s" sisältää virheellisiä merkkejä. follow_blocked_user = Et voi seurata tätä käyttäjää, koska olet estänyt kyseisen käyttäjän tai kyseinen käyttäjä on estänyt sinut. disabled_public_activity = Käyttäjä on poistanut käytöstä toiminnan julkisen näkyvyyden. +form.name_reserved = Käyttäjätunnus "%s" on varattu. +form.name_pattern_not_allowed = Kaava "%s" ei ole sallittu käyttäjätunnuksessa. [settings] @@ -872,7 +883,7 @@ visibility.limited_tooltip = Näkyvissä vain kirjautuneille käyttäjille email_notifications.disable = Poista sähköposti-ilmoitukset käytöstä webauthn_register_key = Lisää turva-avain blocked_users = Estetyt käyttäjät -profile_desc = Määritä, miten muut näkevät profiilisi. Ensisijaista sähköpostiosoitettasi käytetään ilmoitusten ja salasanan palautuspyyntöjen lähettämiseen sekä verkkosivupohjaisiin Git-operaatioihin. +profile_desc = Tietoja sinusta change_password_success = Salasanasi on päivitetty. Kirjaudu jatkossa käyttäen uutta salasanaa. manage_oauth2_applications = Hallitse OAuth2-sovelluksia change_password = Vaihda salasana @@ -929,6 +940,11 @@ oauth2_application_create_description = OAuth2-sovellukset mahdollistavat kolman oauth2_confidential_client = Luottamuksellinen sovellus. Valitse sovelluksille, jotka pitävät salaisuuden luottamuksellisena, kuten web-sovelluksille. Älä valitse natiiveille sovelluksille mukaan lukien työpöytä- ja mobiilisovellukset. ssh_key_deletion_desc = SSH-avaimen poistaminen kumoaa pääsyn tilillesi kyseistä avainta käyttäen. Jatketaanko? add_email_confirmation_sent = Vahvistusviesti on lähetetty osoitteeseen "%s". Vahvista sähköpostiosoitteesi seuraavan %s sisällä. +pronouns_custom_label = Mukautetut pronominit +openid_deletion_desc = Tämän OpenID-osoitteen poistaminen tililtäsi estää kirjautumisen sitä käyttäen. Jatketaanko? +generate_token_name_duplicate = Nimeä %s on jo käytetty sovelluksen nimenä. Käytä eri nimeä. +ssh_signonly = SSH on tällä hetkellä poistettu käytöstä, joten näitä avaimia käytetään vain kommittien allekirjoituksen vahvistamiseen. +oauth2_applications_desc = OAuth2-sovellukset mahdollistavat käyttämäsi kolmannen osapuolen sovelluksen todentaa turvallisesti käyttäjiä tähän Forgejo-instanssiin. [repo] owner=Omistaja @@ -2064,6 +2080,8 @@ settings.allow_only_contributors_to_track_time = Salli vain avustajien seurata a settings.actions_desc = Käytä integroituja CI-/CD-putkia Forgejo Actionsia hyödyntäen settings.admin_enable_close_issues_via_commit_in_any_branch = Sulje ongelma kommitin toimesta, joka on tehty muuhun kuin oletusarvoiseen haaraan settings.mirror_settings.pushed_repository = Työnnetty repo +pulls.compare_changes_desc = Valitse haara, johon yhdistetään, ja haara, josta vedetään. +no_eol.text = Ei EOL:ää diff --git a/options/locale/locale_fil.ini b/options/locale/locale_fil.ini index 9d0ec9f308..8bde8032b1 100644 --- a/options/locale/locale_fil.ini +++ b/options/locale/locale_fil.ini @@ -3279,6 +3279,7 @@ users.activated.description = Pagkumpleto ng email verification. Ang owner ng hi users.admin.description = Binibigyan ang user na ito ng punong access sa lahat ng mga tagapangasiwang feature na available sa pamamagitan ng web UI at ang API. config.db_ssl_mode = SSL config.enable_openid_signin = I-enable ang OpenID sign-in +monitor.duration = Tagal (s) [org] repo_updated = Binago %s @@ -3565,6 +3566,7 @@ owner.settings.cargo.rebuild.success = Matagumpay na na-rebuild ang Cargo index. owner.settings.cleanuprules.title = Mga cleanup rule container.layers = Mga layer ng image container.images.title = Mga image +search_in_external_registry = Maghanap sa %s [actions] runners.last_online = Huling oras na online diff --git a/options/locale/locale_fr-FR.ini b/options/locale/locale_fr-FR.ini index 09d66771a3..f67b11dc04 100644 --- a/options/locale/locale_fr-FR.ini +++ b/options/locale/locale_fr-FR.ini @@ -1,7 +1,7 @@ [common] home=Accueil dashboard=Tableau de bord -explore=Explorateur +explore=Explorer help=Aide logo=Logo sign_in=Connexion @@ -520,7 +520,7 @@ issue.action.force_push=%[1]s a forcé %[2]s de %[3]s vers %[4]s. issue.action.push_1=@%[1]s a soumis %[3]d révision sur %[2]s issue.action.push_n=@%[1]s a soumis %[3]d révisions sur %[2]s issue.action.close=@%[1]s a fermé #%[2]d. -issue.action.reopen=@%[1]s a réouvert #%[2]d. +issue.action.reopen=@%[1]s a rouvert #%[2]d. issue.action.merge=@%[1]s a fusionné de #%[2]d vers %[3]s. issue.action.approve=@%[1]s a approuvé cette demande d'ajout. issue.action.reject=@%[1]s a demandé des modifications sur cette demande d'ajout. @@ -745,7 +745,7 @@ uid=UID webauthn=Clés de sécurité à deux facteurs public_profile=Profil public -biography_placeholder=Parlez-nous un peu de vous ! (Markdown est interprété) +biography_placeholder=Parlez-nous un peu de vous ! (Markdown est supporté) location_placeholder=Partagez votre position approximative avec d'autres personnes profile_desc=À propos de vous password_username_disabled=Les utilisateurs externes ne sont pas autorisés à modifier leur nom d'utilisateur. Veuillez contacter l'administrateur de votre site pour plus de détails. @@ -1055,6 +1055,7 @@ keep_activity_private.description = Vous seul pourrez voir votre ac language.localization_project = Aidez-nous à traduire Forgejo dans votre langue ! En savoir plus. language.description = Cette langue sera enregistrée dans votre compte et utilisée comme langue par défaut après votre connexion. user_block_yourself = Vous ne pouvez pas vous bloquer vous même. +pronouns_custom_label = Pronoms personnalisés [repo] new_repo_helper=Un dépôt contient tous les fichiers d’un projet, ainsi que l’historique de leurs modifications. Vous avez déjà ça ailleurs ? Migrez-le ici.. @@ -1619,7 +1620,7 @@ issues.reopen_issue=Rouvrir issues.reopen_comment_issue=Réouvrir avec le commentaire issues.create_comment=Commenter issues.closed_at=`a fermé ce ticket %[2]s.` -issues.reopened_at=`a réouvert ce ticket %[2]s.` +issues.reopened_at=`a rouvert ce ticket %[2]s.` issues.commit_ref_at=`a référencé ce ticket depuis une révision %[2]s.` issues.ref_issue_from=`a fait référence à %[4]s ce ticket %[2]s.` issues.ref_pull_from=`a fait référence à cette demande d'ajout %[4]s %[2]s.` @@ -1779,7 +1780,7 @@ issues.review.approve=a approuvé ces modifications %s issues.review.comment=a évalué cette demande d’ajout %s issues.review.dismissed=a révoqué l’évaluation de %s %s issues.review.dismissed_label=Révoquée -issues.review.left_comment=laisser un commentaire +issues.review.left_comment=a laissé un commentaire issues.review.content.empty=Vous devez laisser un commentaire indiquant le(s) changement(s) demandé(s). issues.review.reject=a requis les changements %s issues.review.wait=a été sollicité pour évaluer cette demande d’ajout %s @@ -2850,6 +2851,20 @@ editor.add_tmpl.filename = fichier issues.num_reviews_one = %d revue issues.num_reviews_few = %d revues settings.default_update_style_desc = Style de mise à jour des demandes de fusion qui sont en retard par rapport à la branche de base. +release.summary_card_alt = Carte résumé de la publication dont le titre est "%s" dans le dépôt %s +pulls.sign_in_require = Identifiez vous pour créer une nouvelle demande d'ajout. +new_from_template = Utiliser un modèle +new_from_template_description = Vous pouvez sélectionner un modèle de dépôt existant sur cette instance et appliquer ses paramètres. +new_advanced = Options avancées +new_advanced_expand = Cliquer pour développer +auto_init_description = Débuter l'historique Git avec un README et ajouter en option les fichier de licence et .gitignore. +issues.reaction.add = Ajouter une réaction +issues.reaction.alt_few = %[1]s a réagit %[2]s. +issues.reaction.alt_many = %[1]s et %[2]d de plus ont réagit %[3]s. +issues.reaction.alt_remove = Enlever la réaction %[1]s du commentaire. +issues.reaction.alt_add = Ajouter la réaction %[1]s du commentaire. +issues.context.menu = Menu commentaire +summary_card_alt = Carte résumé du dépôt %s [graphs] component_loading = Chargement %s... @@ -3544,6 +3559,7 @@ users.block.description = Bloquer cet utilisateur d'interagir avec ce service vi users.admin.description = Accorder à cet utilisateur un accès complet à toutes les fonctionnalités administratives disponibles via l'interface web et l'API. users.restricted.description = Autoriser uniquement l'interaction avec les dépôts et les organisations où cet utilisateur est ajouté en tant que collaborateur. Cela empêche l'accès aux dépôts publics sur cette instance. users.local_import.description = Autoriser l'importation de dépôts à partir du système de fichiers local du serveur. Cela peut poser un problème de sécurité. +monitor.duration = Durée (s) [action] create_repo=a créé le dépôt %s @@ -3551,10 +3567,10 @@ rename_repo=a rebaptisé le dépôt %[1]s en %[3]s< commit_repo=a soumis sur %[3]s dans %[4]s create_issue=`a ouvert le ticket %[3]s#%[2]s` close_issue=`a fermé le ticket %[3]s#%[2]s` -reopen_issue=`a réouvert le ticket %[3]s#%[2]s` +reopen_issue=`a rouvert le ticket %[3]s#%[2]s` create_pull_request=`a créé la demande d’ajout %[3]s#%[2]s` close_pull_request=`a fermé la demande d’ajout %[3]s#%[2]s` -reopen_pull_request=`a réouvert la demande d’ajout %[3]s#%[2]s` +reopen_pull_request=`a rouvert la demande d’ajout %[3]s#%[2]s` comment_issue=`a commenté le ticket %[3]s#%[2]s` comment_pull=`a commenté la demande d’ajout %[3]s#%[2]s` merge_pull_request=`a fusionné la demande d’ajout %[3]s#%[2]s` @@ -3804,6 +3820,7 @@ arch.version.replaces = Remplace arch.version.backup = Sauvegarde arch.version.makedepends = Faire des dépendances container.images.title = Images +search_in_external_registry = Rechercher dans %s [secrets] secrets=Secrets @@ -3952,7 +3969,7 @@ keyword_search_unavailable = La recherche par mot-clé n'est pas disponible actu fuzzy_tooltip = Inclure les résultats proches des termes recherchés match = Correspondance match_tooltip = Uniquement inclure les résultats correspondant exactement aux termes recherchés -repo_kind = Chercher dans les dépôt... +repo_kind = Chercher dans les dépôts... user_kind = Chercher les utilisateurs... org_kind = Chercher les organisations... team_kind = Chercher les équipes... diff --git a/options/locale/locale_ko-KR.ini b/options/locale/locale_ko-KR.ini index 54ee0ab002..e2bdb940ae 100644 --- a/options/locale/locale_ko-KR.ini +++ b/options/locale/locale_ko-KR.ini @@ -128,7 +128,7 @@ copy_success = 복사되었습니다! copy_error = 복사 실패 copy_type_unsupported = 이 파일 형식은 복사할 수 없습니다 error = 오류 -error404 = 도달하려는 페이지가 존재하지 않거나 볼 수 있도록 인증되지 않았습니다. +error404 = 도달하려는 페이지가 존재하지 않거나 볼 수 있는 권한이 없습니다. go_back = 돌아가기 invalid_data = 유효하지 않는 데이터: %v unknown = 알 수 없음 @@ -164,6 +164,9 @@ new_repo.link = 새 저장소 new_org.link = 새 조직 new_repo.title = 새 저장소 new_org.title = 새 조직 +error413 = 사용 가능한 할당량을 모두 소진하였습니다. +new_migrate.title = 마이그레이션 +new_migrate.link = 새 마이그레이션 [aria] navbar = 내비게이션 바 @@ -187,6 +190,20 @@ buttons.bold.tooltip = 두꺼운 텍스트 추가 buttons.code.tooltip = 코드 추가 buttons.link.tooltip = 링크 추가 buttons.quote.tooltip = 인용구 추가 +buttons.list.unordered.tooltip = 불릿 리스트 추가 +buttons.ref.tooltip = 이슈 또는 풀 리퀘스트 참조 +buttons.list.ordered.tooltip = 번호로 된 리스트 추가 +buttons.mention.tooltip = 사용자 또는 팀을 언급 +buttons.switch_to_legacy.tooltip = 대신에 구형 편집기 사용 +buttons.enable_monospace_font = 고정 폭 글꼴 활성화 +buttons.disable_monospace_font = 고정 폭 글꼴 비활성화 +buttons.list.task.tooltip = 작업 목록 추가 +buttons.new_table.tooltip = 테이블 추가 +table_modal.header = 테이블 추가 +table_modal.placeholder.header = 헤더 +table_modal.placeholder.content = 내용 +table_modal.label.rows = 행 +table_modal.label.columns = 열 [filter] string.desc = 하 - 가 @@ -195,6 +212,9 @@ string.asc = 가 - 하 [error] network_error = 네트워크 오류 server_internal = 내부 서버 오류 +not_found = 타겟을 찾을 수 없습니다. +occurred = 에러가 발생함 +report_message = 이것이 Forgejo의 버그라고 생각한다면, Codeberg 에서 이슈를 검색하거나 필요하다면 새 이슈를 만들어주세요. [startpage] app_desc=편리한 설치형 Git 서비스 @@ -202,6 +222,10 @@ install=쉬운 설치 platform=크로스 플랫폼 lightweight=가벼움 license=오픈 소스 +platform_desc = Forgejo는 Linux와 FreeBSD등의 자유 오픈소스 운영 체제를 포함한 다양한 CPU 아키텍처에서 실행됩니다. 마음 가는대로 고르세요! +lightweight_desc = Forgejo의 낮은 전력 소모량은 값싼 Raspberry Pi마저 구동할 수 있게 합니다. 기기의 에너지를 절약하세요! +license_desc = Forgejo를 설치해보세요! Forgejo를 개선하기 위해 기여할 수 있습니다. 기여자가 되기를 망설이지 마세요! +install_desc = 간단히 당신의 기기에서바이너리를 실행하거나, Docker를 사용하거나, 패키지 저장소에서 설치할 수 있습니다. [install] install=설치 @@ -210,7 +234,7 @@ docker_helper=Forgejo를 Docker에서 실행하려면 설정 전에 이 형식으로 입력하세요. -mailer_user=SMTP 사용자이름 +mailer_user=SMTP 사용자명 mailer_password=SMTP 비밀번호 register_confirm=가입시 이메일 확인 필수 mail_notify=이메일 알림 켜기 @@ -255,9 +279,9 @@ server_service_title=서버 및 기타 서비스 설정 offline_mode=로컬 모드 켜기 offline_mode.description=타사 콘텐츠 전송 네트워크를 사용하지 않도록 설정하고 모든 리소스를 로컬에서 제공합니다. disable_gravatar=Gravatar 사용안함 -disable_gravatar.description=Gravatar 및 타사 아바타 소스를 사용하지 않도록 설정합니다. 사용자가 로컬로 아바타를 업로드하지 않는 한 기본 아바타가 사용됩니다. +disable_gravatar.description=Gravatar를 비롯한 타사 아바타 출처를 사용하지 않도록 설정합니다. 사용자가 직접 아바타를 업로드하지 않는 한 기본 아바타를 사용합니다. federated_avatar_lookup=탈중앙화 아바타 사용 -federated_avatar_lookup.description=libravatar 기반 오픈소스 연합 아바타 조회를 허용합니다. +federated_avatar_lookup.description=Libravatar 아바타를 조회합니다. disable_registration=사용자 등록 비활성화 disable_registration.description=인스턴스 관리자만이 새 사용자 계정을 추가할 수 있게 됩니다. 공개 인스턴스를 제공할 예정이고 많은 양의 스팸 계정을 감당할 준비가 되어 있지 않다면 사용자 등록을 비활성화 할 것을 강력히 권고합니다. allow_only_external_registration.description=새 계정을 등록하려는 사용자는 설정된 외부 서비스를 이용해야만 새 계정을 등록할 수 있습니다. @@ -269,7 +293,7 @@ enable_captcha.description=사용자 등록시 캡차를 요구합니다. require_sign_in_view=인스턴스의 콘텐츠를 볼때 로그인 요구 admin_setting.description=관리자 계정을 만드는 것은 선택사항입니다. 첫번째로 등록된 사용자는 자동적으로 관리자로 지정됩니다. admin_title=관리자 계정 설정 -admin_name=관리자 이름 +admin_name=관리자의 사용자명 admin_password=비밀번호 confirm_password=비밀번호 확인 admin_email=이메일 주소 @@ -278,27 +302,37 @@ test_git_failed='git' 명령 테스트 실패: %v sqlite3_not_available=해당 버전에서는 SQLite3를 지원하지 않습니다. %s에서 공식 버전을 다운로드해주세요. ('gobuild' 버전이 아닙니다). invalid_db_setting=데이터베이스 설정이 올바르지 않습니다: %v invalid_repo_path=저장소(레파지토리) 의 경로가 올바르지 않습니다: %v -run_user_not_match=실행 사용자명이 현재 사용자명과 다릅니다: %s -> %s +run_user_not_match="실행 사용자명"이 현재 사용자명과 다릅니다: %s -> %s save_config_failed=설정을 저장할 수 없습니다: %v invalid_admin_setting=관리자 계정 설정이 올바르지 않습니다: %v invalid_log_root_path=로그(Log) 의 경로가 올바르지 않습니다: %v default_keep_email_private=이메일 주소 숨김처리를 기본값으로 설정 -default_keep_email_private.description=새 사용자에 대한 이메일 주소 숨김처리를 기본값으로 설정합니다. +default_keep_email_private.description=새 사용자에 대한 이메일 주소 숨김처리를 기본값으로 설정해 가입 직후 정보가 유출되는것을 방지합니다. default_allow_create_organization=조직 생성 허용을 기본값으로 설정 -default_allow_create_organization.description=신규 사용자 생성시 조직 생성을 기본값으로 설정합니다. -default_enable_timetracking=시간 추적 사용을 기본값으로 설정 -default_enable_timetracking.description=신규 레포지토리에 대한 시간 추적 사용을 기본값으로 설정합니다. +default_allow_create_organization.description=신규 사용자에게 기본적으로 조직 생성 권한을 부여합니다. 이 옵션이 꺼져있다면, 관리자가 신규 사용자에게 조직 생성 권한을 부여해야합니다. +default_enable_timetracking=시간 기록 기능을 기본적으로 사용 +default_enable_timetracking.description=신규 저장소가 시간기록 기능을 기본적으로 사용할 수 있습니다. no_reply_address=가려진 이메일 도메인 -no_reply_address_helper=가려진 이메일을 가진 사용자에게 적용될 이메일 도메인입니다. 예를 들어, 사용자 'joe'의 가려잔 이메일 도메인이 'noreply.example.org'로 설정되어 있으면 'joe@noreply.example.org'로 처리 됩니다. +no_reply_address_helper=이메일을 가린 사용자에게 적용될 이메일 도메인입니다. 예를 들어, 사용자명 'joe'가 도메인'noreply.example.org'로 이메일을 가리면 Git에 'joe@noreply.example.org'로 로그인 하게 됩니다. db_schema_helper = 데이터베이스 기본값 ("공개")를 사용하려면 빈 칸으로 두세요. require_db_desc = Forgejo를 사용하려면 MySQL, PostgreSQL, SQLite3 또는 TiDB (MySQL 프로토콜) 이 설치되어 있어야 합니다. domain = 서버 도메인 smtp_from_invalid = "이메일 발신인" 주소가 유효하지 않습니다 enable_captcha = 등록 시 CAPTCHA 활성화 allow_only_external_registration = 외부 서비스를 통한 등록만 허용 +reinstall_confirm_check_3 = Forgejo가 올바른 app.ini 위치로 실행중이며 그것이 다시 설치할 대상이 맞다는것을 전적으로 확신합니다. 위의 위험성들을 인지하고 있음에 동의합니다. +reinstall_error = 이미 존재하는 Forgejo 데이터베이스에 설치를 시도중임 +reinstall_confirm_message = 이미 존재하는 Forgejo 데이터베이스에 재설치를 하는것은 다수의 문제의 원인이 될 수 있습니다. 대부분의 경우 이미 존재하는 "app.ini" 를 사용해 Forgejo를 구동해야합니다. 당신이 무엇을 하고있는지 명확히 알고있다면 다음 사항들을 확인하세요: +err_admin_name_pattern_not_allowed = 관리자의 사용자명이 올바르지 않음, 사용자명이 예약된 패턴과 일치함 +allow_dots_in_usernames = 사용자들이 마침표를 사용자명에 사용할 수 있도록 허가합니다. 이미 존재하는 계정에는 영향을 주지 않습니다. +app_slogan = 인스턴스 슬로건 +app_slogan_helper = 인스턴스의 슬로건을 입력하세요. 비워두면 비활성화됩니다. +reinstall_confirm_check_1 = app.ini의 SECRET_KEY로 암호화 되어있는 데이터를 잃을 수 있습니다: 2FA/OTP를 통해 로그인 할 수 없으며 & 미러가 제대로 작동하지 않게됩니다. app.ini 파일에 정확한 SECRET_KEY가 있는것이 확실하다면 체크하세요. +run_user_helper = Forgejo를 구동하는 운영체제의 사용자명입니다. 이 사용자는 저장소 루트 경로에 접근권한이 있어야 합니다. +reinstall_confirm_check_2 = 저장소와 설정에 재동기화가 요구될 수 있습니다. 이 박스에 체크하면 저장소의 훅과 authorized_key 들을 수동으로 재동기화해야 한다는 것을 인지한다는 것을 의미합니다. 저장소와 미러의 설정이 올바른지 확인하세요. [home] -uname_holder=사용자 이름 또는 이메일 주소 +uname_holder=사용자명 또는 이메일 주소 password_holder=비밀번호 switch_dashboard_context=대시보드 컨텍스트 바꾸기 my_repos=저장소 @@ -400,6 +434,7 @@ issue.action.merge = @%[1]s님이 #%[2]d를 %[3]s에 병합했습니다. issue.action.review_dismissed = @%[1]s님이 이 풀 리퀘스트에 대한 %[2]s의 마지막 검토를 거부했습니다. issue.action.reject = @%[1]s님이 이 풀 리퀘스트에 수정을 요청했습니다. issue.action.new = @%[1]s님이 #%[2]d를 만들었습니다. +register_notify.text_2 = 당신의 계정에 사용자명으로 로그인 할 수 있습니다: %s @@ -414,8 +449,8 @@ cancel=취소 modify=변경하기 [form] -UserName=사용자 이름 -RepoName=저장소 이름 +UserName=사용자명 +RepoName=저장소명 Email=이메일 주소 Password=비밀번호 Retype=비밀번호 확인 @@ -449,14 +484,14 @@ captcha_incorrect=CAPTCHA 코드가 올바르지 않습니다. password_not_match=비밀번호가 일치하지 않습니다. lang_select_error=목록에서 언어를 선택해주세요. -username_been_taken=이미 사용하고 있는 아이디입니다. -repo_name_been_taken=이미 사용하고 있는 저장소 이름입니다. +username_been_taken=이미 사용되는 사용자명입니다. +repo_name_been_taken=이미 사용중인 저장소명 입니다. org_name_been_taken=이미 사용중인 조직 이름입니다. team_name_been_taken=이미 사용중인 팀 이름입니다. team_no_units_error=최소 하나 이상의 레포지토리 섹션에 대한 접근을 허용하십시오. email_been_used=이미 사용 중인 이메일 주소입니다. -username_password_incorrect=사용자 이름 또는 암호가 올바르지 않습니다. -enterred_invalid_repo_name=입력한 저장소의 이름이 올바르지 않습니다. +username_password_incorrect=사용자명 또는 암호가 올바르지 않습니다. +enterred_invalid_repo_name=입력한 저장소명이 올바르지 않습니다. enterred_invalid_owner_name=새로운 소유자 이름이 올바르지 않습니다. enterred_invalid_password=입력한 비밀번호는 올바르지 않습니다. user_not_exist=존재하지 않는 사용자입니다. @@ -472,8 +507,10 @@ target_branch_not_exist=대상 브랜치가 존재하지 않습니다. url_error = `"%s"는 유효한 URL이 아닙니다.` include_error = `"%s"을/를 포함해야 합니다.` regex_pattern_error = `regex 패턴이 잘못되었습니다: %s` -username_error = `영문("a-z", "A-Z"), 숫자("0-9"), 대시("-"), 밑줄("_"), 점(".")만 포함할 수 있습니다. 영문 혹은 숫자가 아닌 문자로 시작하거나 끝날 수 없으며 연속된 영문 혹은 숫자가 아닌 문자도 금지됩니다.` +username_error = `영문("a-z", "A-Z"), 숫자("0-9"), 대시("-"), 밑줄("_"), 마침표(".")만 포함할 수 있습니다. 영문 혹은 숫자가 아닌 문자로 시작하거나 끝날 수 없으며 연속된 영문 혹은 숫자가 아닌 문자도 금지됩니다.` glob_pattern_error = `glob 패턴이 잘못되었습니다: %s` +username_error_no_dots = `영문("a-z", "A-Z"), 숫자("0-9"), 대시("-"), 밑줄("_")만 포함할 수 있습니다. 영문 혹은 숫자가 아닌 문자로 시작하거나 끝날 수 없으며 연속된 영문 혹은 숫자가 아닌 문자도 금지됩니다.` +username_change_not_local_user = 외부 사용자들은 사용자명을 변경할 수 없습니다. [user] @@ -489,6 +526,9 @@ unfollow=추적해제 user_bio=소개 projects = 프로젝트 watched = 주시중인 저장소 +form.name_reserved = "%s" 사용자명이 예약(reserved)되었습니다. +form.name_pattern_not_allowed = "%s" 패턴이 사용자명으로 사용할 수 없습니다. +form.name_chars_not_allowed = "%s" 사용자명이 유효하지 않은 문자를 포함합니다. [settings] @@ -508,14 +548,14 @@ account_link=연결된 계정 organization=조직 public_profile=공개 프로필 -password_username_disabled=로컬 사용자가 아닌 경우 사용자 이름 변경을 할 수 없습니다. 자세한 내용은 관리자에게 문의해주세요. +password_username_disabled=로컬 사용자가 아닌 경우 사용자명을 변경 할 수 없습니다. 자세한 내용은 관리자에게 문의해주세요. full_name=성명 website=웹 사이트 location=위치 update_theme=테마 변경 update_profile=프로필 업데이트 update_profile_success=프로필이 업데이트 되었습니다. -change_username=사용자 이름 변경 되었습니다. +change_username=사용자명이 변경 되었습니다. continue=계속하기 cancel=취소 language=언어 @@ -666,11 +706,14 @@ visibility.private=비공개 change_password = 비밀번호 변경 email_desc = 당신의 대표 이메일 주소는 알림, 비밀번호 재설정과 웹에서의 Git 작동에 사용되며 가려지지 않습니다. comment_type_group_dependency = 전제조건 +change_username_prompt = 참고: 사용자명의 변경은 계정의 URL을 변경시킵니다. +change_username_redirect_prompt = 과거 사용자명은 누군가 사용하기 전까지 리디렉트됩니다. +comment_type_group_time_tracking = 시간 기록 [repo] owner=소유자 -repo_name=저장소 이름 -repo_name_helper=좋은 저장소 이름은 보통 짧고 기억하기 좋은 특별한 키워드로 이루어 집니다. +repo_name=저장소명 +repo_name_helper=좋은 저장소명은 보통 짧고 기억하기 좋은 특별한 키워드로 이루어 집니다. repo_size=저장소 용량 template=템플릿 template_select=템플릿을 선택합니다. @@ -919,7 +962,7 @@ issues.subscribe=구독하기 issues.unsubscribe=구독 취소 issues.delete=삭제 issues.tracker=타임 트래커 -issues.start_tracking=타임 트래킹 시작 +issues.start_tracking=시간 기록 시작 issues.start_tracking_history=`님이 %s 작업 시작` issues.stop_tracking_history=`님이 %s 작업 중단` issues.add_time=수동으로 시간 입력 @@ -1119,7 +1162,7 @@ settings.tracker_url_format=외부 이슈 트래커 URL 형식 settings.tracker_issue_style=외부 이슈 트래커 숫자 포맷 settings.tracker_issue_style.numeric=숫자 settings.tracker_issue_style.alphanumeric=문자 숫자 -settings.enable_timetracker=시간 추적 활성화 +settings.enable_timetracker=시간 기록 활성화 settings.allow_only_contributors_to_track_time=기여자 트랙 타임만 settings.pulls_desc=저장소 풀 리퀘스트 활성화 settings.pulls.ignore_whitespace=공백은 충돌에서 무시하기 @@ -1165,7 +1208,7 @@ settings.update_githook=Hook 갱신 settings.payload_url=대상 URL settings.content_type=POST Content Type settings.secret=비밀 -settings.slack_username=사용자 이름 +settings.slack_username=사용자명 settings.slack_icon_url=아이콘 URL settings.discord_username=사용자명 settings.discord_icon_url=아이콘 URL @@ -1306,7 +1349,7 @@ settings.trust_model.committer.desc = 유효한 서명이 커미터와 일치할 visibility_helper = 저장소 비공개로 만들기 projects.description = 설명 (선택) settings.external_tracker_url_desc = 방문자들이 이슈 탭을 클릭하면 외부 이슈 트레커 URL로 연결됩니다. -settings.tracker_url_format_desc = {user}, {repo} and {index}를 사용자 이름, 저장소 이름, 이슈 번호로 사용할 수 있습니다. +settings.tracker_url_format_desc = {user}를 사용자명, {repo}를 저장소명, {index}를 이슈 번호로 사용할 수 있습니다. projects = 프로젝트 projects.desc = 이슈와 풀 리퀘스트를 프로젝트에서 관리합니다. projects.create = 프로젝트 만들기 @@ -1368,6 +1411,16 @@ issues.blocked_by_user = 당신은 이 저장소의 소유자에게 차단당했 issues.comment.blocked_by_user = 당신은 이 저장소의 소유자 혹은 이 이슈의 작성자 에게 차단당했기 떄문에 이슈에 댓글을 달 수 없습니다. author_search_tooltip = 최대 30명의 사용자를 표시함 pulls.merged_title_desc_one = 님이 %[2]s 에서 %[3]s 로 %[1]d 커밋을 %[4]s 병합함 +issues.stop_tracking = 타이머 정지 +issues.start_tracking_short = 타이머 시작 +mirror_password_help = 사용자명을 변경해 저장된 비밀번호를 지우세요. +issues.cancel_tracking_history = `취소된 시간 기록 %s` +settings.enter_repo_name = 표시된 소유자와 저장소명을 정확하게 입력하세요: +settings.packagist_username = Packagist 사용자명 +issues.tracking_already_started = `당신은 이미 다른 이슈에서 시간을 기록중입니다!` +adopt_search = 사용자명을 입력해 소유자가 누락된 저장소를 검색... (모두 찾으려면 비워두기) +form.name_reserved = "%s" 저장소명이 예약되어 있습니다. +form.name_pattern_not_allowed = "%s" 패턴이 저장소명으로 사용할 수 없습니다. @@ -1375,7 +1428,7 @@ pulls.merged_title_desc_one = 님이 %[2]s 에서 %[3]snorādēs par aizsargātajām birkām. settings.bot_token=Robotprogrammatūras pilnvara settings.chat_id=Tērzēšanas ID -settings.thread_id=Pavediena ID +settings.thread_id=Pavediena identifikators settings.matrix.homeserver_url=Mājas servera URL settings.matrix.room_id=Istabas ID settings.matrix.message_type=Ziņojuma veids @@ -2516,7 +2516,7 @@ settings.lfs_findcommits=Atrast iesūtījumus settings.lfs_lfs_file_no_commits=Šai LFS datnei netika atrasts neviens iesūtījums settings.lfs_noattribute=Šim ceļam noklusējuma zarā nav slēdzamības atribūta settings.lfs_delete=Izdzēst LFS datni ar OID %s -settings.lfs_delete_warning=LFS datnes izdzēšana var izraisīt kļūdu "object does not exist" veicot paņemšanu. Tiešām izdzēst? +settings.lfs_delete_warning=LFS datnes izdzēšana var izraisīt kļūdu "object does not exist" paņemšanas laikā. Tiešām izdzēst? settings.lfs_findpointerfiles=Atrast norāžu datnes settings.lfs_locks=Slēdzenes settings.lfs_invalid_locking_path=Nederīgs ceļš: %s @@ -2604,7 +2604,7 @@ release.detail=Informācija par laidienu release.tags=Tagi release.new_release=Jauns laidiens release.draft=Melnraksts -release.prerelease=Pirmslaidiens +release.prerelease=Pirmsizlaide release.stable=Stabila release.compare=Salīdzināt release.edit=Labot @@ -2622,7 +2622,7 @@ release.tag_helper_existing=Esoša birka. release.title=Laidiena nosaukums release.title_empty=Nosaukums nevar būt tukšs. release.message=Aprakstīt šo laidienu -release.prerelease_desc=Atzīmēt kā pirmslaidienu +release.prerelease_desc=Atzīmēt kā pirmsizlaidi release.prerelease_helper=Atzīmēt, ka šo laidienu nav ieteicams lietot produkcijā. release.cancel=Atcelt release.publish=Laist klajā laidienu @@ -2879,7 +2879,7 @@ org_name_holder=Apvienības nosaukums org_full_name_holder=Apvienības pilnais nosaukums org_name_helper=Apvienību nosaukumiem vajadzētu būt īsiem un viegli iegaumējamiem. create_org=Izveidot apvienību -repo_updated=Atjaunināts %s +repo_updated=Atjaunināta %s members=Dalībnieki teams=Komandas code=Kods @@ -3055,9 +3055,9 @@ dashboard.archive_cleanup=Izdzēst vecos glabātavu arhīvus dashboard.deleted_branches_cleanup=Notīrīt izdzēstos zarus dashboard.update_migration_poster_id=Atjaunināt pārcelšanas ierosinātāja identifikatorus dashboard.git_gc_repos=Veikt drazu savākšanu visās glabātavās -dashboard.resync_all_sshkeys=Atjaunināt datni '.ssh/authorized_keys' ar Forgejo SSH atslēgām. +dashboard.resync_all_sshkeys=Atjaunināt datni ".ssh/authorized_keys" ar Forgejo SSH atslēgām. dashboard.resync_all_sshprincipals=Atjaunināt datni ".ssh/authorized_principals" ar Forgejo SSH identitātēm. -dashboard.resync_all_hooks=Atkārtoti sinhroznēt pirmssaņemšanas, atjaunināšanas un pēcsaņemšans aizķeres visās glabātavās +dashboard.resync_all_hooks=Atkārtoti sinhronizēt pirmssaņemšanas, atjaunināšanas un pēcsaņemšans aizķeres visās glabātavās dashboard.reinit_missing_repos=Atkārtoti sāknēt visas trūkstošās Git glabātavas, par kurām ir ieraksti dashboard.sync_external_users=Sinhronizēt ārējo lietotāju datus dashboard.cleanup_hook_task_table=Iztīrīt tabulu hook_task @@ -3068,8 +3068,8 @@ dashboard.current_goroutine=Pašreizējās gorutīnas dashboard.current_memory_usage=Pašreizējais atmiņas lietojums dashboard.total_memory_allocated=Kopējā iedalītā atmiņa dashboard.memory_obtained=Iegūtā atmiņa -dashboard.pointer_lookup_times=Rādītāju pārlūkošanas reizes -dashboard.memory_allocate_times=Atmiņas piešķīrumi +dashboard.pointer_lookup_times=Rādītāju uzmeklēšanas reizes +dashboard.memory_allocate_times=Atmiņas iedalīšanas dashboard.memory_free_times=Atmiņas atbrīvošanas dashboard.current_heap_usage=Pašreizējais grēdas lietojums dashboard.heap_memory_obtained=Iegūtā grēdas atmiņa @@ -3426,30 +3426,30 @@ config.test_email_placeholder=E-pasts (piemēram, test@example.com) config.send_test_mail=Nosūtīt pārbaudes e-pasta ziņojumu config.send_test_mail_submit=Sūtīt config.test_mail_failed=Neizdevās nosūtīt pārbaudes e-pasta ziņojumu uz "%s": %v -config.test_mail_sent=Pārbaudes e-pasts tika nosūtīts uz "%s". +config.test_mail_sent=Pārbaudes e-pasta ziņojums tika nosūtīts uz "%s". config.oauth_config=OAuth konfigurācija config.oauth_enabled=Iespējots config.cache_config=Kešatmiņas konfigurācija config.cache_adapter=Kešatmiņas adapteris -config.cache_interval=Kešatmiņas intervāls -config.cache_conn=Kešatmiņas pieslēguma parametri +config.cache_interval=Kešatmiņas starplaiks +config.cache_conn=Kešatmiņas savienojums config.cache_item_ttl=Kešatmiņas vienuma TTL config.session_config=Sesijas konfigurācja config.session_provider=Sesijas nodrošinātājs -config.provider_config=Pakalpojumu sniedzēja konfigurācija +config.provider_config=Nodrošinātāja konfigurācija config.cookie_name=Sīkdatnes nosaukums -config.gc_interval_time=GC laika intervāls +config.gc_interval_time=GC starplaiks config.session_life_time=Sesijas ilgums config.https_only=Tikai HTTPS config.cookie_life_time=Sīkdatņu glabāšanas ilgums -config.picture_config=Attēlu un profila bilžu konfigurācija -config.picture_service=Lokāli attēli +config.picture_config=Attēlu un profila attēlu konfigurācija +config.picture_service=Attēlu pakalpojums config.disable_gravatar=Atspējot Gravatar -config.enable_federated_avatar=Iespējot apvienotās profila bildes +config.enable_federated_avatar=Iespējot vienotos profila attēlus config.git_config=Git konfigurācija config.git_disable_diff_highlight=Atspējot salīdzināšanas sintakses iekrāsošanu @@ -3463,10 +3463,10 @@ config.git_clone_timeout=Klonēšanas darbības noildze config.git_pull_timeout=Atgādāšanas darbības noildze config.git_gc_timeout=GC darbības noildze -config.log_config=Žurnalizēšanas konfigurācija +config.log_config=Žurnāla konfigurācija config.logger_name_fmt=Žurnalizētājs: %s config.disabled_logger=Atspējots -config.access_log_mode=Piekļuves žurnalizēšanas veids +config.access_log_mode=Piekļuves žurnalēšanas veids config.access_log_template=Piekļuves žurnāla sagatave config.xorm_log_sql=SQL žurnalizēšana @@ -3474,7 +3474,7 @@ config.set_setting_failed=`Neizdevās uzstādīt iestatījumu "%s"` monitor.stats=Statistika -monitor.cron=Cron uzdevumi +monitor.cron=Atkārtojamie uzdevumi monitor.name=Nosaukums monitor.schedule=Grafiks monitor.next=Nākamā reize @@ -3500,7 +3500,7 @@ monitor.queue.type=Veids monitor.queue.exemplar=Eksemplāra veids monitor.queue.numberworkers=Strādņu skaits monitor.queue.activeworkers=Darbojošies strādņi -monitor.queue.maxnumberworkers=Maksimālais strādņu skaits +monitor.queue.maxnumberworkers=Lielākais pieļaujamais strādņu skaits monitor.queue.numberinqueue=Skaits rindsarakstā monitor.queue.review_add=Pārskatīt/pievienot strādņus monitor.queue.settings.title=Pūla iestatījumi @@ -3509,18 +3509,18 @@ monitor.queue.settings.maxnumberworkers=Maksimālais strādņu skaits monitor.queue.settings.maxnumberworkers.placeholder=Pašalaik %[1]d monitor.queue.settings.maxnumberworkers.error=Maksimālajam strādņu skaitam ir jābūt skaitlim monitor.queue.settings.submit=Atjaunināt iestatījumus -monitor.queue.settings.changed=Iestatījumi saglabāti +monitor.queue.settings.changed=Iestatījumi atjaunināti monitor.queue.settings.remove_all_items=Noņemt visus monitor.queue.settings.remove_all_items_done=Visi rindsaraksta vienumi tika noņemti. notices.system_notice_list=Sistēmas paziņojumi -notices.view_detail_header=Skatīt paziņojuma detaļas +notices.view_detail_header=Apskatīt paziņojuma informāciju notices.operations=Darbības -notices.select_all=Iezīmēt visu -notices.deselect_all=Atcelt visa iezīmēšanu -notices.inverse_selection=Apgriezeniskā iezīmēšana -notices.delete_selected=Dzēst iezīmēto -notices.delete_all=Dzēst visus paziņojumus +notices.select_all=Atlasīt visus +notices.deselect_all=Atcelt visa atlasīšanu +notices.inverse_selection=Apvērst atlasīto +notices.delete_selected=Izdzēst atlasītos +notices.delete_all=Izdzēst visus paziņojumus notices.type=Veids notices.type_1=Glabātava notices.type_2=Uzdevums @@ -3637,7 +3637,7 @@ default_key=Parakstīts ar noklusējuma atslēgu error.extract_sign=Neizdevās izgūt parakstu error.generate_hash=Neizdevās izveidot iesūtījuma jaucējkodu error.no_committer_account=Iesūtītāja e-pasta adrese nav piesaistīta nevienam kontam -error.no_gpg_keys_found=Šim parakstam datu bāzē netika atrasta zināma atslēga +error.no_gpg_keys_found=Šim parakstam datubāzē netika atrasta zināma atslēga error.not_signed_commit=Nav parakstīts iesūtījums error.failed_retrieval_gpg_keys=Neizdevās iegūt nevienu iesūtītāja kontam piesaistītu atslēgu error.probable_bad_signature=UZMANĪBU! Lai arī datubāzē ir atslēga ar šādu identifikatoru, tā neapliecina šo iesūtījumu. Šis iesūtījums ir AIZDOMĪGS. @@ -3669,9 +3669,9 @@ dependencies=Atkarības keywords=Atslēgvārdi details=Papildu informācija details.author=Autors -details.project_site=Projekta lapa +details.project_site=Projekta tīmekļvietne details.repository_site=Glabātavas tīmekļvietne -details.documentation_site=Dokumentācijas lapa +details.documentation_site=Dokumentācijas tīmekļvietne details.license=Licence assets=Resursi versions=Versijas @@ -3699,7 +3699,7 @@ conan.registry=Šis reģistrs ir uzstādāms komandrindā: conan.install=Lai uzstādītu pakotni ar Conan, jāizpilda šī komanda: conda.registry=Izveidot šo reģistru kā Conda glabātavu datnē .condarc: conda.install=Lai uzstādītu pakotni ar Conda, jāizpilda šī komanda: -container.details.type=Attēla formāts +container.details.type=Attēla veids container.details.platform=Platforma container.pull=Atgādāt attēlu komandrindā: container.digest=Īssavilkums @@ -3733,8 +3733,8 @@ npm.install=Lai uzstādītu pakotni ar npm, jāizpilda šī komanda: npm.install2=vai datnē package.json jāpievieno: npm.dependencies=Atkarības npm.dependencies.development=Izstrādes atkarības -npm.dependencies.peer=Netiešās atkarības -npm.dependencies.optional=Neobligātās atkarības +npm.dependencies.peer=Līdzatkarības +npm.dependencies.optional=Izvēles atkarības npm.details.tag=Tags pub.install=Lai uzstādītu pakotni ar Dart, jāizpilda šī komanda: pypi.requires=Nepieciešams Python @@ -3767,7 +3767,7 @@ settings.delete.notice=Tiks izdzēsta pakotne %s (%s). Šī darbība ir neatgrie settings.delete.success=Pakotne tika izdzēsta. settings.delete.error=Neizdevās izdzēst pakotni. owner.settings.cargo.title=Cargo reģistra inkdess -owner.settings.cargo.initialize=Inicializēt indeksu +owner.settings.cargo.initialize=Sāknēt indeksu owner.settings.cargo.initialize.description=Ir nepieciešams īpaša indeksa Git glabātava, lai izmantotu Cargo reģistru. Šīs iespējas izmantošana (atkārtoti) izveidos glabātavu un automātiski to iestatīs. owner.settings.cargo.initialize.error=Neizdevās inicializēt Cargo indeksu: %v owner.settings.cargo.initialize.success=Cargo indekss tika sekmīgi izveidots. @@ -3833,7 +3833,7 @@ deletion=Dzēst noslēpumu deletion.description=Noslēpuma dzēšana ir neatgriezeniska. Vai turpināt? deletion.success=Noslēpums tika izdzēsts. deletion.failed=Neizdevās dzēst noslēpumu. -management=Noslēpumu pārvaldība +management=Pārvaldīt noslēpumus [actions] actions=Darbības @@ -3843,15 +3843,15 @@ unit.desc=Iebūvēto CI/CD cauruļvadu pārvaldīšana ar Forgejo Actions. status.unknown=Nezināms status.waiting=Gaida status.running=Izpildās -status.success=Pabeigts +status.success=Sekmīgi status.failure=Atteice status.cancelled=Atcelts status.skipped=Izlaists status.blocked=Aizturēts runners=Izpildītāji -runners.runner_manage_panel=Izpildītāju pārvaldība -runners.new=Pievienot jaunu izpildītāju +runners.runner_manage_panel=Pārvaldīt izpildītājus +runners.new=Izveidot jaunu izpildītāju runners.new_notice=Kā uzstādīt izpildītāju runners.status=Statuss runners.id=ID @@ -3886,7 +3886,7 @@ runners.version=Versija runners.reset_registration_token=Atiestatīt reģistrācijas pilnvaru runners.reset_registration_token_success=Izpildītāja reģistrācijas pilnvara tika sekmīgi atiestatīta -runs.all_workflows=Visas darbaplūsmas +runs.all_workflows=Visas darbplūsmas runs.commit=Iesūtījums runs.scheduled=Ieplānots runs.pushed_by=aizgādāja @@ -3910,7 +3910,7 @@ workflow.disabled=Darbplūsma ir atspējota. need_approval_desc=Nepieciešams apstiprinājums, lai izpildītu darbplūsmas izmaiņu pieprasījumos no atzarojumiem. variables=Mainīgie -variables.management=Mainīgo pārvaldība +variables.management=Pārvaldīt mainīgos variables.creation=Pievienot mainīgo variables.none=Vēl nav neviena mainīgā. variables.deletion=Noņemt mainīgo @@ -3939,7 +3939,7 @@ workflow.dispatch.warn_input_limit = Attēlo tikai pirmos %d ievades mainīgos. workflow.dispatch.trigger_found = Šai darbplūsmai ir workflow_dispatch notikuma izraisītājs. [projects] -type-1.display_name=Individuālais projekts +type-1.display_name=Atsevišķs projekts type-2.display_name=Glabātavas projekts type-3.display_name=Apvienības projekts deleted.display_name = Izdzēsts projekts diff --git a/options/locale/locale_nb_NO.ini b/options/locale/locale_nb_NO.ini index 3a4dd27d54..18c9835df0 100644 --- a/options/locale/locale_nb_NO.ini +++ b/options/locale/locale_nb_NO.ini @@ -123,13 +123,26 @@ sign_out = Logg ut sign_up = Opprett konto confirm_delete_artifact = Er du sikker på at du vil slette artefakten "%s" ? webauthn_sign_in = Trykk på knappen på sikkerhetsnøkkelen din. Dersom nøkkelen din ikke har en knapp, sett den inn på nytt. +copy_path = Kopier sti +webauthn_error_unable_to_process = Tjeneren kunne ikke behandle forespørselen din. +webauthn_error_empty = Du må gi nøkkelen et navn. [search] search = Søk... type_tooltip = Søketype fuzzy = Fuzzy union = Union +regexp = RegExp +exact = Nøyaktig [auth] verify = Bekreft -sign_up_button = Opprett konto nå. \ No newline at end of file +sign_up_button = Opprett konto nå. +change_unconfirmed_email_error = Kan ikke endre e-postadresse: %v +login_userpass = Logg inn +oauth_signup_tab = Registrer ny konto +oauth_signup_title = Fullfør ny konto +oauth_signup_submit = Fullfør konto + +[home] +uname_holder = Brukernavn eller e-postadresse \ No newline at end of file diff --git a/options/locale/locale_pl-PL.ini b/options/locale/locale_pl-PL.ini index ef20124ec9..7192f6a366 100644 --- a/options/locale/locale_pl-PL.ini +++ b/options/locale/locale_pl-PL.ini @@ -166,6 +166,7 @@ new_repo.link = Nowe repozytorium new_migrate.link = Nowa migracja new_org.link = Nowa organizacja filter.not_fork = Nie forki +copy_path = Skopiuj ścieżkę [aria] navbar = Pasek nawigacji @@ -254,7 +255,7 @@ err_empty_db_path=Ścieżka do bazy danych SQLite3 nie może być pusta. no_admin_and_disable_registration=Nie możesz wyłączyć możliwości samodzielnej rejestracji kont użytkowników bez stworzenia konta administratora. err_empty_admin_password=Hasło administratora nie może być puste. err_empty_admin_email=Pole adresu e-mail administratora nie może być puste. -err_admin_name_is_reserved=Nazwa użytkownika administratora jest nieprawidłowa, pseudonim jest zastrzeżony +err_admin_name_is_reserved=Nazwa użytkownika administratora jest nieprawidłowa, pseudonim jest zarezerwowany err_admin_name_pattern_not_allowed=Nazwa użytkownika administratora jest nieprawidłowa, pseudonim zawiera zastrzeżone znaki err_admin_name_is_invalid=Nazwa użytkownika administratora jest nieprawidłowa @@ -477,6 +478,7 @@ sign_in_openid = Kontynuuj z OpenID hint_login = Masz już konto? Zaloguj się teraz! sign_up_button = Zarejestruj się. use_onetime_code = Użyj kodu jednorazowego +unauthorized_credentials = Dane uwierzytelniające są nieprawidłowe lub wygasły. Spróbuj ponownie wykonać polecenie lub zobacz %s, aby uzyskać więcej informacji [mail] view_it_on=Zobacz na %s diff --git a/options/locale/locale_pt-BR.ini b/options/locale/locale_pt-BR.ini index 19ae305a25..f6cf73620c 100644 --- a/options/locale/locale_pt-BR.ini +++ b/options/locale/locale_pt-BR.ini @@ -3557,6 +3557,7 @@ users.restricted.description = Permitir interação somente com os repositórios users.organization_creation.description = Permitir a criação de novas organizações. users.local_import.description = Permitir importar repositórios do sistema de arquivos local do servidor. Isso pode ser um problema de segurança. self_check.database_collation_case_insensitive = O banco de dados está usando um ordenamento %s, que é um ordenamento insensível. Embora o Forgejo possa funcionar com ele, pode haver alguns casos raros que não funcionam como esperado. +monitor.duration = Duração (s) [action] @@ -3818,6 +3819,7 @@ arch.version.checkdepends = Verificar dependências owner.settings.cargo.initialize.description = É necessário um repositório Git especial de índice para usar o registro Cargo. Usar esta opção irá (re-)criar o repositório e configurá-lo automaticamente. owner.settings.chef.keypair.description = É necessário um par de chaves para autenticar no registro Chef. Se você já gerou um par de chaves, gere um novo par e descarte o antigo. container.images.title = Imagens +search_in_external_registry = Buscar em %s [secrets] secrets=Segredos diff --git a/options/locale/locale_pt-PT.ini b/options/locale/locale_pt-PT.ini index 4aecb88490..ca1199dd54 100644 --- a/options/locale/locale_pt-PT.ini +++ b/options/locale/locale_pt-PT.ini @@ -3820,6 +3820,7 @@ arch.version.conflicts = Conflitos arch.version.backup = Cópia de segurança arch.version.replaces = Substitui container.images.title = Imagens +search_in_external_registry = Procurar em %s [secrets] secrets=Segredos diff --git a/options/locale/locale_ru-RU.ini b/options/locale/locale_ru-RU.ini index df24992e52..4c15717a75 100644 --- a/options/locale/locale_ru-RU.ini +++ b/options/locale/locale_ru-RU.ini @@ -319,8 +319,8 @@ test_git_failed=Не удалось проверить команду «git»: % sqlite3_not_available=Эта версия Forgejo не поддерживает SQLite3. Пожалуйста, скачайте официальную сборку из %s (не версию «gobuild»). invalid_db_setting=Некорректные настройки базы данных: %v invalid_db_table=Таблица «%s» базы данных некорректна: %v -invalid_repo_path=Недопустимый путь к корню репозитория: %v -invalid_app_data_path=Неверный путь к приложению: %v +invalid_repo_path=Неверный путь к корню репозиториев: %v +invalid_app_data_path=Неверный путь к данным приложения: %v run_user_not_match=Текущий пользователь не является пользователем для запуска: %s -> %s internal_token_failed=Не удалось создать внутренний токен: %v secret_key_failed=Не удалось создать секретный ключ: %v @@ -2197,9 +2197,9 @@ settings.transfer_perform=Выполнить передачу settings.transfer_started=Репозиторий ожидает подтверждения передачи от «%s» settings.transfer_succeed=Репозиторий перенесён. settings.signing_settings=Настройки проверки подписей -settings.trust_model=Модель доверия подписи -settings.trust_model.default=Модель доверия по умолчанию -settings.trust_model.default.desc=Использовать стандартную модель доверия репозитория для этой установки. +settings.trust_model=Факторы доверия подписям +settings.trust_model.default=Фактор доверия по умолчанию +settings.trust_model.default.desc=Использовать фактор доверия по умолчанию, используемый на этом сервере. settings.trust_model.collaborator=Соучастник settings.trust_model.collaborator.long=Соучастник: доверять подписям соучастников settings.trust_model.collaborator.desc=Действительные подписи соучастников этого репозитория будут помечены как «доверенные» (независимо от того, соответствуют ли они автору коммита). В остальных случаях действительные подписи будут помечены как «недоверенные», если подпись соответствует автору коммита, и «не совпадающие», если нет. @@ -2744,7 +2744,7 @@ pulls.made_using_agit = AGit activity.navbar.contributors = Соавторы activity.navbar.code_frequency = Частота изменений activity.navbar.recent_commits = Недавние коммиты -settings.confirmation_string = Подтверждение +settings.confirmation_string = Строка подтверждения settings.archive.text = Архивация репозитория сделает всё его содержимое доступным только для чтения. Он будет скрыт с домашнего экрана. Никто (включая вас!) не сможет добавлять коммиты, открывать задачи и запросы слияний. release.deletion_desc = Удаление выпуска удаляет его только в Forgejo. Это действие не затронет тег в git, содержимое репозитория и его историю. Продолжить? pulls.agit_explanation = Создано через рабочий поток AGit. С ним можно предлагать изменения, используя команду «git push», без необходимости в создании ответвления или новой ветви. @@ -3831,6 +3831,7 @@ arch.version.backup = Рез. копия arch.version.conflicts = Конфликтует с arch.version.checkdepends = Проверочные зависимости container.images.title = Образы +search_in_external_registry = Найти в %s [secrets] secrets=Секреты diff --git a/options/locale/locale_tr-TR.ini b/options/locale/locale_tr-TR.ini index 01b00d87ea..9a8d716083 100644 --- a/options/locale/locale_tr-TR.ini +++ b/options/locale/locale_tr-TR.ini @@ -17,10 +17,10 @@ page=Sayfa template=Şablon language=Dil notifications=Bildirimler -active_stopwatch=Etkin Zaman Takibi +active_stopwatch=Etkin Zaman Takipçisi tracked_time_summary=Konu listesi süzgeçlerine dayanan takip edilen zamanın özeti create_new=Oluştur… -user_profile_and_more=Profil ve Ayarlar… +user_profile_and_more=Profil ve ayarlar… signed_in_as=Giriş yapan: enable_javascript=Bu web sitesinin çalışması için JavaScript gereklidir. toc=İçindekiler Tablosu @@ -28,12 +28,12 @@ licenses=Lisanslar return_to_forgejo=Forgejo'ya Dön username=Kullanıcı Adı -email=E-posta Adresi +email=E-posta adresi password=Parola access_token=Erişim Kodu -re_type=Parolayı Doğrula +re_type=Parolayı doğrula captcha=CAPTCHA -twofa=İki Aşamalı Doğrulama +twofa=İki aşamalı doğrulama twofa_scratch=İki aşamalı kazınmış kod passcode=Şifre @@ -59,10 +59,10 @@ new_migrate=Yeni Göç new_mirror=Yeni Yansı new_fork=Yeni Depo Çatalı new_org=Yeni Organizasyon -new_project=Yeni Proje -new_project_column=Yeni Sütun +new_project=Yeni proje +new_project_column=Yeni sütun manage_org=Organizasyonları Yönet -admin_panel=Site Yönetimi +admin_panel=Site yönetimi account_settings=Hesap Ayarları settings=Ayarlar your_profile=Profil @@ -87,9 +87,9 @@ rerun=Yeniden çalıştır rerun_all=Tüm görevleri yeniden çalıştır save=Kaydet add=Ekle -add_all=Tümünü Ekle +add_all=Tümünü ekle remove=Kaldır -remove_all=Tümünü Kaldır +remove_all=Tümünü kaldır remove_label_str=`"%s" öğesini kaldır` edit=Düzenle view=Görüntüle @@ -118,7 +118,7 @@ go_back=Geri Git never=Asla unknown=Bilinmiyor -rss_feed=RSS Beslemesi +rss_feed=RSS yayını pin=Sabitle unpin=Sabitlemeyi kaldır @@ -141,17 +141,17 @@ confirm_delete_selected=Tüm seçili öğeleri gerçekten silmek istiyor musunuz name=İsim value=Değer -copy_generic = Kopyala +copy_generic = Panoya kopyala filter = Filtrele filter.not_archived = Arşivlenmemiş filter.clear = Filtreleri Temizle filter.is_archived = Arşivlenmiş filter.is_mirror = Yansılaştırılmış -filter.is_fork = Çatallanmış -filter.not_fork = Çatallanmamış +filter.is_fork = Çatallar +filter.not_fork = Çatallanmayanlar filter.not_mirror = Yansılanmamış filter.is_template = Şablon -filter.not_template = Şablon değil +filter.not_template = Şablon olmayan filter.public = Herkese açık filter.private = Gizli more_items = Daha fazla öğe @@ -168,9 +168,9 @@ new_migrate.link = Yeni geçiş copy_path = Dizini kopyala [aria] -navbar=Gezinti Çubuğu +navbar=Gezinti çubuğu footer=Alt Bilgi -footer.software=Yazılım Hakkında +footer.software=Bu yazılım hakkında footer.links=Bağlantılar [heatmap] @@ -231,12 +231,12 @@ install=Kurulum title=Başlangıç Yapılandırması docker_helper=Eğer Forgejo'yı Docker içerisinde çalıştırıyorsanız, lütfen herhangi bir değişiklik yapmadan önce belgeleri okuyun. require_db_desc=Forgejo MySQL, PostgreSQL, SQLite3 veya TiDB (MySQL protokolü) gerektirir. -db_title=Veritabanı Ayarları -db_type=Veritabanı Türü +db_title=Veritabanı ayarları +db_type=Veritabanı tipi host=Sunucu user=Kullanıcı adı password=Parola -db_name=Veritabanı Adı +db_name=Veritabanı adı db_schema=Şema db_schema_helper=Veritabanı varsayılanı için boş bırakın ("genel"). ssl_mode=SSL @@ -255,16 +255,16 @@ err_admin_name_is_reserved=Yönetici Kullanıcı Adı geçersiz, bu kullanıcı err_admin_name_pattern_not_allowed=Yönetici kullanıcı adı geçersiz, kullanıcı adı ayrılmış bir desenle eşleşiyor err_admin_name_is_invalid=Yönetici Kullanıcı Adı geçersiz -general_title=Genel Ayarlar +general_title=Genel ayarlar app_name=Site Başlığı app_name_helper=Şirket adınızı buraya girebilirsiniz. -repo_path=Depo Kök Yolu +repo_path=Depo kök dizini repo_path_helper=Tüm uzak Git depoları bu dizine kaydedilecektir. -lfs_path=Git LFS Kök Yolu +lfs_path=Git LFS kök dizini lfs_path_helper=Git LFS tarafından izlenen dosyalar bu dizinde saklanacaktır. LFS'yi devre dışı bırakmak için boş bırakın. run_user=Şu Kullanıcı Olarak Çalıştır run_user_helper=Forgejo'nin çalışacağı işletim sistemi kullanıcı adı. Bu kullanıcının depo kök yoluna erişiminin olması gerektiğini unutmayın. -domain=Sunucu Alan Adı +domain=Sunucu alan adı domain_helper=Sunucu için alan adı veya ana bilgisayar adresi. ssh_port=SSH Sunucu Portu ssh_port_helper=SSH sunucusunun dinleyeceği port numarası. Etkisizleştimek için boş bırakın. @@ -276,15 +276,15 @@ log_root_path=Günlük Dosyaları Yolu log_root_path_helper=Günlük dosyaları bu dizine kaydedilecektir. optional_title=İsteğe Bağlı Ayarlar -email_title=E-posta Ayarları -smtp_addr=SMTP Sunucusu -smtp_port=SMTP Portu +email_title=E-posta ayarları +smtp_addr=SMTP sunucusu +smtp_port=SMTP portu smtp_from=E-posta Gönderen smtp_from_helper=Forgejo'nın kullanacağı e-posta adresi. Yalın bir e-posta adresi girin veya "İsim" biçimini kullanın. -mailer_user=SMTP Kullanıcı Adı -mailer_password=SMTP Parolası +mailer_user=SMTP kullanıcı adı +mailer_password=SMTP parolası register_confirm=Kayıt için E-posta Doğrulaması Gereksin -mail_notify=E-Posta Bildirimlerini Etkinleştir +mail_notify=E-Posta bildirimlerini etkinleştir server_service_title=Sunucu ve Diğer Servis Ayarları offline_mode=Yerel Kipi Etkinleştir offline_mode.description=Üçüncü parti içerik teslim ağlarını etkisizleştirin ve bütün kaynakları yerelden sunun. @@ -304,11 +304,11 @@ enable_captcha.description=Kullanıcının kendi kendine kaydolması için captc require_sign_in_view=Sayfaları Görüntülemek için Giriş Yapmak Gereksin require_sign_in_view.description=Sayfa erişimini giriş yapmış kullanıcılarla sınırlandır. Ziyaretçiler sadece oturum açma ve kayıt sayfalarını görecektir. admin_setting.description=Bir yönetici hesabı açmak isteğe bağlıdır. İlk kayıt olan kullanıcı kendiliğinden yönetici olacaktır. -admin_title=Yönetici Hesabı Ayarları -admin_name=Yönetici Kullanıcı Adı +admin_title=Yönetici hesabı ayarları +admin_name=Yönetici kullanıcı adı admin_password=Parola -confirm_password=Parolayı Doğrula -admin_email=E-posta Adresi +confirm_password=Parolayı doğrula +admin_email=E-posta adresi install_btn_confirm=Forgejo'u Kur test_git_failed='git' komut testi başarısız: %v sqlite3_not_available=Bu Gieta sürümü SQLite3 desteklemiyor. Lütfen %s adresinden resmi çalışır sürümü ('gobuild' sürümünü değil) indirin. @@ -323,7 +323,7 @@ save_config_failed=%v Yapılandırması kaydedilirken hata oluştu invalid_admin_setting=Yönetici hesap ayarları geçersiz: %v invalid_log_root_path=Log dosya yolu geçersiz: %v default_keep_email_private=E-posta adreslerini varsayılan olarak gizle -default_keep_email_private.description=Yeni kullanıcı hesaplarının e-posta adreslerini varsayılan olarak gizle. +default_keep_email_private.description=Kayıt olunduktan hemen sonra bilgi sızıntısı olmaması için yeni kullanıcı hesaplarının e-posta adreslerini varsayılan olarak gizle. default_allow_create_organization=Varsayılan Olarak Organizasyon Oluşturmaya İzin Ver default_allow_create_organization.description=Varsayılan olarak yeni kullanıcı hesaplarının organizasyon oluşturmasına izin ver. default_enable_timetracking=Varsayılan Olarak Zaman Takibini Etkinleştir @@ -333,7 +333,7 @@ no_reply_address_helper=Gizlenmiş e-posta adresine sahip kullanıcılar için a password_algorithm=Parola Hash Algoritması invalid_password_algorithm=Hatalı parola hash algoritması password_algorithm_helper=Parola hash algoritmasını ayarlayın. Algoritmalar değişen gereksinimlere ve güce sahiptirler. argon2 algoritması iyi özelliklere sahip olmasına rağmen fazla miktarda bellek kullanır ve küçük sistemler için uygun olmayabilir. -enable_update_checker=Güncelleme Denetleyicisini Etkinleştir +enable_update_checker=Güncelleme denetleyicisini etkinleştir env_config_keys=Ortam Yapılandırma env_config_keys_prompt=Aşağıdaki ortam değişkenleri de yapılandırma dosyanıza eklenecektir: allow_only_external_registration = Sadece dış hizmetler aracılığıyla kullanıcı kaydına izin ver @@ -343,7 +343,7 @@ enable_update_checker_helper_forgejo = release.forgejo.org adresindeki TXT DNS k allow_dots_in_usernames = Kullanıcı isimlerinde noktaya izin ver. Var olan kullanıcıları etkilemez. [home] -uname_holder=Kullanıcı Adı veya E-Posta Adresi +uname_holder=Kullanıcı adı veya e-posta adresi password_holder=Parola switch_dashboard_context=Panoya Geçiş Yap my_repos=Depolar @@ -396,13 +396,13 @@ forks_one = %d çatal forks_few = %d çatal [auth] -create_new_account=Hesap Oluştur +create_new_account=Hesap oluştur register_helper_msg=Bir hesabınız var mı? Şimdi giriş yapın! social_register_helper_msg=Hesabınız var mı? Hemen bağlayın! disable_register_prompt=Kayıt işlemi devre dışıdır. Lütfen site yöneticinizle iletişim kurun. disable_register_mail=Kayıt için e-posta doğrulama devre dışıdır. manual_activation_only=Etkinleştirmeyi tamamlamak için site yöneticinizle bağlantıya geçin. -remember_me=Bu Aygıtı hatırla +remember_me=Bu cihazı hatırla remember_me.compromised=Oturum açma tokeni artık geçerli değil, bu ele geçirilmiş bir hesaba işaret ediyor olabilir. Lütfen hesabınızda olağandışı faaliyet olup olmadığını denetleyin. forgot_password_title=Şifremi unuttum forgot_password=Şifrenizi mi unuttunuz? @@ -421,7 +421,7 @@ has_unconfirmed_mail=Merhaba %s, doğrulanmamış bir e-posta adresin var (%s resend_mail=Etkinleştirme e-postasını tekrar almak için buraya tıklayın email_not_associate=Bu e-posta adresi hiçbir hesap ile ilişkilendirilmemiştir. send_reset_mail=Hesap Kurtarma E-postası Gönder -reset_password=Hesap Kurtarma +reset_password=Hesap kurtarma invalid_code=Doğrulama kodunuz geçersiz veya süresi dolmuş. invalid_code_forgot_password=Onay kodunuz hatalı veya süresi geçmiş. Yeni bir oturum başlatmak için buraya tıklayın. invalid_password=Parolanız hesap oluşturulurken kullanılan parolayla eşleşmiyor. @@ -435,9 +435,9 @@ use_scratch_code=Bir çizgi kodu kullanınız twofa_scratch_used=Geçici kodunuzu kullandınız. İki aşamalı ayarlar sayfasına yönlendirildiniz, burada aygıt kaydınızı kaldırabilir veya yeni bir geçici kod oluşturabilirsiniz. twofa_passcode_incorrect=Şifreniz yanlış. Aygıtınızı yanlış yerleştirdiyseniz, oturum açmak için çizgi kodunuzu kullanın. twofa_scratch_token_incorrect=Çizgi kodunuz doğru değildir. -login_userpass=Oturum Aç +login_userpass=Oturum aç tab_openid=Açık Kimlik -oauth_signup_tab=Yeni Hesap Oluştur +oauth_signup_tab=Yeni hesap oluştur oauth_signup_title=Yeni Hesabı Tamamla oauth_signup_submit=Hesabı Tamamla oauth_signin_tab=Mevcut Hesaba Bağla @@ -3677,7 +3677,7 @@ need_approval_desc=Değişiklik isteği çatalında iş akışı çalıştırmak variables=Değişkenler variables.management=Değişken Yönetimi -variables.creation=Değişken Ekle +variables.creation=Değişken ekle variables.none=Henüz hiçbir değişken yok. variables.deletion=Değişkeni kaldır variables.deletion.description=Bir değişkeni kaldırma kalıcıdır ve geri alınamaz. Devam edilsin mi? @@ -3729,3 +3729,6 @@ issue_kind = Sorunları ara... pull_kind = Birleştirme isteklerini ara... code_search_by_git_grep = Anlık kod araması sonuçları "git grep" komutu tarafından sağlanmaktadır. Site yöneticisinin kod endekslemesini açması durumunda daha iyi sonuçlar verilmesi mümkün olabilir. keyword_search_unavailable = Anahtar kelime ile arama şu anda kullanıma açık değildir. Lütfen site yöneticisi ile iletişime geçin. +fuzzy_tooltip = Arama terimine yakın olan eşleşmeleri dahil et +union_tooltip = Boşlukla ayrılmış anahtar kelime eşleşmelerini dahil et +exact_tooltip = Sadece arama terimiyle tam uyuşan sonuçları dahit et. diff --git a/options/locale/locale_zh-CN.ini b/options/locale/locale_zh-CN.ini index 7b8336c057..79a806f70e 100644 --- a/options/locale/locale_zh-CN.ini +++ b/options/locale/locale_zh-CN.ini @@ -1144,7 +1144,7 @@ adopt_preexisting_label=收录文件 adopt_preexisting=收录已存在的仓库 adopt_preexisting_content=从 %s 创建仓库 adopt_preexisting_success=从 %s 收录仓库成功 -delete_preexisting_label=刪除 +delete_preexisting_label=删除 delete_preexisting=删除已存在的文件 delete_preexisting_content=删除 %s 中的文件 delete_preexisting_success=删除 %s 中未收录的文件 @@ -1612,7 +1612,7 @@ issues.context.copy_link=复制链接 issues.context.quote_reply=引用回复 issues.context.reference_issue=在新工单中引用 issues.context.edit=编辑 -issues.context.delete=刪除 +issues.context.delete=删除 issues.no_content=没有提供说明。 issues.close=关闭 issues.comment_pull_merged_at=已合并提交 %[1]s 到 %[2]s %[3]s @@ -2324,7 +2324,7 @@ settings.event_choose=自定义事件… settings.event_header_repository=仓库事件 settings.event_create=创建 settings.event_create_desc=创建分支或标签。 -settings.event_delete=刪除 +settings.event_delete=删除 settings.event_delete_desc=分支或标签已删除。 settings.event_fork=派生 settings.event_fork_desc=仓库被派生。 @@ -2661,7 +2661,7 @@ release.tags_for=%s 的标签 branch.name=分支名称 branch.already_exists=名为 %s 的分支已存在。 -branch.delete_head=刪除 +branch.delete_head=删除 branch.delete=删除分支 "%s" branch.delete_html=删除分支 branch.delete_desc=删除分支是永久的。虽然已删除的分支在实际被删除前有可能会短时间存在,但这在大多数情况下无法撤销。是否继续? @@ -2868,7 +2868,7 @@ release.summary_card_alt = 仓库 %[2]s 中标题为 %[1]s 的版本发布的摘 summary_card_alt = 仓库 %s 的摘要卡片 [graphs] -component_loading=正在加载 %s... +component_loading=正在加载 %s… component_loading_failed=无法加载 %s component_loading_info=这可能需要一点… component_failed_to_load=意外的错误发生了。 @@ -3558,7 +3558,7 @@ users.admin.description = 授予此用户对通过 Web UI 和 API 提供的所 users.restricted.description = 仅允许与添加此用户作为协作者的仓库和组织进行交互。这将阻止访问此实例上的公开仓库。 users.local_import.description = 允许从服务器的本地文件系统导入仓库。这可能是一个安全问题。 users.organization_creation.description = 允许创建新组织。 -monitor.duration = 时长 +monitor.duration = 时长(秒) [action] create_repo=创建了仓库 %s @@ -3851,8 +3851,8 @@ status.skipped=已忽略 status.blocked=阻塞中 runners=运行器 -runners.runner_manage_panel=管理 Runners -runners.new=创建 Runner +runners.runner_manage_panel=管理运行器 +runners.new=创建新运行器 runners.new_notice=如何启动一个运行器 runners.status=状态 runners.id=ID @@ -3959,18 +3959,18 @@ submodule=子模块 [search] keyword_search_unavailable = 关键词搜索目前不可用,请联系站点管理员。 -search = 搜索... -repo_kind = 搜索仓库... -user_kind = 搜索用户... -org_kind = 搜索组织... -team_kind = 搜索团队... -code_kind = 搜索代码... +search = 搜索… +repo_kind = 搜索仓库… +user_kind = 搜索用户… +org_kind = 搜索组织… +team_kind = 搜索团队… +code_kind = 搜索代码… code_search_unavailable = 代码搜索目前不可用,请联系站点管理员。 -package_kind = 搜索软件包... -project_kind = 搜索项目... -branch_kind = 搜索分支... -commit_kind = 搜索提交... -runner_kind = 搜索Runners... +package_kind = 搜索软件包… +project_kind = 搜索项目… +branch_kind = 搜索分支… +commit_kind = 搜索提交… +runner_kind = 搜索运行器… no_results = 未找到匹配的结果。 type_tooltip = 搜索类型 fuzzy = 模糊 @@ -3979,8 +3979,8 @@ match = 匹配 match_tooltip = 仅包含与搜索词完全匹配的结果 fuzzy_tooltip = 在搜索结果中包含与搜索词相近的项目 exact = 精确 -issue_kind = 搜索工单... -pull_kind = 搜索合并请求... +issue_kind = 搜索工单… +pull_kind = 搜索合并请求… exact_tooltip = 仅包含与搜索词精确匹配的结果 milestone_kind = 搜索里程碑… union_tooltip = 包括与任何空格分隔的关键字匹配的结果 From a013acb632307194344b376cc80d04d62494fc33 Mon Sep 17 00:00:00 2001 From: Renovate Bot Date: Tue, 14 Jan 2025 07:07:49 +0000 Subject: [PATCH 146/198] Update https://data.forgejo.org/infrastructure/issue-action action to v1.3.0 (forgejo) (#6563) Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/6563 Reviewed-by: Michael Kriese Co-authored-by: Renovate Bot Co-committed-by: Renovate Bot --- .forgejo/workflows/publish-release.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.forgejo/workflows/publish-release.yml b/.forgejo/workflows/publish-release.yml index aceeb0580a..0dffff7306 100644 --- a/.forgejo/workflows/publish-release.yml +++ b/.forgejo/workflows/publish-release.yml @@ -61,14 +61,14 @@ jobs: - name: get trigger mirror issue id: mirror - uses: https://data.forgejo.org/infrastructure/issue-action/get@v1.1.0 + uses: https://data.forgejo.org/infrastructure/issue-action/get@v1.3.0 with: forgejo: https://code.forgejo.org repository: forgejo/forgejo labels: mirror-trigger - name: trigger the mirror - uses: https://data.forgejo.org/infrastructure/issue-action/set@v1.1.0 + uses: https://data.forgejo.org/infrastructure/issue-action/set@v1.3.0 with: forgejo: https://code.forgejo.org repository: forgejo/forgejo From 9f842f0dec6a20edcaae47d91b78028e52ad24f3 Mon Sep 17 00:00:00 2001 From: Jaime merino Date: Tue, 14 Jan 2025 11:17:42 +0000 Subject: [PATCH 147/198] Add search action jobs for API routes, repo, org and global level (#6300) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This PR wants to improve information of the tasks waiting to be executed on a global, organization, user and repository leve. The main motivation is explained here https://codeberg.org/forgejo/discussions/issues/241 ## Checklist The [contributor guide](https://forgejo.org/docs/next/contributor/) contains information that will be helpful to first time contributors. There also are a few [conditions for merging Pull Requests in Forgejo repositories](https://codeberg.org/forgejo/governance/src/branch/main/PullRequestsAgreement.md). You are also welcome to join the [Forgejo development chatroom](https://matrix.to/#/#forgejo-development:matrix.org). ### Tests - I added test coverage for Go changes... - [x] in their respective `*_test.go` for unit tests. - [x] in the `tests/integration` directory if it involves interactions with a live Forgejo server. - I added test coverage for JavaScript changes... - [ ] in `web_src/js/*.test.js` if it can be unit tested. - [ ] in `tests/e2e/*.test.e2e.js` if it requires interactions with a live Forgejo server (see also the [developer guide for JavaScript testing](https://codeberg.org/forgejo/forgejo/src/branch/forgejo/tests/e2e/README.md#end-to-end-tests)). ### Documentation - [ ] I created a pull request [to the documentation](https://codeberg.org/forgejo/docs) to explain to Forgejo users how to use this change. - [x] I did not document these changes and I do not expect someone else to do it. ### Release notes - [ ] I do not want this change to show in the release notes. - [x] I want the title to show in the release notes with a link to this pull request. - [ ] I want the content of the `release-notes/.md` to be be used for the release notes instead of the title. ## Release notes - Features - [PR](https://codeberg.org/forgejo/forgejo/pulls/6300): Add search action jobs for API routes, repo, org and global level Co-authored-by: jaime merino Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/6300 Reviewed-by: Earl Warren Co-authored-by: Jaime merino Co-committed-by: Jaime merino --- models/actions/run_job.go | 10 + models/actions/run_job_test.go | 29 +++ models/actions/task.go | 17 +- models/actions/task_list.go | 6 +- models/fixtures/action_run_job.yml | 45 +++++ modules/container/set.go | 9 + modules/container/set_test.go | 5 + modules/structs/action.go | 25 +++ routers/api/v1/admin/runners.go | 20 ++ routers/api/v1/api.go | 3 + routers/api/v1/org/action.go | 25 +++ routers/api/v1/repo/action.go | 30 +++ routers/api/v1/shared/runners.go | 48 +++++ routers/api/v1/user/runners.go | 22 +++ routers/web/shared/actions/runners.go | 2 +- services/actions/clear_tasks.go | 4 +- services/actions/interface.go | 2 + templates/swagger/v1_json.tmpl | 202 ++++++++++++++++++++ tests/integration/api_admin_actions_test.go | 39 ++++ tests/integration/api_org_actions_test.go | 38 ++++ tests/integration/api_repo_actions_test.go | 43 +++++ tests/integration/api_user_actions_test.go | 38 ++++ 22 files changed, 640 insertions(+), 22 deletions(-) create mode 100644 models/actions/run_job_test.go create mode 100644 modules/structs/action.go create mode 100644 tests/integration/api_admin_actions_test.go create mode 100644 tests/integration/api_org_actions_test.go create mode 100644 tests/integration/api_repo_actions_test.go create mode 100644 tests/integration/api_user_actions_test.go diff --git a/models/actions/run_job.go b/models/actions/run_job.go index de4b6aab66..9f8edfe4fc 100644 --- a/models/actions/run_job.go +++ b/models/actions/run_job.go @@ -10,6 +10,7 @@ import ( "time" "code.gitea.io/gitea/models/db" + "code.gitea.io/gitea/modules/container" "code.gitea.io/gitea/modules/timeutil" "code.gitea.io/gitea/modules/util" @@ -71,6 +72,15 @@ func (job *ActionRunJob) LoadAttributes(ctx context.Context) error { return job.Run.LoadAttributes(ctx) } +func (job *ActionRunJob) ItRunsOn(labels []string) bool { + if len(labels) == 0 || len(job.RunsOn) == 0 { + return false + } + labelSet := make(container.Set[string]) + labelSet.AddMultiple(labels...) + return labelSet.IsSubset(job.RunsOn) +} + func GetRunJobByID(ctx context.Context, id int64) (*ActionRunJob, error) { var job ActionRunJob has, err := db.GetEngine(ctx).Where("id=?", id).Get(&job) diff --git a/models/actions/run_job_test.go b/models/actions/run_job_test.go new file mode 100644 index 0000000000..50a4ba10d8 --- /dev/null +++ b/models/actions/run_job_test.go @@ -0,0 +1,29 @@ +// SPDX-License-Identifier: MIT + +package actions + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestActionRunJob_ItRunsOn(t *testing.T) { + actionJob := ActionRunJob{RunsOn: []string{"ubuntu"}} + agentLabels := []string{"ubuntu", "node-20"} + + assert.True(t, actionJob.ItRunsOn(agentLabels)) + assert.False(t, actionJob.ItRunsOn([]string{})) + + actionJob.RunsOn = append(actionJob.RunsOn, "node-20") + + assert.True(t, actionJob.ItRunsOn(agentLabels)) + + agentLabels = []string{"ubuntu"} + + assert.False(t, actionJob.ItRunsOn(agentLabels)) + + actionJob.RunsOn = []string{} + + assert.False(t, actionJob.ItRunsOn(agentLabels)) +} diff --git a/models/actions/task.go b/models/actions/task.go index 8bd139a2d6..31655d2f1d 100644 --- a/models/actions/task.go +++ b/models/actions/task.go @@ -12,7 +12,6 @@ import ( auth_model "code.gitea.io/gitea/models/auth" "code.gitea.io/gitea/models/db" "code.gitea.io/gitea/models/unit" - "code.gitea.io/gitea/modules/container" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/timeutil" @@ -245,7 +244,7 @@ func CreateTaskForRunner(ctx context.Context, runner *ActionRunner) (*ActionTask var job *ActionRunJob log.Trace("runner labels: %v", runner.AgentLabels) for _, v := range jobs { - if isSubset(runner.AgentLabels, v.RunsOn) { + if v.ItRunsOn(runner.AgentLabels) { job = v break } @@ -482,20 +481,6 @@ func FindOldTasksToExpire(ctx context.Context, olderThan timeutil.TimeStamp, lim Find(&tasks) } -func isSubset(set, subset []string) bool { - m := make(container.Set[string], len(set)) - for _, v := range set { - m.Add(v) - } - - for _, v := range subset { - if !m.Contains(v) { - return false - } - } - return true -} - func convertTimestamp(timestamp *timestamppb.Timestamp) timeutil.TimeStamp { if timestamp.GetSeconds() == 0 && timestamp.GetNanos() == 0 { return timeutil.TimeStamp(0) diff --git a/models/actions/task_list.go b/models/actions/task_list.go index df4b43c5ef..502d29e1a3 100644 --- a/models/actions/task_list.go +++ b/models/actions/task_list.go @@ -50,7 +50,7 @@ type FindTaskOptions struct { RepoID int64 OwnerID int64 CommitSHA string - Status Status + Status []Status UpdatedBefore timeutil.TimeStamp StartedBefore timeutil.TimeStamp RunnerID int64 @@ -67,8 +67,8 @@ func (opts FindTaskOptions) ToConds() builder.Cond { if opts.CommitSHA != "" { cond = cond.And(builder.Eq{"commit_sha": opts.CommitSHA}) } - if opts.Status > StatusUnknown { - cond = cond.And(builder.Eq{"status": opts.Status}) + if opts.Status != nil { + cond = cond.And(builder.In("status", opts.Status)) } if opts.UpdatedBefore > 0 { cond = cond.And(builder.Lt{"updated": opts.UpdatedBefore}) diff --git a/models/fixtures/action_run_job.yml b/models/fixtures/action_run_job.yml index 117bb5ea05..702c6bc832 100644 --- a/models/fixtures/action_run_job.yml +++ b/models/fixtures/action_run_job.yml @@ -83,3 +83,48 @@ status: 1 started: 1683636528 stopped: 1683636626 +- + id: 393 + run_id: 891 + repo_id: 1 + owner_id: 1 + commit_sha: 985f0301dba5e7b34be866819cd15ad3d8f508ee + is_fork_pull_request: 0 + name: job_2 + attempt: 1 + job_id: job_2 + task_id: 47 + status: 5 + runs_on: '["ubuntu-latest"]' + started: 1683636528 + stopped: 1683636626 +- + id: 394 + run_id: 891 + repo_id: 1 + owner_id: 2 + commit_sha: 985f0301dba5e7b34be866819cd15ad3d8f508ee + is_fork_pull_request: 0 + name: job_2 + attempt: 1 + job_id: job_2 + task_id: 47 + status: 5 + runs_on: '["debian-latest"]' + started: 1683636528 + stopped: 1683636626 +- + id: 395 + run_id: 891 + repo_id: 1 + owner_id: 3 + commit_sha: 985f0301dba5e7b34be866819cd15ad3d8f508ee + is_fork_pull_request: 0 + name: job_2 + attempt: 1 + job_id: job_2 + task_id: 47 + status: 5 + runs_on: '["fedora"]' + started: 1683636528 + stopped: 1683636626 diff --git a/modules/container/set.go b/modules/container/set.go index 15779983fd..2d654d0aee 100644 --- a/modules/container/set.go +++ b/modules/container/set.go @@ -29,6 +29,15 @@ func (s Set[T]) AddMultiple(values ...T) { } } +func (s Set[T]) IsSubset(subset []T) bool { + for _, v := range subset { + if !s.Contains(v) { + return false + } + } + return true +} + // Contains determines whether a set contains the specified element. // Returns true if the set contains the specified element; otherwise, false. func (s Set[T]) Contains(value T) bool { diff --git a/modules/container/set_test.go b/modules/container/set_test.go index 1502236034..3cfbf7cc2c 100644 --- a/modules/container/set_test.go +++ b/modules/container/set_test.go @@ -33,4 +33,9 @@ func TestSet(t *testing.T) { assert.False(t, s.Contains("key1")) assert.True(t, s.Contains("key6")) assert.True(t, s.Contains("key7")) + + assert.True(t, s.IsSubset([]string{"key6", "key7"})) + assert.False(t, s.IsSubset([]string{"key1"})) + + assert.True(t, s.IsSubset([]string{})) } diff --git a/modules/structs/action.go b/modules/structs/action.go new file mode 100644 index 0000000000..df9f845adc --- /dev/null +++ b/modules/structs/action.go @@ -0,0 +1,25 @@ +// Copyright 2024 The Gitea Authors. All rights reserved. +// SPDX-License-Identifier: MIT + +package structs + +// ActionRunJob represents a job of a run +// swagger:model +type ActionRunJob struct { + // the action run job id + ID int64 `json:"id"` + // the repository id + RepoID int64 `json:"repo_id"` + // the owner id + OwnerID int64 `json:"owner_id"` + // the action run job name + Name string `json:"name"` + // the action run job needed ids + Needs []string `json:"needs"` + // the action run job labels to run on + RunsOn []string `json:"runs_on"` + // the action run job latest task id + TaskID int64 `json:"task_id"` + // the action run job status + Status string `json:"status"` +} diff --git a/routers/api/v1/admin/runners.go b/routers/api/v1/admin/runners.go index 329242d9f6..d0cfef8e48 100644 --- a/routers/api/v1/admin/runners.go +++ b/routers/api/v1/admin/runners.go @@ -24,3 +24,23 @@ func GetRegistrationToken(ctx *context.APIContext) { shared.GetRegistrationToken(ctx, 0, 0) } + +// SearchActionRunJobs return a list of actions jobs filtered by the provided parameters +func SearchActionRunJobs(ctx *context.APIContext) { + // swagger:operation GET /admin/runners/jobs admin adminSearchRunJobs + // --- + // summary: Search action jobs according filter conditions + // produces: + // - application/json + // parameters: + // - name: labels + // in: query + // description: a comma separated list of run job labels to search for + // type: string + // responses: + // "200": + // "$ref": "#/responses/RunJobList" + // "403": + // "$ref": "#/responses/forbidden" + shared.GetActionRunJobs(ctx, 0, 0) +} diff --git a/routers/api/v1/api.go b/routers/api/v1/api.go index 4928c9ff58..89338d6977 100644 --- a/routers/api/v1/api.go +++ b/routers/api/v1/api.go @@ -822,6 +822,7 @@ func Routes() *web.Route { m.Group("/runners", func() { m.Get("/registration-token", reqToken(), reqChecker, act.GetRegistrationToken) + m.Get("/jobs", reqToken(), reqChecker, act.SearchActionRunJobs) }) }) } @@ -975,6 +976,7 @@ func Routes() *web.Route { m.Group("/runners", func() { m.Get("/registration-token", reqToken(), user.GetRegistrationToken) + m.Get("/jobs", reqToken(), user.SearchActionRunJobs) }) }) @@ -1631,6 +1633,7 @@ func Routes() *web.Route { }) m.Group("/runners", func() { m.Get("/registration-token", admin.GetRegistrationToken) + m.Get("/jobs", admin.SearchActionRunJobs) }) if setting.Quota.Enabled { m.Group("/quota", func() { diff --git a/routers/api/v1/org/action.go b/routers/api/v1/org/action.go index 03a1fa8ccc..8cd2e00e00 100644 --- a/routers/api/v1/org/action.go +++ b/routers/api/v1/org/action.go @@ -189,6 +189,31 @@ func (Action) GetRegistrationToken(ctx *context.APIContext) { shared.GetRegistrationToken(ctx, ctx.Org.Organization.ID, 0) } +// SearchActionRunJobs return a list of actions jobs filtered by the provided parameters +func (Action) SearchActionRunJobs(ctx *context.APIContext) { + // swagger:operation GET /orgs/{org}/actions/runners/jobs organization orgSearchRunJobs + // --- + // summary: Search for organization's action jobs according filter conditions + // produces: + // - application/json + // parameters: + // - name: org + // in: path + // description: name of the organization + // type: string + // required: true + // - name: labels + // in: query + // description: a comma separated list of run job labels to search for + // type: string + // responses: + // "200": + // "$ref": "#/responses/RunJobList" + // "403": + // "$ref": "#/responses/forbidden" + shared.GetActionRunJobs(ctx, ctx.Org.Organization.ID, 0) +} + // ListVariables list org-level variables func (Action) ListVariables(ctx *context.APIContext) { // swagger:operation GET /orgs/{org}/actions/variables organization getOrgVariablesList diff --git a/routers/api/v1/repo/action.go b/routers/api/v1/repo/action.go index 0c7506b13b..2ff52c3744 100644 --- a/routers/api/v1/repo/action.go +++ b/routers/api/v1/repo/action.go @@ -507,6 +507,36 @@ func (Action) GetRegistrationToken(ctx *context.APIContext) { shared.GetRegistrationToken(ctx, 0, ctx.Repo.Repository.ID) } +// SearchActionRunJobs return a list of actions jobs filtered by the provided parameters +func (Action) SearchActionRunJobs(ctx *context.APIContext) { + // swagger:operation GET /repos/{owner}/{repo}/actions/runners/jobs repository repoSearchRunJobs + // --- + // summary: Search for repository's action jobs according filter conditions + // produces: + // - application/json + // parameters: + // - name: owner + // in: path + // description: owner of the repo + // type: string + // required: true + // - name: repo + // in: path + // description: name of the repo + // type: string + // required: true + // - name: labels + // in: query + // description: a comma separated list of run job labels to search for + // type: string + // responses: + // "200": + // "$ref": "#/responses/RunJobList" + // "403": + // "$ref": "#/responses/forbidden" + shared.GetActionRunJobs(ctx, 0, ctx.Repo.Repository.ID) +} + var _ actions_service.API = new(Action) // Action implements actions_service.API diff --git a/routers/api/v1/shared/runners.go b/routers/api/v1/shared/runners.go index f184786d7d..53761a07e9 100644 --- a/routers/api/v1/shared/runners.go +++ b/routers/api/v1/shared/runners.go @@ -6,8 +6,11 @@ package shared import ( "errors" "net/http" + "strings" actions_model "code.gitea.io/gitea/models/actions" + "code.gitea.io/gitea/models/db" + "code.gitea.io/gitea/modules/structs" "code.gitea.io/gitea/modules/util" "code.gitea.io/gitea/services/context" ) @@ -30,3 +33,48 @@ func GetRegistrationToken(ctx *context.APIContext, ownerID, repoID int64) { ctx.JSON(http.StatusOK, RegistrationToken{Token: token.Token}) } + +// RunJobList is a list of action run jobs +// swagger:response RunJobList +type RunJobList struct { + // in:body + Body []*structs.ActionRunJob `json:"body"` +} + +func GetActionRunJobs(ctx *context.APIContext, ownerID, repoID int64) { + labels := strings.Split(ctx.FormTrim("labels"), ",") + + total, err := db.Find[actions_model.ActionRunJob](ctx, &actions_model.FindTaskOptions{ + Status: []actions_model.Status{actions_model.StatusWaiting, actions_model.StatusRunning}, + OwnerID: ownerID, + RepoID: repoID, + }) + if err != nil { + ctx.Error(http.StatusInternalServerError, "CountWaitingActionRunJobs", err) + return + } + + res := new(RunJobList) + res.Body = fromRunJobModelToResponse(total, labels) + + ctx.JSON(http.StatusOK, res) +} + +func fromRunJobModelToResponse(job []*actions_model.ActionRunJob, labels []string) []*structs.ActionRunJob { + var res []*structs.ActionRunJob + for i := range job { + if job[i].ItRunsOn(labels) { + res = append(res, &structs.ActionRunJob{ + ID: job[i].ID, + RepoID: job[i].RepoID, + OwnerID: job[i].OwnerID, + Name: job[i].Name, + Needs: job[i].Needs, + RunsOn: job[i].RunsOn, + TaskID: job[i].TaskID, + Status: job[i].Status.String(), + }) + } + } + return res +} diff --git a/routers/api/v1/user/runners.go b/routers/api/v1/user/runners.go index dc4c187ffe..5e8cdbeb58 100644 --- a/routers/api/v1/user/runners.go +++ b/routers/api/v1/user/runners.go @@ -28,3 +28,25 @@ func GetRegistrationToken(ctx *context.APIContext) { shared.GetRegistrationToken(ctx, ctx.Doer.ID, 0) } + +// SearchActionRunJobs return a list of actions jobs filtered by the provided parameters +func SearchActionRunJobs(ctx *context.APIContext) { + // swagger:operation GET /user/actions/runners/jobs user userSearchRunJobs + // --- + // summary: Search for user's action jobs according filter conditions + // produces: + // - application/json + // parameters: + // - name: labels + // in: query + // description: a comma separated list of run job labels to search for + // type: string + // responses: + // "200": + // "$ref": "#/responses/RunJobList" + // "401": + // "$ref": "#/responses/unauthorized" + // "403": + // "$ref": "#/responses/forbidden" + shared.GetActionRunJobs(ctx, ctx.Doer.ID, 0) +} diff --git a/routers/web/shared/actions/runners.go b/routers/web/shared/actions/runners.go index f38933226b..7ed3f88f6c 100644 --- a/routers/web/shared/actions/runners.go +++ b/routers/web/shared/actions/runners.go @@ -79,7 +79,7 @@ func RunnerDetails(ctx *context.Context, page int, runnerID, ownerID, repoID int Page: page, PageSize: 30, }, - Status: actions_model.StatusUnknown, // Unknown means all + Status: []actions_model.Status{actions_model.StatusUnknown}, // Unknown means all RunnerID: runner.ID, } diff --git a/services/actions/clear_tasks.go b/services/actions/clear_tasks.go index 67373782d5..f146c22372 100644 --- a/services/actions/clear_tasks.go +++ b/services/actions/clear_tasks.go @@ -19,7 +19,7 @@ import ( // StopZombieTasks stops the task which have running status, but haven't been updated for a long time func StopZombieTasks(ctx context.Context) error { return stopTasks(ctx, actions_model.FindTaskOptions{ - Status: actions_model.StatusRunning, + Status: []actions_model.Status{actions_model.StatusRunning}, UpdatedBefore: timeutil.TimeStamp(time.Now().Add(-setting.Actions.ZombieTaskTimeout).Unix()), }) } @@ -27,7 +27,7 @@ func StopZombieTasks(ctx context.Context) error { // StopEndlessTasks stops the tasks which have running status and continuous updates, but don't end for a long time func StopEndlessTasks(ctx context.Context) error { return stopTasks(ctx, actions_model.FindTaskOptions{ - Status: actions_model.StatusRunning, + Status: []actions_model.Status{actions_model.StatusRunning}, StartedBefore: timeutil.TimeStamp(time.Now().Add(-setting.Actions.EndlessTaskTimeout).Unix()), }) } diff --git a/services/actions/interface.go b/services/actions/interface.go index d4fa782fec..76bee6f153 100644 --- a/services/actions/interface.go +++ b/services/actions/interface.go @@ -25,4 +25,6 @@ type API interface { UpdateVariable(*context.APIContext) // GetRegistrationToken get registration token GetRegistrationToken(*context.APIContext) + // SearchActionRunJobs get pending Action run jobs + SearchActionRunJobs(*context.APIContext) } diff --git a/templates/swagger/v1_json.tmpl b/templates/swagger/v1_json.tmpl index f726176883..1832e9d732 100644 --- a/templates/swagger/v1_json.tmpl +++ b/templates/swagger/v1_json.tmpl @@ -992,6 +992,34 @@ } } }, + "/admin/runners/jobs": { + "get": { + "produces": [ + "application/json" + ], + "tags": [ + "admin" + ], + "summary": "Search action jobs according filter conditions", + "operationId": "adminSearchRunJobs", + "parameters": [ + { + "type": "string", + "description": "a comma separated list of run job labels to search for", + "name": "labels", + "in": "query" + } + ], + "responses": { + "200": { + "$ref": "#/responses/RunJobList" + }, + "403": { + "$ref": "#/responses/forbidden" + } + } + } + }, "/admin/runners/registration-token": { "get": { "produces": [ @@ -2284,6 +2312,41 @@ } } }, + "/orgs/{org}/actions/runners/jobs": { + "get": { + "produces": [ + "application/json" + ], + "tags": [ + "organization" + ], + "summary": "Search for organization's action jobs according filter conditions", + "operationId": "orgSearchRunJobs", + "parameters": [ + { + "type": "string", + "description": "name of the organization", + "name": "org", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "a comma separated list of run job labels to search for", + "name": "labels", + "in": "query" + } + ], + "responses": { + "200": { + "$ref": "#/responses/RunJobList" + }, + "403": { + "$ref": "#/responses/forbidden" + } + } + } + }, "/orgs/{org}/actions/runners/registration-token": { "get": { "produces": [ @@ -4639,6 +4702,48 @@ } } }, + "/repos/{owner}/{repo}/actions/runners/jobs": { + "get": { + "produces": [ + "application/json" + ], + "tags": [ + "repository" + ], + "summary": "Search for repository's action jobs according filter conditions", + "operationId": "repoSearchRunJobs", + "parameters": [ + { + "type": "string", + "description": "owner of the repo", + "name": "owner", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of the repo", + "name": "repo", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "a comma separated list of run job labels to search for", + "name": "labels", + "in": "query" + } + ], + "responses": { + "200": { + "$ref": "#/responses/RunJobList" + }, + "403": { + "$ref": "#/responses/forbidden" + } + } + } + }, "/repos/{owner}/{repo}/actions/runners/registration-token": { "get": { "produces": [ @@ -17399,6 +17504,37 @@ } } }, + "/user/actions/runners/jobs": { + "get": { + "produces": [ + "application/json" + ], + "tags": [ + "user" + ], + "summary": "Search for user's action jobs according filter conditions", + "operationId": "userSearchRunJobs", + "parameters": [ + { + "type": "string", + "description": "a comma separated list of run job labels to search for", + "name": "labels", + "in": "query" + } + ], + "responses": { + "200": { + "$ref": "#/responses/RunJobList" + }, + "401": { + "$ref": "#/responses/unauthorized" + }, + "403": { + "$ref": "#/responses/forbidden" + } + } + } + }, "/user/actions/runners/registration-token": { "get": { "produces": [ @@ -20387,6 +20523,63 @@ }, "x-go-package": "code.gitea.io/gitea/modules/structs" }, + "ActionRunJob": { + "description": "ActionRunJob represents a job of a run", + "type": "object", + "properties": { + "id": { + "description": "the action run job id", + "type": "integer", + "format": "int64", + "x-go-name": "ID" + }, + "name": { + "description": "the action run job name", + "type": "string", + "x-go-name": "Name" + }, + "needs": { + "description": "the action run job needed ids", + "type": "array", + "items": { + "type": "string" + }, + "x-go-name": "Needs" + }, + "owner_id": { + "description": "the owner id", + "type": "integer", + "format": "int64", + "x-go-name": "OwnerID" + }, + "repo_id": { + "description": "the repository id", + "type": "integer", + "format": "int64", + "x-go-name": "RepoID" + }, + "runs_on": { + "description": "the action run job labels to run on", + "type": "array", + "items": { + "type": "string" + }, + "x-go-name": "RunsOn" + }, + "status": { + "description": "the action run job status", + "type": "string", + "x-go-name": "Status" + }, + "task_id": { + "description": "the action run job latest task id", + "type": "integer", + "format": "int64", + "x-go-name": "TaskID" + } + }, + "x-go-package": "code.gitea.io/gitea/modules/structs" + }, "ActionTask": { "description": "ActionTask represents a ActionTask", "type": "object", @@ -28678,6 +28871,15 @@ } } }, + "RunJobList": { + "description": "RunJobList is a list of action run jobs", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/ActionRunJob" + } + } + }, "SearchResults": { "description": "SearchResults", "schema": { diff --git a/tests/integration/api_admin_actions_test.go b/tests/integration/api_admin_actions_test.go new file mode 100644 index 0000000000..22590dc4c4 --- /dev/null +++ b/tests/integration/api_admin_actions_test.go @@ -0,0 +1,39 @@ +// Copyright 2024 The Forgejo Authors c/o Codeberg e.V.. All rights reserved. +// SPDX-License-Identifier: MIT + +package integration + +import ( + "fmt" + "net/http" + "testing" + + actions_model "code.gitea.io/gitea/models/actions" + auth_model "code.gitea.io/gitea/models/auth" + "code.gitea.io/gitea/models/unittest" + "code.gitea.io/gitea/routers/api/v1/shared" + "code.gitea.io/gitea/tests" + + "github.com/stretchr/testify/assert" +) + +func TestAPISearchActionJobs_GlobalRunner(t *testing.T) { + defer tests.PrepareTestEnv(t)() + + job := unittest.AssertExistsAndLoadBean(t, &actions_model.ActionRunJob{ID: 393}) + adminUsername := "user1" + token := getUserToken(t, adminUsername, auth_model.AccessTokenScopeWriteAdmin) + + req := NewRequest( + t, + "GET", + fmt.Sprintf("/api/v1/admin/runners/jobs?labels=%s", "ubuntu-latest"), + ).AddTokenAuth(token) + res := MakeRequest(t, req, http.StatusOK) + + var jobs shared.RunJobList + DecodeJSON(t, res, &jobs) + + assert.Len(t, jobs.Body, 1) + assert.EqualValues(t, job.ID, jobs.Body[0].ID) +} diff --git a/tests/integration/api_org_actions_test.go b/tests/integration/api_org_actions_test.go new file mode 100644 index 0000000000..c8ebbdf293 --- /dev/null +++ b/tests/integration/api_org_actions_test.go @@ -0,0 +1,38 @@ +// Copyright 2025 The Forgejo Authors. All rights reserved. +// SPDX-License-Identifier: MIT + +package integration + +import ( + "fmt" + "net/http" + "testing" + + actions_model "code.gitea.io/gitea/models/actions" + auth_model "code.gitea.io/gitea/models/auth" + "code.gitea.io/gitea/models/unittest" + "code.gitea.io/gitea/routers/api/v1/shared" + "code.gitea.io/gitea/tests" + + "github.com/stretchr/testify/assert" +) + +func TestAPISearchActionJobs_OrgRunner(t *testing.T) { + defer tests.PrepareTestEnv(t)() + + session := loginUser(t, "user1") + token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteOrganization) + + job := unittest.AssertExistsAndLoadBean(t, &actions_model.ActionRunJob{ID: 395}) + + req := NewRequest(t, "GET", + fmt.Sprintf("/api/v1/orgs/org3/actions/runners/jobs?labels=%s", "fedora")). + AddTokenAuth(token) + res := MakeRequest(t, req, http.StatusOK) + + var jobs shared.RunJobList + DecodeJSON(t, res, &jobs) + + assert.Len(t, jobs.Body, 1) + assert.EqualValues(t, job.ID, jobs.Body[0].ID) +} diff --git a/tests/integration/api_repo_actions_test.go b/tests/integration/api_repo_actions_test.go new file mode 100644 index 0000000000..9c3b6aa2b6 --- /dev/null +++ b/tests/integration/api_repo_actions_test.go @@ -0,0 +1,43 @@ +// Copyright 2025 The Forgejo Authors. All rights reserved. +// SPDX-License-Identifier: MIT + +package integration + +import ( + "net/http" + "testing" + + actions_model "code.gitea.io/gitea/models/actions" + auth_model "code.gitea.io/gitea/models/auth" + repo_model "code.gitea.io/gitea/models/repo" + "code.gitea.io/gitea/models/unittest" + user_model "code.gitea.io/gitea/models/user" + "code.gitea.io/gitea/routers/api/v1/shared" + "code.gitea.io/gitea/tests" + + "github.com/stretchr/testify/assert" +) + +func TestAPISearchActionJobs_RepoRunner(t *testing.T) { + defer tests.PrepareTestEnv(t)() + + repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}) + user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) + token := getUserToken(t, user2.LowerName, auth_model.AccessTokenScopeWriteRepository) + job := unittest.AssertExistsAndLoadBean(t, &actions_model.ActionRunJob{ID: 393}) + + req := NewRequestf( + t, + "GET", + "/api/v1/repos/%s/%s/actions/runners/jobs?labels=%s", + repo.OwnerName, repo.Name, + "ubuntu-latest", + ).AddTokenAuth(token) + res := MakeRequest(t, req, http.StatusOK) + + var jobs shared.RunJobList + DecodeJSON(t, res, &jobs) + + assert.Len(t, jobs.Body, 1) + assert.EqualValues(t, job.ID, jobs.Body[0].ID) +} diff --git a/tests/integration/api_user_actions_test.go b/tests/integration/api_user_actions_test.go new file mode 100644 index 0000000000..f9c9c1df4e --- /dev/null +++ b/tests/integration/api_user_actions_test.go @@ -0,0 +1,38 @@ +// Copyright 2025 The Forgejo Authors. All rights reserved. +// SPDX-License-Identifier: MIT + +package integration + +import ( + "fmt" + "net/http" + "testing" + + actions_model "code.gitea.io/gitea/models/actions" + auth_model "code.gitea.io/gitea/models/auth" + "code.gitea.io/gitea/models/unittest" + "code.gitea.io/gitea/routers/api/v1/shared" + "code.gitea.io/gitea/tests" + + "github.com/stretchr/testify/assert" +) + +func TestAPISearchActionJobs_UserRunner(t *testing.T) { + defer tests.PrepareTestEnv(t)() + + normalUsername := "user2" + session := loginUser(t, normalUsername) + token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteUser) + job := unittest.AssertExistsAndLoadBean(t, &actions_model.ActionRunJob{ID: 394}) + + req := NewRequest(t, "GET", + fmt.Sprintf("/api/v1/user/actions/runners/jobs?labels=%s", "debian-latest")). + AddTokenAuth(token) + res := MakeRequest(t, req, http.StatusOK) + + var jobs shared.RunJobList + DecodeJSON(t, res, &jobs) + + assert.Len(t, jobs.Body, 1) + assert.EqualValues(t, job.ID, jobs.Body[0].ID) +} From c30d13b97c9a8c3f3736adc8001e5607a35dc439 Mon Sep 17 00:00:00 2001 From: forgejo-release-manager Date: Wed, 15 Jan 2025 07:19:55 +0000 Subject: [PATCH 148/198] chore(release-notes): Forgejo v10.0.0 --- release-notes-published/10.0.0.md | 585 ++++++++++++++++++++++++++++++ 1 file changed, 585 insertions(+) diff --git a/release-notes-published/10.0.0.md b/release-notes-published/10.0.0.md index e69de29bb2..adc9928dfd 100644 --- a/release-notes-published/10.0.0.md +++ b/release-notes-published/10.0.0.md @@ -0,0 +1,585 @@ + + + + +## Release notes + +- Security bug fixes + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5997): fix(security): [commit](https://codeberg.org/forgejo/forgejo/commit/45435a8789f8ff69603799a9031246d2d621d139) Fix and refactor markdown rendering +- Security features + - [PR](https://codeberg.org/forgejo/forgejo/pulls/6074): migrate TOTP secrets to `keying` +- Breaking bug fixes + - [PR](https://codeberg.org/forgejo/forgejo/pulls/6240): Ensure `source_id` parameter is not skipped when set to 0 and correctly filter users in `/api/v1/admin/users` endpoint +- User Interface features + - [PR](https://codeberg.org/forgejo/forgejo/pulls/6407) ([backported](https://codeberg.org/forgejo/forgejo/pulls/6423)): Rework user profile settings + - [PR](https://codeberg.org/forgejo/forgejo/pulls/6386) ([backported](https://codeberg.org/forgejo/forgejo/pulls/6399)): Rework new repository dialog + - [PR](https://codeberg.org/forgejo/forgejo/pulls/6344): Show repository size on mobile + - [PR](https://codeberg.org/forgejo/forgejo/pulls/6274): Add links to commit lists in contributors graph page + - [PR](https://codeberg.org/forgejo/forgejo/pulls/6079): Add copy path button to file view + - [PR](https://codeberg.org/forgejo/forgejo/pulls/6044): Put issue actions in a single row on mobile + - [PR](https://codeberg.org/forgejo/forgejo/pulls/6018): Don't display email in profile settings when hidden + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5899): Highlight user mention in comments and commit messages + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5819): When [bleve is used for issue search](https://forgejo.org/docs/next/admin/config-cheat-sheet/#indexer-indexer), a `fuzzy` search now applies to each word instead of all of them, as if they were a phrase. For instance, searching for `activitypub spam moderation` previously [returned no result in Forgejo discussions](https://v9.next.forgejo.org/snematoda/forgejo-discussions/issues?state=open&type=all&q=activitypub+spam+moderation&fuzzy=true) and now returns the [relevant issues](https://codeberg.org/forgejo/discussions/issues?state=open&type=all&q=activitypub+spam+moderation&fuzzy=true). If the search results are too broad, or for searching exact phrases prefer using an `exact` search. Sorting by newest is still available as a non default option under `Sort`. The query was also reworked to improve performances. It makes a significant difference for large instances such as Codeberg. + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5777): Add search to releases page + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5695): Combine review requests comments + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5677): If you select a portion of a comment and use the 'Quote reply' feature in the context menu, only that portion will be quoted. The markdown syntax is preserved. + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5593): Set "your repositories" as the default filter for org dashboards + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5589): Add button to create a Markdown table in a comment + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5518): Add a bullet symbol between author and committer + - [PR](https://codeberg.org/forgejo/forgejo/pulls/4125): Added link to show all Issues/PullRequests +- User Interface bug fixes + - [PR](https://codeberg.org/forgejo/forgejo/pulls/6122): Fix Action log UI race condition that occasionally prevents logs from loading + - [PR](https://codeberg.org/forgejo/forgejo/pulls/6063): Fix wiki search overflowing on wide screens + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5838): Move "forgot_password"-link to fix login tab order + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5697): Update help links on page with no workflows +- Localization + - [PR](https://codeberg.org/forgejo/forgejo/pulls/6566): i18n: update of translations from Codeberg Translate + - [PR](https://codeberg.org/forgejo/forgejo/pulls/6514): i18n: update of translations from Codeberg Translate + - [PR](https://codeberg.org/forgejo/forgejo/pulls/6378) ([backported](https://codeberg.org/forgejo/forgejo/pulls/6450)): i18n: update of translations from Codeberg Translate + - [PR](https://codeberg.org/forgejo/forgejo/pulls/6331) ([backported](https://codeberg.org/forgejo/forgejo/pulls/6377)): i18n: update of translations from Codeberg Translate + - [PR](https://codeberg.org/forgejo/forgejo/pulls/6242): i18n: update of translations from Codeberg Translate + - [PR](https://codeberg.org/forgejo/forgejo/pulls/6161): i18n: update of translations from Codeberg Translate + - [PR](https://codeberg.org/forgejo/forgejo/pulls/6091): i18n: update of translations from Codeberg Translate + - [PR](https://codeberg.org/forgejo/forgejo/pulls/6072): Add Low German to list of default languages + - [PR](https://codeberg.org/forgejo/forgejo/pulls/6041): i18n: update of translations from Codeberg Translate + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5960): i18n: update of translations from Codeberg Translate + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5845): i18n: update of translations from Codeberg Translate + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5786): i18n: Add dummy language for checking translation keys (#5785) + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5754): i18n: update of translations from Codeberg Translate + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5681): i18n: update of translations from Codeberg Translate + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5583): i18n: update of translations from Codeberg Translate +- Features + - [PR](https://codeberg.org/forgejo/forgejo/pulls/6448): Add summary card for repos and releases + - [PR](https://codeberg.org/forgejo/forgejo/pulls/6271): [commit](https://codeberg.org/forgejo/forgejo/commit/b0d6a7f07bff836190a8e87fe5645d5557893e32) Implement update branch API + - [PR](https://codeberg.org/forgejo/forgejo/pulls/6265): Allow changing default branch update style + - [PR](https://codeberg.org/forgejo/forgejo/pulls/6228): Add sorting functionality to `/api/v1/admin/users` endpoint + - [PR](https://codeberg.org/forgejo/forgejo/pulls/6200): [commit](https://codeberg.org/forgejo/forgejo/commit/0786ddc5de37a01d1c3e3bf99b794665341b3c12) Add Swift login endpoint + - [PR](https://codeberg.org/forgejo/forgejo/pulls/6180): Add support for `pacman -F` in Arch package + - [PR](https://codeberg.org/forgejo/forgejo/pulls/6170): Make LFS http_client parallel within a batch + - [PR](https://codeberg.org/forgejo/forgejo/pulls/6146): Improve performance of notifications page for MySQL + - [PR](https://codeberg.org/forgejo/forgejo/pulls/6143): Filepath filter for code search + - [PR](https://codeberg.org/forgejo/forgejo/pulls/6112): Add option to disable builtin authentication + - [PR](https://codeberg.org/forgejo/forgejo/pulls/6110): [commit](https://codeberg.org/forgejo/forgejo/commit/3973f1022d57a3134e8f775e1c1cc6d398681bb4) Add github compatible tarball download API endpoints + - [PR](https://codeberg.org/forgejo/forgejo/pulls/6100): Improve performance of allowed org repo creation query + - [PR](https://codeberg.org/forgejo/forgejo/pulls/6062): [commit](https://codeberg.org/forgejo/forgejo/commit/ddabba5f89c4b196daeeb2af17de9ec2cec14b63) Allow the actions user to login via the jwt token + - [PR](https://codeberg.org/forgejo/forgejo/pulls/6053): Add a "summary card" to issues & PRs for consumption by OpenGraph clients + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5997): [commit](https://codeberg.org/forgejo/forgejo/commit/dd3c4d7096cff91854bcc6641f55d9d093e5c86e) Add a doctor check to disable the "Actions" unit for mirrors + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5940): Make AVIF Images work with Forgejo + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5822): Trim spaces from repo names on form submission + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5789): [commit](https://codeberg.org/forgejo/forgejo/commit/1e595979625e54d375a0eaa440b84ef5e17af160) Add new [lfs_client].BATCH_SIZE and [server].LFS_MAX_BATCH_SIZE config settings. + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5787): Add setting to block disposable emails + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5751): mermaid: [Add the Kanban board diagram type](https://github.com/mermaid-js/mermaid/pull/5999). + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5751): mermaid: [Class diagram includes a new "classBox" shape, classDef statement, support for styling the default class and lollipop interfaces](https://github.com/mermaid-js/mermaid/pull/5880). + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5714): [commit](https://codeberg.org/forgejo/forgejo/commit/ab660c5944d59cdb4ecc071401445ac9f53cee45) Add `DISABLE_ORGANIZATIONS_PAGE` and `DISABLE_CODE_PAGE` settings for explore pages + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5689): Add branch deletion for scheduled PRs + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5621): [commit](https://codeberg.org/forgejo/forgejo/commit/c3741d7fb0114691da73f00ae0ac9dced87e884d) The `requested_reviewers` data is included in more webhook events. + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5621): [commit](https://codeberg.org/forgejo/forgejo/commit/89446e60a6e7ec3441f0c480164c09851ae54ce7) Support migrating GitHub/GitLab PR draft status. + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5601): Language detection in the repository learned about the following languages: [Java Template Engine](https://github.com/github-linguist/linguist/pull/6610), [Noir](https://github.com/github-linguist/linguist/pull/6432), [Cylc](https://github.com/github-linguist/linguist/pull/6832), [iCalendar](https://github.com/github-linguist/linguist/pull/6940), [vCard (aka. VCF: Virtual Contact File) and Variant Call Format (VCF)](https://github.com/github-linguist/linguist/pull/6941), [B4X](https://github.com/github-linguist/linguist/pull/6965), [Carbon](https://github.com/github-linguist/linguist/pull/7011), [LiveCode Script](https://github.com/github-linguist/linguist/pull/6833), [Dune (OCaml build system)](https://github.com/github-linguist/linguist/pull/6814). + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5601): The following extensions or filenames in a repository are associated with the matching language: [deno.lock](https://github.com/github-linguist/linguist/pull/6885), [uv.lock](https://github.com/github-linguist/linguist/pull/7006), [HOSTS.TXT](https://github.com/github-linguist/linguist/pull/7014), [.peggy](https://github.com/github-linguist/linguist/pull/7017), [.resource](https://github.com/github-linguist/linguist/pull/6500). + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5543): [commit](https://codeberg.org/forgejo/forgejo/commit/d0af8fe4dc7b294fe5409b2271468494267d5a7d) Allow filtering pull requests by poster in the API. + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5477): [commit](https://codeberg.org/forgejo/forgejo/commit/af901ac7bb03d27f175f2292581fc67fa9c8d567) Add support for searching users by email. + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5459): New mermaid [flowchart shapes](https://mermaid.js.org/syntax/flowchart.html#complete-list-of-new-shapes). + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5416): [commit](https://codeberg.org/forgejo/forgejo/commit/8178d6eaba64d05799fd3b62fa889bd13bee07c7) Code search results when using the bleve indexer are sorted by relevance. + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5372): [commit](https://codeberg.org/forgejo/forgejo/commit/9d3473119893ffde0ab36d98e7a0e41c5d0ba9a3) Add bin to Composer Metadata. + - [PR](https://codeberg.org/forgejo/forgejo/pulls/4968): Support regexp in git-grep search + - [PR](https://codeberg.org/forgejo/forgejo/pulls/4753): Git notes can be modified via the API or the UI +- Bug fixes + - [PR](https://codeberg.org/forgejo/forgejo/pulls/6343): avoid Gitea migration warnings + - [PR](https://codeberg.org/forgejo/forgejo/pulls/6329): maven package where actual pom has no group-id defined, fallback to parent group-id + - [PR](https://codeberg.org/forgejo/forgejo/pulls/6271): [commit](https://codeberg.org/forgejo/forgejo/commit/96a7f0a3f065c5db8fdf352c93c8367e24d259de) Fix missing outputs for jobs with matrix + - [PR](https://codeberg.org/forgejo/forgejo/pulls/6271): [commit](https://codeberg.org/forgejo/forgejo/commit/2b5c69c451a684b20119e2521dc23734c7869241) Detect whether action view branch was deleted + - [PR](https://codeberg.org/forgejo/forgejo/pulls/6271): [commit](https://codeberg.org/forgejo/forgejo/commit/bf934c96c92d643678ac7a18697b6563bc9d20a5) Add standard-compliant route to serve outdated R packages + - [PR](https://codeberg.org/forgejo/forgejo/pulls/6105): Fix unconditional DB queries in commit status fetches + - [PR](https://codeberg.org/forgejo/forgejo/pulls/6062): [commit](https://codeberg.org/forgejo/forgejo/commit/32a91add34519ef7768ec907888ed837ad0dde2f) Fix GetInactiveUsers + - [PR](https://codeberg.org/forgejo/forgejo/pulls/6062): [commit](https://codeberg.org/forgejo/forgejo/commit/64824290912b6300ede2b2f95ff77d55dde9859b) Fix submodule parsing + - [PR](https://codeberg.org/forgejo/forgejo/pulls/6062): [commit](https://codeberg.org/forgejo/forgejo/commit/ddabba5f89c4b196daeeb2af17de9ec2cec14b63) allow the actions user to login via the jwt token + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5997): [commit](https://codeberg.org/forgejo/forgejo/commit/a8f2002a9b061ec1092df67c6f05e30aa7d2e2d2) Remove transaction for archive download + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5997): [commit](https://codeberg.org/forgejo/forgejo/commit/96ee0f56475204b2bbdc7f2aeb35b1c32eac469c) Fix oauth2 error handle not return immediately + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5997): [commit](https://codeberg.org/forgejo/forgejo/commit/c2e8790df37a14b4d2f72c7377db75309e0ebf1d) Trim title before insert/update to database to match the size requirements of database + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5997): [commit](https://codeberg.org/forgejo/forgejo/commit/03ab73d92eabaf774278effe3332623b1dc3580a) Fix nil panic if repo doesn't exist + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5997): [commit](https://codeberg.org/forgejo/forgejo/commit/56971f9ed90a01fd74a634b7496593e6f62ac260) Disable Oauth check if oauth disabled + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5997): [commit](https://codeberg.org/forgejo/forgejo/commit/56971f9ed90a01fd74a634b7496593e6f62ac260) Disable OAuth check if OAuth disabled + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5988): [commit](https://codeberg.org/forgejo/forgejo/commit/fc26becba4b08877a726f2e7e453992310245fe5) When a tag was removed and a release existed for that tag, it would be broken. The release is no longer broken the tag can be added again. + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5811): Escaping specific markdown in commit messages on Discord-type embeds + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5789): [commit](https://codeberg.org/forgejo/forgejo/commit/362ad0ba39bdbc87202e349678e21fc2a75ff7cb) Update force-pushed tags too when syncing mirrors + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5789): [commit](https://codeberg.org/forgejo/forgejo/commit/4c5bdddf7751a35985c08ba6506f1f30103749d6) Fix `missing signature key` error when pulling Docker images with `SERVE_DIRECT` enabled + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5789): [commit](https://codeberg.org/forgejo/forgejo/commit/2c5fdb108ff9e23e8f907fb6afe59177c6bb202e) Fix the missing menu in organization project view page + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5789): [commit](https://codeberg.org/forgejo/forgejo/commit/2358c0d899faec8311e46dcb0550041496bcd532) Properly clean temporary index files + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5781): Preview picture not visible on Markdown file + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5714): [commit](https://codeberg.org/forgejo/forgejo/commit/d13a4ab5632d6a9697bd0907f9c69ed57d949340) Fixed a bug related to disabling two-factor authentication + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5621): [commit](https://codeberg.org/forgejo/forgejo/commit/f3f386545ee97b91f1aaac4142480e70a443c655) Always update expiration time when creating an artifact, so that artifacts from re-ran jobs do not get lost. + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5621): [commit](https://codeberg.org/forgejo/forgejo/commit/c163bf6fb55c922ab0cf552b47475fc8fc8b99d9) Remove the button toolbar when deleting a diff comment. + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5621): [commit](https://codeberg.org/forgejo/forgejo/commit/e8700cee612f0aa769dc6929772d9b04c6c21807) Run scheduled tasks against the latest commit. + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5517): Allow Organisations to remove the Email Address + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5477): [commit](https://codeberg.org/forgejo/forgejo/commit/1dfe58ad11bc6fdc73a2b5ffb3c1481fbddbf46b) PR creation on forked repositories. + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5477): [commit](https://codeberg.org/forgejo/forgejo/commit/b67b7c12385059898fc8cb7997755a88b3afa483) The logic of finding the latest pull review commit ID is incorrect. + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5416): [commit](https://codeberg.org/forgejo/forgejo/commit/b496317b5a2aea970bc94ccf6fcde35cd417ec20) After migrating a repository that contains merged pull requests, the branch is missing and cannot be deleted. + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5416): [commit](https://codeberg.org/forgejo/forgejo/commit/a226064711899da07d6b1455a68ef758f2f3e7e0) Forgejo Actions artifact v4 upload above 8MB. + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5307): Don't allow modification to internal reference +- Other changes without a feature or bug label + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5789): chore: [commit](https://codeberg.org/forgejo/forgejo/commit/b308bcca7c950b7f0d127ee4282019c2a9923299) Improved diff view performance + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5714): chore: [commit](https://codeberg.org/forgejo/forgejo/commit/ab26d880932dbc116c43ea277029984c7a6d4e94) Emit a log message when failing to delete an inactive user +- Included for completeness but not worth a release note + - [PR](https://codeberg.org/forgejo/forgejo/pulls/6553): Update module github.com/alecthomas/chroma/v2 to v2.15.0 (v10.0/forgejo) + - [PR](https://codeberg.org/forgejo/forgejo/pulls/6513) ([backported](https://codeberg.org/forgejo/forgejo/pulls/6517)): Add lock for parallel maven upload + - [PR](https://codeberg.org/forgejo/forgejo/pulls/6496): Update module github.com/go-git/go-git/v5 to v5.13.1 (v10.0/forgejo) + - [PR](https://codeberg.org/forgejo/forgejo/pulls/6491) ([backported](https://codeberg.org/forgejo/forgejo/pulls/6493)): fix: upgrade gof3 package and driver + - [PR](https://codeberg.org/forgejo/forgejo/pulls/6488) ([backported](https://codeberg.org/forgejo/forgejo/pulls/6492)): chore: remove illegal git usage + - [PR](https://codeberg.org/forgejo/forgejo/pulls/6463) ([backported](https://codeberg.org/forgejo/forgejo/pulls/6465)): fix(ui): show oauth divider on signup page + - [PR](https://codeberg.org/forgejo/forgejo/pulls/6432) ([backported](https://codeberg.org/forgejo/forgejo/pulls/6444)): Fix editing pr review + - [PR](https://codeberg.org/forgejo/forgejo/pulls/6441) ([backported](https://codeberg.org/forgejo/forgejo/pulls/6442)): fix(code search): empty mode dropdown when keyword is empty + - [PR](https://codeberg.org/forgejo/forgejo/pulls/6427) ([backported](https://codeberg.org/forgejo/forgejo/pulls/6430)): fix(ui): use primary color for button in table modal + - [PR](https://codeberg.org/forgejo/forgejo/pulls/6421) ([backported](https://codeberg.org/forgejo/forgejo/pulls/6426)): Fix edit cancel button + - [PR](https://codeberg.org/forgejo/forgejo/pulls/6419) ([backported](https://codeberg.org/forgejo/forgejo/pulls/6424)): Fix issue/comment menus + - [PR](https://codeberg.org/forgejo/forgejo/pulls/6403) ([backported](https://codeberg.org/forgejo/forgejo/pulls/6420)): chore(branding): strip metadata information from the footer + - [PR](https://codeberg.org/forgejo/forgejo/pulls/6410) ([backported](https://codeberg.org/forgejo/forgejo/pulls/6418)): fix: use DateUtils for blocked users list + - [PR](https://codeberg.org/forgejo/forgejo/pulls/6391) ([backported](https://codeberg.org/forgejo/forgejo/pulls/6416)): [gitea] week 2024-53 cherry pick (gitea/main -> forgejo) + - [PR](https://codeberg.org/forgejo/forgejo/pulls/6405) ([backported](https://codeberg.org/forgejo/forgejo/pulls/6406)): fix: xorm needs to be lowercase otherwise it is ignored + - [PR](https://codeberg.org/forgejo/forgejo/pulls/6401) ([backported](https://codeberg.org/forgejo/forgejo/pulls/6402)): Cosmetic changes and fixes around repo homepage + - [PR](https://codeberg.org/forgejo/forgejo/pulls/6286) ([backported](https://codeberg.org/forgejo/forgejo/pulls/6398)): feat: When comparing in repos, mention that pull request creation requires sign-in + - [PR](https://codeberg.org/forgejo/forgejo/pulls/6390) ([backported](https://codeberg.org/forgejo/forgejo/pulls/6392)): Fix overflow in git notes + - [PR](https://codeberg.org/forgejo/forgejo/pulls/6372) ([backported](https://codeberg.org/forgejo/forgejo/pulls/6382)): Revert "Update dependency idiomorph to v0.4.0" + - [PR](https://codeberg.org/forgejo/forgejo/pulls/6375) ([backported](https://codeberg.org/forgejo/forgejo/pulls/6376)): chore(i18n): user/label translations in danish/latvian + - [PR](https://codeberg.org/forgejo/forgejo/pulls/6368): harden keying implementation + - [PR](https://codeberg.org/forgejo/forgejo/pulls/6367): Update dependency webpack-cli to v6 (forgejo) + - [PR](https://codeberg.org/forgejo/forgejo/pulls/6366): Update linters (forgejo) + - [PR](https://codeberg.org/forgejo/forgejo/pulls/6365): Update dependency djlint to v1.36.4 (forgejo) + - [PR](https://codeberg.org/forgejo/forgejo/pulls/6364): Update dependency @vitest/eslint-plugin to v1.1.20 (forgejo) + - [PR](https://codeberg.org/forgejo/forgejo/pulls/6363): Update github.com/shurcooL/vfsgen digest to 0000e14 (forgejo) + - [PR](https://codeberg.org/forgejo/forgejo/pulls/6357): chore(docs): explain vars.SKIP_END_TO_END when building a release + - [PR](https://codeberg.org/forgejo/forgejo/pulls/6355): Update dependency idiomorph to v0.4.0 (forgejo) + - [PR](https://codeberg.org/forgejo/forgejo/pulls/6354): Update module google.golang.org/protobuf to v1.36.1 (forgejo) + - [PR](https://codeberg.org/forgejo/forgejo/pulls/6349): Lock file maintenance (forgejo) + - [PR](https://codeberg.org/forgejo/forgejo/pulls/6348): Update module github.com/go-testfixtures/testfixtures/v3 to v3.14.0 (forgejo) + - [PR](https://codeberg.org/forgejo/forgejo/pulls/6347): Update renovate Docker tag to v39.82.1 (forgejo) + - [PR](https://codeberg.org/forgejo/forgejo/pulls/6342): [gitea] week 2024-52 cherry pick (gitea/main -> forgejo) + - [PR](https://codeberg.org/forgejo/forgejo/pulls/6339): repo avatar generating (#6338) + - [PR](https://codeberg.org/forgejo/forgejo/pulls/6337): keep commit count limit in file history pagination static and not increase with every page + - [PR](https://codeberg.org/forgejo/forgejo/pulls/6335): template config path (#2836) + - [PR](https://codeberg.org/forgejo/forgejo/pulls/6330): branding: update contrib/legal + - [PR](https://codeberg.org/forgejo/forgejo/pulls/6324): chore(release): link to the standalone release notes file + - [PR](https://codeberg.org/forgejo/forgejo/pulls/6322): Update module google.golang.org/grpc to v1.69.2 (forgejo) + - [PR](https://codeberg.org/forgejo/forgejo/pulls/6321): Update dependency globals to v15.14.0 (forgejo) + - [PR](https://codeberg.org/forgejo/forgejo/pulls/6320): Update actions/cascading-pr action to v2.2.0 (forgejo) + - [PR](https://codeberg.org/forgejo/forgejo/pulls/6319): Update dependency katex to v0.16.18 (forgejo) + - [PR](https://codeberg.org/forgejo/forgejo/pulls/6316): Update module golang.org/x/net to v0.33.0 (forgejo) + - [PR](https://codeberg.org/forgejo/forgejo/pulls/6313): actions move to data.forgejo.org + - [PR](https://codeberg.org/forgejo/forgejo/pulls/6311): chore: avoid using gock + - [PR](https://codeberg.org/forgejo/forgejo/pulls/6310): chore: remove unused dependency from build.go + - [PR](https://codeberg.org/forgejo/forgejo/pulls/6309): Update dependency markdownlint-cli to v0.43.0 (forgejo) + - [PR](https://codeberg.org/forgejo/forgejo/pulls/6308): Update dependency @playwright/test to v1.49.1 (forgejo) + - [PR](https://codeberg.org/forgejo/forgejo/pulls/6307): Update vitest monorepo to v2.1.8 (forgejo) + - [PR](https://codeberg.org/forgejo/forgejo/pulls/6306): Update module github.com/blevesearch/bleve/v2 to v2.4.4 (forgejo) + - [PR](https://codeberg.org/forgejo/forgejo/pulls/6305): Update dependency tailwindcss to v3.4.17 (forgejo) + - [PR](https://codeberg.org/forgejo/forgejo/pulls/6304): Update dependency katex to v0.16.17 (forgejo) + - [PR](https://codeberg.org/forgejo/forgejo/pulls/6303): Update dependency eslint-plugin-import-x to v4.5.1 (forgejo) + - [PR](https://codeberg.org/forgejo/forgejo/pulls/6301): Replace actions/cascading-pr action with actions/cascading-pr v2.1.1 (forgejo) + - [PR](https://codeberg.org/forgejo/forgejo/pulls/6299): chore: Make Forgejo build with go1.24 + - [PR](https://codeberg.org/forgejo/forgejo/pulls/6298): Update actions/setup-forgejo action to v2 (forgejo) + - [PR](https://codeberg.org/forgejo/forgejo/pulls/6296): Add readme to locale folder + - [PR](https://codeberg.org/forgejo/forgejo/pulls/6295): Update module google.golang.org/protobuf to v1.36.0 (forgejo) + - [PR](https://codeberg.org/forgejo/forgejo/pulls/6293): Update dependency eslint-plugin-sonarjs to v3 (forgejo) + - [PR](https://codeberg.org/forgejo/forgejo/pulls/6292): Update linters (forgejo) + - [PR](https://codeberg.org/forgejo/forgejo/pulls/6291): Update module github.com/golangci/golangci-lint/cmd/golangci-lint to v1.62.2 (forgejo) + - [PR](https://codeberg.org/forgejo/forgejo/pulls/6290): Update dependency @vitest/eslint-plugin to v1.1.16 (forgejo) + - [PR](https://codeberg.org/forgejo/forgejo/pulls/6288): Some improvements to base locale + - [PR](https://codeberg.org/forgejo/forgejo/pulls/6287): Don't notify when a user self-request as reviewer + - [PR](https://codeberg.org/forgejo/forgejo/pulls/6282): Update module github.com/go-chi/chi/v5 to v5.2.0 (forgejo) + - [PR](https://codeberg.org/forgejo/forgejo/pulls/6281): Update actions/cascading-pr action to v2.2.0 (forgejo) + - [PR](https://codeberg.org/forgejo/forgejo/pulls/6278): Update renovate to v39.69.2 (forgejo) + - [PR](https://codeberg.org/forgejo/forgejo/pulls/6264): Update forgejo/forgejo-build-publish action to v5.2.1 (forgejo) + - [PR](https://codeberg.org/forgejo/forgejo/pulls/6260): Update module golang.org/x/tools/gopls to v0.17.0 (forgejo) + - [PR](https://codeberg.org/forgejo/forgejo/pulls/6259): Update dependency @primer/octicons to v19.14.0 (forgejo) + - [PR](https://codeberg.org/forgejo/forgejo/pulls/6258): Update module github.com/gliderlabs/ssh to v0.3.8 (forgejo) + - [PR](https://codeberg.org/forgejo/forgejo/pulls/6256): chore(release-notes): Forgejo v9.0.3 [skip ci] + - [PR](https://codeberg.org/forgejo/forgejo/pulls/6255): chore(release-notes): Forgejo v7.0.12 [skip ci] + - [PR](https://codeberg.org/forgejo/forgejo/pulls/6254): Use correct title for container images + - [PR](https://codeberg.org/forgejo/forgejo/pulls/6245): Adjust MySQL instruction + - [PR](https://codeberg.org/forgejo/forgejo/pulls/6243): Update module golang.org/x/crypto to v0.31.0 (forgejo) + - [PR](https://codeberg.org/forgejo/forgejo/pulls/6237): Avoid having to store i18n linter exceptions for + - [PR](https://codeberg.org/forgejo/forgejo/pulls/6234): Update github.com/grafana/go-json digest to a119ee5 (forgejo) + - [PR](https://codeberg.org/forgejo/forgejo/pulls/6233): Add missing automerge feed message + - [PR](https://codeberg.org/forgejo/forgejo/pulls/6229): Update dependency katex to v0.16.15 (forgejo) + - [PR](https://codeberg.org/forgejo/forgejo/pulls/6227): Replace actions/setup-forgejo action with actions/setup-forgejo v1.0.1 (forgejo) + - [PR](https://codeberg.org/forgejo/forgejo/pulls/6226): Replace actions/cascading-pr action with actions/cascading-pr v2.1.1 (forgejo) + - [PR](https://codeberg.org/forgejo/forgejo/pulls/6223): chore(ci): set the milestone when a pull request is closed (take 4) + - [PR](https://codeberg.org/forgejo/forgejo/pulls/6222): Clipboard read permission for Chromium + - [PR](https://codeberg.org/forgejo/forgejo/pulls/6221): Add `-` as reserved user + - [PR](https://codeberg.org/forgejo/forgejo/pulls/6219): chore(ci): set the milestone when a pull request is open (take 3) + - [PR](https://codeberg.org/forgejo/forgejo/pulls/6213): chore(ci): set the milestone when a pull request is open (take 2) + - [PR](https://codeberg.org/forgejo/forgejo/pulls/6211): chore(ci): set the milestone when a pull request is open [skip ci] + - [PR](https://codeberg.org/forgejo/forgejo/pulls/6210): Update dependency forgejo-lxc to v12 (forgejo) + - [PR](https://codeberg.org/forgejo/forgejo/pulls/6206): Cleanup `package/arch` route + - [PR](https://codeberg.org/forgejo/forgejo/pulls/6205): Update dependency katex to v0.16.14 (forgejo) + - [PR](https://codeberg.org/forgejo/forgejo/pulls/6204): Update renovate to v39.57.4 (forgejo) + - [PR](https://codeberg.org/forgejo/forgejo/pulls/6202): nix-dev-improvements + - [PR](https://codeberg.org/forgejo/forgejo/pulls/6201): Simplify main-attribute labels + - [PR](https://codeberg.org/forgejo/forgejo/pulls/6199): feat(secret): generate FORGEJO_TOKEN for all tasks + - [PR](https://codeberg.org/forgejo/forgejo/pulls/6196): Rebrand help text in `forgejo migrate` #6194 + - [PR](https://codeberg.org/forgejo/forgejo/pulls/6191): Do not offer duplicating a PR for a recently pushed branch + - [PR](https://codeberg.org/forgejo/forgejo/pulls/6190): Update x/tools to v0.28.0 (forgejo) + - [PR](https://codeberg.org/forgejo/forgejo/pulls/6188): don't specify FOR clause for index hint + - [PR](https://codeberg.org/forgejo/forgejo/pulls/6182): chore(ci): common issue-labels name for all related workflows + - [PR](https://codeberg.org/forgejo/forgejo/pulls/6178): Revert "chore(ci): merge jobs in issue-labels.yml in one workflow" + - [PR](https://codeberg.org/forgejo/forgejo/pulls/6177): chore(ci): docker-runner-one is not a known label + - [PR](https://codeberg.org/forgejo/forgejo/pulls/6175): Update module golang.org/x/net to v0.32.0 (forgejo) + - [PR](https://codeberg.org/forgejo/forgejo/pulls/6172): Update dependency webpack to v5.97.1 (forgejo) + - [PR](https://codeberg.org/forgejo/forgejo/pulls/6171): Update dependency @github/relative-time-element to v4.4.4 (forgejo) + - [PR](https://codeberg.org/forgejo/forgejo/pulls/6165): chore(release-notes): keep release notes in release-notes-published + - [PR](https://codeberg.org/forgejo/forgejo/pulls/6160): Update module golang.org/x/image to v0.23.0 (forgejo) + - [PR](https://codeberg.org/forgejo/forgejo/pulls/6159): Update module golang.org/x/crypto to v0.30.0 (forgejo) + - [PR](https://codeberg.org/forgejo/forgejo/pulls/6157): Update dependency @primer/octicons to v19.13.0 (forgejo) + - [PR](https://codeberg.org/forgejo/forgejo/pulls/6153): highlight Gradle Kotlin as Kotlin + - [PR](https://codeberg.org/forgejo/forgejo/pulls/6152): remove softbreak from github legacy callout + - [PR](https://codeberg.org/forgejo/forgejo/pulls/6151): build: only require go minor + - [PR](https://codeberg.org/forgejo/forgejo/pulls/6150): Update module code.forgejo.org/go-chi/session to v1.0.1 (forgejo) + - [PR](https://codeberg.org/forgejo/forgejo/pulls/6148): Update module code.forgejo.org/go-chi/captcha to v1.0.1 (forgejo) + - [PR](https://codeberg.org/forgejo/forgejo/pulls/6145): Update dependency go to v1.23.4 (forgejo) + - [PR](https://codeberg.org/forgejo/forgejo/pulls/6144): correct permission loading for limited organisation + - [PR](https://codeberg.org/forgejo/forgejo/pulls/6140): Update dependency webpack to v5.97.0 (forgejo) + - [PR](https://codeberg.org/forgejo/forgejo/pulls/6139): Update dependency tailwindcss to v3.4.16 (forgejo) + - [PR](https://codeberg.org/forgejo/forgejo/pulls/6137): Update fnetx/setup-cache-go digest to 4b50dd2 (forgejo) + - [PR](https://codeberg.org/forgejo/forgejo/pulls/6136): build: relax required go version for local development + - [PR](https://codeberg.org/forgejo/forgejo/pulls/6130): avoid sorting for `MakeSelfOnTop` + - [PR](https://codeberg.org/forgejo/forgejo/pulls/6128): clean up log files that no longer exist + - [PR](https://codeberg.org/forgejo/forgejo/pulls/6120): chore(ci): run merge conditions when a new commit is pushed + - [PR](https://codeberg.org/forgejo/forgejo/pulls/6119): Lock file maintenance (forgejo) + - [PR](https://codeberg.org/forgejo/forgejo/pulls/6118): Update dependency globals to v15.13.0 (forgejo) + - [PR](https://codeberg.org/forgejo/forgejo/pulls/6117): Regular visual regression testing + - [PR](https://codeberg.org/forgejo/forgejo/pulls/6115): Update renovate to v39.42.4 (forgejo) + - [PR](https://codeberg.org/forgejo/forgejo/pulls/6114): return correct type in `GetSubModule` + - [PR](https://codeberg.org/forgejo/forgejo/pulls/6113): Rework GetLatestCommitStatusForPairs query using a subquery for PG compatibility + - [PR](https://codeberg.org/forgejo/forgejo/pulls/6109): Update dependency happy-dom to v15.11.7 (forgejo) + - [PR](https://codeberg.org/forgejo/forgejo/pulls/6108): Update dependency djlint to v1.36.3 (forgejo) + - [PR](https://codeberg.org/forgejo/forgejo/pulls/6107): Update dependency @vitest/eslint-plugin to v1.1.13 (forgejo) + - [PR](https://codeberg.org/forgejo/forgejo/pulls/6106): Update dependency @stoplight/spectral-cli to v6.14.2 (forgejo) + - [PR](https://codeberg.org/forgejo/forgejo/pulls/6095): Update dependency sortablejs to v1.15.6 (forgejo) + - [PR](https://codeberg.org/forgejo/forgejo/pulls/6090): chore(i18): cleanup locales + - [PR](https://codeberg.org/forgejo/forgejo/pulls/6089): typos, mostly from `codespell`, others just by eyeballing + - [PR](https://codeberg.org/forgejo/forgejo/pulls/6088): Update dependency sortablejs to v1.15.5 (forgejo) + - [PR](https://codeberg.org/forgejo/forgejo/pulls/6087): Update dependency mermaid to v11.4.1 (forgejo) + - [PR](https://codeberg.org/forgejo/forgejo/pulls/6084): normalize guessed languages from enry + - [PR](https://codeberg.org/forgejo/forgejo/pulls/6083): improve wording of limited visibility + - [PR](https://codeberg.org/forgejo/forgejo/pulls/6082): Update dependency chartjs-plugin-zoom to v2.2.0 (forgejo) + - [PR](https://codeberg.org/forgejo/forgejo/pulls/6071): Use user.FullName in Oauth2 id_token response + - [PR](https://codeberg.org/forgejo/forgejo/pulls/6067): Lock file maintenance (forgejo) + - [PR](https://codeberg.org/forgejo/forgejo/pulls/6066): Update dependency sortablejs to v1.15.4 (forgejo) + - [PR](https://codeberg.org/forgejo/forgejo/pulls/6065): Update renovate to v39.28.0 (forgejo) + - [PR](https://codeberg.org/forgejo/forgejo/pulls/6059): Improve colors used by colorblind-friendly forgejo themes + - [PR](https://codeberg.org/forgejo/forgejo/pulls/6058): Update module github.com/stretchr/testify to v1.10.0 (forgejo) + - [PR](https://codeberg.org/forgejo/forgejo/pulls/6052): Show page titles in wiki search results (#6048) + - [PR](https://codeberg.org/forgejo/forgejo/pulls/6050): Improve Swagger documentation for user endpoints + - [PR](https://codeberg.org/forgejo/forgejo/pulls/6049): Update dependency typescript to v5.7.2 (forgejo) + - [PR](https://codeberg.org/forgejo/forgejo/pulls/6046): ci: use more `tmpfs` and `noatime` for faster CI + - [PR](https://codeberg.org/forgejo/forgejo/pulls/6045): test: fix e2e test + - [PR](https://codeberg.org/forgejo/forgejo/pulls/6034): chore(ci): remove unused experimental DNS updates + - [PR](https://codeberg.org/forgejo/forgejo/pulls/6029): bug: git notes edit/remove button displayed to anonymous visitors + - [PR](https://codeberg.org/forgejo/forgejo/pulls/6027): Apply smaller padding to comment headers + - [PR](https://codeberg.org/forgejo/forgejo/pulls/6025): Improve git notes UI + - [PR](https://codeberg.org/forgejo/forgejo/pulls/6023): Update dependency chartjs-plugin-zoom to v2.1.0 (forgejo) + - [PR](https://codeberg.org/forgejo/forgejo/pulls/6021): chore(ci): merge jobs issue label jobs in one workflow + - [PR](https://codeberg.org/forgejo/forgejo/pulls/6020): chore(ci): make release-notes-assistant job copy/pastable (part two) + - [PR](https://codeberg.org/forgejo/forgejo/pulls/6019): chore(ci): make release-notes-assistant job copy/pastable + - [PR](https://codeberg.org/forgejo/forgejo/pulls/6013): fix(test): TestGitAttributeCheckerError must allow broken pipe + - [PR](https://codeberg.org/forgejo/forgejo/pulls/6010): Lock file maintenance (forgejo) + - [PR](https://codeberg.org/forgejo/forgejo/pulls/6008): Update renovate to v39.19.1 (forgejo) + - [PR](https://codeberg.org/forgejo/forgejo/pulls/6006): vertical center the date on GPG keys + - [PR](https://codeberg.org/forgejo/forgejo/pulls/6003): chore(release-notes-assistant): security fix / features come first + - [PR](https://codeberg.org/forgejo/forgejo/pulls/6002): chore(ci): make backporting job copy/pastable + - [PR](https://codeberg.org/forgejo/forgejo/pulls/6001): chore(ci): make merge-conditions job copy/pastable + - [PR](https://codeberg.org/forgejo/forgejo/pulls/6000): chore(ci): make end-to-end job copy/pastable + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5996): check read permissions for code owner review requests + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5995): remember fuzzy for open/close state + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5994): Revert defaulting to EdDSA + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5991): api repo compare with commit hashes + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5989): use better code to group UID and stopwatches + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5987): Default to generating EdDSA for OAuth JWT signing key + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5986): bug: correctly generate oauth2 jwt signing key + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5984): extend `forgejo_auth_token` table (part two) + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5983): improve `GetLatestCommitStatusForPairs` + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5981): Update dependency vue to v3.5.13 (forgejo) + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5980): Update github.com/grafana/go-json digest to f14426c (forgejo) + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5978): chore(release-notes): fix the v9.0.2 links + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5977): chore: fix e2e + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5973): ci: upload all e2e artifacts + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5969): Update module google.golang.org/grpc to v1.68.0 (forgejo) + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5968): test: fix e2e tests + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5966): Update dependency tailwindcss to v3.4.15 (forgejo) + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5965): use oci mirror for `tonistiigi/xx` image + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5964): ci: proper job name + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5963): ci: use oci mirror images + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5962): ci: disable postgresql fsync + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5958): ci: use tmpfs for service storage + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5957): ci: disable mysql binlog + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5956): test: use sqlite in-memory db for integration + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5955): test: add trailing newline to `testlogger.go:recordError` message + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5954): chore: improve slow tests + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5951): chore(i18n): allow datnes nosaukums for filename (Latvian) + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5949): Update module code.forgejo.org/forgejo/act to v1.22.0 (forgejo) + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5948): chore: improve preparing tests + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5946): Update module github.com/blevesearch/bleve/v2 to v2.4.3 (forgejo) + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5944): chore(ci): ROLE forgejo-coding & forgejo-testing (part two) + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5943): chore(release-notes): update the v9.0.2 & v7.0.11 links + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5942): chore(ci): ROLE forgejo-coding & forgejo-testing + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5935): chore(renovate): throttle down upgrade of linters & test packages + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5934): Update linters (forgejo) + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5933): Update dependency @stoplight/spectral-cli to v6.14.0 (forgejo) + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5932): Update dependency happy-dom to v15.11.4 (forgejo) + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5931): Update dependency @vitest/eslint-plugin to v1.1.10 (forgejo) + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5929): tests(e2e): Refactor various tests + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5928): chore(lint): Ignore playwright reports for linting + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5924): fix(ci): synchronize updates the commit status asynchronously + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5923): chore(renovate): always set the test/not-needed label + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5922): Update module github.com/buildkite/terminal-to-html/v3 to v3.16.4 (forgejo) + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5921): Update dependency postcss to v8.4.49 (forgejo) + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5920): Update dependency happy-dom to v15.11.2 (forgejo) + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5919): Update dependency @axe-core/playwright to v4.10.1 (forgejo) + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5916): chore(e2e): Update global patterns + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5913): chore: set recommend vscode settings for golangci-lint + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5912): test: fix test linting + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5911): Update module github.com/golangci/golangci-lint/cmd/golangci-lint to v1.62.0 (forgejo) + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5910): Update dependency @vitejs/plugin-vue to v5.1.5 (forgejo) + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5909): Re-add least recently updated as sort order + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5908): Update dependency postcss to v8.4.48 (forgejo) + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5907): Update renovate to v39.9.1 (forgejo) + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5906): chore: improve database docker instructions + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5904): chore: improve test quality + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5903): chore: simplify CopyDir + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5896): fix(ci): only trigger end-to-end tests when the label is set + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5892): Proper parsing of date for git commits + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5890): Update module golang.org/x/net to v0.31.0 (forgejo) + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5888): chore: lazy-loaded version of goccy/go-json + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5886): chore(ci): Enforce test label with CI check + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5885): fix(ui): Details icon in repo settings sidebar + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5883): Update module golang.org/x/crypto to v0.29.0 (forgejo) + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5881): [THEME] Copy ansi terminal colours from gitea to forgejo themes + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5878): fix(ci): slow runners may need more than 50 minutes for a test + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5869): bug: require.Eventually must not test with assert + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5865): Update module code.forgejo.org/go-chi/session to v1 (forgejo) + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5864): Update module code.forgejo.org/go-chi/captcha to v1 (forgejo) + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5863): Update module code.forgejo.org/go-chi/cache to v1 (forgejo) + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5862): Update module code.forgejo.org/go-chi/binding to v1 (forgejo) + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5858): chore(renovate): only run if renovate workflow changed + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5857): chore(renovate): update settings + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5843): issue labels are not set after deleting one label + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5840): Update dependency happy-dom to v15.11.0 (forgejo) + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5837): Update dependency eslint-plugin-playwright to v2.0.1 (forgejo) + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5836): Update dependency go to v1.23.3 (forgejo) + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5835): Make direnv optional to let developers use their own direnv configuration + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5832): chore(renovate): fix regex + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5830): chore(renovate): use squash for automerge + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5829): Update renovate to v39 (forgejo) (major) + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5825): Update dependency happy-dom to v15.10.1 (forgejo) + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5824): Update dependency djlint to v1.36.0 (forgejo) + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5820): chore(ci): deprecate legacy infrastructure supporting v*.next + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5817): test: enable gitea migration tests + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5816): test: enable github migration tests + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5815): Update linters to v8.13.0 (forgejo) + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5814): Update dependency globals to v15.12.0 (forgejo) + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5813): Update dependency happy-dom to v15.9.0 (forgejo) + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5804): Lock file maintenance (forgejo) + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5803): Update dependency happy-dom to v15.8.3 (forgejo) + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5802): Update renovate to v38.142.5 (forgejo) + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5796): [PORT] Replace DateTime with proper functions (gitea#32402) + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5795): support `www.github.com` for migrations + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5794): [PORT] Fix git error handling (gitea#32401) + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5793): [PORT] Refactor the DB migration system slightly (gitea#32344) + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5792): [PORT] Fix toAbsoluteLocaleDate and add more tests (gitea#32387) + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5791): [PORT] Fix a number of typescript issues (gitea#32308) + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5790): [PORT] Refactor tests to prevent from unnecessary preparations (gitea#32398) + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5788): chore(cleanup): remove unused TestCreateFile + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5784): Update dependency eslint-plugin-array-func to v5 (forgejo) + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5783): Update module github.com/gorilla/sessions to v1.4.0 (forgejo) + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5782): Update actions/git-backporting action to v4.8.4 (forgejo) + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5780): Update module github.com/yuin/goldmark to v1.7.8 (forgejo) + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5779): support color dots for 4 character hex. + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5775): Update module github.com/fsnotify/fsnotify to v1.8.0 (forgejo) + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5774): Update linters (forgejo) + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5773): Update dependency happy-dom to v15.8.0 (forgejo) + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5772): Update dependency djlint to v1.35.4 (forgejo) + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5771): tests: improve actvititypub integration test code + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5769): Revert: chore(ci): Enforce test label with CI check + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5768): chore(renovate): explicit base branches + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5767): Improvements to some English strings + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5766): Update infrastructure/next-digest action to v1.1.0 (forgejo) + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5764): Update dependency webpack to v5.96.1 (forgejo) + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5763): Update dependency mini-css-extract-plugin to v2.9.2 (forgejo) + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5762): Update module code.forgejo.org/forgejo/act to v1.21.5 (forgejo) + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5756): chore(ci): Enforce test label with CI check + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5755): chore(ci): use rootless for the container images sent to k8s + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5750): Update dependency djlint to v1.35.3 (forgejo) + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5747): chore(ci): notify the k8s cluster about experimental releases + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5738): Update module github.com/meilisearch/meilisearch-go to v0.29.0 (forgejo) + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5737): Update vitest monorepo to v2.1.4 (forgejo) + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5734): refactor: Migrate playwright to typescript + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5732): chore(release): also copy the release to code.forgejo.org + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5729): docs: add links to the v7.0.10 & v9.0.1 release notes + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5717): Lock file maintenance (forgejo) + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5716): Update renovate to v38.133.0 (forgejo) + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5713): i18n: fix placeholders in string for refusing to review + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5712): Link back to one-time code page from scratch code page + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5705): Update linters (forgejo) + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5704): Update dependency @playwright/test to v1.48.2 (forgejo) + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5703): harden localization against malicious HTML + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5702): use buffered iterate for debian searchpackages + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5698): Update internationalization label in release-notes-assistant + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5692): tests(e2e): skip browser downloads + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5690): Add typescript support + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5688): make branch protection work for new branches + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5685): chore: output playwright directly to std{out,err} + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5684): reset `history.scrollRestoration` if set to `manual` and no issue anchor in url + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5678): Update dependency postcss-nesting to v13.0.1 (forgejo) + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5669): Update dependency eslint-plugin-playwright to v2 (forgejo) + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5668): chore: remove eslint v9 restriction in renovate + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5665): Update module github.com/jhillyerd/enmime to v2 (forgejo) + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5664): Update dependency postcss-nesting to v13 (forgejo) + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5663): Update dependency eslint-plugin-unicorn to v56 (forgejo) + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5662): chore: move to Eslint flat config + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5657): use combo markdown editor for milestone description + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5653): don't show truncated comments in RSS/Atom feeds + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5652): typo on releases for source code downloads + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5651): link to security policy in security.txt + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5646): chore(release-notes): no need to specify they are draft + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5644): conf: Improve delete_old_actions description + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5641): make syncronize tags to database handle annoted tags + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5640): Revert "add gap between branch dropdown and PR button" + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5638): Better messages for cases of private profiles + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5637): feat(ci): allow manual triggering of the test suite + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5633): Lock file maintenance (forgejo) + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5632): Update renovate to v38.128.6 (forgejo) + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5625): fix(i18n): edit should not be lowercase here + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5617): Create temporary user helper function + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5615): Don't double escape delete branch text + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5608): Update code.forgejo.org/go-chi/session digest to 2a99226 (forgejo) + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5595): Add server logging for OAuth server errors + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5592): forgejo-cli is now a symlink and cannot be used for sanity checks + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5591): Update dependency @primer/octicons to v19.12.0 (forgejo) + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5590): Update dependency @playwright/test to v1.48.1 (forgejo) + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5578): Update module github.com/buildkite/terminal-to-html/v3 to v3.16.3 (forgejo) + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5576): Update dependency chart.js to v4.4.5 (forgejo) + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5569): Update vitest monorepo to v2.1.3 (forgejo) + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5568): Update module github.com/redis/go-redis/v9 to v9.6.2 (forgejo) + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5563): Update security option in issue template + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5561): Fix typo in English locale file + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5560): regression from #4125 + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5555): i18n: update of translations from Codeberg Translate + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5554): Fix typo in #5537 + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5550): Update module github.com/urfave/cli/v2 to v2.27.5 (forgejo) + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5549): Update renovate to v38.121.0 (forgejo) + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5541): Update module github.com/minio/minio-go/v7 to v7.0.78 (forgejo) + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5540): Update module github.com/klauspost/compress to v1.17.11 (forgejo) + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5539): Update dependency vue to v3.5.12 (forgejo) + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5537): i18n: Improve translation strings for webhook events + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5536): use column flex on mobile to prevent project title from wrapping + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5533): i18n: remove unnecessary variable + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5530): Make chroma match case-insenstive + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5523): i18n: Fine tune language for units + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5522): Update dependency @github/text-expander-element to v2.8.0 (forgejo) + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5514): i18n: update of translations from Codeberg Translate + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5511): Update x/tools to v0.26.0 (forgejo) + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5510): Update module google.golang.org/protobuf to v1.35.1 (forgejo) + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5509): Update module golang.org/x/sys to v0.26.0 (forgejo) + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5508): Update module golang.org/x/net to v0.30.0 (forgejo) + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5506): Do not change stroke size in the loading animation + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5505): Small fixes and rename for #5482 + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5503): update git book link to v2 + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5502): Update module golang.org/x/image to v0.21.0 (forgejo) + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5501): Update dependency @playwright/test to v1.48.0 (forgejo) + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5498): Update actions/cache action to v4.1.1 (forgejo) + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5495): Update dependency eslint-plugin-wc to v2.2.0 (forgejo) + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5494): Update dependency @vitest/eslint-plugin to v1.1.7 (forgejo) + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5493): Update actions/git-backporting action to v4.8.2 (forgejo) + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5491): correct documentation for non 200 responses in swagger + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5485): chore(ci): update changed-files actions URL for consistency + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5483): Update renovate to v38.110.2 (forgejo) + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5482): "Assign to me" button on PR and Issues #5215 + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5479): Improve 'Verify' error message, stopgap for #2809 + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5476): Update dependency @stylistic/eslint-plugin-js to v2.9.0 (forgejo) + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5474): Update actions/cache action to v4.1.0 (forgejo) + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5473): Update module github.com/mattn/go-sqlite3 to v1.14.24 (forgejo) + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5472): "forked from" note alignment on 404 error pages #5324 + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5471): i18n: update of translations from Codeberg Translate + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5467): Update dependency @vitest/eslint-plugin to v1.1.6 (forgejo) + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5466): Update dependency @stylistic/stylelint-plugin to v3.1.1 (forgejo) + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5458): Update dependency vue to v3.5.11 (forgejo) + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5456): log concise repo names in lfs doctor + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5454): Update vitest monorepo to v2.1.2 (forgejo) + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5453): Update module github.com/caddyserver/certmagic to v0.21.4 (forgejo) + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5452): Update dependency @vitest/eslint-plugin to v1.1.5 (forgejo) + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5450): ci/tests(e2e): always run e2e tests, but only on changed files + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5449): Update dependency go to v1.23.2 (forgejo) + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5441): Update actions/setup-go action to v5 (forgejo) + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5437): Update ghcr.io/devcontainers/features/git-lfs Docker tag to v1.2.3 (forgejo) + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5436): Update dependency eslint-plugin-sonarjs to v2.0.3 (forgejo) + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5435): Update github.com/google/pprof digest to 017d972 (forgejo) + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5434): chore: remove spurious comment in tests + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5430): referenced sha256:* container images may be deleted + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5428): Update actions/setup-node action to v4 (forgejo) + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5427): Update actions/checkout action to v4 (forgejo) + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5426): Update actions/cache action to v4 (forgejo) + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5424): Lock file maintenance (forgejo) + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5422): Update renovate to v38.101.1 (forgejo) + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5421): ci: move composite workflow location + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5415): document sqlite3 as suggested database + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5413): i18n: update of translations from Codeberg Translate + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5411): Update dependency webpack to v5.95.0 (forgejo) + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5410): ci: Move preparations to local actions + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5405): Update dependency markdownlint-cli to v0.42.0 (forgejo) + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5404): Update dependency @vitest/eslint-plugin to v1.1.4 (forgejo) + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5403): Update dependency @stylistic/stylelint-plugin to v3.1.0 (forgejo) + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5402): Update dependency vue to v3.5.10 (forgejo) + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5398): Update module github.com/minio/minio-go/v7 to v7.0.77 (forgejo) + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5397): Update module github.com/klauspost/compress to v1.17.10 (forgejo) + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5396): Update dependency @github/text-expander-element to v2.7.2 (forgejo) + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5395): Update citation-js monorepo (forgejo) + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5391): docs: add link to the v9.0.0 release notes + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5389): mail issue: Display issue type in email header + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5374): Update dependency monaco-editor to v0.51.0 (forgejo) + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5370): Update module google.golang.org/grpc to v1.67.1 (forgejo) + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5355): i18n: update of translations from Codeberg Translate + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5353): Remove some Windows-specific files + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5351): Add architecture-specific removal support for arch package + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5328): ci: use custom action for Go caching + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5294): tests(e2e): Refactor branch protection test + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5249): Makefile: support gotestsum + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5240): Update module github.com/prometheus/client_golang to v1.20.5 (forgejo) + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5158): use ValidateEmail as binding across web forms +- Already announced in the release notes of an older stable release + - [PR](https://codeberg.org/forgejo/forgejo/pulls/6249): Revert "allow synchronizing user status from OAuth2 login providers (#31572)" + - [PR](https://codeberg.org/forgejo/forgejo/pulls/6248): ensure correct ssh public key is used for authentication + - [PR](https://codeberg.org/forgejo/forgejo/pulls/6124): doctor fails with pq: syntax error at or near "." whilst counting Authorization token without existing User + - [PR](https://codeberg.org/forgejo/forgejo/pulls/6097): Do not rewrite ssh keys files when deleting a user without one + - [PR](https://codeberg.org/forgejo/forgejo/pulls/6054): Do not delete global Oauth2 applications + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5974): [commit](https://codeberg.org/forgejo/forgejo/commit/1ce33aa38d1d258d14523ff2c7c2dbf339f22b74) it was possible to use a token sent via email for secondary email validation to reset the password instead. In other words, a token sent for a given action (registration, password reset or secondary email validation) could be used to perform a different action. It is no longer possible to use a token for an action that is different from its original purpose. + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5974): [commit](https://codeberg.org/forgejo/forgejo/commit/061abe60045212acf8c3f5c49b5cc758b4cbcde9) a fork of a public repository would show in the list of forks, even if its owner was not a public user or organization. Such a fork is now hidden from the list of forks of the public repository. + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5974): [commit](https://codeberg.org/forgejo/forgejo/commit/3e3ef76808100cb1c853378733d0f6a910324ac6) the members of an organization team with read access to a repository (e.g. to read issues) but no read access to the code could read the RSS or atom feeds which include the commit activity. Reading the RSS or atom feeds is now denied unless the team has read permissions on the code. + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5974): [commit](https://codeberg.org/forgejo/forgejo/commit/9508aa7713632ed40124a933d91d5766cf2369c2) the tokens used when [replying by email to issues or pull requests](https://forgejo.org/docs/v9.0/user/incoming/) were weaker than the [rfc2104 recommendations](https://datatracker.ietf.org/doc/html/rfc2104#section-5). The tokens are now truncated to 128 bits instead of 80 bits. It is no longer possible to reply to emails sent before the upgrade because the weaker tokens are invalid. + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5974): [commit](https://codeberg.org/forgejo/forgejo/commit/786dfc7fb81ee76d4292ca5fcb33e6ea7bdccc29) a registered user could modify the update frequency of any push mirror (e.g. every 4h instead of every 8h). They are now only able to do that if they have administrative permissions on the repository. + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5974): [commit](https://codeberg.org/forgejo/forgejo/commit/e6bbecb02d47730d3cc630d419fe27ef2fb5cb39) it was possible to use basic authorization (i.e. user:password) for requests to the API even when security keys were enrolled for a user. It is no longer possible, an application token must be used instead. + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5974): [commit](https://codeberg.org/forgejo/forgejo/commit/7067cc7da4f144cc8a2fd2ae6e5307e0465ace7f) some markup sanitation rules were not as strong as they could be (e.g. allowing `emoji somethingelse` as well as `emoji`). The rules are now stricter and do not allow for such cases. + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5974): [commit](https://codeberg.org/forgejo/forgejo/commit/b70196653f9d7d3b9d4e72d114e5cc6f472988c4) when Forgejo is configured to enable instance wide search (e.g. with [bleve](https://blevesearch.com/)), results found in the repositories of private or limited users were displayed to anonymous visitors. The results found in private or limited organizations were not displayed. The search results found in the repositories of private or limited user are no longer displayed to anonymous visitors. + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5941): handle renamed dependency for cargo registry + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5850): [PORT] Fix code owners will not be mentioned when a pull request comes from a forked repository (gitea#30476) + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5831): labels are missing in the pull request payload removing a label + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5778): In a Forgejo Actions workflow, the `unlabeled` event type for pull requests was incorrectly mapped to the labeled event type. + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5778): When a Forgejo Actions issue or pull request workflow is triggered by an `labeled` or `unlabeled` event type, it misses information about the label added or removed. It is now available in the `label` data member of the event payload. + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5778): The pull request workflow must always update the head SHA commit status. Not just when the PR is synchronized, opened or closed. Otherwise it makes it impossible to define a job to be a required check (for instance a job that is triggered when labels are modified and verifies that a given combination is present). + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5746): git-grep for code search when git version is below 2.38 + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5719): Forgejo generates a token which is used to authenticate web endpoints that are only meant to be used internally, for instance when the SSH daemon is used to push a commit with Git. The verification of this token was not done in constant time and was susceptible to [timing attacks](https://en.wikipedia.org/wiki/Timing_attack). A pre-condition for such an attack is the precise measurements of the time for each operation. Since it requires observing the timing of network operations, the issue is mitigated when a Forgejo instance is accessed over the internet because the ISP introduce unpredictable random delays. + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5718): Because of a missing permission check, the branch used to propose a pull request to a repository can always be deleted by the user performing the merge. It was fixed so that such a deletion is only allowed if the user performing the merge has write permission to the repository from which the pull request was made. + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5634): package arch database not updating when uploading "any" architecture + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5627): correct SQL query for active issues + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5626): specify default value for `EXPLORE_DEFAULT_SORT`. + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5613): Add `recentupdated` as recognized sort option + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5587): Dockerfile: use alpine:3.20 instead of golang:1.23-alpine3.20 + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5585): Dockerfile: unnecessary container image layer duplication + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5529): Don't allow owner team with incorrect unit access (includes doctor fix) + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5515): **Fixing this bug is a breaking change because existing tokens with a public scope will no longer return private resources. They have to be deleted and re-created without the public scope to restore their original behavior**. The public scope of an application token does not filter out private repositories, organizations or packages in some cases. This scope is not the default, it has to be manually set via the web UI or the API. When the public scope is explicitly added to an application token that is allowed to list the repositories and packages of a user or an organization, it is meant as a restriction. For instance if a user has two repositories, one private and the other publicly visible, a token with the public scope used with the API endpoint listing the repositories that belong to this user must only return the publicly visible one and not reveal the existence of the private one. + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5492): correct Discord webhook JSON for issue events + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5470): don't cancel schedule workflows on push to main branch + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5439): Fix boolean inputs in workflow_dispatch + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5372): [commit](https://codeberg.org/forgejo/forgejo/commit/f709de24039ab7e605d3e09e3b61240836381603) Fix wrong last modify time. + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5372): [commit](https://codeberg.org/forgejo/forgejo/commit/2675a24649af2fff34f5c7e416d6ff78591d8d9c) Repo Activity: count new issues that were closed. + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5372): [commit](https://codeberg.org/forgejo/forgejo/commit/526054332acb221e061d3900bba2dc6e012da52d) Fix incorrect /tokens api. + - [PR](https://codeberg.org/forgejo/forgejo/pulls/5372): [commit](https://codeberg.org/forgejo/forgejo/commit/0cafec4c7a2faf810953e9d522faf5dc019e1522) Do not escape relative path in RPM primary index. + From 92a5fe04c614e267e7f78b9b847aa7aede306069 Mon Sep 17 00:00:00 2001 From: 0ko <0ko@noreply.codeberg.org> Date: Wed, 15 Jan 2025 07:40:18 +0000 Subject: [PATCH 149/198] Squash translation updates --- release-notes-published/10.0.0.md | 15 ++------------- 1 file changed, 2 insertions(+), 13 deletions(-) diff --git a/release-notes-published/10.0.0.md b/release-notes-published/10.0.0.md index adc9928dfd..850e57a26b 100644 --- a/release-notes-published/10.0.0.md +++ b/release-notes-published/10.0.0.md @@ -33,21 +33,10 @@ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5838): Move "forgot_password"-link to fix login tab order - [PR](https://codeberg.org/forgejo/forgejo/pulls/5697): Update help links on page with no workflows - Localization - - [PR](https://codeberg.org/forgejo/forgejo/pulls/6566): i18n: update of translations from Codeberg Translate - - [PR](https://codeberg.org/forgejo/forgejo/pulls/6514): i18n: update of translations from Codeberg Translate - - [PR](https://codeberg.org/forgejo/forgejo/pulls/6378) ([backported](https://codeberg.org/forgejo/forgejo/pulls/6450)): i18n: update of translations from Codeberg Translate - - [PR](https://codeberg.org/forgejo/forgejo/pulls/6331) ([backported](https://codeberg.org/forgejo/forgejo/pulls/6377)): i18n: update of translations from Codeberg Translate - - [PR](https://codeberg.org/forgejo/forgejo/pulls/6242): i18n: update of translations from Codeberg Translate - - [PR](https://codeberg.org/forgejo/forgejo/pulls/6161): i18n: update of translations from Codeberg Translate - - [PR](https://codeberg.org/forgejo/forgejo/pulls/6091): i18n: update of translations from Codeberg Translate - [PR](https://codeberg.org/forgejo/forgejo/pulls/6072): Add Low German to list of default languages - - [PR](https://codeberg.org/forgejo/forgejo/pulls/6041): i18n: update of translations from Codeberg Translate - - [PR](https://codeberg.org/forgejo/forgejo/pulls/5960): i18n: update of translations from Codeberg Translate - - [PR](https://codeberg.org/forgejo/forgejo/pulls/5845): i18n: update of translations from Codeberg Translate - [PR](https://codeberg.org/forgejo/forgejo/pulls/5786): i18n: Add dummy language for checking translation keys (#5785) - - [PR](https://codeberg.org/forgejo/forgejo/pulls/5754): i18n: update of translations from Codeberg Translate - - [PR](https://codeberg.org/forgejo/forgejo/pulls/5681): i18n: update of translations from Codeberg Translate - - [PR](https://codeberg.org/forgejo/forgejo/pulls/5583): i18n: update of translations from Codeberg Translate + - Updates from Codeberg Translate: [[1]](https://codeberg.org/forgejo/forgejo/pulls/6566), [[2]](https://codeberg.org/forgejo/forgejo/pulls/6514), [[3]](https://codeberg.org/forgejo/forgejo/pulls/6378) ([backport](https://codeberg.org/forgejo/forgejo/pulls/6450)), [[4]](https://codeberg.org/forgejo/forgejo/pulls/6331) ([backport](https://codeberg.org/forgejo/forgejo/pulls/6377)), [[5]](https://codeberg.org/forgejo/forgejo/pulls/6242), [[6]](https://codeberg.org/forgejo/forgejo/pulls/6161), [[7]](https://codeberg.org/forgejo/forgejo/pulls/6091), [[8]](https://codeberg.org/forgejo/forgejo/pulls/6041), [[9]](https://codeberg.org/forgejo/forgejo/pulls/5960), [[10]](https://codeberg.org/forgejo/forgejo/pulls/5845), [[11]](https://codeberg.org/forgejo/forgejo/pulls/5754), [[12]](https://codeberg.org/forgejo/forgejo/pulls/5681), [[13]](https://codeberg.org/forgejo/forgejo/pulls/5583) + - Features - [PR](https://codeberg.org/forgejo/forgejo/pulls/6448): Add summary card for repos and releases - [PR](https://codeberg.org/forgejo/forgejo/pulls/6271): [commit](https://codeberg.org/forgejo/forgejo/commit/b0d6a7f07bff836190a8e87fe5645d5557893e32) Implement update branch API From a975b6ab94344d802e72e2ac6a98212794ed9896 Mon Sep 17 00:00:00 2001 From: Otto Richter Date: Tue, 14 Jan 2025 22:13:31 +0100 Subject: [PATCH 150/198] tests(e2e): Explicitly generate screenshots As per https://codeberg.org/forgejo/forgejo/pulls/6400, the after hook runs for every test, resulting in duplicated screenshots. Not all tests are supposed to generate screenshots, especially because they could be flaky (also see https://code.forgejo.org/forgejo/visual-browser-testing/commit/206d4cfb7a4af6d8d7043026cdd4d63708798b2a ). Additionally, the implicit behaviour might have caused confusion, so we now create screenshots explicitly, adding the statements from the tests that already generated screenshots. --- tests/e2e/actions.test.e2e.ts | 1 + tests/e2e/clipboard-copy.test.e2e.ts | 5 ++++- tests/e2e/dashboard-ci-status.test.e2e.ts | 5 +++-- tests/e2e/example.test.e2e.ts | 3 ++- tests/e2e/explore.test.e2e.ts | 3 ++- tests/e2e/markup.test.e2e.ts | 3 ++- tests/e2e/repo-code.test.e2e.ts | 2 ++ tests/e2e/repo-commitgraph.test.e2e.ts | 3 ++- tests/e2e/repo-migrate.test.e2e.ts | 3 ++- tests/e2e/repo-wiki.test.e2e.ts | 4 +++- tests/e2e/right-settings-button.test.e2e.ts | 5 ++++- tests/e2e/utils_e2e.ts | 9 --------- 12 files changed, 27 insertions(+), 19 deletions(-) diff --git a/tests/e2e/actions.test.e2e.ts b/tests/e2e/actions.test.e2e.ts index 6236fe70d3..4e93b89ee0 100644 --- a/tests/e2e/actions.test.e2e.ts +++ b/tests/e2e/actions.test.e2e.ts @@ -71,4 +71,5 @@ test('workflow dispatch box not available for unauthenticated users', async ({pa await page.goto('/user2/test_workflows/actions?workflow=test-dispatch.yml&actor=0&status=0'); await expect(page.locator('body')).not.toContainText(workflow_trigger_notification_text); + await save_visual(page); }); diff --git a/tests/e2e/clipboard-copy.test.e2e.ts b/tests/e2e/clipboard-copy.test.e2e.ts index 70a3425868..2ae0e0dfff 100644 --- a/tests/e2e/clipboard-copy.test.e2e.ts +++ b/tests/e2e/clipboard-copy.test.e2e.ts @@ -8,7 +8,7 @@ // @watch end import {expect} from '@playwright/test'; -import {test} from './utils_e2e.ts'; +import {save_visual, test} from './utils_e2e.ts'; test('copy src file path to clipboard', async ({page}, workerInfo) => { test.skip(['Mobile Safari', 'webkit'].includes(workerInfo.project.name), 'Apple clipboard API addon - starting at just $499!'); @@ -19,6 +19,7 @@ test('copy src file path to clipboard', async ({page}, workerInfo) => { await page.click('[data-clipboard-text]'); const clipboardText = await page.evaluate(() => navigator.clipboard.readText()); expect(clipboardText).toContain('README.md'); + await save_visual(page); }); test('copy diff file path to clipboard', async ({page}, workerInfo) => { @@ -30,4 +31,6 @@ test('copy diff file path to clipboard', async ({page}, workerInfo) => { await page.click('[data-clipboard-text]'); const clipboardText = await page.evaluate(() => navigator.clipboard.readText()); expect(clipboardText).toContain('README.md'); + await expect(page.getByText('Copied')).toBeVisible(); + await save_visual(page); }); diff --git a/tests/e2e/dashboard-ci-status.test.e2e.ts b/tests/e2e/dashboard-ci-status.test.e2e.ts index 800fc951e6..d35fe299ff 100644 --- a/tests/e2e/dashboard-ci-status.test.e2e.ts +++ b/tests/e2e/dashboard-ci-status.test.e2e.ts @@ -3,7 +3,7 @@ // @watch end import {expect} from '@playwright/test'; -import {save_visual, test} from './utils_e2e.ts'; +import {test} from './utils_e2e.ts'; test.use({user: 'user2'}); @@ -23,5 +23,6 @@ test('Correct link and tooltip', async ({page}, testInfo) => { const repoStatus = page.locator('.dashboard-repos .repo-owner-name-list > li:nth-child(1) > a:nth-child(2)'); await expect(repoStatus).toHaveAttribute('href', '/user2/test_workflows/actions', {timeout: 10000}); await expect(repoStatus).toHaveAttribute('data-tooltip-content', /^(Error|Failure)$/); - await save_visual(page); + // ToDo: Ensure stable screenshot of dashboard. Known to be flaky: https://code.forgejo.org/forgejo/visual-browser-testing/commit/206d4cfb7a4af6d8d7043026cdd4d63708798b2a + // await save_visual(page); }); diff --git a/tests/e2e/example.test.e2e.ts b/tests/e2e/example.test.e2e.ts index b2a679a82d..97c5b8684b 100644 --- a/tests/e2e/example.test.e2e.ts +++ b/tests/e2e/example.test.e2e.ts @@ -5,7 +5,7 @@ // @watch end import {expect} from '@playwright/test'; -import {test} from './utils_e2e.ts'; +import {save_visual, test} from './utils_e2e.ts'; test('Load Homepage', async ({page}) => { const response = await page.goto('/'); @@ -26,6 +26,7 @@ test('Register Form', async ({page}, workerInfo) => { expect(page.url()).toBe(`${workerInfo.project.use.baseURL}/`); await expect(page.locator('.secondary-nav span>img.ui.avatar')).toBeVisible(); await expect(page.locator('.ui.positive.message.flash-success')).toHaveText('Account was successfully created. Welcome!'); + await save_visual(page); }); // eslint-disable-next-line playwright/no-skipped-test diff --git a/tests/e2e/explore.test.e2e.ts b/tests/e2e/explore.test.e2e.ts index 44c9b21f58..1bb5af3cc6 100644 --- a/tests/e2e/explore.test.e2e.ts +++ b/tests/e2e/explore.test.e2e.ts @@ -7,7 +7,7 @@ // @watch end import {expect} from '@playwright/test'; -import {test} from './utils_e2e.ts'; +import {save_visual, test} from './utils_e2e.ts'; test('Explore view taborder', async ({page}) => { await page.goto('/explore/repos'); @@ -42,4 +42,5 @@ test('Explore view taborder', async ({page}) => { } } expect(res).toBe(exp); + await save_visual(page); }); diff --git a/tests/e2e/markup.test.e2e.ts b/tests/e2e/markup.test.e2e.ts index 2726942d57..398a0a6300 100644 --- a/tests/e2e/markup.test.e2e.ts +++ b/tests/e2e/markup.test.e2e.ts @@ -3,7 +3,7 @@ // @watch end import {expect} from '@playwright/test'; -import {test} from './utils_e2e.ts'; +import {save_visual, test} from './utils_e2e.ts'; test('markup with #xyz-mode-only', async ({page}) => { const response = await page.goto('/user2/repo1/issues/1'); @@ -13,4 +13,5 @@ test('markup with #xyz-mode-only', async ({page}) => { await expect(comment).toBeVisible(); await expect(comment.locator('[src$="#gh-light-mode-only"]')).toBeVisible(); await expect(comment.locator('[src$="#gh-dark-mode-only"]')).toBeHidden(); + await save_visual(page); }); diff --git a/tests/e2e/repo-code.test.e2e.ts b/tests/e2e/repo-code.test.e2e.ts index 335fb5b7f5..11b710c956 100644 --- a/tests/e2e/repo-code.test.e2e.ts +++ b/tests/e2e/repo-code.test.e2e.ts @@ -49,6 +49,7 @@ test('Line Range Selection', async ({page}) => { // out-of-bounds end line await page.goto(`${filePath}#L1-L100`); await assertSelectedLines(page, ['1', '2', '3']); + await save_visual(page); }); test('Readable diff', async ({page}, workerInfo) => { @@ -75,6 +76,7 @@ test('Readable diff', async ({page}, workerInfo) => { await expect(page.getByText(thisDiff.added, {exact: true})).toHaveCSS('background-color', 'rgb(134, 239, 172)'); } } + await save_visual(page); }); test.describe('As authenticated user', () => { diff --git a/tests/e2e/repo-commitgraph.test.e2e.ts b/tests/e2e/repo-commitgraph.test.e2e.ts index 5f0cad117a..39c5661900 100644 --- a/tests/e2e/repo-commitgraph.test.e2e.ts +++ b/tests/e2e/repo-commitgraph.test.e2e.ts @@ -5,7 +5,7 @@ // @watch end import {expect} from '@playwright/test'; -import {test} from './utils_e2e.ts'; +import {save_visual, test} from './utils_e2e.ts'; test('Commit graph overflow', async ({page}) => { await page.goto('/user2/diff-test/graph'); @@ -28,4 +28,5 @@ test('Switch branch', async ({page}) => { await expect(page.locator('#loading-indicator')).toBeHidden(); await expect(page.locator('#rel-container')).toBeVisible(); await expect(page.locator('#rev-container')).toBeVisible(); + await save_visual(page); }); diff --git a/tests/e2e/repo-migrate.test.e2e.ts b/tests/e2e/repo-migrate.test.e2e.ts index 428c2cb171..5e67f89ed1 100644 --- a/tests/e2e/repo-migrate.test.e2e.ts +++ b/tests/e2e/repo-migrate.test.e2e.ts @@ -21,7 +21,6 @@ test('Migration Progress Page', async ({page, browser}, workerInfo) => { await form.locator('button.primary').click({timeout: 5000}); await expect(page).toHaveURL('user2/invalidrepo'); await save_visual(page); - // page screenshot of unauthenticatedPage is checked automatically after the test const ctx = await test_context(browser); const unauthenticatedPage = await ctx.newPage(); @@ -37,4 +36,6 @@ test('Migration Progress Page', async ({page, browser}, workerInfo) => { await save_visual(page); await deleteModal.getByRole('button', {name: 'Delete repository'}).click(); await expect(page).toHaveURL('/'); + // checked last to preserve the order of screenshots from first run + await save_visual(unauthenticatedPage); }); diff --git a/tests/e2e/repo-wiki.test.e2e.ts b/tests/e2e/repo-wiki.test.e2e.ts index f32fe3fc91..4ce66da8bc 100644 --- a/tests/e2e/repo-wiki.test.e2e.ts +++ b/tests/e2e/repo-wiki.test.e2e.ts @@ -4,7 +4,7 @@ // @watch end import {expect} from '@playwright/test'; -import {test} from './utils_e2e.ts'; +import {save_visual, test} from './utils_e2e.ts'; for (const searchTerm of ['space', 'consectetur']) { for (const width of [null, 2560, 4000]) { @@ -23,6 +23,7 @@ for (const searchTerm of ['space', 'consectetur']) { await page.getByPlaceholder('Search wiki').dispatchEvent('keyup'); // timeout is necessary because HTMX search could be slow await expect(page.locator('#wiki-search a[href]')).toBeInViewport({ratio: 1}); + await save_visual(page); }); } } @@ -36,4 +37,5 @@ test(`Search results show titles (and not file names)`, async ({page}, workerInf // so we manually "type" the last letter await page.getByPlaceholder('Search wiki').dispatchEvent('keyup'); await expect(page.locator('#wiki-search a[href] b')).toHaveText('Page With Spaced Name'); + await save_visual(page); }); diff --git a/tests/e2e/right-settings-button.test.e2e.ts b/tests/e2e/right-settings-button.test.e2e.ts index e1c40fdd4d..3bea329ba0 100644 --- a/tests/e2e/right-settings-button.test.e2e.ts +++ b/tests/e2e/right-settings-button.test.e2e.ts @@ -5,7 +5,7 @@ // @watch end import {expect} from '@playwright/test'; -import {test} from './utils_e2e.ts'; +import {save_visual, test} from './utils_e2e.ts'; test.describe('desktop viewport as user 2', () => { test.use({user: 'user2', viewport: {width: 1920, height: 300}}); @@ -54,6 +54,7 @@ test.describe('desktop viewport, unauthenticated', () => { await expect(page.locator('.overflow-menu-items>#settings-btn')).toHaveCount(0); await expect(page.locator('.overflow-menu-button')).toHaveCount(0); + await save_visual(page); }); }); @@ -78,6 +79,7 @@ test.describe('small viewport', () => { const items = shownItems.concat(overflowItems); expect(Array.from(new Set(items))).toHaveLength(items.length); + await save_visual(page); }); test('Settings button in overflow menu of org header', async ({page}) => { @@ -121,5 +123,6 @@ test.describe('small viewport, unauthenticated', () => { const items = shownItems.concat(overflowItems); expect(Array.from(new Set(items))).toHaveLength(items.length); + await save_visual(page); }); }); diff --git a/tests/e2e/utils_e2e.ts b/tests/e2e/utils_e2e.ts index 80412e437d..18d23753dd 100644 --- a/tests/e2e/utils_e2e.ts +++ b/tests/e2e/utils_e2e.ts @@ -26,15 +26,6 @@ export const test = baseTest.extend({ }, user: null, authScope: 'shared', - // see https://playwright.dev/docs/test-fixtures#adding-global-beforeeachaftereach-hooks - forEachTest: [async ({page}, use) => { - await use(); - // some tests create a new page which is not yet available here - // only operate on tests that make the URL available - if (page.url() !== 'about:blank') { - await save_visual(page); - } - }, {auto: true}], }); export async function test_context(browser: Browser, options?: BrowserContextOptions) { From f7ba8f0e413db23006e72af7e78d5b9ec2f36413 Mon Sep 17 00:00:00 2001 From: Otto Richter Date: Tue, 14 Jan 2025 22:28:13 +0100 Subject: [PATCH 151/198] tests(e2e): Do not fail early when comparing screenshots Also set a unique outputDir so that artifacts are preserved and not overwritten by the following tests. --- tests/e2e/e2e_test.go | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/tests/e2e/e2e_test.go b/tests/e2e/e2e_test.go index 88b254b6f9..8e4a9653cd 100644 --- a/tests/e2e/e2e_test.go +++ b/tests/e2e/e2e_test.go @@ -82,6 +82,7 @@ func TestE2e(t *testing.T) { runArgs := []string{"npx", "playwright", "test"} + _, testVisual := os.LookupEnv("VISUAL_TEST") // To update snapshot outputs if _, set := os.LookupEnv("ACCEPT_VISUAL"); set { runArgs = append(runArgs, "--update-snapshots") @@ -105,6 +106,10 @@ func TestE2e(t *testing.T) { onForgejoRun(t, func(*testing.T, *url.URL) { defer DeclareGitRepos(t)() thisTest := runArgs + // when all tests are run, use unique artifacts directories per test to preserve artifacts from other tests + if testVisual { + thisTest = append(thisTest, "--output=tests/e2e/test-artifacts/"+testname) + } thisTest = append(thisTest, path) cmd := exec.Command(runArgs[0], thisTest...) cmd.Env = os.Environ() @@ -114,7 +119,7 @@ func TestE2e(t *testing.T) { cmd.Stderr = os.Stderr err := cmd.Run() - if err != nil { + if err != nil && !testVisual { log.Fatal("Playwright Failed: %s", err) } }) From e7299eb0fb0e75601e264977ba391e80c1924b2c Mon Sep 17 00:00:00 2001 From: Otto Richter Date: Wed, 15 Jan 2025 15:30:41 +0100 Subject: [PATCH 152/198] tests(e2e): Mask user heatmap in screenshots It depends on both relative activity and date the test is run on --- tests/e2e/utils_e2e.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/e2e/utils_e2e.ts b/tests/e2e/utils_e2e.ts index 18d23753dd..ff921a2cf3 100644 --- a/tests/e2e/utils_e2e.ts +++ b/tests/e2e/utils_e2e.ts @@ -119,6 +119,7 @@ export async function save_visual(page: Page) { // update order of recently created repos is not fully deterministic page.locator('.flex-item-main').filter({hasText: 'relative time in repo'}), page.locator('#activity-feed'), + page.locator('#user-heatmap'), // dynamic IDs in fixed-size inputs page.locator('input[value*="dyn-id-"]'), ], From dd1523c72ee622a4d38b347668bf56003984eba0 Mon Sep 17 00:00:00 2001 From: 0ko <0ko@noreply.codeberg.org> Date: Wed, 15 Jan 2025 19:56:17 +0000 Subject: [PATCH 153/198] fix(ui): correct switch ordering (#6576) Regressions of #6459 and #6542: `templates/repo/issue/navbar.tmpl`: * `issue-list-navbar` is the ordering class which was incorrectly removed * and then it was incorrectly replaced with `list-header-toggle` `templates/repo/issue/openclose.tmpl`: * it did not have ordering rules in the first place * but then `list-header-toggle` was incorrectly applied to it Thanks to @fnetX for spotting and notifying! Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/6576 Reviewed-by: Otto Co-authored-by: 0ko <0ko@noreply.codeberg.org> Co-committed-by: 0ko <0ko@noreply.codeberg.org> --- templates/repo/issue/navbar.tmpl | 2 +- templates/repo/issue/openclose.tmpl | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/templates/repo/issue/navbar.tmpl b/templates/repo/issue/navbar.tmpl index 4874bf2ad4..4d90ca3c0e 100644 --- a/templates/repo/issue/navbar.tmpl +++ b/templates/repo/issue/navbar.tmpl @@ -1,4 +1,4 @@ -
+ diff --git a/templates/repo/issue/openclose.tmpl b/templates/repo/issue/openclose.tmpl index d93c7e01f5..efe4fa6756 100644 --- a/templates/repo/issue/openclose.tmpl +++ b/templates/repo/issue/openclose.tmpl @@ -1,4 +1,4 @@ -
+
{{if .PageIsMilestones}} {{svg "octicon-milestone" 16 "tw-mr-2"}} From 4c7bfedf55ed4e7490f9e4a55c46ccfb5d40c224 Mon Sep 17 00:00:00 2001 From: Earl Warren Date: Wed, 15 Jan 2025 21:47:32 +0000 Subject: [PATCH 154/198] chore(ci): upgrade forgejo-build-publish/build@v5.3.1 (#6573) So that it does not use docker.io The test happens at `.forgejo/workflows/build-release-integration.yml` Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/6573 Reviewed-by: Michael Kriese Co-authored-by: Earl Warren Co-committed-by: Earl Warren --- .forgejo/workflows/build-release.yml | 4 ++-- .forgejo/workflows/publish-release.yml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.forgejo/workflows/build-release.yml b/.forgejo/workflows/build-release.yml index f633ab1df0..9d88cb43dd 100644 --- a/.forgejo/workflows/build-release.yml +++ b/.forgejo/workflows/build-release.yml @@ -164,7 +164,7 @@ jobs: - name: build container & release if: ${{ secrets.TOKEN != '' }} - uses: https://data.forgejo.org/forgejo/forgejo-build-publish/build@v5.3.0 + uses: https://data.forgejo.org/forgejo/forgejo-build-publish/build@v5.3.1 with: forgejo: "${{ env.GITHUB_SERVER_URL }}" owner: "${{ env.GITHUB_REPOSITORY_OWNER }}" @@ -183,7 +183,7 @@ jobs: - name: build rootless container if: ${{ secrets.TOKEN != '' }} - uses: https://data.forgejo.org/forgejo/forgejo-build-publish/build@v5.3.0 + uses: https://data.forgejo.org/forgejo/forgejo-build-publish/build@v5.3.1 with: forgejo: "${{ env.GITHUB_SERVER_URL }}" owner: "${{ env.GITHUB_REPOSITORY_OWNER }}" diff --git a/.forgejo/workflows/publish-release.yml b/.forgejo/workflows/publish-release.yml index 0dffff7306..0e75912a3a 100644 --- a/.forgejo/workflows/publish-release.yml +++ b/.forgejo/workflows/publish-release.yml @@ -42,7 +42,7 @@ jobs: - uses: actions/checkout@v4 - name: copy & sign - uses: https://data.forgejo.org/forgejo/forgejo-build-publish/publish@v5.3.0 + uses: https://data.forgejo.org/forgejo/forgejo-build-publish/publish@v5.3.1 with: from-forgejo: ${{ vars.FORGEJO }} to-forgejo: ${{ vars.FORGEJO }} From 30038124770f959f6817921f30a5b62b42edee6d Mon Sep 17 00:00:00 2001 From: Earl Warren Date: Wed, 15 Jan 2025 22:06:38 +0000 Subject: [PATCH 155/198] fix: avoid Gitea migration warnings (take 2) (#6577) 274bc480b41132920e36c1cbee8a0f0e69a4ba0c introduced a regression in https://codeberg.org/forgejo/forgejo/pulls/6343 Trying to remove fields that have already been removed by https://codeberg.org/forgejo/forgejo/src/commit/dd1523c72ee622a4d38b347668bf56003984eba0/models/forgejo_migrations/v14.go Is a noop for SQLite and went undetected by the upgrade tests. Fixes: https://codeberg.org/forgejo/forgejo/issues/6575 Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/6577 Reviewed-by: Gusted Reviewed-by: Michael Kriese Co-authored-by: Earl Warren Co-committed-by: Earl Warren --- models/migrations/v1_23/v303.go | 36 ++++++++++++++++++++------------- 1 file changed, 22 insertions(+), 14 deletions(-) diff --git a/models/migrations/v1_23/v303.go b/models/migrations/v1_23/v303.go index c1e74c596a..e3ee180539 100644 --- a/models/migrations/v1_23/v303.go +++ b/models/migrations/v1_23/v303.go @@ -4,6 +4,8 @@ package v1_23 //nolint import ( + "fmt" + "code.gitea.io/gitea/models/migrations/base" "xorm.io/xorm" @@ -13,20 +15,26 @@ func GiteaLastDrop(x *xorm.Engine) error { sess := x.NewSession() defer sess.Close() - if err := base.DropTableColumns(sess, "badge", "slug"); err != nil { - return err - } - if err := base.DropTableColumns(sess, "oauth2_application", "skip_secondary_authorization"); err != nil { - return err - } - if err := base.DropTableColumns(sess, "repository", "default_wiki_branch"); err != nil { - return err - } - // the migration v297.go that adds everyone_access_mode exists in Gitea >= v1.22 and the column must be dropped - // but it does not exist in Forgejo and a failure to drop the column can be ignored - base.DropTableColumns(sess, "repo_unit", "everyone_access_mode") - if err := base.DropTableColumns(sess, "protected_branch", "can_force_push", "enable_force_push_allowlist", "force_push_allowlist_user_i_ds", "force_push_allowlist_team_i_ds", "force_push_allowlist_deploy_keys"); err != nil { - return err + for _, drop := range []struct { + table string + field string + }{ + {"badge", "slug"}, + {"oauth2_application", "skip_secondary_authorization"}, + {"repository", "default_wiki_branch"}, + {"repo_unit", "everyone_access_mode"}, + {"protected_branch", "can_force_push"}, + {"protected_branch", "enable_force_push_allowlist"}, + {"protected_branch", "force_push_allowlist_user_i_ds"}, + {"protected_branch", "force_push_allowlist_team_i_ds"}, + {"protected_branch", "force_push_allowlist_deploy_keys"}, + } { + if _, err := sess.Exec(fmt.Sprintf("SELECT `%s` FROM `%s` WHERE 0 = 1", drop.field, drop.table)); err != nil { + continue + } + if err := base.DropTableColumns(sess, drop.table, drop.field); err != nil { + return err + } } return sess.Commit() From 909738e6f60c62b4cc0d5558bb57dc22f705e619 Mon Sep 17 00:00:00 2001 From: Renovate Bot Date: Thu, 16 Jan 2025 15:20:57 +0000 Subject: [PATCH 156/198] Update renovate Docker tag to v39.111.0 (forgejo) (#6570) Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/6570 Reviewed-by: Michael Kriese Co-authored-by: Renovate Bot Co-committed-by: Renovate Bot --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 3f05ae0b93..039004603c 100644 --- a/Makefile +++ b/Makefile @@ -49,7 +49,7 @@ GOVULNCHECK_PACKAGE ?= golang.org/x/vuln/cmd/govulncheck@v1 # renovate: datasour DEADCODE_PACKAGE ?= golang.org/x/tools/cmd/deadcode@v0.29.0 # renovate: datasource=go GOMOCK_PACKAGE ?= go.uber.org/mock/mockgen@v0.4.0 # renovate: datasource=go GOPLS_PACKAGE ?= golang.org/x/tools/gopls@v0.17.1 # renovate: datasource=go -RENOVATE_NPM_PACKAGE ?= renovate@39.106.0 # renovate: datasource=docker packageName=data.forgejo.org/renovate/renovate +RENOVATE_NPM_PACKAGE ?= renovate@39.111.0 # renovate: datasource=docker packageName=data.forgejo.org/renovate/renovate # https://github.com/disposable-email-domains/disposable-email-domains/commits/main/ DISPOSABLE_EMAILS_SHA ?= 0c27e671231d27cf66370034d7f6818037416989 # renovate: ... From 907ab8bdef4237bd9240b3fd36c884b4b2375499 Mon Sep 17 00:00:00 2001 From: Renovate Bot Date: Thu, 16 Jan 2025 22:51:49 +0000 Subject: [PATCH 157/198] Update dependency @github/relative-time-element to v4.4.5 (forgejo) (#6559) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This PR contains the following updates: | Package | Type | Update | Change | |---|---|---|---| | [@github/relative-time-element](https://github.com/github/relative-time-element) | dependencies | patch | [`4.4.4` -> `4.4.5`](https://renovatebot.com/diffs/npm/@github%2frelative-time-element/4.4.4/4.4.5) | --- ### Release Notes
github/relative-time-element (@​github/relative-time-element) ### [`v4.4.5`](https://github.com/github/relative-time-element/releases/tag/v4.4.5) [Compare Source](https://github.com/github/relative-time-element/compare/v4.4.4...v4.4.5) #### What's Changed - fix: wrap Intl.<>() calls in try/catch by [@​francinelucca](https://github.com/francinelucca) in https://github.com/github/relative-time-element/pull/297 - get main branch green by [@​keithamus](https://github.com/keithamus) in https://github.com/github/relative-time-element/pull/302 - Make `applyDuration` reversible by [@​leduyquang753](https://github.com/leduyquang753) in https://github.com/github/relative-time-element/pull/298 - Use node v22 by [@​camertron](https://github.com/camertron) in https://github.com/github/relative-time-element/pull/303 #### New Contributors - [@​francinelucca](https://github.com/francinelucca) made their first contribution in https://github.com/github/relative-time-element/pull/297 - [@​leduyquang753](https://github.com/leduyquang753) made their first contribution in https://github.com/github/relative-time-element/pull/298 - [@​camertron](https://github.com/camertron) made their first contribution in https://github.com/github/relative-time-element/pull/303 **Full Changelog**: https://github.com/github/relative-time-element/compare/v4.4.4...v4.4.5
--- ### Configuration 📅 **Schedule**: Branch creation - "* 0-3 * * *" (UTC), Automerge - "* 0-3 * * *" (UTC). 🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied. ♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] If you want to rebase/retry this PR, check this box --- This PR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate). Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/6559 Reviewed-by: Otto Co-authored-by: Renovate Bot Co-committed-by: Renovate Bot --- package-lock.json | 8 ++++---- package.json | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package-lock.json b/package-lock.json index 223dfbd310..9dbfaf2551 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,7 +10,7 @@ "@citation-js/plugin-software-formats": "0.6.1", "@github/markdown-toolbar-element": "2.2.3", "@github/quote-selection": "2.1.0", - "@github/relative-time-element": "4.4.4", + "@github/relative-time-element": "4.4.5", "@github/text-expander-element": "2.8.0", "@mcaptcha/vanilla-glue": "0.1.0-alpha-3", "@primer/octicons": "19.14.0", @@ -2854,9 +2854,9 @@ "license": "MIT" }, "node_modules/@github/relative-time-element": { - "version": "4.4.4", - "resolved": "https://registry.npmjs.org/@github/relative-time-element/-/relative-time-element-4.4.4.tgz", - "integrity": "sha512-Oi8uOL8O+ZWLD7dHRWCkm2cudcTYtB3VyOYf9BtzCgDGm+OKomyOREtItNMtWl1dxvec62BTKErq36uy+RYxQg==", + "version": "4.4.5", + "resolved": "https://registry.npmjs.org/@github/relative-time-element/-/relative-time-element-4.4.5.tgz", + "integrity": "sha512-9ejPtayBDIJfEU8x1fg/w2o5mahHkkp1SC6uObDtoKs4Gn+2a1vNK8XIiNDD8rMeEfpvDjydgSZZ+uk+7N0VsQ==", "license": "MIT" }, "node_modules/@github/text-expander-element": { diff --git a/package.json b/package.json index 86b1b17029..944789f0a7 100644 --- a/package.json +++ b/package.json @@ -9,7 +9,7 @@ "@citation-js/plugin-software-formats": "0.6.1", "@github/markdown-toolbar-element": "2.2.3", "@github/quote-selection": "2.1.0", - "@github/relative-time-element": "4.4.4", + "@github/relative-time-element": "4.4.5", "@github/text-expander-element": "2.8.0", "@mcaptcha/vanilla-glue": "0.1.0-alpha-3", "@primer/octicons": "19.14.0", From cefd786685b8b6f56cc26cb84019376a5a281be3 Mon Sep 17 00:00:00 2001 From: Robert Wolff Date: Thu, 16 Jan 2025 23:59:21 +0000 Subject: [PATCH 158/198] Remove source branch from pr list, fix #5009, #6080 (#6522) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ### What? It removes the source branch that is not necessary in the PR list (see #5009). It adds a little chevron to the right in front of the target branch. That could be replaced by words (“into”), or removed, if preferred. But, I think it looks decent like that. ### Screenshots #### Before ![image](/attachments/be3c9817-2207-4610-b6bd-70304436f81d) #### After ![image](/attachments/a7c84d2f-1592-4a82-aecc-d038f9495ef7) ### Testing Run the development version of forgejo from the PR. For any existing repository with PRs, open the pulls list. Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/6522 Reviewed-by: Otto Reviewed-by: Gusted Co-authored-by: Robert Wolff Co-committed-by: Robert Wolff --- templates/shared/issuelist.tmpl | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/templates/shared/issuelist.tmpl b/templates/shared/issuelist.tmpl index 7ce7cd6795..b71fde685e 100644 --- a/templates/shared/issuelist.tmpl +++ b/templates/shared/issuelist.tmpl @@ -70,21 +70,13 @@ {{end}} {{if .IsPull}}
{{end}} {{if and .Milestone (ne $.listType "milestone")}} From b2a3a0411c7e26d4805e6846e9413299e999b636 Mon Sep 17 00:00:00 2001 From: Gusted Date: Fri, 17 Jan 2025 03:17:10 +0000 Subject: [PATCH 159/198] [PORT] Remove SHA1 for support for ssh rsa signing (#31857) (#5303) https://github.com/go-fed/httpsig seems to be unmaintained. Switch to github.com/42wim/httpsig which has removed deprecated crypto and default sha256 signing for ssh rsa. No impact for those that use ed25519 ssh certificates. This is a breaking change for: - gitea.com/gitea/tea (go-sdk) - I'll be sending a PR there too - activitypub using deprecated crypto (is this actually used?) (cherry picked from commit 01dec7577a051d9bb30e91f6cf6653dc51a37d06) --- Conflict resolution: trivial Co-authored-by: Wim Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/5303 Reviewed-by: Earl Warren --- go.mod | 4 ++-- go.sum | 4 ++-- modules/activitypub/client.go | 2 +- modules/setting/federation.go | 2 +- routers/api/v1/activitypub/reqsignature.go | 2 +- services/auth/httpsign.go | 4 ++-- tests/integration/api_httpsig_test.go | 2 +- 7 files changed, 10 insertions(+), 10 deletions(-) diff --git a/go.mod b/go.mod index e069a33996..48e9e49075 100644 --- a/go.mod +++ b/go.mod @@ -17,6 +17,7 @@ require ( codeberg.org/gusted/mcaptcha v0.0.0-20220723083913-4f3072e1d570 connectrpc.com/connect v1.17.0 gitea.com/lunny/levelqueue v0.4.2-0.20230414023320-3c0159fe0fe4 + github.com/42wim/httpsig v1.2.2 github.com/42wim/sshsig v0.0.0-20211121163825-841cf5bbc121 github.com/Azure/go-ntlmssp v0.0.0-20221128193559-754e69321358 github.com/ProtonMail/go-crypto v1.1.4 @@ -43,7 +44,6 @@ require ( github.com/go-chi/cors v1.2.1 github.com/go-co-op/gocron v1.37.0 github.com/go-enry/go-enry/v2 v2.9.1 - github.com/go-fed/httpsig v1.1.1-0.20201223112313-55836744818e github.com/go-git/go-git/v5 v5.13.1 github.com/go-ldap/ldap/v3 v3.4.6 github.com/go-openapi/spec v0.20.14 @@ -131,7 +131,6 @@ require ( dario.cat/mergo v1.0.0 // indirect filippo.io/edwards25519 v1.1.0 // indirect git.sr.ht/~mariusor/go-xsd-duration v0.0.0-20220703122237-02e73435a078 // indirect - github.com/42wim/httpsig v1.2.2 // indirect github.com/DataDog/zstd v1.5.5 // indirect github.com/GoogleCloudPlatform/grpc-gcp-go/grpcgcp v1.5.0 // indirect github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.24.2 // indirect @@ -184,6 +183,7 @@ require ( github.com/go-ap/errors v0.0.0-20231003111023-183eef4b31b7 // indirect github.com/go-asn1-ber/asn1-ber v1.5.5 // indirect github.com/go-enry/go-oniguruma v1.2.1 // indirect + github.com/go-fed/httpsig v1.1.0 // indirect github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 // indirect github.com/go-git/go-billy/v5 v5.6.1 // indirect github.com/go-ini/ini v1.67.0 // indirect diff --git a/go.sum b/go.sum index 58abf76d25..28e1f22870 100644 --- a/go.sum +++ b/go.sum @@ -919,8 +919,8 @@ github.com/go-faster/city v1.0.1 h1:4WAxSZ3V2Ws4QRDrscLEDcibJY8uf41H6AhXDrNDcGw= github.com/go-faster/city v1.0.1/go.mod h1:jKcUJId49qdW3L1qKHH/3wPeUstCVpVSXTM6vO3VcTw= github.com/go-faster/errors v0.7.1 h1:MkJTnDoEdi9pDabt1dpWf7AA8/BaSYZqibYyhZ20AYg= github.com/go-faster/errors v0.7.1/go.mod h1:5ySTjWFiphBs07IKuiL69nxdfd5+fzh1u7FPGZP2quo= -github.com/go-fed/httpsig v1.1.1-0.20201223112313-55836744818e h1:oRq/fiirun5HqlEWMLIcDmLpIELlG4iGbd0s8iqgPi8= -github.com/go-fed/httpsig v1.1.1-0.20201223112313-55836744818e/go.mod h1:RCMrTZvN1bJYtofsG4rd5NaO5obxQ5xBkdiS7xsT7bM= +github.com/go-fed/httpsig v1.1.0 h1:9M+hb0jkEICD8/cAiNqEB66R87tTINszBRTjwjQzWcI= +github.com/go-fed/httpsig v1.1.0/go.mod h1:RCMrTZvN1bJYtofsG4rd5NaO5obxQ5xBkdiS7xsT7bM= github.com/go-fonts/dejavu v0.1.0/go.mod h1:4Wt4I4OU2Nq9asgDCteaAaWZOV24E+0/Pwo0gppep4g= github.com/go-fonts/latin-modern v0.2.0/go.mod h1:rQVLdDMK+mK1xscDwsqM5J8U2jrRa3T0ecnM9pNujks= github.com/go-fonts/liberation v0.1.1/go.mod h1:K6qoJYypsmfVjWg8KOVDQhLc8UDgIK2HYqyqAO9z7GY= diff --git a/modules/activitypub/client.go b/modules/activitypub/client.go index 064d8984c1..645a4b8c8d 100644 --- a/modules/activitypub/client.go +++ b/modules/activitypub/client.go @@ -22,7 +22,7 @@ import ( "code.gitea.io/gitea/modules/proxy" "code.gitea.io/gitea/modules/setting" - "github.com/go-fed/httpsig" + "github.com/42wim/httpsig" ) const ( diff --git a/modules/setting/federation.go b/modules/setting/federation.go index aeb30683ea..edb18e0054 100644 --- a/modules/setting/federation.go +++ b/modules/setting/federation.go @@ -6,7 +6,7 @@ package setting import ( "code.gitea.io/gitea/modules/log" - "github.com/go-fed/httpsig" + "github.com/42wim/httpsig" ) // Federation settings diff --git a/routers/api/v1/activitypub/reqsignature.go b/routers/api/v1/activitypub/reqsignature.go index 6003f664a0..19d167b50b 100644 --- a/routers/api/v1/activitypub/reqsignature.go +++ b/routers/api/v1/activitypub/reqsignature.go @@ -18,8 +18,8 @@ import ( "code.gitea.io/gitea/modules/setting" gitea_context "code.gitea.io/gitea/services/context" + "github.com/42wim/httpsig" ap "github.com/go-ap/activitypub" - "github.com/go-fed/httpsig" ) func getPublicKeyFromResponse(b []byte, keyID *url.URL) (p crypto.PublicKey, err error) { diff --git a/services/auth/httpsign.go b/services/auth/httpsign.go index b604349f80..83a36bef23 100644 --- a/services/auth/httpsign.go +++ b/services/auth/httpsign.go @@ -17,7 +17,7 @@ import ( "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/setting" - "github.com/go-fed/httpsig" + "github.com/42wim/httpsig" "golang.org/x/crypto/ssh" ) @@ -205,7 +205,7 @@ func doVerify(verifier httpsig.Verifier, sshPublicKeys []ssh.PublicKey) error { case strings.HasPrefix(publicKey.Type(), "ssh-ed25519"): algos = []httpsig.Algorithm{httpsig.ED25519} case strings.HasPrefix(publicKey.Type(), "ssh-rsa"): - algos = []httpsig.Algorithm{httpsig.RSA_SHA1, httpsig.RSA_SHA256, httpsig.RSA_SHA512} + algos = []httpsig.Algorithm{httpsig.RSA_SHA256, httpsig.RSA_SHA512} } for _, algo := range algos { if err := verifier.Verify(cryptoPubkey, algo); err == nil { diff --git a/tests/integration/api_httpsig_test.go b/tests/integration/api_httpsig_test.go index 30aed3cacc..cca477f5e1 100644 --- a/tests/integration/api_httpsig_test.go +++ b/tests/integration/api_httpsig_test.go @@ -15,7 +15,7 @@ import ( "code.gitea.io/gitea/modules/test" "code.gitea.io/gitea/tests" - "github.com/go-fed/httpsig" + "github.com/42wim/httpsig" "golang.org/x/crypto/ssh" ) From 376a2e19eab62640257b40db8163a0cab92c7038 Mon Sep 17 00:00:00 2001 From: Earl Warren Date: Fri, 17 Jan 2025 07:42:20 +0000 Subject: [PATCH 160/198] fix: reduce noise for the v303 migration (#6591) Using SELECT `%s` FROM `%s` WHERE 0 = 1 to assert the existence of a column is simple but noisy: it shows errors in the migrations that are confusing for Forgejo admins because they are not actual errors. Use introspection instead, which is more complicated but leads to the same result. Add a test that ensures it works as expected, for all database types. Although the migration is run for all database types, it does not account for various scenarios and is never tested in the case a column does not exist. Refs: https://codeberg.org/forgejo/forgejo/issues/6583 Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/6591 Reviewed-by: Otto Co-authored-by: Earl Warren Co-committed-by: Earl Warren --- models/migrations/v1_23/v303.go | 35 ++++++++++++++++++------ models/migrations/v1_23/v303_test.go | 41 ++++++++++++++++++++++++++++ 2 files changed, 68 insertions(+), 8 deletions(-) create mode 100644 models/migrations/v1_23/v303_test.go diff --git a/models/migrations/v1_23/v303.go b/models/migrations/v1_23/v303.go index e3ee180539..2fb37ac843 100644 --- a/models/migrations/v1_23/v303.go +++ b/models/migrations/v1_23/v303.go @@ -1,23 +1,27 @@ -// Copyright 2024 The Forgejo Authors. -// SPDX-License-Identifier: MIT +// Copyright 2025 The Forgejo Authors. +// SPDX-License-Identifier: GPL-3.0-or-later package v1_23 //nolint import ( - "fmt" - "code.gitea.io/gitea/models/migrations/base" "xorm.io/xorm" + "xorm.io/xorm/schemas" ) func GiteaLastDrop(x *xorm.Engine) error { + tables, err := x.DBMetas() + if err != nil { + return err + } + sess := x.NewSession() defer sess.Close() for _, drop := range []struct { - table string - field string + table string + column string }{ {"badge", "slug"}, {"oauth2_application", "skip_secondary_authorization"}, @@ -29,10 +33,25 @@ func GiteaLastDrop(x *xorm.Engine) error { {"protected_branch", "force_push_allowlist_team_i_ds"}, {"protected_branch", "force_push_allowlist_deploy_keys"}, } { - if _, err := sess.Exec(fmt.Sprintf("SELECT `%s` FROM `%s` WHERE 0 = 1", drop.field, drop.table)); err != nil { + var table *schemas.Table + found := false + + for _, table = range tables { + if table.Name == drop.table { + found = true + break + } + } + + if !found { continue } - if err := base.DropTableColumns(sess, drop.table, drop.field); err != nil { + + if table.GetColumn(drop.column) == nil { + continue + } + + if err := base.DropTableColumns(sess, drop.table, drop.column); err != nil { return err } } diff --git a/models/migrations/v1_23/v303_test.go b/models/migrations/v1_23/v303_test.go new file mode 100644 index 0000000000..752eacee0c --- /dev/null +++ b/models/migrations/v1_23/v303_test.go @@ -0,0 +1,41 @@ +// Copyright 2025 The Forgejo Authors. +// SPDX-License-Identifier: GPL-3.0-or-later + +package v1_23 //nolint + +import ( + "testing" + + migration_tests "code.gitea.io/gitea/models/migrations/test" + + "github.com/stretchr/testify/require" + "xorm.io/xorm/schemas" +) + +func Test_GiteaLastDrop(t *testing.T) { + type Badge struct { + ID int64 `xorm:"pk autoincr"` + Slug string + } + + x, deferable := migration_tests.PrepareTestEnv(t, 0, new(Badge)) + defer deferable() + if x == nil || t.Failed() { + return + } + + getColumn := func() *schemas.Column { + tables, err := x.DBMetas() + require.NoError(t, err) + require.Len(t, tables, 1) + table := tables[0] + require.Equal(t, "badge", table.Name) + return table.GetColumn("slug") + } + + require.NotNil(t, getColumn(), "slug column exists") + require.NoError(t, GiteaLastDrop(x)) + require.Nil(t, getColumn(), "slug column was deleted") + // idempotent + require.NoError(t, GiteaLastDrop(x)) +} From a2787bb09edcf00f29a65c4f405de6371b4d434e Mon Sep 17 00:00:00 2001 From: Benedikt Straub Date: Mon, 30 Dec 2024 20:03:37 +0100 Subject: [PATCH 161/198] Initial support for localization and pluralization with go-i18n-JSON-v2 format --- .deadcode-out | 1 + modules/translation/i18n/dummy.go | 20 +- modules/translation/i18n/errors.go | 6 +- modules/translation/i18n/i18n.go | 23 ++- modules/translation/i18n/i18n_test.go | 106 +++++++++- modules/translation/i18n/localestore.go | 180 +++++++++++++++-- modules/translation/mock.go | 4 + modules/translation/plural_rules.go | 253 ++++++++++++++++++++++++ modules/translation/translation.go | 16 +- modules/translation/translation_test.go | 108 ++++++++++ options/locale/locale_en-US.ini | 5 - options/locale_next/locale_ar.json | 1 + options/locale_next/locale_be.json | 1 + options/locale_next/locale_bg.json | 14 ++ options/locale_next/locale_bn.json | 1 + options/locale_next/locale_bs.json | 1 + options/locale_next/locale_ca.json | 5 + options/locale_next/locale_cs-CZ.json | 17 ++ options/locale_next/locale_da.json | 5 + options/locale_next/locale_de-DE.json | 17 ++ options/locale_next/locale_el-GR.json | 17 ++ options/locale_next/locale_en-US.json | 17 ++ options/locale_next/locale_eo.json | 5 + options/locale_next/locale_es-ES.json | 17 ++ options/locale_next/locale_et.json | 5 + options/locale_next/locale_fa-IR.json | 12 ++ options/locale_next/locale_fi-FI.json | 15 ++ options/locale_next/locale_fil.json | 17 ++ options/locale_next/locale_fr-FR.json | 17 ++ options/locale_next/locale_gl.json | 1 + options/locale_next/locale_hi.json | 1 + options/locale_next/locale_hu-HU.json | 15 ++ options/locale_next/locale_id-ID.json | 12 ++ options/locale_next/locale_is-IS.json | 9 + options/locale_next/locale_it-IT.json | 17 ++ options/locale_next/locale_ja-JP.json | 15 ++ options/locale_next/locale_ko-KR.json | 12 ++ options/locale_next/locale_lt.json | 5 + options/locale_next/locale_lv-LV.json | 17 ++ options/locale_next/locale_ml-IN.json | 1 + options/locale_next/locale_nb_NO.json | 1 + options/locale_next/locale_nds.json | 17 ++ options/locale_next/locale_nl-NL.json | 17 ++ options/locale_next/locale_pl-PL.json | 15 ++ options/locale_next/locale_pt-BR.json | 17 ++ options/locale_next/locale_pt-PT.json | 17 ++ options/locale_next/locale_ru-RU.json | 17 ++ options/locale_next/locale_si-LK.json | 12 ++ options/locale_next/locale_sk-SK.json | 1 + options/locale_next/locale_sl.json | 1 + options/locale_next/locale_sr-SP.json | 1 + options/locale_next/locale_sv-SE.json | 15 ++ options/locale_next/locale_tr-TR.json | 15 ++ options/locale_next/locale_uk-UA.json | 17 ++ options/locale_next/locale_vi.json | 1 + options/locale_next/locale_yi.json | 1 + options/locale_next/locale_zh-CN.json | 15 ++ options/locale_next/locale_zh-HK.json | 9 + options/locale_next/locale_zh-TW.json | 15 ++ templates/repo/issue/view_title.tmpl | 8 +- tools/migrate_locales.sh | 145 ++++++++++++++ 61 files changed, 1317 insertions(+), 51 deletions(-) create mode 100644 modules/translation/plural_rules.go create mode 100644 options/locale_next/locale_ar.json create mode 100644 options/locale_next/locale_be.json create mode 100644 options/locale_next/locale_bg.json create mode 100644 options/locale_next/locale_bn.json create mode 100644 options/locale_next/locale_bs.json create mode 100644 options/locale_next/locale_ca.json create mode 100644 options/locale_next/locale_cs-CZ.json create mode 100644 options/locale_next/locale_da.json create mode 100644 options/locale_next/locale_de-DE.json create mode 100644 options/locale_next/locale_el-GR.json create mode 100644 options/locale_next/locale_en-US.json create mode 100644 options/locale_next/locale_eo.json create mode 100644 options/locale_next/locale_es-ES.json create mode 100644 options/locale_next/locale_et.json create mode 100644 options/locale_next/locale_fa-IR.json create mode 100644 options/locale_next/locale_fi-FI.json create mode 100644 options/locale_next/locale_fil.json create mode 100644 options/locale_next/locale_fr-FR.json create mode 100644 options/locale_next/locale_gl.json create mode 100644 options/locale_next/locale_hi.json create mode 100644 options/locale_next/locale_hu-HU.json create mode 100644 options/locale_next/locale_id-ID.json create mode 100644 options/locale_next/locale_is-IS.json create mode 100644 options/locale_next/locale_it-IT.json create mode 100644 options/locale_next/locale_ja-JP.json create mode 100644 options/locale_next/locale_ko-KR.json create mode 100644 options/locale_next/locale_lt.json create mode 100644 options/locale_next/locale_lv-LV.json create mode 100644 options/locale_next/locale_ml-IN.json create mode 100644 options/locale_next/locale_nb_NO.json create mode 100644 options/locale_next/locale_nds.json create mode 100644 options/locale_next/locale_nl-NL.json create mode 100644 options/locale_next/locale_pl-PL.json create mode 100644 options/locale_next/locale_pt-BR.json create mode 100644 options/locale_next/locale_pt-PT.json create mode 100644 options/locale_next/locale_ru-RU.json create mode 100644 options/locale_next/locale_si-LK.json create mode 100644 options/locale_next/locale_sk-SK.json create mode 100644 options/locale_next/locale_sl.json create mode 100644 options/locale_next/locale_sr-SP.json create mode 100644 options/locale_next/locale_sv-SE.json create mode 100644 options/locale_next/locale_tr-TR.json create mode 100644 options/locale_next/locale_uk-UA.json create mode 100644 options/locale_next/locale_vi.json create mode 100644 options/locale_next/locale_yi.json create mode 100644 options/locale_next/locale_zh-CN.json create mode 100644 options/locale_next/locale_zh-HK.json create mode 100644 options/locale_next/locale_zh-TW.json create mode 100755 tools/migrate_locales.sh diff --git a/.deadcode-out b/.deadcode-out index 64741ec7ac..a44599b6f1 100644 --- a/.deadcode-out +++ b/.deadcode-out @@ -246,6 +246,7 @@ code.gitea.io/gitea/modules/translation MockLocale.TrString MockLocale.Tr MockLocale.TrN + MockLocale.TrPluralString MockLocale.TrSize MockLocale.PrettyNumber diff --git a/modules/translation/i18n/dummy.go b/modules/translation/i18n/dummy.go index fe15c250f4..861672c619 100644 --- a/modules/translation/i18n/dummy.go +++ b/modules/translation/i18n/dummy.go @@ -22,20 +22,7 @@ func (k *KeyLocale) HasKey(trKey string) bool { // TrHTML implements Locale. func (k *KeyLocale) TrHTML(trKey string, trArgs ...any) template.HTML { - args := slices.Clone(trArgs) - for i, v := range args { - switch v := v.(type) { - case nil, bool, int, int8, int16, int32, int64, uint, uint8, uint16, uint32, uint64, float32, float64, template.HTML: - // for most basic types (including template.HTML which is safe), just do nothing and use it - case string: - args[i] = template.HTMLEscapeString(v) - case fmt.Stringer: - args[i] = template.HTMLEscapeString(v.String()) - default: - args[i] = template.HTMLEscapeString(fmt.Sprint(v)) - } - } - return template.HTML(k.TrString(trKey, args...)) + return template.HTML(k.TrString(trKey, PrepareArgsForHTML(trArgs...)...)) } // TrString implements Locale. @@ -43,6 +30,11 @@ func (k *KeyLocale) TrString(trKey string, trArgs ...any) string { return FormatDummy(trKey, trArgs...) } +// TrPluralString implements Locale. +func (k *KeyLocale) TrPluralString(count any, trKey string, trArgs ...any) template.HTML { + return template.HTML(FormatDummy(trKey, PrepareArgsForHTML(trArgs...)...)) +} + func FormatDummy(trKey string, args ...any) string { if len(args) == 0 { return fmt.Sprintf("(%s)", trKey) diff --git a/modules/translation/i18n/errors.go b/modules/translation/i18n/errors.go index 7f64ccf908..ee9436a8f7 100644 --- a/modules/translation/i18n/errors.go +++ b/modules/translation/i18n/errors.go @@ -8,6 +8,8 @@ import ( ) var ( - ErrLocaleAlreadyExist = util.SilentWrap{Message: "lang already exists", Err: util.ErrAlreadyExist} - ErrUncertainArguments = util.SilentWrap{Message: "arguments to i18n should not contain uncertain slices", Err: util.ErrInvalidArgument} + ErrLocaleAlreadyExist = util.SilentWrap{Message: "lang already exists", Err: util.ErrAlreadyExist} + ErrLocaleDoesNotExist = util.SilentWrap{Message: "lang does not exist", Err: util.ErrNotExist} + ErrTranslationDoesNotExist = util.SilentWrap{Message: "translation does not exist", Err: util.ErrNotExist} + ErrUncertainArguments = util.SilentWrap{Message: "arguments to i18n should not contain uncertain slices", Err: util.ErrInvalidArgument} ) diff --git a/modules/translation/i18n/i18n.go b/modules/translation/i18n/i18n.go index 1555cd961e..e447502a3b 100644 --- a/modules/translation/i18n/i18n.go +++ b/modules/translation/i18n/i18n.go @@ -8,11 +8,28 @@ import ( "io" ) +type ( + PluralFormIndex uint8 + PluralFormRule func(int64) PluralFormIndex +) + +const ( + PluralFormZero PluralFormIndex = iota + PluralFormOne + PluralFormTwo + PluralFormFew + PluralFormMany + PluralFormOther +) + var DefaultLocales = NewLocaleStore() type Locale interface { // TrString translates a given key and arguments for a language TrString(trKey string, trArgs ...any) string + // TrPluralString translates a given pluralized key and arguments for a language. + // This function returns an error if new-style support for the given key is not available. + TrPluralString(count any, trKey string, trArgs ...any) template.HTML // TrHTML translates a given key and arguments for a language, string arguments are escaped to HTML TrHTML(trKey string, trArgs ...any) template.HTML // HasKey reports if a locale has a translation for a given key @@ -31,8 +48,10 @@ type LocaleStore interface { Locale(langName string) (Locale, bool) // HasLang returns whether a given language is present in the store HasLang(langName string) bool - // AddLocaleByIni adds a new language to the store - AddLocaleByIni(langName, langDesc string, source, moreSource []byte) error + // AddLocaleByIni adds a new old-style language to the store + AddLocaleByIni(langName, langDesc string, pluralRule PluralFormRule, source, moreSource []byte) error + // AddLocaleByJSON adds new-style content to an existing language to the store + AddToLocaleFromJSON(langName string, source []byte) error } // ResetDefaultLocales resets the current default locales diff --git a/modules/translation/i18n/i18n_test.go b/modules/translation/i18n/i18n_test.go index 244f6ffbb3..41f85931aa 100644 --- a/modules/translation/i18n/i18n_test.go +++ b/modules/translation/i18n/i18n_test.go @@ -12,6 +12,26 @@ import ( "github.com/stretchr/testify/require" ) +var MockPluralRule PluralFormRule = func(n int64) PluralFormIndex { + if n == 0 { + return PluralFormZero + } + if n == 1 { + return PluralFormOne + } + if n >= 2 && n <= 4 { + return PluralFormFew + } + return PluralFormOther +} + +var MockPluralRuleEnglish PluralFormRule = func(n int64) PluralFormIndex { + if n == 1 { + return PluralFormOne + } + return PluralFormOther +} + func TestLocaleStore(t *testing.T) { testData1 := []byte(` .dot.name = Dot Name @@ -27,11 +47,48 @@ fmt = %[2]s %[1]s [section] sub = Changed Sub String +commits = fallback value for commits +`) + + testDataJSON2 := []byte(` +{ + "section.json": "the JSON is %s", + "section.commits": { + "one": "one %d commit", + "few": "some %d commits", + "other": "lots of %d commits" + }, + "section.incomplete": { + "few": "some %d objects (translated)" + }, + "nested": { + "outer": { + "inner": { + "json": "Hello World", + "issue": { + "one": "one %d issue", + "few": "some %d issues", + "other": "lots of %d issues" + } + } + } + } +} +`) + testDataJSON1 := []byte(` +{ + "section.incomplete": { + "one": "[untranslated] some %d object", + "other": "[untranslated] some %d objects" + } +} `) ls := NewLocaleStore() - require.NoError(t, ls.AddLocaleByIni("lang1", "Lang1", testData1, nil)) - require.NoError(t, ls.AddLocaleByIni("lang2", "Lang2", testData2, nil)) + require.NoError(t, ls.AddLocaleByIni("lang1", "Lang1", MockPluralRuleEnglish, testData1, nil)) + require.NoError(t, ls.AddLocaleByIni("lang2", "Lang2", MockPluralRule, testData2, nil)) + require.NoError(t, ls.AddToLocaleFromJSON("lang1", testDataJSON1)) + require.NoError(t, ls.AddToLocaleFromJSON("lang2", testDataJSON2)) ls.SetDefaultLang("lang1") lang1, _ := ls.Locale("lang1") @@ -56,6 +113,45 @@ sub = Changed Sub String result2 := lang2.TrHTML("section.mixed", "a&b") assert.EqualValues(t, `test value; a&b`, result2) + result = lang2.TrString("section.json", "valid") + assert.Equal(t, "the JSON is valid", result) + + result = lang2.TrString("nested.outer.inner.json") + assert.Equal(t, "Hello World", result) + + result = lang2.TrString("section.commits") + assert.Equal(t, "lots of %d commits", result) + + result2 = lang2.TrPluralString(1, "section.commits", 1) + assert.EqualValues(t, "one 1 commit", result2) + + result2 = lang2.TrPluralString(3, "section.commits", 3) + assert.EqualValues(t, "some 3 commits", result2) + + result2 = lang2.TrPluralString(8, "section.commits", 8) + assert.EqualValues(t, "lots of 8 commits", result2) + + result2 = lang2.TrPluralString(0, "section.commits") + assert.EqualValues(t, "section.commits", result2) + + result2 = lang2.TrPluralString(1, "nested.outer.inner.issue", 1) + assert.EqualValues(t, "one 1 issue", result2) + + result2 = lang2.TrPluralString(3, "nested.outer.inner.issue", 3) + assert.EqualValues(t, "some 3 issues", result2) + + result2 = lang2.TrPluralString(9, "nested.outer.inner.issue", 9) + assert.EqualValues(t, "lots of 9 issues", result2) + + result2 = lang2.TrPluralString(3, "section.incomplete", 3) + assert.EqualValues(t, "some 3 objects (translated)", result2) + + result2 = lang2.TrPluralString(1, "section.incomplete", 1) + assert.EqualValues(t, "[untranslated] some 1 object", result2) + + result2 = lang2.TrPluralString(7, "section.incomplete", 7) + assert.EqualValues(t, "[untranslated] some 7 objects", result2) + langs, descs := ls.ListLangNameDesc() assert.ElementsMatch(t, []string{"lang1", "lang2"}, langs) assert.ElementsMatch(t, []string{"Lang1", "Lang2"}, descs) @@ -77,7 +173,7 @@ c=22 `) ls := NewLocaleStore() - require.NoError(t, ls.AddLocaleByIni("lang1", "Lang1", testData1, testData2)) + require.NoError(t, ls.AddLocaleByIni("lang1", "Lang1", MockPluralRule, testData1, testData2)) lang1, _ := ls.Locale("lang1") assert.Equal(t, "11", lang1.TrString("a")) assert.Equal(t, "21", lang1.TrString("b")) @@ -118,7 +214,7 @@ func (e *errorPointerReceiver) Error() string { func TestLocaleWithTemplate(t *testing.T) { ls := NewLocaleStore() - require.NoError(t, ls.AddLocaleByIni("lang1", "Lang1", []byte(`key=%s`), nil)) + require.NoError(t, ls.AddLocaleByIni("lang1", "Lang1", MockPluralRule, []byte(`key=%s`), nil)) lang1, _ := ls.Locale("lang1") tmpl := template.New("test").Funcs(template.FuncMap{"tr": lang1.TrHTML}) @@ -181,7 +277,7 @@ func TestLocaleStoreQuirks(t *testing.T) { for _, testData := range testDataList { ls := NewLocaleStore() - err := ls.AddLocaleByIni("lang1", "Lang1", []byte("a="+testData.in), nil) + err := ls.AddLocaleByIni("lang1", "Lang1", nil, []byte("a="+testData.in), nil) lang1, _ := ls.Locale("lang1") require.NoError(t, err, testData.hint) assert.Equal(t, testData.out, lang1.TrString("a"), testData.hint) diff --git a/modules/translation/i18n/localestore.go b/modules/translation/i18n/localestore.go index 0e6ddab401..e80b2592ae 100644 --- a/modules/translation/i18n/localestore.go +++ b/modules/translation/i18n/localestore.go @@ -8,8 +8,10 @@ import ( "html/template" "slices" + "code.gitea.io/gitea/modules/json" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/setting" + "code.gitea.io/gitea/modules/util" ) // This file implements the static LocaleStore that will not watch for changes @@ -18,6 +20,9 @@ type locale struct { store *localeStore langName string idxToMsgMap map[int]string // the map idx is generated by store's trKeyToIdxMap + + newStyleMessages map[string]string + pluralRule PluralFormRule } var _ Locale = (*locale)(nil) @@ -38,8 +43,19 @@ func NewLocaleStore() LocaleStore { return &localeStore{localeMap: make(map[string]*locale), trKeyToIdxMap: make(map[string]int)} } +const ( + PluralFormSeparator string = "\036" +) + +// A note about pluralization rules. +// go-i18n supports plural rules in theory. +// In practice, it relies on another library that hardcodes a list of common languages +// and their plural rules, and does not support languages not hardcoded there. +// So we pretend that all languages are English and use our own function to extract +// the correct plural form for a given count and language. + // AddLocaleByIni adds locale by ini into the store -func (store *localeStore) AddLocaleByIni(langName, langDesc string, source, moreSource []byte) error { +func (store *localeStore) AddLocaleByIni(langName, langDesc string, pluralRule PluralFormRule, source, moreSource []byte) error { if _, ok := store.localeMap[langName]; ok { return ErrLocaleAlreadyExist } @@ -47,7 +63,7 @@ func (store *localeStore) AddLocaleByIni(langName, langDesc string, source, more store.langNames = append(store.langNames, langName) store.langDescs = append(store.langDescs, langDesc) - l := &locale{store: store, langName: langName, idxToMsgMap: make(map[int]string)} + l := &locale{store: store, langName: langName, idxToMsgMap: make(map[int]string), pluralRule: pluralRule, newStyleMessages: make(map[string]string)} store.localeMap[l.langName] = l iniFile, err := setting.NewConfigProviderForLocale(source, moreSource) @@ -78,6 +94,98 @@ func (store *localeStore) AddLocaleByIni(langName, langDesc string, source, more return nil } +func RecursivelyAddTranslationsFromJSON(locale *locale, object map[string]any, prefix string) error { + for key, value := range object { + var fullkey string + if prefix != "" { + fullkey = prefix + "." + key + } else { + fullkey = key + } + + switch v := value.(type) { + case string: + // Check whether we are adding a plural form to the parent object, or a new nested JSON object. + + if key == "zero" || key == "one" || key == "two" || key == "few" || key == "many" { + locale.newStyleMessages[prefix+PluralFormSeparator+key] = v + } else if key == "other" { + locale.newStyleMessages[prefix] = v + } else { + locale.newStyleMessages[fullkey] = v + } + + case map[string]any: + err := RecursivelyAddTranslationsFromJSON(locale, v, fullkey) + if err != nil { + return err + } + + case nil: + default: + return fmt.Errorf("Unrecognized JSON value '%s'", value) + } + } + + return nil +} + +func (store *localeStore) AddToLocaleFromJSON(langName string, source []byte) error { + locale, ok := store.localeMap[langName] + if !ok { + return ErrLocaleDoesNotExist + } + + var result map[string]any + if err := json.Unmarshal(source, &result); err != nil { + return err + } + + return RecursivelyAddTranslationsFromJSON(locale, result, "") +} + +func (l *locale) LookupNewStyleMessage(trKey string) string { + if msg, ok := l.newStyleMessages[trKey]; ok { + return msg + } + return "" +} + +func (l *locale) LookupPlural(trKey string, count any) string { + n, err := util.ToInt64(count) + if err != nil { + log.Error("Invalid plural count '%s'", count) + return "" + } + + pluralForm := l.pluralRule(n) + suffix := "" + switch pluralForm { + case PluralFormZero: + suffix = PluralFormSeparator + "zero" + case PluralFormOne: + suffix = PluralFormSeparator + "one" + case PluralFormTwo: + suffix = PluralFormSeparator + "two" + case PluralFormFew: + suffix = PluralFormSeparator + "few" + case PluralFormMany: + suffix = PluralFormSeparator + "many" + case PluralFormOther: + // No suffix for the "other" string. + default: + log.Error("Invalid plural form index %d for count %d", pluralForm, count) + return "" + } + + if result, ok := l.newStyleMessages[trKey+suffix]; ok { + return result + } + + log.Error("Missing translation for plural form index %d for count %d", pluralForm, count) + return "" +} + func (store *localeStore) HasLang(langName string) bool { _, ok := store.localeMap[langName] return ok @@ -113,22 +221,37 @@ func (store *localeStore) Close() error { func (l *locale) TrString(trKey string, trArgs ...any) string { format := trKey - idx, ok := l.store.trKeyToIdxMap[trKey] - found := false - if ok { - if msg, ok := l.idxToMsgMap[idx]; ok { - format = msg // use the found translation - found = true - } else if def, ok := l.store.localeMap[l.store.defaultLang]; ok { - // try to use default locale's translation - if msg, ok := def.idxToMsgMap[idx]; ok { - format = msg + if msg := l.LookupNewStyleMessage(trKey); msg != "" { + format = msg + } else { + // First fallback: old-style translation + idx, ok := l.store.trKeyToIdxMap[trKey] + found := false + if ok { + if msg, ok := l.idxToMsgMap[idx]; ok { + format = msg // use the found translation found = true } } - } - if !found { - log.Error("Missing translation %q", trKey) + + if !found { + // Second fallback: new-style default language + if defaultLang, ok := l.store.localeMap[l.store.defaultLang]; ok { + if msg := defaultLang.LookupNewStyleMessage(trKey); msg != "" { + format = msg + } else { + // Third fallback: old-style default language + if msg, ok := defaultLang.idxToMsgMap[idx]; ok { + format = msg + found = true + } + } + } + + if !found { + log.Error("Missing translation %q", trKey) + } + } } msg, err := Format(format, trArgs...) @@ -138,7 +261,7 @@ func (l *locale) TrString(trKey string, trArgs ...any) string { return msg } -func (l *locale) TrHTML(trKey string, trArgs ...any) template.HTML { +func PrepareArgsForHTML(trArgs ...any) []any { args := slices.Clone(trArgs) for i, v := range args { switch v := v.(type) { @@ -152,7 +275,30 @@ func (l *locale) TrHTML(trKey string, trArgs ...any) template.HTML { args[i] = template.HTMLEscapeString(fmt.Sprint(v)) } } - return template.HTML(l.TrString(trKey, args...)) + return args +} + +func (l *locale) TrHTML(trKey string, trArgs ...any) template.HTML { + return template.HTML(l.TrString(trKey, PrepareArgsForHTML(trArgs...)...)) +} + +func (l *locale) TrPluralString(count any, trKey string, trArgs ...any) template.HTML { + message := l.LookupPlural(trKey, count) + + if message == "" { + if defaultLang, ok := l.store.localeMap[l.store.defaultLang]; ok { + message = defaultLang.LookupPlural(trKey, count) + } + if message == "" { + message = trKey + } + } + + message, err := Format(message, PrepareArgsForHTML(trArgs...)...) + if err != nil { + log.Error("Error whilst formatting %q in %s: %v", trKey, l.langName, err) + } + return template.HTML(message) } // HasKey returns whether a key is present in this locale or not diff --git a/modules/translation/mock.go b/modules/translation/mock.go index fe3a1502ea..4d9acce26f 100644 --- a/modules/translation/mock.go +++ b/modules/translation/mock.go @@ -31,6 +31,10 @@ func (l MockLocale) TrN(cnt any, key1, keyN string, args ...any) template.HTML { return template.HTML(key1) } +func (l MockLocale) TrPluralString(count any, trKey string, trArgs ...any) template.HTML { + return template.HTML(trKey) +} + func (l MockLocale) TrSize(s int64) ReadableSize { return ReadableSize{fmt.Sprint(s), ""} } diff --git a/modules/translation/plural_rules.go b/modules/translation/plural_rules.go new file mode 100644 index 0000000000..b8c00ceef7 --- /dev/null +++ b/modules/translation/plural_rules.go @@ -0,0 +1,253 @@ +// Copyright 2024 The Forgejo Authors. All rights reserved. +// SPDX-License-Identifier: MIT + +// Some useful links: +// https://www.unicode.org/cldr/charts/46/supplemental/language_plural_rules.html +// https://translate.codeberg.org/languages/$LANGUAGE_CODE/#information +// https://github.com/WeblateOrg/language-data/blob/main/languages.csv +// Note that in some cases there is ambiguity about the correct form for a given language. In this case, ask the locale's translators. + +package translation + +import ( + "strings" + + "code.gitea.io/gitea/modules/log" + "code.gitea.io/gitea/modules/translation/i18n" +) + +// The constants refer to indices below in `PluralRules` and also in i18n.js, keep them in sync! +const ( + PluralRuleDefault = 0 + PluralRuleBengali = 1 + PluralRuleIcelandic = 2 + PluralRuleFilipino = 3 + PluralRuleOneForm = 4 + PluralRuleCzech = 5 + PluralRuleRussian = 6 + PluralRulePolish = 7 + PluralRuleLatvian = 8 + PluralRuleLithuanian = 9 + PluralRuleFrench = 10 + PluralRuleCatalan = 11 + PluralRuleSlovenian = 12 + PluralRuleArabic = 13 +) + +func GetPluralRuleImpl(langName string) int { + // First, check for languages with country-specific plural rules. + switch langName { + case "pt-BR": + return PluralRuleFrench + + case "pt-PT": + return PluralRuleCatalan + + default: + break + } + + // Remove the country portion of the locale name. + langName = strings.Split(strings.Split(langName, "_")[0], "-")[0] + + // When adding a new language not in the list, add its plural rule definition here. + switch langName { + case "en", "aa", "ab", "abr", "ada", "ae", "aeb", "af", "afh", "aii", "ain", "akk", "ale", "aln", "alt", "ami", "an", "ang", "anp", "apc", "arc", "arp", "arq", "arw", "arz", "asa", "ast", "av", "avk", "awa", "ayc", "az", "azb", "ba", "bal", "ban", "bar", "bas", "bbc", "bci", "bej", "bem", "ber", "bew", "bez", "bg", "bgc", "bgn", "bhb", "bhi", "bi", "bik", "bin", "bjj", "bjn", "bla", "bnt", "bqi", "bra", "brb", "brh", "brx", "bua", "bug", "bum", "byn", "cad", "cak", "car", "ce", "cgg", "ch", "chb", "chg", "chk", "chm", "chn", "cho", "chp", "chr", "chy", "ckb", "co", "cop", "cpe", "cpf", "cr", "crp", "cu", "cv", "da", "dak", "dar", "dcc", "de", "del", "den", "dgr", "din", "dje", "dnj", "dnk", "dru", "dry", "dua", "dum", "dv", "dyu", "ee", "efi", "egl", "egy", "eka", "el", "elx", "enm", "eo", "et", "eu", "ewo", "ext", "fan", "fat", "fbl", "ffm", "fi", "fj", "fo", "fon", "frk", "frm", "fro", "frr", "frs", "fuq", "fur", "fuv", "fvr", "fy", "gaa", "gay", "gba", "gbm", "gez", "gil", "gl", "glk", "gmh", "gn", "goh", "gom", "gon", "gor", "got", "grb", "gsw", "guc", "gum", "gur", "guz", "gwi", "ha", "hai", "haw", "haz", "hil", "hit", "hmn", "hnd", "hne", "hno", "ho", "hoc", "hoj", "hrx", "ht", "hu", "hup", "hus", "hz", "ia", "iba", "ibb", "ie", "ik", "ilo", "inh", "io", "jam", "jgo", "jmc", "jpr", "jrb", "ka", "kaa", "kac", "kaj", "kam", "kaw", "kbd", "kcg", "kfr", "kfy", "kg", "kha", "khn", "kho", "ki", "kj", "kk", "kkj", "kl", "kln", "kmb", "kmr", "kok", "kpe", "kr", "krc", "kri", "krl", "kru", "ks", "ksb", "ku", "kum", "kut", "kv", "kxm", "ky", "la", "lad", "laj", "lam", "lb", "lez", "lfn", "lg", "li", "lij", "ljp", "lki", "lmn", "lmo", "lol", "loz", "lrc", "lu", "lua", "lui", "lun", "luo", "lus", "luy", "luz", "mad", "mag", "mai", "mak", "man", "mas", "mdf", "mdh", "mdr", "men", "mer", "mfa", "mga", "mgh", "mgo", "mh", "mhr", "mic", "min", "mjw", "ml", "mn", "mnc", "mni", "mnw", "moe", "moh", "mos", "mr", "mrh", "mtr", "mus", "mwk", "mwl", "mwr", "mxc", "myv", "myx", "mzn", "na", "nah", "nap", "nb", "nd", "ndc", "nds", "ne", "new", "ng", "ngl", "nia", "nij", "niu", "nl", "nn", "nnh", "nod", "noe", "nog", "non", "nr", "nuk", "nv", "nwc", "ny", "nym", "nyn", "nyo", "nzi", "oj", "om", "or", "os", "ota", "otk", "ovd", "pag", "pal", "pam", "pap", "pau", "pbb", "pdt", "peo", "phn", "pi", "pms", "pon", "pro", "ps", "pwn", "qu", "quc", "qug", "qya", "raj", "rap", "rar", "rcf", "rej", "rhg", "rif", "rkt", "rm", "rmt", "rn", "rng", "rof", "rom", "rue", "rup", "rw", "rwk", "sad", "sai", "sam", "saq", "sas", "sc", "sck", "sco", "sd", "sdh", "sef", "seh", "sel", "sga", "sgn", "sgs", "shn", "sid", "sjd", "skr", "sm", "sml", "sn", "snk", "so", "sog", "sou", "sq", "srn", "srr", "ss", "ssy", "st", "suk", "sus", "sux", "sv", "sw", "swg", "swv", "sxu", "syc", "syl", "syr", "szy", "ta", "tay", "tcy", "te", "tem", "teo", "ter", "tet", "tig", "tiv", "tk", "tkl", "tli", "tly", "tmh", "tn", "tog", "tr", "trv", "ts", "tsg", "tsi", "tsj", "tts", "tum", "tvl", "tw", "ty", "tyv", "tzj", "tzl", "udm", "ug", "uga", "umb", "und", "unr", "ur", "uz", "vai", "ve", "vls", "vmf", "vmw", "vo", "vot", "vro", "vun", "wae", "wal", "war", "was", "wbq", "wbr", "wep", "wtm", "xal", "xh", "xnr", "xog", "yao", "yap", "yi", "yua", "za", "zap", "zbl", "zen", "zgh", "zun", "zza": + return PluralRuleDefault + + case "ach", "ady", "ak", "am", "arn", "as", "bh", "bho", "bn", "csw", "doi", "fa", "ff", "frc", "frp", "gu", "gug", "gun", "guw", "hi", "hy", "kab", "kn", "ln", "mfe", "mg", "mi", "mia", "nso", "oc", "pa", "pcm", "pt", "qdt", "qtp", "si", "tg", "ti", "wa", "zu": + return PluralRuleBengali + + case "is": + return PluralRuleIcelandic + + case "fil": + return PluralRuleFilipino + + case "ace", "ay", "bm", "bo", "cdo", "cpx", "crh", "dz", "gan", "hak", "hnj", "hsn", "id", "ig", "ii", "ja", "jbo", "jv", "kde", "kea", "km", "ko", "kos", "lkt", "lo", "lzh", "ms", "my", "nan", "nqo", "osa", "sah", "ses", "sg", "son", "su", "th", "tlh", "to", "tok", "tpi", "tt", "vi", "wo", "wuu", "yo", "yue", "zh": + return PluralRuleOneForm + + case "cpp", "cs", "sk": + return PluralRuleCzech + + case "be", "bs", "cnr", "hr", "ru", "sr", "uk", "wen": + return PluralRuleRussian + + case "csb", "pl", "szl": + return PluralRulePolish + + case "lv", "prg": + return PluralRuleLatvian + + case "lt": + return PluralRuleLithuanian + + case "fr": + return PluralRuleFrench + + case "ca", "es", "it": + return PluralRuleCatalan + + case "sl": + return PluralRuleSlovenian + + case "ar": + return PluralRuleArabic + + default: + break + } + + log.Error("No plural rule defined for language %s", langName) + return PluralRuleDefault +} + +var PluralRules = []i18n.PluralFormRule{ + // [ 0] Common 2-form, e.g. English, German + func(n int64) i18n.PluralFormIndex { + if n != 1 { + return i18n.PluralFormOther + } + return i18n.PluralFormOne + }, + + // [ 1] Bengali + func(n int64) i18n.PluralFormIndex { + if n > 1 { + return i18n.PluralFormOther + } + return i18n.PluralFormOne + }, + + // [ 2] Icelandic + func(n int64) i18n.PluralFormIndex { + if n%10 != 1 || n%100 == 11 { + return i18n.PluralFormOther + } + return i18n.PluralFormOne + }, + + // [ 3] Filipino + func(n int64) i18n.PluralFormIndex { + if n != 1 && n != 2 && n != 3 && (n%10 == 4 || n%10 == 6 || n%10 == 9) { + return i18n.PluralFormOther + } + return i18n.PluralFormOne + }, + + // [ 4] OneForm + func(n int64) i18n.PluralFormIndex { + return i18n.PluralFormOther + }, + + // [ 5] Czech + func(n int64) i18n.PluralFormIndex { + if n == 1 { + return i18n.PluralFormOne + } + if n >= 2 && n <= 4 { + return i18n.PluralFormFew + } + return i18n.PluralFormOther + }, + + // [ 6] Russian + func(n int64) i18n.PluralFormIndex { + if n%10 == 1 && n%100 != 11 { + return i18n.PluralFormOne + } + if n%10 >= 2 && n%10 <= 4 && (n%100 < 10 || n%100 >= 20) { + return i18n.PluralFormFew + } + return i18n.PluralFormMany + }, + + // [ 7] Polish + func(n int64) i18n.PluralFormIndex { + if n == 1 { + return i18n.PluralFormOne + } + if n%10 >= 2 && n%10 <= 4 && (n%100 < 10 || n%100 >= 20) { + return i18n.PluralFormFew + } + return i18n.PluralFormMany + }, + + // [ 8] Latvian + func(n int64) i18n.PluralFormIndex { + if n%10 == 0 || n%100 >= 11 && n%100 <= 19 { + return i18n.PluralFormZero + } + if n%10 == 1 && n%100 != 11 { + return i18n.PluralFormOne + } + return i18n.PluralFormOther + }, + + // [ 9] Lithuanian + func(n int64) i18n.PluralFormIndex { + if n%10 == 1 && (n%100 < 11 || n%100 > 19) { + return i18n.PluralFormOne + } + if n%10 >= 2 && n%10 <= 9 && (n%100 < 11 || n%100 > 19) { + return i18n.PluralFormFew + } + return i18n.PluralFormMany + }, + + // [10] French + func(n int64) i18n.PluralFormIndex { + if n == 0 || n == 1 { + return i18n.PluralFormOne + } + if n != 0 && n%1000000 == 0 { + return i18n.PluralFormMany + } + return i18n.PluralFormOther + }, + + // [11] Catalan + func(n int64) i18n.PluralFormIndex { + if n == 1 { + return i18n.PluralFormOne + } + if n != 0 && n%1000000 == 0 { + return i18n.PluralFormMany + } + return i18n.PluralFormOther + }, + + // [12] Slovenian + func(n int64) i18n.PluralFormIndex { + if n%100 == 1 { + return i18n.PluralFormOne + } + if n%100 == 2 { + return i18n.PluralFormTwo + } + if n%100 == 3 || n%100 == 4 { + return i18n.PluralFormFew + } + return i18n.PluralFormOther + }, + + // [13] Arabic + func(n int64) i18n.PluralFormIndex { + if n == 0 { + return i18n.PluralFormZero + } + if n == 1 { + return i18n.PluralFormOne + } + if n == 2 { + return i18n.PluralFormTwo + } + if n%100 >= 3 && n%100 <= 10 { + return i18n.PluralFormFew + } + if n%100 >= 11 { + return i18n.PluralFormMany + } + return i18n.PluralFormOther + }, +} diff --git a/modules/translation/translation.go b/modules/translation/translation.go index 6687d3d817..7d1c627c84 100644 --- a/modules/translation/translation.go +++ b/modules/translation/translation.go @@ -32,6 +32,9 @@ type Locale interface { TrString(string, ...any) string Tr(key string, args ...any) template.HTML + // New-style pluralized strings + TrPluralString(count any, trKey string, trArgs ...any) template.HTML + // Old-style pseudo-pluralized strings, deprecated TrN(cnt any, key1, keyN string, args ...any) template.HTML TrSize(size int64) ReadableSize @@ -100,8 +103,17 @@ func InitLocales(ctx context.Context) { } key := "locale_" + setting.Langs[i] + ".ini" - if err = i18n.DefaultLocales.AddLocaleByIni(setting.Langs[i], setting.Names[i], localeDataBase, localeData[key]); err != nil { - log.Error("Failed to set messages to %s: %v", setting.Langs[i], err) + if err = i18n.DefaultLocales.AddLocaleByIni(setting.Langs[i], setting.Names[i], PluralRules[GetPluralRuleImpl(setting.Langs[i])], localeDataBase, localeData[key]); err != nil { + log.Error("Failed to set old-style messages to %s: %v", setting.Langs[i], err) + } + + key = "locale_next/locale_" + setting.Langs[i] + ".json" + if bytes, err := options.AssetFS().ReadFile(key); err == nil { + if err = i18n.DefaultLocales.AddToLocaleFromJSON(setting.Langs[i], bytes); err != nil { + log.Error("Failed to add new-style messages to %s: %v", setting.Langs[i], err) + } + } else { + log.Error("Failed to open new-style messages for %s: %v", setting.Langs[i], err) } } if len(setting.Langs) != 0 { diff --git a/modules/translation/translation_test.go b/modules/translation/translation_test.go index bffbb155ca..5b3eefb355 100644 --- a/modules/translation/translation_test.go +++ b/modules/translation/translation_test.go @@ -48,3 +48,111 @@ func TestPrettyNumber(t *testing.T) { assert.EqualValues(t, "1,000,000", l.PrettyNumber(1000000)) assert.EqualValues(t, "1,000,000.1", l.PrettyNumber(1000000.1)) } + +func TestGetPluralRule(t *testing.T) { + assert.Equal(t, PluralRuleDefault, GetPluralRuleImpl("en")) + assert.Equal(t, PluralRuleDefault, GetPluralRuleImpl("en-US")) + assert.Equal(t, PluralRuleDefault, GetPluralRuleImpl("en_UK")) + assert.Equal(t, PluralRuleDefault, GetPluralRuleImpl("nds")) + assert.Equal(t, PluralRuleDefault, GetPluralRuleImpl("de-DE")) + + assert.Equal(t, PluralRuleOneForm, GetPluralRuleImpl("zh")) + assert.Equal(t, PluralRuleOneForm, GetPluralRuleImpl("ja")) + + assert.Equal(t, PluralRuleBengali, GetPluralRuleImpl("bn")) + + assert.Equal(t, PluralRuleIcelandic, GetPluralRuleImpl("is")) + + assert.Equal(t, PluralRuleFilipino, GetPluralRuleImpl("fil")) + + assert.Equal(t, PluralRuleCzech, GetPluralRuleImpl("cs")) + + assert.Equal(t, PluralRuleRussian, GetPluralRuleImpl("ru")) + + assert.Equal(t, PluralRulePolish, GetPluralRuleImpl("pl")) + + assert.Equal(t, PluralRuleLatvian, GetPluralRuleImpl("lv")) + + assert.Equal(t, PluralRuleLithuanian, GetPluralRuleImpl("lt")) + + assert.Equal(t, PluralRuleFrench, GetPluralRuleImpl("fr")) + + assert.Equal(t, PluralRuleCatalan, GetPluralRuleImpl("ca")) + + assert.Equal(t, PluralRuleSlovenian, GetPluralRuleImpl("sl")) + + assert.Equal(t, PluralRuleArabic, GetPluralRuleImpl("ar")) + + assert.Equal(t, PluralRuleCatalan, GetPluralRuleImpl("pt-PT")) + assert.Equal(t, PluralRuleFrench, GetPluralRuleImpl("pt-BR")) + + assert.Equal(t, PluralRuleDefault, GetPluralRuleImpl("invalid")) +} + +func TestApplyPluralRule(t *testing.T) { + testCases := []struct { + expect i18n.PluralFormIndex + pluralRule int + values []int64 + }{ + {i18n.PluralFormOne, PluralRuleDefault, []int64{1}}, + {i18n.PluralFormOther, PluralRuleDefault, []int64{0, 2, 10, 256}}, + + {i18n.PluralFormOther, PluralRuleOneForm, []int64{0, 1, 2}}, + + {i18n.PluralFormOne, PluralRuleBengali, []int64{0, 1}}, + {i18n.PluralFormOther, PluralRuleBengali, []int64{2, 10, 256}}, + + {i18n.PluralFormOne, PluralRuleIcelandic, []int64{1, 21, 31}}, + {i18n.PluralFormOther, PluralRuleIcelandic, []int64{0, 2, 11, 15, 256}}, + + {i18n.PluralFormOne, PluralRuleFilipino, []int64{0, 1, 2, 3, 5, 7, 8, 10, 11, 12, 257}}, + {i18n.PluralFormOther, PluralRuleFilipino, []int64{4, 6, 9, 14, 16, 19, 256}}, + + {i18n.PluralFormOne, PluralRuleCzech, []int64{1}}, + {i18n.PluralFormFew, PluralRuleCzech, []int64{2, 3, 4}}, + {i18n.PluralFormOther, PluralRuleCzech, []int64{5, 0, 12, 78, 254}}, + + {i18n.PluralFormOne, PluralRuleRussian, []int64{1, 21, 31}}, + {i18n.PluralFormFew, PluralRuleRussian, []int64{2, 23, 34}}, + {i18n.PluralFormMany, PluralRuleRussian, []int64{0, 5, 11, 37, 111, 256}}, + + {i18n.PluralFormOne, PluralRulePolish, []int64{1}}, + {i18n.PluralFormFew, PluralRulePolish, []int64{2, 23, 34}}, + {i18n.PluralFormMany, PluralRulePolish, []int64{0, 5, 11, 21, 37, 256}}, + + {i18n.PluralFormZero, PluralRuleLatvian, []int64{0, 10, 11, 17}}, + {i18n.PluralFormOne, PluralRuleLatvian, []int64{1, 21, 71}}, + {i18n.PluralFormOther, PluralRuleLatvian, []int64{2, 7, 22, 23, 256}}, + + {i18n.PluralFormOne, PluralRuleLithuanian, []int64{1, 21, 31}}, + {i18n.PluralFormFew, PluralRuleLithuanian, []int64{2, 5, 9, 23, 34, 256}}, + {i18n.PluralFormMany, PluralRuleLithuanian, []int64{0, 10, 11, 18}}, + + {i18n.PluralFormOne, PluralRuleFrench, []int64{0, 1}}, + {i18n.PluralFormMany, PluralRuleFrench, []int64{1000000, 2000000}}, + {i18n.PluralFormOther, PluralRuleFrench, []int64{2, 4, 10, 256}}, + + {i18n.PluralFormOne, PluralRuleCatalan, []int64{1}}, + {i18n.PluralFormMany, PluralRuleCatalan, []int64{1000000, 2000000}}, + {i18n.PluralFormOther, PluralRuleCatalan, []int64{0, 2, 4, 10, 256}}, + + {i18n.PluralFormOne, PluralRuleSlovenian, []int64{1, 101, 201, 501}}, + {i18n.PluralFormTwo, PluralRuleSlovenian, []int64{2, 102, 202, 502}}, + {i18n.PluralFormFew, PluralRuleSlovenian, []int64{3, 103, 203, 503, 4, 104, 204, 504}}, + {i18n.PluralFormOther, PluralRuleSlovenian, []int64{0, 5, 11, 12, 20, 256}}, + + {i18n.PluralFormZero, PluralRuleArabic, []int64{0}}, + {i18n.PluralFormOne, PluralRuleArabic, []int64{1}}, + {i18n.PluralFormTwo, PluralRuleArabic, []int64{2}}, + {i18n.PluralFormFew, PluralRuleArabic, []int64{3, 4, 9, 10, 103, 104}}, + {i18n.PluralFormMany, PluralRuleArabic, []int64{11, 12, 13, 14, 17, 111, 256}}, + {i18n.PluralFormOther, PluralRuleArabic, []int64{100, 101, 102}}, + } + + for _, tc := range testCases { + for _, n := range tc.values { + assert.Equal(t, tc.expect, PluralRules[tc.pluralRule](n), "Testcase for plural rule %d, value %d", tc.pluralRule, n) + } + } +} diff --git a/options/locale/locale_en-US.ini b/options/locale/locale_en-US.ini index eaeab11a9d..127e629e80 100644 --- a/options/locale/locale_en-US.ini +++ b/options/locale/locale_en-US.ini @@ -190,7 +190,6 @@ commit_kind = Search commits... runner_kind = Search runners... no_results = No matching results found. issue_kind = Search issues... -milestone_kind = Search milestones... pull_kind = Search pulls... keyword_search_unavailable = Searching by keyword is currently not available. Please contact the site administrator. @@ -1887,10 +1886,6 @@ pulls.nothing_to_compare_have_tag = The selected branch/tag are equal. pulls.nothing_to_compare_and_allow_empty_pr = These branches are equal. This PR will be empty. pulls.has_pull_request = `A pull request between these branches already exists: %[2]s#%[3]d` pulls.create = Create pull request -pulls.title_desc_one = wants to merge %[1]d commit from %[2]s into %[3]s -pulls.title_desc_few = wants to merge %[1]d commits from %[2]s into %[3]s -pulls.merged_title_desc_one = merged %[1]d commit from %[2]s into %[3]s %[4]s -pulls.merged_title_desc_few = merged %[1]d commits from %[2]s into %[3]s %[4]s pulls.change_target_branch_at = `changed target branch from %s to %s %s` pulls.tab_conversation = Conversation pulls.tab_commits = Commits diff --git a/options/locale_next/locale_ar.json b/options/locale_next/locale_ar.json new file mode 100644 index 0000000000..0967ef424b --- /dev/null +++ b/options/locale_next/locale_ar.json @@ -0,0 +1 @@ +{} diff --git a/options/locale_next/locale_be.json b/options/locale_next/locale_be.json new file mode 100644 index 0000000000..0967ef424b --- /dev/null +++ b/options/locale_next/locale_be.json @@ -0,0 +1 @@ +{} diff --git a/options/locale_next/locale_bg.json b/options/locale_next/locale_bg.json new file mode 100644 index 0000000000..bec72c556a --- /dev/null +++ b/options/locale_next/locale_bg.json @@ -0,0 +1,14 @@ +{ + "repo": { + "pulls": { + "merged_title_desc": { + "one": "сля %[1]d подаване от %[2]s в %[3]s %[4]s", + "other": "сля %[1]d подавания от %[2]s в %[3]s %[4]s" + }, + "title_desc": { + "one": "иска да слее %[1]d подаване от %[2]s в %[3]s", + "other": "иска да слее %[1]d подавания от %[2]s в %[3]s" + } + } + } +} diff --git a/options/locale_next/locale_bn.json b/options/locale_next/locale_bn.json new file mode 100644 index 0000000000..0967ef424b --- /dev/null +++ b/options/locale_next/locale_bn.json @@ -0,0 +1 @@ +{} diff --git a/options/locale_next/locale_bs.json b/options/locale_next/locale_bs.json new file mode 100644 index 0000000000..0967ef424b --- /dev/null +++ b/options/locale_next/locale_bs.json @@ -0,0 +1 @@ +{} diff --git a/options/locale_next/locale_ca.json b/options/locale_next/locale_ca.json new file mode 100644 index 0000000000..8aee80092d --- /dev/null +++ b/options/locale_next/locale_ca.json @@ -0,0 +1,5 @@ +{ + "search": { + "milestone_kind": "Cerca fites..." + } +} diff --git a/options/locale_next/locale_cs-CZ.json b/options/locale_next/locale_cs-CZ.json new file mode 100644 index 0000000000..373b9dc31e --- /dev/null +++ b/options/locale_next/locale_cs-CZ.json @@ -0,0 +1,17 @@ +{ + "repo": { + "pulls": { + "merged_title_desc": { + "one": "sloučil %[1]d commit z %[2]s do %[3]s %[4]s", + "other": "sloučil %[1]d commity z větve %[2]s do větve %[3]s před %[4]s" + }, + "title_desc": { + "one": "žádá o sloučení %[1]d commitu z %[2]s do %[3]s", + "other": "chce sloučit %[1]d commity z větve %[2]s do %[3]s" + } + } + }, + "search": { + "milestone_kind": "Hledat milníky..." + } +} diff --git a/options/locale_next/locale_da.json b/options/locale_next/locale_da.json new file mode 100644 index 0000000000..834f66024f --- /dev/null +++ b/options/locale_next/locale_da.json @@ -0,0 +1,5 @@ +{ + "search": { + "milestone_kind": "Søg milepæle..." + } +} diff --git a/options/locale_next/locale_de-DE.json b/options/locale_next/locale_de-DE.json new file mode 100644 index 0000000000..82e4ea54d4 --- /dev/null +++ b/options/locale_next/locale_de-DE.json @@ -0,0 +1,17 @@ +{ + "repo": { + "pulls": { + "merged_title_desc": { + "one": "hat %[1]d Commit von %[2]s nach %[3]s %[4]s zusammengeführt", + "other": "hat %[1]d Commits von %[2]s nach %[3]s %[4]s zusammengeführt" + }, + "title_desc": { + "one": "möchte %[1]d Commit von %[2]s nach %[3]s zusammenführen", + "other": "möchte %[1]d Commits von %[2]s nach %[3]s zusammenführen" + } + } + }, + "search": { + "milestone_kind": "Meilensteine suchen …" + } +} diff --git a/options/locale_next/locale_el-GR.json b/options/locale_next/locale_el-GR.json new file mode 100644 index 0000000000..9fa112cf0f --- /dev/null +++ b/options/locale_next/locale_el-GR.json @@ -0,0 +1,17 @@ +{ + "repo": { + "pulls": { + "merged_title_desc": { + "one": "συγχώνευσε %[1]d υποβολή από τον κλάδο %[2]s στον κλάδο %[3]s %[4]s", + "other": "συγχώνευσε %[1]d υποβολές από %[2]s σε %[3]s %[4]s" + }, + "title_desc": { + "one": ": θα ήθελε να συγχωνεύσει %[1]d υποβολή από τον κλάδο %[2]s στον κλάδο %[3]s", + "other": "θέλει να συγχωνεύσει %[1]d υποβολές από %[2]s σε %[3]s" + } + } + }, + "search": { + "milestone_kind": "Αναζήτηση ορόσημων..." + } +} diff --git a/options/locale_next/locale_en-US.json b/options/locale_next/locale_en-US.json new file mode 100644 index 0000000000..64e3e50abc --- /dev/null +++ b/options/locale_next/locale_en-US.json @@ -0,0 +1,17 @@ +{ + "repo": { + "pulls": { + "merged_title_desc": { + "one": "merged %[1]d commit from %[2]s into %[3]s %[4]s", + "other": "merged %[1]d commits from %[2]s into %[3]s %[4]s" + }, + "title_desc": { + "one": "wants to merge %[1]d commit from %[2]s into %[3]s", + "other": "wants to merge %[1]d commits from %[2]s into %[3]s" + } + } + }, + "search": { + "milestone_kind": "Search milestones..." + } +} diff --git a/options/locale_next/locale_eo.json b/options/locale_next/locale_eo.json new file mode 100644 index 0000000000..c57b462d5f --- /dev/null +++ b/options/locale_next/locale_eo.json @@ -0,0 +1,5 @@ +{ + "search": { + "milestone_kind": "Serĉi celojn..." + } +} diff --git a/options/locale_next/locale_es-ES.json b/options/locale_next/locale_es-ES.json new file mode 100644 index 0000000000..7313cdc0a7 --- /dev/null +++ b/options/locale_next/locale_es-ES.json @@ -0,0 +1,17 @@ +{ + "repo": { + "pulls": { + "merged_title_desc": { + "one": "fusionó %[1]d commit de %[2]s en %[3]s %[4]s", + "other": "fusionó %[1]d commits de %[2]s en %[3]s %[4]s" + }, + "title_desc": { + "one": "quiere fusionar %[1]d commit de %[2]s en %[3]s", + "other": "quiere fusionar %[1]d commits de %[2]s en %[3]s" + } + } + }, + "search": { + "milestone_kind": "Buscar hitos…" + } +} diff --git a/options/locale_next/locale_et.json b/options/locale_next/locale_et.json new file mode 100644 index 0000000000..ac009856db --- /dev/null +++ b/options/locale_next/locale_et.json @@ -0,0 +1,5 @@ +{ + "search": { + "milestone_kind": "Otsi verstapostid..." + } +} diff --git a/options/locale_next/locale_fa-IR.json b/options/locale_next/locale_fa-IR.json new file mode 100644 index 0000000000..6964db4934 --- /dev/null +++ b/options/locale_next/locale_fa-IR.json @@ -0,0 +1,12 @@ +{ + "repo": { + "pulls": { + "merged_title_desc": { + "other": "%[1]d کامیت ادغام شده از %[2]s به %[3]s %[4]s" + }, + "title_desc": { + "other": "قصد ادغام %[1]d تغییر را از %[2]s به %[3]s دارد" + } + } + } +} diff --git a/options/locale_next/locale_fi-FI.json b/options/locale_next/locale_fi-FI.json new file mode 100644 index 0000000000..88a2110bcb --- /dev/null +++ b/options/locale_next/locale_fi-FI.json @@ -0,0 +1,15 @@ +{ + "repo": { + "pulls": { + "merged_title_desc": { + "other": "yhdistetty %[1]d committia lähteestä %[2]s kohteeseen %[3]s %[4]s" + }, + "title_desc": { + "other": "haluaa yhdistää %[1]d committia lähteestä %[2]s kohteeseen %[3]s" + } + } + }, + "search": { + "milestone_kind": "Etsi merkkipaaluja..." + } +} diff --git a/options/locale_next/locale_fil.json b/options/locale_next/locale_fil.json new file mode 100644 index 0000000000..6be27dbb8c --- /dev/null +++ b/options/locale_next/locale_fil.json @@ -0,0 +1,17 @@ +{ + "repo": { + "pulls": { + "merged_title_desc": { + "one": "isinali ang %[1]d commit mula%[2]s patungong %[3]s %[4]s", + "other": "isinali ang %[1]d mga commit mula sa %[2]s patungong %[3]s %[4]s" + }, + "title_desc": { + "one": "hinihiling na isama ang %[1]d commit mula %[2]s patungong %[3]s", + "other": "hiniling na isama ang %[1]d mga commit mula sa %[2]s patungong %[3]s" + } + } + }, + "search": { + "milestone_kind": "Maghanap ng mga milestone…" + } +} diff --git a/options/locale_next/locale_fr-FR.json b/options/locale_next/locale_fr-FR.json new file mode 100644 index 0000000000..995a2be8bb --- /dev/null +++ b/options/locale_next/locale_fr-FR.json @@ -0,0 +1,17 @@ +{ + "repo": { + "pulls": { + "merged_title_desc": { + "one": "fusionné %[1]d commit depuis %[2]s vers %[3]s %[4]s", + "other": "a fusionné %[1]d révision(s) à partir de %[2]s vers %[3]s %[4]s" + }, + "title_desc": { + "one": "veut fusionner %[1]d commit depuis %[2]s vers %[3]s", + "other": "souhaite fusionner %[1]d révision(s) depuis %[2]s vers %[3]s" + } + } + }, + "search": { + "milestone_kind": "Recherche dans les jalons..." + } +} diff --git a/options/locale_next/locale_gl.json b/options/locale_next/locale_gl.json new file mode 100644 index 0000000000..0967ef424b --- /dev/null +++ b/options/locale_next/locale_gl.json @@ -0,0 +1 @@ +{} diff --git a/options/locale_next/locale_hi.json b/options/locale_next/locale_hi.json new file mode 100644 index 0000000000..0967ef424b --- /dev/null +++ b/options/locale_next/locale_hi.json @@ -0,0 +1 @@ +{} diff --git a/options/locale_next/locale_hu-HU.json b/options/locale_next/locale_hu-HU.json new file mode 100644 index 0000000000..2a21d68095 --- /dev/null +++ b/options/locale_next/locale_hu-HU.json @@ -0,0 +1,15 @@ +{ + "repo": { + "pulls": { + "merged_title_desc": { + "other": "egyesítve %[1]d változás(ok) a %[2]s-ból %[3]s-ba %[4]s" + }, + "title_desc": { + "other": "egyesíteni szeretné %[1]d változás(oka)t a(z) %[2]s-ból %[3]s-ba" + } + } + }, + "search": { + "milestone_kind": "Mérföldkövek keresése..." + } +} diff --git a/options/locale_next/locale_id-ID.json b/options/locale_next/locale_id-ID.json new file mode 100644 index 0000000000..13580f3cfe --- /dev/null +++ b/options/locale_next/locale_id-ID.json @@ -0,0 +1,12 @@ +{ + "repo": { + "pulls": { + "merged_title_desc": { + "other": "commit %[1]d telah digabungkan dari %[2]s menjadi %[3]s %[4]s" + }, + "title_desc": { + "other": "ingin menggabungkan komit %[1]d dari %[2]s menuju %[3]s" + } + } + } +} diff --git a/options/locale_next/locale_is-IS.json b/options/locale_next/locale_is-IS.json new file mode 100644 index 0000000000..40d5a7e7aa --- /dev/null +++ b/options/locale_next/locale_is-IS.json @@ -0,0 +1,9 @@ +{ + "repo": { + "pulls": { + "title_desc": { + "other": "vill sameina %[1]d framlög frá %[2]s í %[3]s" + } + } + } +} diff --git a/options/locale_next/locale_it-IT.json b/options/locale_next/locale_it-IT.json new file mode 100644 index 0000000000..61cb012433 --- /dev/null +++ b/options/locale_next/locale_it-IT.json @@ -0,0 +1,17 @@ +{ + "repo": { + "pulls": { + "merged_title_desc": { + "one": "ha fuso %[1]d commit da %[2]s in %[3]s %[4]s", + "other": "ha unito %[1]d commit da %[2]s a %[3]s %[4]s" + }, + "title_desc": { + "one": "vuole fondere %[1]d commit da %[2]s in %[3]s", + "other": "vuole unire %[1]d commit da %[2]s a %[3]s" + } + } + }, + "search": { + "milestone_kind": "Ricerca tappe..." + } +} diff --git a/options/locale_next/locale_ja-JP.json b/options/locale_next/locale_ja-JP.json new file mode 100644 index 0000000000..447ee8ae22 --- /dev/null +++ b/options/locale_next/locale_ja-JP.json @@ -0,0 +1,15 @@ +{ + "repo": { + "pulls": { + "merged_title_desc": { + "other": "が %[1]d 個のコミットを %[2]s から %[3]s へマージ %[4]s" + }, + "title_desc": { + "other": "が %[2]s から %[3]s への %[1]d コミットのマージを希望しています" + } + } + }, + "search": { + "milestone_kind": "マイルストーンを検索..." + } +} diff --git a/options/locale_next/locale_ko-KR.json b/options/locale_next/locale_ko-KR.json new file mode 100644 index 0000000000..1beaec4627 --- /dev/null +++ b/options/locale_next/locale_ko-KR.json @@ -0,0 +1,12 @@ +{ + "repo": { + "pulls": { + "merged_title_desc": { + "other": "님이 %[2]s 에서 %[3]s 로 %[1]d 커밋을 %[4]s 병합함" + }, + "title_desc": { + "other": "%[2]s 에서 %[3]s 로 %[1]d개의 커밋들을 병합하려함" + } + } + } +} diff --git a/options/locale_next/locale_lt.json b/options/locale_next/locale_lt.json new file mode 100644 index 0000000000..cce5782546 --- /dev/null +++ b/options/locale_next/locale_lt.json @@ -0,0 +1,5 @@ +{ + "search": { + "milestone_kind": "Ieškoti gairių..." + } +} diff --git a/options/locale_next/locale_lv-LV.json b/options/locale_next/locale_lv-LV.json new file mode 100644 index 0000000000..e338556aab --- /dev/null +++ b/options/locale_next/locale_lv-LV.json @@ -0,0 +1,17 @@ +{ + "repo": { + "pulls": { + "merged_title_desc": { + "one": "iekļāva %[1]d iesūtījumu no %[2]s %[3]s %[4]s", + "other": "Iekļāva %[1]d iesūtījumus no %[2]s zarā %[3]s %[4]s" + }, + "title_desc": { + "one": "vēlas iekļaut %[1]d iesūtījumu no %[2]s %[3]s", + "other": "vēlas iekļaut %[1]d iesūtījumus no %[2]s zarā %[3]s" + } + } + }, + "search": { + "milestone_kind": "Meklēt atskaites punktus..." + } +} diff --git a/options/locale_next/locale_ml-IN.json b/options/locale_next/locale_ml-IN.json new file mode 100644 index 0000000000..0967ef424b --- /dev/null +++ b/options/locale_next/locale_ml-IN.json @@ -0,0 +1 @@ +{} diff --git a/options/locale_next/locale_nb_NO.json b/options/locale_next/locale_nb_NO.json new file mode 100644 index 0000000000..0967ef424b --- /dev/null +++ b/options/locale_next/locale_nb_NO.json @@ -0,0 +1 @@ +{} diff --git a/options/locale_next/locale_nds.json b/options/locale_next/locale_nds.json new file mode 100644 index 0000000000..a141362816 --- /dev/null +++ b/options/locale_next/locale_nds.json @@ -0,0 +1,17 @@ +{ + "repo": { + "pulls": { + "merged_title_desc": { + "one": "hett %[1]d Kommitteren vun %[2]s na %[3]s %[4]s tosamenföhrt", + "other": "hett %[1]d Kommitterens vun %[2]s na %[3]s %[4]s tosamenföhrt" + }, + "title_desc": { + "one": "will %[1]d Kommitteren vun %[2]s na %[3]s tosamenföhren", + "other": "will %[1]d Kommitterens vun %[2]s na %[3]s tosamenföhren" + } + } + }, + "search": { + "milestone_kind": "In Markstenen söken …" + } +} diff --git a/options/locale_next/locale_nl-NL.json b/options/locale_next/locale_nl-NL.json new file mode 100644 index 0000000000..9bbfc0fecd --- /dev/null +++ b/options/locale_next/locale_nl-NL.json @@ -0,0 +1,17 @@ +{ + "repo": { + "pulls": { + "merged_title_desc": { + "one": "heeft %[1]d commit van %[2]s samengevoegd in %[3]s %[4]s", + "other": "heeft %[1]d commits samengevoegd van %[2]s naar %[3]s %[4]s" + }, + "title_desc": { + "one": "wilt %[1]d commit van %[2]s samenvoegen in %[3]s", + "other": "wilt %[1]d commits van %[2]s samenvoegen met %[3]s" + } + } + }, + "search": { + "milestone_kind": "Zoek mijlpalen..." + } +} diff --git a/options/locale_next/locale_pl-PL.json b/options/locale_next/locale_pl-PL.json new file mode 100644 index 0000000000..1f2def3ea0 --- /dev/null +++ b/options/locale_next/locale_pl-PL.json @@ -0,0 +1,15 @@ +{ + "repo": { + "pulls": { + "merged_title_desc": { + "many": "scala %[1]d commity/ów z %[2]s do %[3]s %[4]s" + }, + "title_desc": { + "many": "chce scalić %[1]d commity/ów z %[2]s do %[3]s" + } + } + }, + "search": { + "milestone_kind": "Wyszukaj kamienie milowe..." + } +} diff --git a/options/locale_next/locale_pt-BR.json b/options/locale_next/locale_pt-BR.json new file mode 100644 index 0000000000..e7758ef1bf --- /dev/null +++ b/options/locale_next/locale_pt-BR.json @@ -0,0 +1,17 @@ +{ + "repo": { + "pulls": { + "merged_title_desc": { + "one": "mesclou %[1]d commit de %[2]s em %[3]s %[4]s", + "other": "mesclou %[1]d commits de %[2]s em %[3]s %[4]s" + }, + "title_desc": { + "one": "quer mesclar %[1]d commit de %[2]s em %[3]s", + "other": "quer mesclar %[1]d commits de %[2]s em %[3]s" + } + } + }, + "search": { + "milestone_kind": "Pesquisar marcos..." + } +} diff --git a/options/locale_next/locale_pt-PT.json b/options/locale_next/locale_pt-PT.json new file mode 100644 index 0000000000..475023d461 --- /dev/null +++ b/options/locale_next/locale_pt-PT.json @@ -0,0 +1,17 @@ +{ + "repo": { + "pulls": { + "merged_title_desc": { + "one": "integrou %[1]d cometimento do ramo %[2]s no ramo %[3]s %[4]s", + "other": "integrou %[1]d cometimento(s) do ramo %[2]s no ramo %[3]s %[4]s" + }, + "title_desc": { + "one": "quer integrar %[1]d cometimento do ramo %[2]s no ramo %[3]s", + "other": "quer integrar %[1]d cometimento(s) do ramo %[2]s no ramo %[3]s" + } + } + }, + "search": { + "milestone_kind": "Procurar etapas..." + } +} diff --git a/options/locale_next/locale_ru-RU.json b/options/locale_next/locale_ru-RU.json new file mode 100644 index 0000000000..de310505a3 --- /dev/null +++ b/options/locale_next/locale_ru-RU.json @@ -0,0 +1,17 @@ +{ + "repo": { + "pulls": { + "merged_title_desc": { + "one": "слит %[1]d коммит из %[2]s в %[3]s %[4]s", + "many": "слито %[1]d коммит(ов) из %[2]s в %[3]s %[4]s" + }, + "title_desc": { + "one": "хочет влить %[1]d коммит из %[2]s в %[3]s", + "many": "хочет влить %[1]d коммит(ов) из %[2]s в %[3]s" + } + } + }, + "search": { + "milestone_kind": "Найти этапы..." + } +} diff --git a/options/locale_next/locale_si-LK.json b/options/locale_next/locale_si-LK.json new file mode 100644 index 0000000000..25e149f9b8 --- /dev/null +++ b/options/locale_next/locale_si-LK.json @@ -0,0 +1,12 @@ +{ + "repo": { + "pulls": { + "merged_title_desc": { + "other": "මර්ජ්%[1]d සිට %[2]s දක්වා %[3]s %[4]s" + }, + "title_desc": { + "other": "%[1]d සිට %[2]s දක්වා %[3]s" + } + } + } +} diff --git a/options/locale_next/locale_sk-SK.json b/options/locale_next/locale_sk-SK.json new file mode 100644 index 0000000000..0967ef424b --- /dev/null +++ b/options/locale_next/locale_sk-SK.json @@ -0,0 +1 @@ +{} diff --git a/options/locale_next/locale_sl.json b/options/locale_next/locale_sl.json new file mode 100644 index 0000000000..0967ef424b --- /dev/null +++ b/options/locale_next/locale_sl.json @@ -0,0 +1 @@ +{} diff --git a/options/locale_next/locale_sr-SP.json b/options/locale_next/locale_sr-SP.json new file mode 100644 index 0000000000..0967ef424b --- /dev/null +++ b/options/locale_next/locale_sr-SP.json @@ -0,0 +1 @@ +{} diff --git a/options/locale_next/locale_sv-SE.json b/options/locale_next/locale_sv-SE.json new file mode 100644 index 0000000000..fe68f161c2 --- /dev/null +++ b/options/locale_next/locale_sv-SE.json @@ -0,0 +1,15 @@ +{ + "repo": { + "pulls": { + "merged_title_desc": { + "other": "sammanfogade %[1]d incheckningar från %[2]s in i %[3]s %[4]s" + }, + "title_desc": { + "other": "vill sammanfoga %[1]d incheckningar från s[2]s in i %[3]s" + } + } + }, + "search": { + "milestone_kind": "Sök milstolpar..." + } +} diff --git a/options/locale_next/locale_tr-TR.json b/options/locale_next/locale_tr-TR.json new file mode 100644 index 0000000000..ef2cdb6584 --- /dev/null +++ b/options/locale_next/locale_tr-TR.json @@ -0,0 +1,15 @@ +{ + "repo": { + "pulls": { + "merged_title_desc": { + "other": "%[4]s %[2]s içindeki %[1]d işlemeyi %[3]s ile birleştirdi" + }, + "title_desc": { + "other": "%[2]s içindeki %[1]d işlemeyi %[3]s ile birleştirmek istiyor" + } + } + }, + "search": { + "milestone_kind": "Kilometre taşlarını ara..." + } +} diff --git a/options/locale_next/locale_uk-UA.json b/options/locale_next/locale_uk-UA.json new file mode 100644 index 0000000000..aded9786b4 --- /dev/null +++ b/options/locale_next/locale_uk-UA.json @@ -0,0 +1,17 @@ +{ + "repo": { + "pulls": { + "merged_title_desc": { + "one": "об'єднав %[1]d коміт з %[2]s в %[3]s %[4]s", + "many": "об'єднав %[1]d комітів з %[2]s в %[3]s %[4]s" + }, + "title_desc": { + "one": "хоче об'єднати %[1]d коміт з %[2]s в %[3]s", + "many": "хоче об'єднати %[1]d комітів з %[2]s в %[3]s" + } + } + }, + "search": { + "milestone_kind": "Шукати віхи..." + } +} diff --git a/options/locale_next/locale_vi.json b/options/locale_next/locale_vi.json new file mode 100644 index 0000000000..0967ef424b --- /dev/null +++ b/options/locale_next/locale_vi.json @@ -0,0 +1 @@ +{} diff --git a/options/locale_next/locale_yi.json b/options/locale_next/locale_yi.json new file mode 100644 index 0000000000..0967ef424b --- /dev/null +++ b/options/locale_next/locale_yi.json @@ -0,0 +1 @@ +{} diff --git a/options/locale_next/locale_zh-CN.json b/options/locale_next/locale_zh-CN.json new file mode 100644 index 0000000000..091b3fe609 --- /dev/null +++ b/options/locale_next/locale_zh-CN.json @@ -0,0 +1,15 @@ +{ + "repo": { + "pulls": { + "merged_title_desc": { + "other": "于 %[4]s 将 %[1]d 次代码提交从 %[2]s合并至 %[3]s" + }, + "title_desc": { + "other": "请求将 %[1]d 次代码提交从 %[2]s 合并至 %[3]s" + } + } + }, + "search": { + "milestone_kind": "搜索里程碑…" + } +} diff --git a/options/locale_next/locale_zh-HK.json b/options/locale_next/locale_zh-HK.json new file mode 100644 index 0000000000..dd7b954559 --- /dev/null +++ b/options/locale_next/locale_zh-HK.json @@ -0,0 +1,9 @@ +{ + "repo": { + "pulls": { + "merged_title_desc": { + "other": "於 %[4]s 將 %[1]d 次代碼提交從 %[2]s合併至 %[3]s" + } + } + } +} diff --git a/options/locale_next/locale_zh-TW.json b/options/locale_next/locale_zh-TW.json new file mode 100644 index 0000000000..4d31a713c0 --- /dev/null +++ b/options/locale_next/locale_zh-TW.json @@ -0,0 +1,15 @@ +{ + "repo": { + "pulls": { + "merged_title_desc": { + "other": "將 %[1]d 次提交從 %[2]s 合併至 %[3]s %[4]s" + }, + "title_desc": { + "other": "請求將 %[1]d 次程式碼提交從 %[2]s 合併至 %[3]s" + } + } + }, + "search": { + "milestone_kind": "搜尋里程碑..." + } +} diff --git a/templates/repo/issue/view_title.tmpl b/templates/repo/issue/view_title.tmpl index 5e30cf3684..936df9d3d2 100644 --- a/templates/repo/issue/view_title.tmpl +++ b/templates/repo/issue/view_title.tmpl @@ -63,10 +63,10 @@ {{$mergedStr:= DateUtils.TimeSince .Issue.PullRequest.MergedUnix}} {{if .Issue.OriginalAuthor}} {{.Issue.OriginalAuthor}} - {{ctx.Locale.TrN .NumCommits "repo.pulls.merged_title_desc_one" "repo.pulls.merged_title_desc_few" .NumCommits $headHref $baseHref $mergedStr}} + {{ctx.Locale.TrPluralString .NumCommits "repo.pulls.merged_title_desc" .NumCommits $headHref $baseHref $mergedStr}} {{else}} {{.Issue.PullRequest.Merger.GetDisplayName}} - {{ctx.Locale.TrN .NumCommits "repo.pulls.merged_title_desc_one" "repo.pulls.merged_title_desc_few" .NumCommits $headHref $baseHref $mergedStr}} + {{ctx.Locale.TrPluralString .NumCommits "repo.pulls.merged_title_desc" .NumCommits $headHref $baseHref $mergedStr}} {{end}} {{if .MadeUsingAGit}} {{/* TODO: Move documentation link to the instructions at the bottom of the PR, show instructions when clicking label */}} @@ -79,11 +79,11 @@ {{end}} {{else}} {{if .Issue.OriginalAuthor}} - {{.Issue.OriginalAuthor}} {{ctx.Locale.TrN .NumCommits "repo.pulls.title_desc_one" "repo.pulls.title_desc_few" .NumCommits $headHref $baseHref "branch_target"}} + {{.Issue.OriginalAuthor}} {{ctx.Locale.TrPluralString .NumCommits "repo.pulls.title_desc" .NumCommits $headHref $baseHref "branch_target"}} {{else}} {{.Issue.Poster.GetDisplayName}} - {{ctx.Locale.TrN .NumCommits "repo.pulls.title_desc_one" "repo.pulls.title_desc_few" .NumCommits $headHref $baseHref "branch_target"}} + {{ctx.Locale.TrPluralString .NumCommits "repo.pulls.title_desc" .NumCommits $headHref $baseHref "branch_target"}} {{end}} {{if .MadeUsingAGit}} diff --git a/tools/migrate_locales.sh b/tools/migrate_locales.sh new file mode 100755 index 0000000000..f02fe702cc --- /dev/null +++ b/tools/migrate_locales.sh @@ -0,0 +1,145 @@ +#!/bin/bash + +# Copyright 2024 The Forgejo Authors. All rights reserved. +# SPDX-License-Identifier: MIT + +if [ -z "$1" ] || [ -z "$2" ] +then + echo "USAGE: $0 section key [key1 [keyN]]" + exit 1 +fi + +if ! [ -d ../options/locale_next ] +then + echo 'Call this script from the `tools` directory.' + exit 1 +fi + +destsection="$1" +keyJSON="$destsection.$2" +key1="" +keyN="" +if [ -n "$3" ] +then + key1="$3" +else + key1="$2" +fi +if [ -n "$4" ] +then + keyN="$4" +fi + +cd ../options/locale + +# Migrate the string in one file. +function process() { + file="$1" + exec 3<$file + + val1="" + valN="" + cursection="" + line1=0 + lineN=0 + lineNumber=0 + + # Parse the file + while read -u 3 line + do + ((++lineNumber)) + if [[ $line =~ ^\[[-._a-zA-Z0-9]+\]$ ]] + then + cursection="${line#[}" + cursection="${cursection%]}" + elif [ "$cursection" = "$destsection" ] + then + key="${line%%=*}" + value="${line#*=}" + key="$(echo $key)" # Trim leading/trailing whitespace + value="$(echo $value)" + + if [ "$key" = "$key1" ] + then + val1="$value" + line1=$lineNumber + fi + if [ -n "$keyN" ] && [ "$key" = "$keyN" ] + then + valN="$value" + lineN=$lineNumber + fi + + if [ -n "$val1" ] && ( [ -n "$valN" ] || [ -z "$keyN" ] ) + then + # Found all desired strings + break + fi + fi + done + + if [ -n "$val1" ] || [ -n "$valN" ] + then + localename="${file#locale_}" + localename="${localename%.ini}" + localename="${localename%-*}" + + if [ "$file" = "locale_en-US.ini" ] + then + # Delete migrated string from source file + if [ $line1 -gt 0 ] && [ $lineN -gt 0 ] && [ $lineN -ne $line1 ] + then + sed -i "${line1}d;${lineN}d" "$file" + elif [ $line1 -gt 0 ] + then + sed -i "${line1}d" "$file" + elif [ $lineN -gt 0 ] + then + sed -i "${lineN}d" "$file" + fi + fi + + # Write JSON + jsonfile="../locale_next/${file/.ini/.json}" + + pluralform="other" + oneform="one" + case $localename in + "be" | "bs" | "cnr" | "csb" | "hr" | "lt" | "pl" | "ru" | "sr" | "szl" | "uk" | "wen") + # These languages have no "other" form and use "many" instead. + pluralform="many" + ;; + "ace" | "ay" | "bm" | "bo" | "cdo" | "cpx" | "crh" | "dz" | "gan" | "hak" | "hnj" | "hsn" | "id" | "ig" | "ii" | "ja" | "jbo" | "jv" | "kde" | "kea" | "km" | "ko" | "kos" | "lkt" | "lo" | "lzh" | "ms" | "my" | "nan" | "nqo" | "osa" | "sah" | "ses" | "sg" | "son" | "su" | "th" | "tlh" | "to" | "tok" | "tpi" | "tt" | "vi" | "wo" | "wuu" | "yo" | "yue" | "zh") + # These languages have no singular form. + oneform="" + ;; + *) + ;; + esac + + content="" + if [ -z "$keyN" ] + then + content="$(jq --arg val "$val1" ".$keyJSON = \$val" < "$jsonfile")" + else + object='{}' + if [ -n "$val1" ] && [ -n "$oneform" ] + then + object=$(jq --arg val "$val1" ".$oneform = \$val" <<< "$object") + fi + if [ -n "$valN" ] + then + object=$(jq --arg val "$valN" ".$pluralform = \$val" <<< "$object") + fi + content="$(jq --argjson val "$object" ".$keyJSON = \$val" < "$jsonfile")" + fi + jq . <<< "$content" > "$jsonfile" + fi +} + +for file in *.ini +do + process "$file" & +done +wait + From 34e1100ae22ef4fe70bace46ffa954aba85a0620 Mon Sep 17 00:00:00 2001 From: Beowulf Date: Fri, 17 Jan 2025 20:14:28 +0000 Subject: [PATCH 162/198] fix(ui): reset content of text field for comments when cancelling (#6595) Currently, the content of the text field is not reset when you cancel editing. This change resets the content of the text field when editing is canceled. If this is not done and you click on cancel and then on edit again, you can no longer return to the initial content without completely reloading the page. Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/6595 Reviewed-by: Otto Reviewed-by: Gusted Co-authored-by: Beowulf Co-committed-by: Beowulf --- tests/e2e/issue-comment.test.e2e.ts | 21 +++++++++++++++++++++ web_src/js/features/repo-legacy.js | 1 + 2 files changed, 22 insertions(+) diff --git a/tests/e2e/issue-comment.test.e2e.ts b/tests/e2e/issue-comment.test.e2e.ts index 933e65fa32..1c19f98c48 100644 --- a/tests/e2e/issue-comment.test.e2e.ts +++ b/tests/e2e/issue-comment.test.e2e.ts @@ -77,6 +77,27 @@ test('Always focus edit tab first on edit', async ({page}) => { await save_visual(page); }); +test('Reset content of comment edit field on cancel', async ({page}) => { + const response = await page.goto('/user2/repo1/issues/1'); + expect(response?.status()).toBe(200); + + const editorTextarea = page.locator('[id="_combo_markdown_editor_1"]'); + + // Change the content of the edit field + await page.click('#issue-1 .comment-container .context-menu'); + await page.click('#issue-1 .comment-container .menu>.edit-content'); + await expect(editorTextarea).toHaveValue('content for the first issue'); + await editorTextarea.fill('some random string'); + await expect(editorTextarea).toHaveValue('some random string'); + await page.click('#issue-1 .comment-container .edit .cancel'); + + // Edit again and assert that the edit field should be reset to the initial content + await page.click('#issue-1 .comment-container .context-menu'); + await page.click('#issue-1 .comment-container .menu>.edit-content'); + await expect(editorTextarea).toHaveValue('content for the first issue'); + await save_visual(page); +}); + test('Quote reply', async ({page}, workerInfo) => { test.skip(workerInfo.project.name !== 'firefox', 'Uses Firefox specific selection quirks'); const response = await page.goto('/user2/repo1/issues/1'); diff --git a/web_src/js/features/repo-legacy.js b/web_src/js/features/repo-legacy.js index 04b6e93b39..c74ba1efbe 100644 --- a/web_src/js/features/repo-legacy.js +++ b/web_src/js/features/repo-legacy.js @@ -405,6 +405,7 @@ async function onEditContent(event) { e.preventDefault(); showElem(renderContent); hideElem(editContentZone); + comboMarkdownEditor.value(rawContent.textContent); comboMarkdownEditor.attachedDropzoneInst?.emit('reload'); }; From 5c8db434470d027d506d987cb5bf6c5641cb5fb7 Mon Sep 17 00:00:00 2001 From: Renovate Bot Date: Sat, 18 Jan 2025 05:30:16 +0000 Subject: [PATCH 163/198] Update dependency katex to v0.16.21 (forgejo) (#6603) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This PR contains the following updates: | Package | Type | Update | Change | |---|---|---|---| | [katex](https://katex.org) ([source](https://github.com/KaTeX/KaTeX)) | dependencies | patch | [`0.16.20` -> `0.16.21`](https://renovatebot.com/diffs/npm/katex/0.16.20/0.16.21) | --- ### Release Notes
KaTeX/KaTeX (katex) ### [`v0.16.21`](https://github.com/KaTeX/KaTeX/blob/HEAD/CHANGELOG.md#01621-2025-01-17) [Compare Source](https://github.com/KaTeX/KaTeX/compare/v0.16.20...v0.16.21) ##### Bug Fixes - escape \htmlData attribute name ([57914ad](https://github.com/KaTeX/KaTeX/commit/57914ad91eff401357f44bf364b136d37eba04f8))
--- ### Configuration 📅 **Schedule**: Branch creation - "* 0-3 * * *" (UTC), Automerge - "* 0-3 * * *" (UTC). 🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied. ♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] If you want to rebase/retry this PR, check this box --- This PR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate). Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/6603 Reviewed-by: Gusted Co-authored-by: Renovate Bot Co-committed-by: Renovate Bot --- package-lock.json | 8 ++++---- package.json | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package-lock.json b/package-lock.json index 9dbfaf2551..78e8494442 100644 --- a/package-lock.json +++ b/package-lock.json @@ -30,7 +30,7 @@ "htmx.org": "1.9.12", "idiomorph": "0.3.0", "jquery": "3.7.1", - "katex": "0.16.20", + "katex": "0.16.21", "mermaid": "11.4.1", "mini-css-extract-plugin": "2.9.2", "minimatch": "10.0.1", @@ -10402,9 +10402,9 @@ "license": "MIT" }, "node_modules/katex": { - "version": "0.16.20", - "resolved": "https://registry.npmjs.org/katex/-/katex-0.16.20.tgz", - "integrity": "sha512-jjuLaMGD/7P8jUTpdKhA9IoqnH+yMFB3sdAFtq5QdAqeP2PjiSbnC3EaguKPNtv6dXXanHxp1ckwvF4a86LBig==", + "version": "0.16.21", + "resolved": "https://registry.npmjs.org/katex/-/katex-0.16.21.tgz", + "integrity": "sha512-XvqR7FgOHtWupfMiigNzmh+MgUVmDGU2kXZm899ZkPfcuoPuFxyHmXsgATDpFZDAXCI8tvinaVcDo8PIIJSo4A==", "funding": [ "https://opencollective.com/katex", "https://github.com/sponsors/katex" diff --git a/package.json b/package.json index 944789f0a7..259a744c2b 100644 --- a/package.json +++ b/package.json @@ -29,7 +29,7 @@ "htmx.org": "1.9.12", "idiomorph": "0.3.0", "jquery": "3.7.1", - "katex": "0.16.20", + "katex": "0.16.21", "mermaid": "11.4.1", "mini-css-extract-plugin": "2.9.2", "minimatch": "10.0.1", From dbec2ed3507e5b84b9a3d39ffe9e52f2c4ebe7fd Mon Sep 17 00:00:00 2001 From: Renovate Bot Date: Sat, 18 Jan 2025 05:31:17 +0000 Subject: [PATCH 164/198] Update module github.com/caddyserver/certmagic to v0.21.7 (forgejo) (#6604) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This PR contains the following updates: | Package | Type | Update | Change | |---|---|---|---| | [github.com/caddyserver/certmagic](https://github.com/caddyserver/certmagic) | require | patch | `v0.21.6` -> `v0.21.7` | --- ### Release Notes
caddyserver/certmagic (github.com/caddyserver/certmagic) ### [`v0.21.7`](https://github.com/caddyserver/certmagic/compare/v0.21.6...v0.21.7) [Compare Source](https://github.com/caddyserver/certmagic/compare/v0.21.6...v0.21.7)
--- ### Configuration 📅 **Schedule**: Branch creation - "* 0-3 * * *" (UTC), Automerge - "* 0-3 * * *" (UTC). 🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied. ♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] If you want to rebase/retry this PR, check this box --- This PR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate). Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/6604 Reviewed-by: Gusted Co-authored-by: Renovate Bot Co-committed-by: Renovate Bot --- go.mod | 4 ++-- go.sum | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/go.mod b/go.mod index 48e9e49075..e6d34f571d 100644 --- a/go.mod +++ b/go.mod @@ -27,7 +27,7 @@ require ( github.com/blakesmith/ar v0.0.0-20190502131153-809d4375e1fb github.com/blevesearch/bleve/v2 v2.4.4 github.com/buildkite/terminal-to-html/v3 v3.16.4 - github.com/caddyserver/certmagic v0.21.6 + github.com/caddyserver/certmagic v0.21.7 github.com/chi-middleware/proxy v1.1.1 github.com/djherbis/buffer v1.2.0 github.com/djherbis/nio/v3 v3.0.1 @@ -221,7 +221,7 @@ require ( github.com/markbates/going v1.0.3 // indirect github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-runewidth v0.0.16 // indirect - github.com/mholt/acmez/v3 v3.0.0 // indirect + github.com/mholt/acmez/v3 v3.0.1 // indirect github.com/miekg/dns v1.1.62 // indirect github.com/minio/md5-simd v1.1.2 // indirect github.com/mitchellh/mapstructure v1.5.0 // indirect diff --git a/go.sum b/go.sum index 28e1f22870..7a74006088 100644 --- a/go.sum +++ b/go.sum @@ -770,8 +770,8 @@ github.com/bsm/gomega v1.27.10 h1:yeMWxP2pV2fG3FgAODIY8EiRE3dy0aeFYt4l7wh6yKA= github.com/bsm/gomega v1.27.10/go.mod h1:JyEr/xRbxbtgWNi8tIEVPUYZ5Dzef52k01W3YH0H+O0= github.com/buildkite/terminal-to-html/v3 v3.16.4 h1:QFYO8IGvRnp7tGgiQb8g9uFU8kY9wOzxsFFx17+yy6Q= github.com/buildkite/terminal-to-html/v3 v3.16.4/go.mod h1:r/J7cC9c3EzBzP3/wDz0RJLPwv5PUAMp+KF2w+ntMc0= -github.com/caddyserver/certmagic v0.21.6 h1:1th6GfprVfsAtFNOu4StNMF5IxK5XiaI0yZhAHlZFPE= -github.com/caddyserver/certmagic v0.21.6/go.mod h1:n1sCo7zV1Ez2j+89wrzDxo4N/T1Ws/Vx8u5NvuBFabw= +github.com/caddyserver/certmagic v0.21.7 h1:66KJioPFJwttL43KYSWk7ErSmE6LfaJgCQuhm8Sg6fg= +github.com/caddyserver/certmagic v0.21.7/go.mod h1:LCPG3WLxcnjVKl/xpjzM0gqh0knrKKKiO5WVttX2eEI= github.com/caddyserver/zerossl v0.1.3 h1:onS+pxp3M8HnHpN5MMbOMyNjmTheJyWRaZYwn+YTAyA= github.com/caddyserver/zerossl v0.1.3/go.mod h1:CxA0acn7oEGO6//4rtrRjYgEoa4MFw/XofZnrYwGqG4= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= @@ -1253,8 +1253,8 @@ github.com/mattn/go-sqlite3 v1.14.24 h1:tpSp2G2KyMnnQu99ngJ47EIkWVmliIizyZBfPrBW github.com/mattn/go-sqlite3 v1.14.24/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y= github.com/meilisearch/meilisearch-go v0.29.0 h1:HZ9NEKN59USINQ/DXJge/aaXq8IrsKbXGTdAoBaaDz4= github.com/meilisearch/meilisearch-go v0.29.0/go.mod h1:2cRCAn4ddySUsFfNDLVPod/plRibQsJkXF/4gLhxbOk= -github.com/mholt/acmez/v3 v3.0.0 h1:r1NcjuWR0VaKP2BTjDK9LRFBw/WvURx3jlaEUl9Ht8E= -github.com/mholt/acmez/v3 v3.0.0/go.mod h1:L1wOU06KKvq7tswuMDwKdcHeKpFFgkppZy/y0DFxagQ= +github.com/mholt/acmez/v3 v3.0.1 h1:4PcjKjaySlgXK857aTfDuRbmnM5gb3Ruz3tvoSJAUp8= +github.com/mholt/acmez/v3 v3.0.1/go.mod h1:L1wOU06KKvq7tswuMDwKdcHeKpFFgkppZy/y0DFxagQ= github.com/microcosm-cc/bluemonday v1.0.27 h1:MpEUotklkwCSLeH+Qdx1VJgNqLlpY2KXwXFM08ygZfk= github.com/microcosm-cc/bluemonday v1.0.27/go.mod h1:jFi9vgW+H7c3V0lb6nR74Ib/DIB5OBs92Dimizgw2cA= github.com/miekg/dns v1.1.62 h1:cN8OuEF1/x5Rq6Np+h1epln8OiyPWV+lROx9LxcGgIQ= From 401906b88e945727d0980f428c026a148c503630 Mon Sep 17 00:00:00 2001 From: Renovate Bot Date: Sat, 18 Jan 2025 05:33:34 +0000 Subject: [PATCH 165/198] Update module google.golang.org/protobuf to v1.36.3 (forgejo) (#6581) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This PR contains the following updates: | Package | Type | Update | Change | |---|---|---|---| | [google.golang.org/protobuf](https://github.com/protocolbuffers/protobuf-go) | require | patch | `v1.36.2` -> `v1.36.3` | --- ### Release Notes
protocolbuffers/protobuf-go (google.golang.org/protobuf) ### [`v1.36.3`](https://github.com/protocolbuffers/protobuf-go/releases/tag/v1.36.3) [Compare Source](https://github.com/protocolbuffers/protobuf-go/compare/v1.36.2...v1.36.3) **Full Changelog**: https://github.com/protocolbuffers/protobuf-go/compare/v1.36.2...v1.36.3 Bug fixes: [CL/642575](https://go-review.googlesource.com/c/protobuf/+/642575): reflect/protodesc: fix panic when working with dynamicpb [CL/641036](https://go-review.googlesource.com/c/protobuf/+/641036): cmd/protoc-gen-go: remove json struct tags from unexported fields User-visible changes: [CL/641876](https://go-review.googlesource.com/c/protobuf/+/641876): proto: add example for GetExtension, SetExtension [CL/642015](https://go-review.googlesource.com/c/protobuf/+/642015): runtime/protolazy: replace internal doc link with external link Maintenance: [CL/641635](https://go-review.googlesource.com/c/protobuf/+/641635): all: split flags.ProtoLegacyWeak out of flags.ProtoLegacy [CL/641019](https://go-review.googlesource.com/c/protobuf/+/641019): internal/impl: remove unused exporter parameter [CL/641018](https://go-review.googlesource.com/c/protobuf/+/641018): internal/impl: switch to reflect.Value.IsZero [CL/641035](https://go-review.googlesource.com/c/protobuf/+/641035): internal/impl: clean up unneeded Go<1.12 MapRange() alternative [CL/641017](https://go-review.googlesource.com/c/protobuf/+/641017): types/dynamicpb: switch atomicExtFiles to atomic.Uint64 type
--- ### Configuration 📅 **Schedule**: Branch creation - "* 0-3 * * *" (UTC), Automerge - "* 0-3 * * *" (UTC). 🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied. ♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] If you want to rebase/retry this PR, check this box --- This PR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate). Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/6581 Reviewed-by: Gusted Co-authored-by: Renovate Bot Co-committed-by: Renovate Bot --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index e6d34f571d..bc93365ff2 100644 --- a/go.mod +++ b/go.mod @@ -109,7 +109,7 @@ require ( golang.org/x/sys v0.29.0 golang.org/x/text v0.21.0 google.golang.org/grpc v1.69.2 - google.golang.org/protobuf v1.36.2 + google.golang.org/protobuf v1.36.3 gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df gopkg.in/ini.v1 v1.67.0 gopkg.in/yaml.v3 v3.0.1 diff --git a/go.sum b/go.sum index 7a74006088..3064c26ba9 100644 --- a/go.sum +++ b/go.sum @@ -2179,8 +2179,8 @@ google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqw google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= google.golang.org/protobuf v1.29.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= -google.golang.org/protobuf v1.36.2 h1:R8FeyR1/eLmkutZOM5CWghmo5itiG9z0ktFlTVLuTmU= -google.golang.org/protobuf v1.36.2/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= +google.golang.org/protobuf v1.36.3 h1:82DV7MYdb8anAVi3qge1wSnMDrnKK7ebr+I0hHRN1BU= +google.golang.org/protobuf v1.36.3/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc h1:2gGKlE2+asNV9m7xrywl36YYNnBG5ZQ0r/BOOxqPpmk= gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc/go.mod h1:m7x9LTH6d71AHyAX77c9yqWCCa3UKHcVEj9y7hAtKDk= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= From f1a92de4e6a78abf3fb639587662ec01f82250df Mon Sep 17 00:00:00 2001 From: Renovate Bot Date: Sat, 18 Jan 2025 06:39:17 +0000 Subject: [PATCH 166/198] Update postcss (forgejo) (#6562) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This PR contains the following updates: | Package | Type | Update | Change | |---|---|---|---| | [postcss](https://postcss.org/) ([source](https://github.com/postcss/postcss)) | dependencies | minor | [`8.4.49` -> `8.5.1`](https://renovatebot.com/diffs/npm/postcss/8.4.49/8.5.1) | | [postcss-html](https://github.com/ota-meshi/postcss-html) | devDependencies | minor | [`1.7.0` -> `1.8.0`](https://renovatebot.com/diffs/npm/postcss-html/1.7.0/1.8.0) | --- ### Release Notes
postcss/postcss (postcss) ### [`v8.5.1`](https://github.com/postcss/postcss/blob/HEAD/CHANGELOG.md#851) [Compare Source](https://github.com/postcss/postcss/compare/8.5.0...8.5.1) - Fixed backwards compatibility for complex cases (by [@​romainmenke](https://github.com/romainmenke)). ### [`v8.5.0`](https://github.com/postcss/postcss/releases/tag/8.5.0): 8.5 “Duke Alloces” [Compare Source](https://github.com/postcss/postcss/compare/8.4.49...8.5.0) President Alloces seal PostCSS 8.5 brought API to work better with non-CSS sources like HTML, Vue.js/Svelte sources or CSS-in-JS. [@​romainmenke](https://github.com/romainmenke) during [his work](https://github.com/postcss/postcss/issues/1995) on [Stylelint](https://stylelint.io) added `Input#document` in additional to `Input#css`. ```js root.source.input.document //=> "

Hello

// " root.source.input.css //=> "p { // color: green; // }" ``` #### Thanks to Sponsors This release was possible thanks to our community. If your company wants to support the sustainability of front-end infrastructure or wants to give some love to PostCSS, you can join our supporters by: - [**Tidelift**](https://tidelift.com/) with a Spotify-like subscription model supporting all projects from your lock file. - Direct donations at [**GitHub Sponsors**](https://github.com/sponsors/ai) or [**Open Collective**](https://opencollective.com/postcss#section-contributors).
ota-meshi/postcss-html (postcss-html) ### [`v1.8.0`](https://github.com/ota-meshi/postcss-html/releases/tag/v1.8.0) [Compare Source](https://github.com/ota-meshi/postcss-html/compare/v1.7.0...v1.8.0) #### What's Changed - update to latest PostCSS by [@​romainmenke](https://github.com/romainmenke) in https://github.com/ota-meshi/postcss-html/pull/134 **Full Changelog**: https://github.com/ota-meshi/postcss-html/compare/v1.7.0...v1.8.0
--- ### Configuration 📅 **Schedule**: Branch creation - "* 0-3 * * *" (UTC), Automerge - "* 0-3 * * *" (UTC). 🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied. ♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox. 👻 **Immortal**: This PR will be recreated if closed unmerged. Get [config help](https://github.com/renovatebot/renovate/discussions) if that's undesired. --- - [ ] If you want to rebase/retry this PR, check this box --- This PR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate). Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/6562 Reviewed-by: Gusted Co-authored-by: Renovate Bot Co-committed-by: Renovate Bot --- package-lock.json | 20 ++++++++++---------- package.json | 4 ++-- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/package-lock.json b/package-lock.json index 78e8494442..445721e70f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -37,7 +37,7 @@ "monaco-editor": "0.52.2", "monaco-editor-webpack-plugin": "7.1.0", "pdfobject": "2.3.0", - "postcss": "8.4.49", + "postcss": "8.5.1", "postcss-loader": "8.1.1", "postcss-nesting": "13.0.1", "pretty-ms": "9.0.0", @@ -89,7 +89,7 @@ "happy-dom": "16.3.0", "license-checker-rseidelsohn": "4.4.2", "markdownlint-cli": "0.43.0", - "postcss-html": "1.7.0", + "postcss-html": "1.8.0", "stylelint": "16.12.0", "stylelint-declaration-block-no-ignored-properties": "2.8.0", "stylelint-declaration-strict-value": "1.10.6", @@ -11867,9 +11867,9 @@ } }, "node_modules/postcss": { - "version": "8.4.49", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.49.tgz", - "integrity": "sha512-OCVPnIObs4N29kxTjzLfUryOkvZEq+pf8jTF0lg8E7uETuWHA+v7j3c/xJmiqpX450191LlmZfUKkXxkTry7nA==", + "version": "8.5.1", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.1.tgz", + "integrity": "sha512-6oz2beyjc5VMn/KV1pPw8fliQkhBXrVn1Z3TVyqZxU8kZpzEKhBdmCFqI6ZbmGtamQvQGuU1sgPTk8ZrXDD7jQ==", "funding": [ { "type": "opencollective", @@ -11886,7 +11886,7 @@ ], "license": "MIT", "dependencies": { - "nanoid": "^3.3.7", + "nanoid": "^3.3.8", "picocolors": "^1.1.1", "source-map-js": "^1.2.1" }, @@ -11895,15 +11895,15 @@ } }, "node_modules/postcss-html": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/postcss-html/-/postcss-html-1.7.0.tgz", - "integrity": "sha512-MfcMpSUIaR/nNgeVS8AyvyDugXlADjN9AcV7e5rDfrF1wduIAGSkL4q2+wgrZgA3sHVAHLDO9FuauHhZYW2nBw==", + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/postcss-html/-/postcss-html-1.8.0.tgz", + "integrity": "sha512-5mMeb1TgLWoRKxZ0Xh9RZDfwUUIqRrcxO2uXO+Ezl1N5lqpCiSU5Gk6+1kZediBfBHFtPCdopr2UZ2SgUsKcgQ==", "dev": true, "license": "MIT", "dependencies": { "htmlparser2": "^8.0.0", "js-tokens": "^9.0.0", - "postcss": "^8.4.0", + "postcss": "^8.5.0", "postcss-safe-parser": "^6.0.0" }, "engines": { diff --git a/package.json b/package.json index 259a744c2b..95129444fb 100644 --- a/package.json +++ b/package.json @@ -36,7 +36,7 @@ "monaco-editor": "0.52.2", "monaco-editor-webpack-plugin": "7.1.0", "pdfobject": "2.3.0", - "postcss": "8.4.49", + "postcss": "8.5.1", "postcss-loader": "8.1.1", "postcss-nesting": "13.0.1", "pretty-ms": "9.0.0", @@ -88,7 +88,7 @@ "happy-dom": "16.3.0", "license-checker-rseidelsohn": "4.4.2", "markdownlint-cli": "0.43.0", - "postcss-html": "1.7.0", + "postcss-html": "1.8.0", "stylelint": "16.12.0", "stylelint-declaration-block-no-ignored-properties": "2.8.0", "stylelint-declaration-strict-value": "1.10.6", From 244ee64c30ceee31ee43ba7c9b074a0711ace5e8 Mon Sep 17 00:00:00 2001 From: 0ko <0ko@noreply.codeberg.org> Date: Sat, 18 Jan 2025 07:35:28 +0000 Subject: [PATCH 167/198] fix(i18n): flatten next locales (#6607) Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/6607 Reviewed-by: Gusted --- options/locale_next/locale_bg.json | 20 ++++++++------------ options/locale_next/locale_ca.json | 4 +--- options/locale_next/locale_cs-CZ.json | 24 +++++++++--------------- options/locale_next/locale_da.json | 4 +--- options/locale_next/locale_de-DE.json | 24 +++++++++--------------- options/locale_next/locale_el-GR.json | 24 +++++++++--------------- options/locale_next/locale_en-US.json | 24 +++++++++--------------- options/locale_next/locale_eo.json | 4 +--- options/locale_next/locale_es-ES.json | 24 +++++++++--------------- options/locale_next/locale_et.json | 4 +--- options/locale_next/locale_fa-IR.json | 16 ++++++---------- options/locale_next/locale_fi-FI.json | 20 +++++++------------- options/locale_next/locale_fil.json | 24 +++++++++--------------- options/locale_next/locale_fr-FR.json | 24 +++++++++--------------- options/locale_next/locale_hu-HU.json | 20 +++++++------------- options/locale_next/locale_id-ID.json | 16 ++++++---------- options/locale_next/locale_is-IS.json | 10 +++------- options/locale_next/locale_it-IT.json | 24 +++++++++--------------- options/locale_next/locale_ja-JP.json | 20 +++++++------------- options/locale_next/locale_ko-KR.json | 16 ++++++---------- options/locale_next/locale_lt.json | 4 +--- options/locale_next/locale_lv-LV.json | 24 +++++++++--------------- options/locale_next/locale_nds.json | 24 +++++++++--------------- options/locale_next/locale_nl-NL.json | 24 +++++++++--------------- options/locale_next/locale_pl-PL.json | 20 +++++++------------- options/locale_next/locale_pt-BR.json | 24 +++++++++--------------- options/locale_next/locale_pt-PT.json | 24 +++++++++--------------- options/locale_next/locale_ru-RU.json | 24 +++++++++--------------- options/locale_next/locale_si-LK.json | 16 ++++++---------- options/locale_next/locale_sv-SE.json | 20 +++++++------------- options/locale_next/locale_tr-TR.json | 20 +++++++------------- options/locale_next/locale_uk-UA.json | 24 +++++++++--------------- options/locale_next/locale_zh-CN.json | 20 +++++++------------- options/locale_next/locale_zh-HK.json | 10 +++------- options/locale_next/locale_zh-TW.json | 20 +++++++------------- 35 files changed, 234 insertions(+), 410 deletions(-) diff --git a/options/locale_next/locale_bg.json b/options/locale_next/locale_bg.json index bec72c556a..02144c8b38 100644 --- a/options/locale_next/locale_bg.json +++ b/options/locale_next/locale_bg.json @@ -1,14 +1,10 @@ { - "repo": { - "pulls": { - "merged_title_desc": { - "one": "сля %[1]d подаване от %[2]s в %[3]s %[4]s", - "other": "сля %[1]d подавания от %[2]s в %[3]s %[4]s" - }, - "title_desc": { - "one": "иска да слее %[1]d подаване от %[2]s в %[3]s", - "other": "иска да слее %[1]d подавания от %[2]s в %[3]s" - } - } - } + "repo.pulls.merged_title_desc": { + "one": "сля %[1]d подаване от %[2]s в %[3]s %[4]s", + "other": "сля %[1]d подавания от %[2]s в %[3]s %[4]s" + }, + "repo.pulls.title_desc": { + "one": "иска да слее %[1]d подаване от %[2]s в %[3]s", + "other": "иска да слее %[1]d подавания от %[2]s в %[3]s" + } } diff --git a/options/locale_next/locale_ca.json b/options/locale_next/locale_ca.json index 8aee80092d..c639c28a99 100644 --- a/options/locale_next/locale_ca.json +++ b/options/locale_next/locale_ca.json @@ -1,5 +1,3 @@ { - "search": { - "milestone_kind": "Cerca fites..." - } + "search.milestone_kind": "Cerca fites..." } diff --git a/options/locale_next/locale_cs-CZ.json b/options/locale_next/locale_cs-CZ.json index 373b9dc31e..8d028b8367 100644 --- a/options/locale_next/locale_cs-CZ.json +++ b/options/locale_next/locale_cs-CZ.json @@ -1,17 +1,11 @@ { - "repo": { - "pulls": { - "merged_title_desc": { - "one": "sloučil %[1]d commit z %[2]s do %[3]s %[4]s", - "other": "sloučil %[1]d commity z větve %[2]s do větve %[3]s před %[4]s" - }, - "title_desc": { - "one": "žádá o sloučení %[1]d commitu z %[2]s do %[3]s", - "other": "chce sloučit %[1]d commity z větve %[2]s do %[3]s" - } - } - }, - "search": { - "milestone_kind": "Hledat milníky..." - } + "repo.pulls.merged_title_desc": { + "one": "sloučil %[1]d commit z %[2]s do %[3]s %[4]s", + "other": "sloučil %[1]d commity z větve %[2]s do větve %[3]s před %[4]s" + }, + "repo.pulls.title_desc": { + "one": "žádá o sloučení %[1]d commitu z %[2]s do %[3]s", + "other": "chce sloučit %[1]d commity z větve %[2]s do %[3]s" + }, + "search.milestone_kind": "Hledat milníky..." } diff --git a/options/locale_next/locale_da.json b/options/locale_next/locale_da.json index 834f66024f..0c2c9a25ea 100644 --- a/options/locale_next/locale_da.json +++ b/options/locale_next/locale_da.json @@ -1,5 +1,3 @@ { - "search": { - "milestone_kind": "Søg milepæle..." - } + "search.milestone_kind": "Søg milepæle..." } diff --git a/options/locale_next/locale_de-DE.json b/options/locale_next/locale_de-DE.json index 82e4ea54d4..f4a15ecdb9 100644 --- a/options/locale_next/locale_de-DE.json +++ b/options/locale_next/locale_de-DE.json @@ -1,17 +1,11 @@ { - "repo": { - "pulls": { - "merged_title_desc": { - "one": "hat %[1]d Commit von %[2]s nach %[3]s %[4]s zusammengeführt", - "other": "hat %[1]d Commits von %[2]s nach %[3]s %[4]s zusammengeführt" - }, - "title_desc": { - "one": "möchte %[1]d Commit von %[2]s nach %[3]s zusammenführen", - "other": "möchte %[1]d Commits von %[2]s nach %[3]s zusammenführen" - } - } - }, - "search": { - "milestone_kind": "Meilensteine suchen …" - } + "repo.pulls.merged_title_desc": { + "one": "hat %[1]d Commit von %[2]s nach %[3]s %[4]s zusammengeführt", + "other": "hat %[1]d Commits von %[2]s nach %[3]s %[4]s zusammengeführt" + }, + "repo.pulls.title_desc": { + "one": "möchte %[1]d Commit von %[2]s nach %[3]s zusammenführen", + "other": "möchte %[1]d Commits von %[2]s nach %[3]s zusammenführen" + }, + "search.milestone_kind": "Meilensteine suchen …" } diff --git a/options/locale_next/locale_el-GR.json b/options/locale_next/locale_el-GR.json index 9fa112cf0f..54ee504201 100644 --- a/options/locale_next/locale_el-GR.json +++ b/options/locale_next/locale_el-GR.json @@ -1,17 +1,11 @@ { - "repo": { - "pulls": { - "merged_title_desc": { - "one": "συγχώνευσε %[1]d υποβολή από τον κλάδο %[2]s στον κλάδο %[3]s %[4]s", - "other": "συγχώνευσε %[1]d υποβολές από %[2]s σε %[3]s %[4]s" - }, - "title_desc": { - "one": ": θα ήθελε να συγχωνεύσει %[1]d υποβολή από τον κλάδο %[2]s στον κλάδο %[3]s", - "other": "θέλει να συγχωνεύσει %[1]d υποβολές από %[2]s σε %[3]s" - } - } - }, - "search": { - "milestone_kind": "Αναζήτηση ορόσημων..." - } + "repo.pulls.merged_title_desc": { + "one": "συγχώνευσε %[1]d υποβολή από τον κλάδο %[2]s στον κλάδο %[3]s %[4]s", + "other": "συγχώνευσε %[1]d υποβολές από %[2]s σε %[3]s %[4]s" + }, + "repo.pulls.title_desc": { + "one": ": θα ήθελε να συγχωνεύσει %[1]d υποβολή από τον κλάδο %[2]s στον κλάδο %[3]s", + "other": "θέλει να συγχωνεύσει %[1]d υποβολές από %[2]s σε %[3]s" + }, + "search.milestone_kind": "Αναζήτηση ορόσημων..." } diff --git a/options/locale_next/locale_en-US.json b/options/locale_next/locale_en-US.json index 64e3e50abc..f8b2bcd0f6 100644 --- a/options/locale_next/locale_en-US.json +++ b/options/locale_next/locale_en-US.json @@ -1,17 +1,11 @@ { - "repo": { - "pulls": { - "merged_title_desc": { - "one": "merged %[1]d commit from %[2]s into %[3]s %[4]s", - "other": "merged %[1]d commits from %[2]s into %[3]s %[4]s" - }, - "title_desc": { - "one": "wants to merge %[1]d commit from %[2]s into %[3]s", - "other": "wants to merge %[1]d commits from %[2]s into %[3]s" - } - } - }, - "search": { - "milestone_kind": "Search milestones..." - } + "repo.pulls.merged_title_desc": { + "one": "merged %[1]d commit from %[2]s into %[3]s %[4]s", + "other": "merged %[1]d commits from %[2]s into %[3]s %[4]s" + }, + "repo.pulls.title_desc": { + "one": "wants to merge %[1]d commit from %[2]s into %[3]s", + "other": "wants to merge %[1]d commits from %[2]s into %[3]s" + }, + "search.milestone_kind": "Search milestones..." } diff --git a/options/locale_next/locale_eo.json b/options/locale_next/locale_eo.json index c57b462d5f..2c76a8562b 100644 --- a/options/locale_next/locale_eo.json +++ b/options/locale_next/locale_eo.json @@ -1,5 +1,3 @@ { - "search": { - "milestone_kind": "Serĉi celojn..." - } + "search.milestone_kind": "Serĉi celojn..." } diff --git a/options/locale_next/locale_es-ES.json b/options/locale_next/locale_es-ES.json index 7313cdc0a7..e95e91f696 100644 --- a/options/locale_next/locale_es-ES.json +++ b/options/locale_next/locale_es-ES.json @@ -1,17 +1,11 @@ { - "repo": { - "pulls": { - "merged_title_desc": { - "one": "fusionó %[1]d commit de %[2]s en %[3]s %[4]s", - "other": "fusionó %[1]d commits de %[2]s en %[3]s %[4]s" - }, - "title_desc": { - "one": "quiere fusionar %[1]d commit de %[2]s en %[3]s", - "other": "quiere fusionar %[1]d commits de %[2]s en %[3]s" - } - } - }, - "search": { - "milestone_kind": "Buscar hitos…" - } + "repo.pulls.merged_title_desc": { + "one": "fusionó %[1]d commit de %[2]s en %[3]s %[4]s", + "other": "fusionó %[1]d commits de %[2]s en %[3]s %[4]s" + }, + "repo.pulls.title_desc": { + "one": "quiere fusionar %[1]d commit de %[2]s en %[3]s", + "other": "quiere fusionar %[1]d commits de %[2]s en %[3]s" + }, + "search.milestone_kind": "Buscar hitos…" } diff --git a/options/locale_next/locale_et.json b/options/locale_next/locale_et.json index ac009856db..f8846a15b8 100644 --- a/options/locale_next/locale_et.json +++ b/options/locale_next/locale_et.json @@ -1,5 +1,3 @@ { - "search": { - "milestone_kind": "Otsi verstapostid..." - } + "search.milestone_kind": "Otsi verstapostid..." } diff --git a/options/locale_next/locale_fa-IR.json b/options/locale_next/locale_fa-IR.json index 6964db4934..0a703d22d7 100644 --- a/options/locale_next/locale_fa-IR.json +++ b/options/locale_next/locale_fa-IR.json @@ -1,12 +1,8 @@ { - "repo": { - "pulls": { - "merged_title_desc": { - "other": "%[1]d کامیت ادغام شده از %[2]s به %[3]s %[4]s" - }, - "title_desc": { - "other": "قصد ادغام %[1]d تغییر را از %[2]s به %[3]s دارد" - } - } - } + "repo.pulls.merged_title_desc": { + "other": "%[1]d کامیت ادغام شده از %[2]s به %[3]s %[4]s" + }, + "repo.pulls.title_desc": { + "other": "قصد ادغام %[1]d تغییر را از %[2]s به %[3]s دارد" + } } diff --git a/options/locale_next/locale_fi-FI.json b/options/locale_next/locale_fi-FI.json index 88a2110bcb..c4c7e1f7dc 100644 --- a/options/locale_next/locale_fi-FI.json +++ b/options/locale_next/locale_fi-FI.json @@ -1,15 +1,9 @@ { - "repo": { - "pulls": { - "merged_title_desc": { - "other": "yhdistetty %[1]d committia lähteestä %[2]s kohteeseen %[3]s %[4]s" - }, - "title_desc": { - "other": "haluaa yhdistää %[1]d committia lähteestä %[2]s kohteeseen %[3]s" - } - } - }, - "search": { - "milestone_kind": "Etsi merkkipaaluja..." - } + "repo.pulls.merged_title_desc": { + "other": "yhdistetty %[1]d committia lähteestä %[2]s kohteeseen %[3]s %[4]s" + }, + "repo.pulls.title_desc": { + "other": "haluaa yhdistää %[1]d committia lähteestä %[2]s kohteeseen %[3]s" + }, + "search.milestone_kind": "Etsi merkkipaaluja..." } diff --git a/options/locale_next/locale_fil.json b/options/locale_next/locale_fil.json index 6be27dbb8c..9c57ef16cc 100644 --- a/options/locale_next/locale_fil.json +++ b/options/locale_next/locale_fil.json @@ -1,17 +1,11 @@ { - "repo": { - "pulls": { - "merged_title_desc": { - "one": "isinali ang %[1]d commit mula%[2]s patungong %[3]s %[4]s", - "other": "isinali ang %[1]d mga commit mula sa %[2]s patungong %[3]s %[4]s" - }, - "title_desc": { - "one": "hinihiling na isama ang %[1]d commit mula %[2]s patungong %[3]s", - "other": "hiniling na isama ang %[1]d mga commit mula sa %[2]s patungong %[3]s" - } - } - }, - "search": { - "milestone_kind": "Maghanap ng mga milestone…" - } + "repo.pulls.merged_title_desc": { + "one": "isinali ang %[1]d commit mula%[2]s patungong %[3]s %[4]s", + "other": "isinali ang %[1]d mga commit mula sa %[2]s patungong %[3]s %[4]s" + }, + "repo.pulls.title_desc": { + "one": "hinihiling na isama ang %[1]d commit mula %[2]s patungong %[3]s", + "other": "hiniling na isama ang %[1]d mga commit mula sa %[2]s patungong %[3]s" + }, + "search.milestone_kind": "Maghanap ng mga milestone…" } diff --git a/options/locale_next/locale_fr-FR.json b/options/locale_next/locale_fr-FR.json index 995a2be8bb..173b10de21 100644 --- a/options/locale_next/locale_fr-FR.json +++ b/options/locale_next/locale_fr-FR.json @@ -1,17 +1,11 @@ { - "repo": { - "pulls": { - "merged_title_desc": { - "one": "fusionné %[1]d commit depuis %[2]s vers %[3]s %[4]s", - "other": "a fusionné %[1]d révision(s) à partir de %[2]s vers %[3]s %[4]s" - }, - "title_desc": { - "one": "veut fusionner %[1]d commit depuis %[2]s vers %[3]s", - "other": "souhaite fusionner %[1]d révision(s) depuis %[2]s vers %[3]s" - } - } - }, - "search": { - "milestone_kind": "Recherche dans les jalons..." - } + "repo.pulls.merged_title_desc": { + "one": "fusionné %[1]d commit depuis %[2]s vers %[3]s %[4]s", + "other": "a fusionné %[1]d révision(s) à partir de %[2]s vers %[3]s %[4]s" + }, + "repo.pulls.title_desc": { + "one": "veut fusionner %[1]d commit depuis %[2]s vers %[3]s", + "other": "souhaite fusionner %[1]d révision(s) depuis %[2]s vers %[3]s" + }, + "search.milestone_kind": "Recherche dans les jalons..." } diff --git a/options/locale_next/locale_hu-HU.json b/options/locale_next/locale_hu-HU.json index 2a21d68095..60c8cfacd3 100644 --- a/options/locale_next/locale_hu-HU.json +++ b/options/locale_next/locale_hu-HU.json @@ -1,15 +1,9 @@ { - "repo": { - "pulls": { - "merged_title_desc": { - "other": "egyesítve %[1]d változás(ok) a %[2]s-ból %[3]s-ba %[4]s" - }, - "title_desc": { - "other": "egyesíteni szeretné %[1]d változás(oka)t a(z) %[2]s-ból %[3]s-ba" - } - } - }, - "search": { - "milestone_kind": "Mérföldkövek keresése..." - } + "repo.pulls.merged_title_desc": { + "other": "egyesítve %[1]d változás(ok) a %[2]s-ból %[3]s-ba %[4]s" + }, + "repo.pulls.title_desc": { + "other": "egyesíteni szeretné %[1]d változás(oka)t a(z) %[2]s-ból %[3]s-ba" + }, + "search.milestone_kind": "Mérföldkövek keresése..." } diff --git a/options/locale_next/locale_id-ID.json b/options/locale_next/locale_id-ID.json index 13580f3cfe..f2dac8114f 100644 --- a/options/locale_next/locale_id-ID.json +++ b/options/locale_next/locale_id-ID.json @@ -1,12 +1,8 @@ { - "repo": { - "pulls": { - "merged_title_desc": { - "other": "commit %[1]d telah digabungkan dari %[2]s menjadi %[3]s %[4]s" - }, - "title_desc": { - "other": "ingin menggabungkan komit %[1]d dari %[2]s menuju %[3]s" - } - } - } + "repo.pulls.merged_title_desc": { + "other": "commit %[1]d telah digabungkan dari %[2]s menjadi %[3]s %[4]s" + }, + "repo.pulls.title_desc": { + "other": "ingin menggabungkan komit %[1]d dari %[2]s menuju %[3]s" + } } diff --git a/options/locale_next/locale_is-IS.json b/options/locale_next/locale_is-IS.json index 40d5a7e7aa..a92d924232 100644 --- a/options/locale_next/locale_is-IS.json +++ b/options/locale_next/locale_is-IS.json @@ -1,9 +1,5 @@ { - "repo": { - "pulls": { - "title_desc": { - "other": "vill sameina %[1]d framlög frá %[2]s í %[3]s" - } - } - } + "repo.pulls.title_desc": { + "other": "vill sameina %[1]d framlög frá %[2]s í %[3]s" + } } diff --git a/options/locale_next/locale_it-IT.json b/options/locale_next/locale_it-IT.json index 61cb012433..ba90fa154f 100644 --- a/options/locale_next/locale_it-IT.json +++ b/options/locale_next/locale_it-IT.json @@ -1,17 +1,11 @@ { - "repo": { - "pulls": { - "merged_title_desc": { - "one": "ha fuso %[1]d commit da %[2]s in %[3]s %[4]s", - "other": "ha unito %[1]d commit da %[2]s a %[3]s %[4]s" - }, - "title_desc": { - "one": "vuole fondere %[1]d commit da %[2]s in %[3]s", - "other": "vuole unire %[1]d commit da %[2]s a %[3]s" - } - } - }, - "search": { - "milestone_kind": "Ricerca tappe..." - } + "repo.pulls.merged_title_desc": { + "one": "ha fuso %[1]d commit da %[2]s in %[3]s %[4]s", + "other": "ha unito %[1]d commit da %[2]s a %[3]s %[4]s" + }, + "repo.pulls.title_desc": { + "one": "vuole fondere %[1]d commit da %[2]s in %[3]s", + "other": "vuole unire %[1]d commit da %[2]s a %[3]s" + }, + "search.milestone_kind": "Ricerca tappe..." } diff --git a/options/locale_next/locale_ja-JP.json b/options/locale_next/locale_ja-JP.json index 447ee8ae22..f72d1a3fb6 100644 --- a/options/locale_next/locale_ja-JP.json +++ b/options/locale_next/locale_ja-JP.json @@ -1,15 +1,9 @@ { - "repo": { - "pulls": { - "merged_title_desc": { - "other": "が %[1]d 個のコミットを %[2]s から %[3]s へマージ %[4]s" - }, - "title_desc": { - "other": "が %[2]s から %[3]s への %[1]d コミットのマージを希望しています" - } - } - }, - "search": { - "milestone_kind": "マイルストーンを検索..." - } + "repo.pulls.merged_title_desc": { + "other": "が %[1]d 個のコミットを %[2]s から %[3]s へマージ %[4]s" + }, + "repo.pulls.title_desc": { + "other": "が %[2]s から %[3]s への %[1]d コミットのマージを希望しています" + }, + "search.milestone_kind": "マイルストーンを検索..." } diff --git a/options/locale_next/locale_ko-KR.json b/options/locale_next/locale_ko-KR.json index 1beaec4627..2acaca6084 100644 --- a/options/locale_next/locale_ko-KR.json +++ b/options/locale_next/locale_ko-KR.json @@ -1,12 +1,8 @@ { - "repo": { - "pulls": { - "merged_title_desc": { - "other": "님이 %[2]s 에서 %[3]s 로 %[1]d 커밋을 %[4]s 병합함" - }, - "title_desc": { - "other": "%[2]s 에서 %[3]s 로 %[1]d개의 커밋들을 병합하려함" - } - } - } + "repo.pulls.merged_title_desc": { + "other": "님이 %[2]s 에서 %[3]s 로 %[1]d 커밋을 %[4]s 병합함" + }, + "repo.pulls.title_desc": { + "other": "%[2]s 에서 %[3]s 로 %[1]d개의 커밋들을 병합하려함" + } } diff --git a/options/locale_next/locale_lt.json b/options/locale_next/locale_lt.json index cce5782546..d81780a2ab 100644 --- a/options/locale_next/locale_lt.json +++ b/options/locale_next/locale_lt.json @@ -1,5 +1,3 @@ { - "search": { - "milestone_kind": "Ieškoti gairių..." - } + "search.milestone_kind": "Ieškoti gairių..." } diff --git a/options/locale_next/locale_lv-LV.json b/options/locale_next/locale_lv-LV.json index e338556aab..a16e3aaf8a 100644 --- a/options/locale_next/locale_lv-LV.json +++ b/options/locale_next/locale_lv-LV.json @@ -1,17 +1,11 @@ { - "repo": { - "pulls": { - "merged_title_desc": { - "one": "iekļāva %[1]d iesūtījumu no %[2]s %[3]s %[4]s", - "other": "Iekļāva %[1]d iesūtījumus no %[2]s zarā %[3]s %[4]s" - }, - "title_desc": { - "one": "vēlas iekļaut %[1]d iesūtījumu no %[2]s %[3]s", - "other": "vēlas iekļaut %[1]d iesūtījumus no %[2]s zarā %[3]s" - } - } - }, - "search": { - "milestone_kind": "Meklēt atskaites punktus..." - } + "repo.pulls.merged_title_desc": { + "one": "iekļāva %[1]d iesūtījumu no %[2]s %[3]s %[4]s", + "other": "Iekļāva %[1]d iesūtījumus no %[2]s zarā %[3]s %[4]s" + }, + "repo.pulls.title_desc": { + "one": "vēlas iekļaut %[1]d iesūtījumu no %[2]s %[3]s", + "other": "vēlas iekļaut %[1]d iesūtījumus no %[2]s zarā %[3]s" + }, + "search.milestone_kind": "Meklēt atskaites punktus..." } diff --git a/options/locale_next/locale_nds.json b/options/locale_next/locale_nds.json index a141362816..564302820a 100644 --- a/options/locale_next/locale_nds.json +++ b/options/locale_next/locale_nds.json @@ -1,17 +1,11 @@ { - "repo": { - "pulls": { - "merged_title_desc": { - "one": "hett %[1]d Kommitteren vun %[2]s na %[3]s %[4]s tosamenföhrt", - "other": "hett %[1]d Kommitterens vun %[2]s na %[3]s %[4]s tosamenföhrt" - }, - "title_desc": { - "one": "will %[1]d Kommitteren vun %[2]s na %[3]s tosamenföhren", - "other": "will %[1]d Kommitterens vun %[2]s na %[3]s tosamenföhren" - } - } - }, - "search": { - "milestone_kind": "In Markstenen söken …" - } + "repo.pulls.merged_title_desc": { + "one": "hett %[1]d Kommitteren vun %[2]s na %[3]s %[4]s tosamenföhrt", + "other": "hett %[1]d Kommitterens vun %[2]s na %[3]s %[4]s tosamenföhrt" + }, + "repo.pulls.title_desc": { + "one": "will %[1]d Kommitteren vun %[2]s na %[3]s tosamenföhren", + "other": "will %[1]d Kommitterens vun %[2]s na %[3]s tosamenföhren" + }, + "search.milestone_kind": "In Markstenen söken …" } diff --git a/options/locale_next/locale_nl-NL.json b/options/locale_next/locale_nl-NL.json index 9bbfc0fecd..fbb78e9280 100644 --- a/options/locale_next/locale_nl-NL.json +++ b/options/locale_next/locale_nl-NL.json @@ -1,17 +1,11 @@ { - "repo": { - "pulls": { - "merged_title_desc": { - "one": "heeft %[1]d commit van %[2]s samengevoegd in %[3]s %[4]s", - "other": "heeft %[1]d commits samengevoegd van %[2]s naar %[3]s %[4]s" - }, - "title_desc": { - "one": "wilt %[1]d commit van %[2]s samenvoegen in %[3]s", - "other": "wilt %[1]d commits van %[2]s samenvoegen met %[3]s" - } - } - }, - "search": { - "milestone_kind": "Zoek mijlpalen..." - } + "repo.pulls.merged_title_desc": { + "one": "heeft %[1]d commit van %[2]s samengevoegd in %[3]s %[4]s", + "other": "heeft %[1]d commits samengevoegd van %[2]s naar %[3]s %[4]s" + }, + "repo.pulls.title_desc": { + "one": "wilt %[1]d commit van %[2]s samenvoegen in %[3]s", + "other": "wilt %[1]d commits van %[2]s samenvoegen met %[3]s" + }, + "search.milestone_kind": "Zoek mijlpalen..." } diff --git a/options/locale_next/locale_pl-PL.json b/options/locale_next/locale_pl-PL.json index 1f2def3ea0..2edcb573c4 100644 --- a/options/locale_next/locale_pl-PL.json +++ b/options/locale_next/locale_pl-PL.json @@ -1,15 +1,9 @@ { - "repo": { - "pulls": { - "merged_title_desc": { - "many": "scala %[1]d commity/ów z %[2]s do %[3]s %[4]s" - }, - "title_desc": { - "many": "chce scalić %[1]d commity/ów z %[2]s do %[3]s" - } - } - }, - "search": { - "milestone_kind": "Wyszukaj kamienie milowe..." - } + "repo.pulls.merged_title_desc": { + "many": "scala %[1]d commity/ów z %[2]s do %[3]s %[4]s" + }, + "repo.pulls.title_desc": { + "many": "chce scalić %[1]d commity/ów z %[2]s do %[3]s" + }, + "search.milestone_kind": "Wyszukaj kamienie milowe..." } diff --git a/options/locale_next/locale_pt-BR.json b/options/locale_next/locale_pt-BR.json index e7758ef1bf..4de44582a5 100644 --- a/options/locale_next/locale_pt-BR.json +++ b/options/locale_next/locale_pt-BR.json @@ -1,17 +1,11 @@ { - "repo": { - "pulls": { - "merged_title_desc": { - "one": "mesclou %[1]d commit de %[2]s em %[3]s %[4]s", - "other": "mesclou %[1]d commits de %[2]s em %[3]s %[4]s" - }, - "title_desc": { - "one": "quer mesclar %[1]d commit de %[2]s em %[3]s", - "other": "quer mesclar %[1]d commits de %[2]s em %[3]s" - } - } - }, - "search": { - "milestone_kind": "Pesquisar marcos..." - } + "repo.pulls.merged_title_desc": { + "one": "mesclou %[1]d commit de %[2]s em %[3]s %[4]s", + "other": "mesclou %[1]d commits de %[2]s em %[3]s %[4]s" + }, + "repo.pulls.title_desc": { + "one": "quer mesclar %[1]d commit de %[2]s em %[3]s", + "other": "quer mesclar %[1]d commits de %[2]s em %[3]s" + }, + "search.milestone_kind": "Pesquisar marcos..." } diff --git a/options/locale_next/locale_pt-PT.json b/options/locale_next/locale_pt-PT.json index 475023d461..cf72ef3e09 100644 --- a/options/locale_next/locale_pt-PT.json +++ b/options/locale_next/locale_pt-PT.json @@ -1,17 +1,11 @@ { - "repo": { - "pulls": { - "merged_title_desc": { - "one": "integrou %[1]d cometimento do ramo %[2]s no ramo %[3]s %[4]s", - "other": "integrou %[1]d cometimento(s) do ramo %[2]s no ramo %[3]s %[4]s" - }, - "title_desc": { - "one": "quer integrar %[1]d cometimento do ramo %[2]s no ramo %[3]s", - "other": "quer integrar %[1]d cometimento(s) do ramo %[2]s no ramo %[3]s" - } - } - }, - "search": { - "milestone_kind": "Procurar etapas..." - } + "repo.pulls.merged_title_desc": { + "one": "integrou %[1]d cometimento do ramo %[2]s no ramo %[3]s %[4]s", + "other": "integrou %[1]d cometimento(s) do ramo %[2]s no ramo %[3]s %[4]s" + }, + "repo.pulls.title_desc": { + "one": "quer integrar %[1]d cometimento do ramo %[2]s no ramo %[3]s", + "other": "quer integrar %[1]d cometimento(s) do ramo %[2]s no ramo %[3]s" + }, + "search.milestone_kind": "Procurar etapas..." } diff --git a/options/locale_next/locale_ru-RU.json b/options/locale_next/locale_ru-RU.json index de310505a3..36f54f405b 100644 --- a/options/locale_next/locale_ru-RU.json +++ b/options/locale_next/locale_ru-RU.json @@ -1,17 +1,11 @@ { - "repo": { - "pulls": { - "merged_title_desc": { - "one": "слит %[1]d коммит из %[2]s в %[3]s %[4]s", - "many": "слито %[1]d коммит(ов) из %[2]s в %[3]s %[4]s" - }, - "title_desc": { - "one": "хочет влить %[1]d коммит из %[2]s в %[3]s", - "many": "хочет влить %[1]d коммит(ов) из %[2]s в %[3]s" - } - } - }, - "search": { - "milestone_kind": "Найти этапы..." - } + "repo.pulls.merged_title_desc": { + "one": "слит %[1]d коммит из %[2]s в %[3]s %[4]s", + "many": "слито %[1]d коммит(ов) из %[2]s в %[3]s %[4]s" + }, + "repo.pulls.title_desc": { + "one": "хочет влить %[1]d коммит из %[2]s в %[3]s", + "many": "хочет влить %[1]d коммит(ов) из %[2]s в %[3]s" + }, + "search.milestone_kind": "Найти этапы..." } diff --git a/options/locale_next/locale_si-LK.json b/options/locale_next/locale_si-LK.json index 25e149f9b8..0cdd44acd0 100644 --- a/options/locale_next/locale_si-LK.json +++ b/options/locale_next/locale_si-LK.json @@ -1,12 +1,8 @@ { - "repo": { - "pulls": { - "merged_title_desc": { - "other": "මර්ජ්%[1]d සිට %[2]s දක්වා %[3]s %[4]s" - }, - "title_desc": { - "other": "%[1]d සිට %[2]s දක්වා %[3]s" - } - } - } + "repo.pulls.merged_title_desc": { + "other": "මර්ජ්%[1]d සිට %[2]s දක්වා %[3]s %[4]s" + }, + "repo.pulls.title_desc": { + "other": "%[1]d සිට %[2]s දක්වා %[3]s" + } } diff --git a/options/locale_next/locale_sv-SE.json b/options/locale_next/locale_sv-SE.json index fe68f161c2..de7099ad3a 100644 --- a/options/locale_next/locale_sv-SE.json +++ b/options/locale_next/locale_sv-SE.json @@ -1,15 +1,9 @@ { - "repo": { - "pulls": { - "merged_title_desc": { - "other": "sammanfogade %[1]d incheckningar från %[2]s in i %[3]s %[4]s" - }, - "title_desc": { - "other": "vill sammanfoga %[1]d incheckningar från s[2]s in i %[3]s" - } - } - }, - "search": { - "milestone_kind": "Sök milstolpar..." - } + "repo.pulls.merged_title_desc": { + "other": "sammanfogade %[1]d incheckningar från %[2]s in i %[3]s %[4]s" + }, + "repo.pulls.title_desc": { + "other": "vill sammanfoga %[1]d incheckningar från s[2]s in i %[3]s" + }, + "search.milestone_kind": "Sök milstolpar..." } diff --git a/options/locale_next/locale_tr-TR.json b/options/locale_next/locale_tr-TR.json index ef2cdb6584..f98b339245 100644 --- a/options/locale_next/locale_tr-TR.json +++ b/options/locale_next/locale_tr-TR.json @@ -1,15 +1,9 @@ { - "repo": { - "pulls": { - "merged_title_desc": { - "other": "%[4]s %[2]s içindeki %[1]d işlemeyi %[3]s ile birleştirdi" - }, - "title_desc": { - "other": "%[2]s içindeki %[1]d işlemeyi %[3]s ile birleştirmek istiyor" - } - } - }, - "search": { - "milestone_kind": "Kilometre taşlarını ara..." - } + "repo.pulls.merged_title_desc": { + "other": "%[4]s %[2]s içindeki %[1]d işlemeyi %[3]s ile birleştirdi" + }, + "repo.pulls.title_desc": { + "other": "%[2]s içindeki %[1]d işlemeyi %[3]s ile birleştirmek istiyor" + }, + "search.milestone_kind": "Kilometre taşlarını ara..." } diff --git a/options/locale_next/locale_uk-UA.json b/options/locale_next/locale_uk-UA.json index aded9786b4..ce37b9bef3 100644 --- a/options/locale_next/locale_uk-UA.json +++ b/options/locale_next/locale_uk-UA.json @@ -1,17 +1,11 @@ { - "repo": { - "pulls": { - "merged_title_desc": { - "one": "об'єднав %[1]d коміт з %[2]s в %[3]s %[4]s", - "many": "об'єднав %[1]d комітів з %[2]s в %[3]s %[4]s" - }, - "title_desc": { - "one": "хоче об'єднати %[1]d коміт з %[2]s в %[3]s", - "many": "хоче об'єднати %[1]d комітів з %[2]s в %[3]s" - } - } - }, - "search": { - "milestone_kind": "Шукати віхи..." - } + "repo.pulls.merged_title_desc": { + "one": "об'єднав %[1]d коміт з %[2]s в %[3]s %[4]s", + "many": "об'єднав %[1]d комітів з %[2]s в %[3]s %[4]s" + }, + "repo.pulls.title_desc": { + "one": "хоче об'єднати %[1]d коміт з %[2]s в %[3]s", + "many": "хоче об'єднати %[1]d комітів з %[2]s в %[3]s" + }, + "search.milestone_kind": "Шукати віхи..." } diff --git a/options/locale_next/locale_zh-CN.json b/options/locale_next/locale_zh-CN.json index 091b3fe609..10b1c9a4be 100644 --- a/options/locale_next/locale_zh-CN.json +++ b/options/locale_next/locale_zh-CN.json @@ -1,15 +1,9 @@ { - "repo": { - "pulls": { - "merged_title_desc": { - "other": "于 %[4]s 将 %[1]d 次代码提交从 %[2]s合并至 %[3]s" - }, - "title_desc": { - "other": "请求将 %[1]d 次代码提交从 %[2]s 合并至 %[3]s" - } - } - }, - "search": { - "milestone_kind": "搜索里程碑…" - } + "repo.pulls.merged_title_desc": { + "other": "于 %[4]s 将 %[1]d 次代码提交从 %[2]s合并至 %[3]s" + }, + "repo.pulls.title_desc": { + "other": "请求将 %[1]d 次代码提交从 %[2]s 合并至 %[3]s" + }, + "search.milestone_kind": "搜索里程碑…" } diff --git a/options/locale_next/locale_zh-HK.json b/options/locale_next/locale_zh-HK.json index dd7b954559..6baf89e022 100644 --- a/options/locale_next/locale_zh-HK.json +++ b/options/locale_next/locale_zh-HK.json @@ -1,9 +1,5 @@ { - "repo": { - "pulls": { - "merged_title_desc": { - "other": "於 %[4]s 將 %[1]d 次代碼提交從 %[2]s合併至 %[3]s" - } - } - } + "repo.pulls.merged_title_desc": { + "other": "於 %[4]s 將 %[1]d 次代碼提交從 %[2]s合併至 %[3]s" + } } diff --git a/options/locale_next/locale_zh-TW.json b/options/locale_next/locale_zh-TW.json index 4d31a713c0..d04e04c264 100644 --- a/options/locale_next/locale_zh-TW.json +++ b/options/locale_next/locale_zh-TW.json @@ -1,15 +1,9 @@ { - "repo": { - "pulls": { - "merged_title_desc": { - "other": "將 %[1]d 次提交從 %[2]s 合併至 %[3]s %[4]s" - }, - "title_desc": { - "other": "請求將 %[1]d 次程式碼提交從 %[2]s 合併至 %[3]s" - } - } - }, - "search": { - "milestone_kind": "搜尋里程碑..." - } + "repo.pulls.merged_title_desc": { + "other": "將 %[1]d 次提交從 %[2]s 合併至 %[3]s %[4]s" + }, + "repo.pulls.title_desc": { + "other": "請求將 %[1]d 次程式碼提交從 %[2]s 合併至 %[3]s" + }, + "search.milestone_kind": "搜尋里程碑..." } From f2e63495e7873f1f3d72a33a08071bd9ceea0042 Mon Sep 17 00:00:00 2001 From: Michael Kriese Date: Sat, 18 Jan 2025 15:19:53 +0100 Subject: [PATCH 168/198] chore(renovate): fix self-update config [skip-ci] --- renovate.json | 19 ++----------------- 1 file changed, 2 insertions(+), 17 deletions(-) diff --git a/renovate.json b/renovate.json index 64e610cd57..c34ae1aaba 100644 --- a/renovate.json +++ b/renovate.json @@ -110,34 +110,19 @@ "matchUpdateTypes": ["patch"], "automerge": true }, - { - "description": "Automerge renovate updates", - "matchDatasources": ["docker"], - "matchPackageNames": ["code.forgejo.org/forgejo-contrib/renovate"], - "matchUpdateTypes": ["minor", "patch", "digest"], - "automerge": true - }, { "description": "Add reviewer and additional labels to renovate PRs", "matchDatasources": ["docker"], - "matchPackageNames": ["code.forgejo.org/forgejo-contrib/renovate"], + "matchPackageNames": ["data.forgejo.org/renovate/renovate"], "reviewers": ["viceice"], "addLabels": ["forgejo/ci", "test/not-needed"] }, - { - "description": "Update renovate with higher prio to come through rate limit", - "matchDatasources": ["docker"], - "matchPackageNames": ["code.forgejo.org/forgejo-contrib/renovate"], - "extends": ["schedule:weekly"], - "prPriority": 10, - "groupName": "renovate" - }, { "description": "Disable renovate self-updates for release branches", "matchBaseBranches": ["/^v\\d+\\.\\d+\\/forgejo$/"], - "matchDatasources": ["docker"], "matchPackageNames": [ "code.forgejo.org/forgejo-contrib/renovate", + "data.forgejo.org/renovate/renovate", "ghcr.io/visualon/renovate" ], "enabled": false From e35afe475a9a1b5dba160d15dc30b7f2461ee34e Mon Sep 17 00:00:00 2001 From: Renovate Bot Date: Sat, 18 Jan 2025 14:56:11 +0000 Subject: [PATCH 169/198] Update renovate Docker tag to v39.115.4 (forgejo) (#6606) Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/6606 Co-authored-by: Renovate Bot Co-committed-by: Renovate Bot --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 039004603c..5865262d1a 100644 --- a/Makefile +++ b/Makefile @@ -49,7 +49,7 @@ GOVULNCHECK_PACKAGE ?= golang.org/x/vuln/cmd/govulncheck@v1 # renovate: datasour DEADCODE_PACKAGE ?= golang.org/x/tools/cmd/deadcode@v0.29.0 # renovate: datasource=go GOMOCK_PACKAGE ?= go.uber.org/mock/mockgen@v0.4.0 # renovate: datasource=go GOPLS_PACKAGE ?= golang.org/x/tools/gopls@v0.17.1 # renovate: datasource=go -RENOVATE_NPM_PACKAGE ?= renovate@39.111.0 # renovate: datasource=docker packageName=data.forgejo.org/renovate/renovate +RENOVATE_NPM_PACKAGE ?= renovate@39.115.4 # renovate: datasource=docker packageName=data.forgejo.org/renovate/renovate # https://github.com/disposable-email-domains/disposable-email-domains/commits/main/ DISPOSABLE_EMAILS_SHA ?= 0c27e671231d27cf66370034d7f6818037416989 # renovate: ... From 276ef10dd5a1167a8bcc20599197f89ff7f9b8a4 Mon Sep 17 00:00:00 2001 From: Beowulf Date: Fri, 17 Jan 2025 18:22:43 +0100 Subject: [PATCH 170/198] Prevent prefix continuation if currently a text expander popup is open This fixes that mentions and emoji autocompletion was broken in e.g. a list, because the list handling take presidency over the text expansion. --- tests/e2e/markdown-editor.test.e2e.ts | 26 +++++++++++++++++++ .../js/features/comp/ComboMarkdownEditor.js | 2 ++ 2 files changed, 28 insertions(+) diff --git a/tests/e2e/markdown-editor.test.e2e.ts b/tests/e2e/markdown-editor.test.e2e.ts index 762113d563..1e30b8d3b9 100644 --- a/tests/e2e/markdown-editor.test.e2e.ts +++ b/tests/e2e/markdown-editor.test.e2e.ts @@ -224,3 +224,29 @@ test('markdown insert table', async ({page}) => { await expect(textarea).toHaveValue('| Header | Header |\n|---------|---------|\n| Content | Content |\n| Content | Content |\n| Content | Content |\n'); await save_visual(page); }); + +test('text expander has higher prio then prefix continuation', async ({page}) => { + const response = await page.goto('/user2/repo1/issues/new'); + expect(response?.status()).toBe(200); + + const textarea = page.locator('textarea[name=content]'); + const initText = `* first`; + await textarea.fill(initText); + await textarea.evaluate((it:HTMLTextAreaElement) => it.setSelectionRange(it.value.indexOf('rst'), it.value.indexOf('rst'))); + await textarea.press('End'); + + // Test emoji completion + await textarea.press('Enter'); + await textarea.pressSequentially(':smile_c'); + await textarea.press('Enter'); + await expect(textarea).toHaveValue(`* first\n* 😸`); + + // Test username completion + await textarea.press('Enter'); + await textarea.pressSequentially('@user'); + await textarea.press('Enter'); + await expect(textarea).toHaveValue(`* first\n* 😸\n* @user2 `); + + await textarea.press('Enter'); + await expect(textarea).toHaveValue(`* first\n* 😸\n* @user2 \n* `); +}); diff --git a/web_src/js/features/comp/ComboMarkdownEditor.js b/web_src/js/features/comp/ComboMarkdownEditor.js index 8ae5defa47..707101190c 100644 --- a/web_src/js/features/comp/ComboMarkdownEditor.js +++ b/web_src/js/features/comp/ComboMarkdownEditor.js @@ -99,6 +99,8 @@ class ComboMarkdownEditor { e.target._shiftDown = true; } if (e.key === 'Enter' && !e.shiftKey && !e.ctrlKey && !e.altKey) { + // Prevent special line break handling if currently a text expander popup is open + if (this.textarea.hasAttribute('aria-expanded')) return; if (!this.breakLine()) return; // Nothing changed, let the default handler work. this.options?.onContentChanged?.(this, e); e.preventDefault(); From 7ea62c5ce475db81f2930a569c98190a52e6cae6 Mon Sep 17 00:00:00 2001 From: Beowulf Date: Fri, 17 Jan 2025 18:42:42 +0100 Subject: [PATCH 171/198] Leave list/quote expanison with double enter When editing a list or similar syntax elements, pressing enter starts a new line with the line introducer (e.g. `- ` for a plain list). But currently it's uncomfortable when someone wants to leave the list. Pressing enter again simply adds more and more lines with the prefix. With this change the list is terminated if enter is pressed on a line which contains the introducer but nothing else. This behavior is known from other markdown editors like the on used by GitLab or GitHub. Additionally I changed the regex for detecting a prefix. - Why: With the change you can add a single whitespace at the end if you want to keep an "empty" line. So if you want to write: ``` - First - - Third ``` You just need to add a whitespace in the second line to prevent that the prefix will be removed. - Changes in detail: - ordered bullet list prefix detection: nothing changed - todo list and unordered list prefix detection: have been split up: - todo list: Changed that only 1 to 4 whitespaces can be between the list char (`-`,`*`,`+`) and the checkbox (`[ ]`,`[x]`) - Why? If more then 4 spaces are between the list char and the checkbox, this is no longer detected as a prefix for a todo item based on the markdown standard. Due to the amount of spaces it is instead parsed as code. - unordered list: The prefix now needs to have exactly one space after the list char (`-`,`*`,`+`). More spaces will not be taken into account for detecting the prefix. - quote prefix detection: nothing changed The current e2e-tests where simplified and duplicated tests where removed. Test cases for the new functionality where added. --- tests/e2e/markdown-editor.test.e2e.ts | 51 +++++++++---------- .../js/features/comp/ComboMarkdownEditor.js | 22 ++++++-- 2 files changed, 43 insertions(+), 30 deletions(-) diff --git a/tests/e2e/markdown-editor.test.e2e.ts b/tests/e2e/markdown-editor.test.e2e.ts index 1e30b8d3b9..35e9de2ea6 100644 --- a/tests/e2e/markdown-editor.test.e2e.ts +++ b/tests/e2e/markdown-editor.test.e2e.ts @@ -109,7 +109,7 @@ test('markdown indentation', async ({page}) => { }); test('markdown list continuation', async ({page}) => { - const initText = `* first\n* second\n* third\n* last`; + const initText = `* first\n* second`; const response = await page.goto('/user2/repo1/issues/new'); expect(response?.status()).toBe(200); @@ -119,25 +119,20 @@ test('markdown list continuation', async ({page}) => { const indent = page.locator('button[data-md-action="indent"]'); await textarea.fill(initText); - // Test continuation of '* ' prefix - await textarea.evaluate((it:HTMLTextAreaElement) => it.setSelectionRange(it.value.indexOf('cond'), it.value.indexOf('cond'))); + // Test continuation of ' * ' prefix + await textarea.evaluate((it:HTMLTextAreaElement) => it.setSelectionRange(it.value.indexOf('rst'), it.value.indexOf('rst'))); + await indent.click(); await textarea.press('End'); await textarea.press('Enter'); - await textarea.pressSequentially('middle'); - await expect(textarea).toHaveValue(`* first\n* second\n* middle\n* third\n* last`); - - // Test continuation of ' * ' prefix - await indent.click(); - await textarea.press('Enter'); await textarea.pressSequentially('muddle'); - await expect(textarea).toHaveValue(`* first\n* second\n${tab}* middle\n${tab}* muddle\n* third\n* last`); + await expect(textarea).toHaveValue(`${tab}* first\n${tab}* muddle\n* second`); // Test breaking in the middle of a line await textarea.evaluate((it:HTMLTextAreaElement) => it.setSelectionRange(it.value.lastIndexOf('ddle'), it.value.lastIndexOf('ddle'))); await textarea.pressSequentially('tate'); await textarea.press('Enter'); await textarea.pressSequentially('me'); - await expect(textarea).toHaveValue(`* first\n* second\n${tab}* middle\n${tab}* mutate\n${tab}* meddle\n* third\n* last`); + await expect(textarea).toHaveValue(`${tab}* first\n${tab}* mutate\n${tab}* meddle\n* second`); // Test not triggering when Shift held await textarea.fill(initText); @@ -145,35 +140,36 @@ test('markdown list continuation', async ({page}) => { await textarea.press('Shift+Enter'); await textarea.press('Enter'); await textarea.pressSequentially('...but not least'); - await expect(textarea).toHaveValue(`* first\n* second\n* third\n* last\n\n...but not least`); + await expect(textarea).toHaveValue(`* first\n* second\n\n...but not least`); // Test continuation of ordered list - await textarea.fill(`1. one\n2. two`); + await textarea.fill(`1. one`); await textarea.evaluate((it:HTMLTextAreaElement) => it.setSelectionRange(it.value.length, it.value.length)); await textarea.press('Enter'); + await textarea.pressSequentially(' '); + await textarea.press('Enter'); await textarea.pressSequentially('three'); - await expect(textarea).toHaveValue(`1. one\n2. two\n3. three`); + await textarea.press('Enter'); + await textarea.press('Enter'); + await expect(textarea).toHaveValue(`1. one\n2. \n3. three\n\n`); // Test continuation of alternative ordered list syntax - await textarea.fill(`1) one\n2) two`); + await textarea.fill(`1) one`); await textarea.evaluate((it:HTMLTextAreaElement) => it.setSelectionRange(it.value.length, it.value.length)); await textarea.press('Enter'); + await textarea.pressSequentially(' '); + await textarea.press('Enter'); await textarea.pressSequentially('three'); - await expect(textarea).toHaveValue(`1) one\n2) two\n3) three`); - - // Test continuation of blockquote - await textarea.fill(`> knowledge is power`); - await textarea.evaluate((it:HTMLTextAreaElement) => it.setSelectionRange(it.value.length, it.value.length)); await textarea.press('Enter'); - await textarea.pressSequentially('france is bacon'); - await expect(textarea).toHaveValue(`> knowledge is power\n> france is bacon`); + await textarea.press('Enter'); + await expect(textarea).toHaveValue(`1) one\n2) \n3) three\n\n`); // Test continuation of checklists - await textarea.fill(`- [ ] have a problem\n- [x] create a solution`); + await textarea.fill(`- [ ]have a problem\n- [x]create a solution`); await textarea.evaluate((it:HTMLTextAreaElement) => it.setSelectionRange(it.value.length, it.value.length)); await textarea.press('Enter'); await textarea.pressSequentially('write a test'); - await expect(textarea).toHaveValue(`- [ ] have a problem\n- [x] create a solution\n- [ ] write a test`); + await expect(textarea).toHaveValue(`- [ ]have a problem\n- [x]create a solution\n- [ ]write a test`); // Test all conceivable syntax (except ordered lists) const prefixes = [ @@ -189,7 +185,6 @@ test('markdown list continuation', async ({page}) => { '> ', '> > ', '- [ ] ', - '- [ ]', // This does seem to render, so allow. '* [ ] ', '+ [ ] ', ]; @@ -197,8 +192,12 @@ test('markdown list continuation', async ({page}) => { await textarea.fill(`${prefix}one`); await textarea.evaluate((it:HTMLTextAreaElement) => it.setSelectionRange(it.value.length, it.value.length)); await textarea.press('Enter'); + await textarea.pressSequentially(' '); + await textarea.press('Enter'); await textarea.pressSequentially('two'); - await expect(textarea).toHaveValue(`${prefix}one\n${prefix}two`); + await textarea.press('Enter'); + await textarea.press('Enter'); + await expect(textarea).toHaveValue(`${prefix}one\n${prefix} \n${prefix}two\n\n`); } }); diff --git a/web_src/js/features/comp/ComboMarkdownEditor.js b/web_src/js/features/comp/ComboMarkdownEditor.js index 707101190c..89a252f6f3 100644 --- a/web_src/js/features/comp/ComboMarkdownEditor.js +++ b/web_src/js/features/comp/ComboMarkdownEditor.js @@ -409,13 +409,27 @@ class ComboMarkdownEditor { // Find the beginning of the current line. const lineStart = Math.max(0, value.lastIndexOf('\n', start - 1) + 1); // Find the end and extract the line. - const lineEnd = value.indexOf('\n', start); - const line = value.slice(lineStart, lineEnd === -1 ? value.length : lineEnd); + const nextLF = value.indexOf('\n', start); + const lineEnd = nextLF === -1 ? value.length : nextLF; + const line = value.slice(lineStart, lineEnd); // Match any whitespace at the start + any repeatable prefix + exactly one space after. - const prefix = line.match(/^\s*((\d+)[.)]\s|[-*+]\s+(\[[ x]\]\s?)?|(>\s+)+)?/); + const prefix = line.match(/^\s*((\d+)[.)]\s|[-*+]\s{1,4}\[[ x]\]\s?|[-*+]\s|(>\s?)+)?/); // Defer to browser if we can't do anything more useful, or if the cursor is inside the prefix. - if (!prefix || !prefix[0].length || lineStart + prefix[0].length > start) return false; + if (!prefix) return false; + const prefixLength = prefix[0].length; + if (!prefixLength || lineStart + prefixLength > start) return false; + // If the prefix is just indentation (which should always be an even number of spaces or tabs), check if a single whitespace is added to the end of the line. + // If this is the case do not leave the indentation and continue with the prefix. + if ((prefixLength % 2 === 1 && /^ +$/.test(prefix[0])) || /^\t+ $/.test(prefix[0])) { + prefix[0] = prefix[0].slice(0, prefixLength - 1); + } else if (prefixLength === lineEnd - lineStart) { + this.textarea.setSelectionRange(lineStart, lineEnd); + if (!document.execCommand('insertText', false, '\n')) { + this.textarea.setRangeText('\n'); + } + return true; + } // Insert newline + prefix. let text = `\n${prefix[0]}`; From d68e0d3e3903093019ce848d541efd60bf5fa1c1 Mon Sep 17 00:00:00 2001 From: Beowulf Date: Sat, 18 Jan 2025 19:39:42 +0000 Subject: [PATCH 172/198] fix(ui): hide git note add button for commit if commit already has a note (#6613) Regression from f5c0570533b0a835a88eb7337da841d071f2de6b Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/6613 Reviewed-by: 0ko <0ko@noreply.codeberg.org> Co-authored-by: Beowulf Co-committed-by: Beowulf --- templates/repo/commit_page.tmpl | 8 +++++--- tests/e2e/git-notes.test.e2e.ts | 3 +++ 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/templates/repo/commit_page.tmpl b/templates/repo/commit_page.tmpl index 66be0c143d..36de789dd1 100644 --- a/templates/repo/commit_page.tmpl +++ b/templates/repo/commit_page.tmpl @@ -128,9 +128,11 @@
-
- {{ctx.Locale.Tr "repo.diff.git-notes.add"}} -
+ {{if not .NoteRendered}} +
+ {{ctx.Locale.Tr "repo.diff.git-notes.add"}} +
+ {{end}}
{{end}} diff --git a/tests/e2e/git-notes.test.e2e.ts b/tests/e2e/git-notes.test.e2e.ts index 4245853b24..1e2cbe76fc 100644 --- a/tests/e2e/git-notes.test.e2e.ts +++ b/tests/e2e/git-notes.test.e2e.ts @@ -8,6 +8,9 @@ test('Change git note', async ({page}) => { let response = await page.goto('/user2/repo1/commit/65f1bf27bc3bf70f64657658635e66094edbcb4d'); expect(response?.status()).toBe(200); + // An add button should not be present, because the commit already has a commit note + await expect(page.locator('#commit-notes-add-button')).toHaveCount(0); + await page.locator('#commit-notes-edit-button').click(); let textarea = page.locator('textarea[name="notes"]'); From 5f2d445d006a22c6adaabeb3e236a6c095785b0f Mon Sep 17 00:00:00 2001 From: Beowulf Date: Sun, 19 Jan 2025 01:42:00 +0100 Subject: [PATCH 173/198] fix(ui): add triangle down octicon to code search options dropdown This adds the triangle down oction to the code search options dropdown to match the other search option dropdowns (issue, pull). --- templates/shared/search/combo_multi.tmpl | 1 + 1 file changed, 1 insertion(+) diff --git a/templates/shared/search/combo_multi.tmpl b/templates/shared/search/combo_multi.tmpl index 89dc20b530..07d0ea8839 100644 --- a/templates/shared/search/combo_multi.tmpl +++ b/templates/shared/search/combo_multi.tmpl @@ -7,6 +7,7 @@
{{template "shared/search/input" dict "Value" .Value "Disabled" .Disabled "Placeholder" .Placeholder}}