Template
1
0
Fork 0
mirror of https://codeberg.org/forgejo/forgejo synced 2024-11-25 11:16:11 +01:00

Merge branch 'forgejo' into syncfork

This commit is contained in:
JakobDev 2024-07-21 20:40:10 +00:00
commit 9570629c9e
110 changed files with 1586 additions and 1483 deletions

View file

@ -49,6 +49,7 @@ jobs:
image: elasticsearch:7.17.22
env:
discovery.type: single-node
ES_JAVA_OPTS: "-Xms512m -Xmx512m"
minio:
image: bitnami/minio:2024.3.30
options: >-

View file

@ -1,6 +1,6 @@
name: 🦋 Bug Report (web interface / frontend)
description: Something doesn't look quite as it should? Report it here!
title: "[BUG] "
title: "bug: "
labels: ["bug/new-report", "forgejo/ui"]
body:
- type: markdown
@ -13,16 +13,29 @@ body:
- Please speak English, as this is the language all maintainers can speak and write.
- Be as clear and concise as possible. A very verbose report is harder to interpret in a concrete way.
- Be civil, and follow the [Forgejo Code of Conduct](https://codeberg.org/forgejo/code-of-conduct).
- Please make sure you are using the latest release of Forgejo and take a moment to [check that your issue hasn't been reported before](https://codeberg.org/forgejo/forgejo/issues?q=&type=all&labels=78137).
- Please give all relevant information below for bug reports, as incomplete details may result in the issue not being considered.
- Take a moment to [check that your issue hasn't been reported before](https://codeberg.org/forgejo/forgejo/issues?q=&type=all&labels=78137).
- type: dropdown
id: can-reproduce
attributes:
label: Can you reproduce the bug on the Forgejo test instance?
description: |
Please try reproducing your issue at https://dev.next.forgejo.org.
It is running the latest development branch and will confirm the problem is not already fixed.
If you can reproduce it, provide a URL in the description.
options:
- "Yes"
- "No"
validations:
required: true
- type: textarea
id: description
attributes:
label: Description
description: |
Please provide a description of your issue here, with a URL if you were able to reproduce the issue (see below).
If you think this is a JavaScript error, show us the JavaScript console.
If the error appears to relate to Forgejo the server, please also give us `DEBUG` level logs. (See https://forgejo.org/docs/latest/admin/logging-documentation/)
Please provide a description of your issue here, with a URL if you were able to reproduce the issue (see above).
If you think this is a JavaScript error, include a copy of the JavaScript console.
validations:
required: true
- type: textarea
id: screenshots
attributes:
@ -35,20 +48,6 @@ body:
attributes:
label: Forgejo Version
description: Forgejo version (or commit reference) your instance is running
validations:
required: true
- type: dropdown
id: can-reproduce
attributes:
label: Can you reproduce the bug on Forgejo Next?
description: |
Please try reproducing your issue at [Forgejo Next](https://next.forgejo.org).
If you can reproduce it, please provide a URL in the Description field.
options:
- "Yes"
- "No"
validations:
required: true
- type: input
id: browser-ver
attributes:
@ -56,8 +55,3 @@ body:
description: The browser and version that you are using to access Forgejo
validations:
required: true
- type: input
id: os-ver
attributes:
label: Operating System
description: The operating system you are using to access Forgejo

View file

@ -1,6 +1,6 @@
name: 🐛 Bug Report (server / backend)
description: Found something you weren't expecting? Report it here!
title: "[BUG] "
title: "bug: "
labels: bug/new-report
body:
- type: markdown

View file

@ -1,6 +1,6 @@
name: 💡 Feature Request
description: Got an idea for a feature that Forgejo doesn't have yet? Suggest it here!
title: "[FEAT] "
title: "feat: "
labels: ["enhancement/feature"]
body:
- type: markdown

View file

@ -19,6 +19,7 @@ linters:
- revive
- staticcheck
- stylecheck
- tenv
- typecheck
- unconvert
- unused

View file

@ -191,7 +191,7 @@ SWAGGER_NEWLINE_COMMAND := -e '$$a\'
SWAGGER_SPEC_BRANDING := s|Gitea API|Forgejo API|g
TEST_MYSQL_HOST ?= mysql:3306
TEST_MYSQL_DBNAME ?= testgitea
TEST_MYSQL_DBNAME ?= testgitea?multiStatements=true
TEST_MYSQL_USERNAME ?= root
TEST_MYSQL_PASSWORD ?=
TEST_PGSQL_HOST ?= pgsql:5432

View file

@ -10,7 +10,127 @@ A [patch or minor release](https://semver.org/spec/v2.0.0.html) (e.g. upgrading
## 8.0.0
TBD
A [companion blog post](https://forgejo.org/2024-07-release-v8-0/) provides additional context on this release. In addition to the pull requests listed below, you will find a complete list in the [v8.0 milestone](https://codeberg.org/forgejo/forgejo/milestone/6042).
<!--start release-notes-assistant-->
<!--URL:https://codeberg.org/forgejo/forgejo-->
- **Breaking**
- [PR](https://codeberg.org/forgejo/forgejo/pulls/3040)</a>: <!--number 3040 --><!--number--><!--description -->remove Microsoft SQL Server support see [the discussion](https://codeberg.org/forgejo/discussions/issues/122).<!--description-->
- **User interface features & enhancements**
- [PR](https://codeberg.org/forgejo/forgejo/pulls/4201)</a>: <!--number 4201 --><!--number--><!--description Make tooltip of Author label in comments more clear-->make the tooltip of the author label in comments clearer.<!--description-->
- [PR](https://codeberg.org/forgejo/forgejo/pulls/4189)</a>: <!--number 4189 --><!--number--><!--description User profiles: only show RSS feed button and Public activity tab when the activity can be accessed, add messages about visibility-->only show the RSS feed button and Public activity tab in user profiles when the activity can be accessed and add messages about visibility.<!--description-->
- [PR](https://codeberg.org/forgejo/forgejo/pulls/4139)</a>: <!--number 4139 --><!--number--><!--description reorder repo tabs for better UX: (i) `Actions` is now the last tab (ii) `Packages` are located after Releases (iii) this puts Projects after Pull requests. (tab positions may depend on which units are enabled in the repo).-->reorder repo tabs for better UX: (i) `Actions` is now the last tab (ii) `Packages` are located after Releases (iii) this puts Projects after Pull requests. (tab positions may depend on which units are enabled in the repo).<!--description-->
- [PR](https://codeberg.org/forgejo/forgejo/pulls/4134)</a>: <!--number 4134 --><!--number--><!--description Code Search results are now displayed in a foldable box-->code search results are now displayed in a foldable box.<!--description-->
- [PR](https://codeberg.org/forgejo/forgejo/pulls/4095)</a>: <!--number 4095 --><!--number--><!--description Disable Subscribe button for guest users.-->disable the `Subscribe` button for guest users.<!--description-->
- [PR](https://codeberg.org/forgejo/forgejo/pulls/4072)</a>: <!--number 4072 --><!--number--><!--description multine placeholder-->
- Added Enter key handling to the new Markdown editor: Pressing Enter while in a list, quote or code block will copy the prefix to the new line - Ordered list index will be increased for the new line, and task list "checkbox" will be unchecked.
- Added indent/unindent function for a line or selection. Currently available as toolbar buttons ([#4263](https://codeberg.org/forgejo/forgejo/pulls/4263)).<!--description-->
- [PR](https://codeberg.org/forgejo/forgejo/pulls/3985)</a>: <!--number 3985 --><!--number--><!--description Added support for displaying images based on the users current color code by using an anchor of `#dark-mode-only` or `#light-mode-only` respectively. Also supporting the github variants (e.g. `#gh-dark-mode-only`).-->added support for displaying images based on the users current color code by using an anchor of `#dark-mode-only` or `#light-mode-only` respectively. Also supporting the github variants (e.g. `#gh-dark-mode-only`).<!--description-->
- [PR](https://codeberg.org/forgejo/forgejo/pulls/3870)</a>: <!--number 3870 --><!--number--><!--description Use CSS-native pattern for image diff background, add dark theme support-->use CSS-native pattern for image diff background, add dark theme support.<!--description-->
- [PR](https://codeberg.org/forgejo/forgejo/pulls/3642)</a>: <!--number 3642 --><!--number--><!--description Allow navigating to the organization dashboard from the organization view-->allow navigating to the organization dashboard from the organization view.<!--description-->
- [PR](https://codeberg.org/forgejo/forgejo/pulls/3434)</a>: <!--number 3434 --><!--number--><!--description When PDFs are displayed in the repository, the [full height of the screen](https://codeberg.org/forgejo/forgejo/pulls/3434) is now used instead of a predefined fixed height-->when PDFs are displayed in the repository, the full height of the screen is now used instead of a predefined fixed height.<!--description-->
- [PR](https://codeberg.org/forgejo/forgejo/pulls/3337)</a>: <!--number 3337 --><!--number--><!--description Added support for grouping of log-lines inside steps between the special `::group::{title}` and `::endgroup::` workflow commands. A runner of v3.4.2 or later is needed.-->added support for grouping of log-lines inside steps between the special `::group::{title}` and `::endgroup::` workflow commands. A runner of v3.4.2 or later is needed.<!--description-->
- [PR](https://codeberg.org/forgejo/forgejo/pulls/3285)</a>: <!--number 3285 --><!--number--><!--description The default for `[repository].USE_COMPAT_SSH_URI` has been changed to `true`. With this change, Forgejo defaults to using the same URL style for SSH clone URLs as for HTTPS ones, instead of the former scp-style.-->the default for `[repository].USE_COMPAT_SSH_URI` has been changed to `true`. With this change, Forgejo defaults to using the same URL style for SSH clone URLs as for HTTPS ones, instead of the former scp-style.<!--description-->
- **Features & Enhancements**
- [PR](https://codeberg.org/forgejo/forgejo/pulls/4283)</a> ([backport](https://codeberg.org/forgejo/forgejo/pulls/4266)): <!--number 4283 --><!--number--><!--description - add support for LFS server implementations which have batch API responses in an older/deprecated schema-->add support for LFS server implementations which have batch API responses in an older/deprecated schema.<!--description-->
- [PR](https://codeberg.org/forgejo/forgejo/pulls/4262)</a>: <!--number 4262 --><!--number--><!--description Introduced branch/tag dropdown in code search page if using git-grep.-->introduce a branch/tag dropdown in the code search page if using git-grep.<!--description-->
- [PR](https://codeberg.org/forgejo/forgejo/pulls/4160)</a>: <!--number 4160 --><!--number--><!--description Added support for fuzzy searching issues and pulls - support for `/issues` and `/pulls` were ported from [`gitea#be5be0ac81`](https://github.com/go-gitea/gitea/commit/be5be0ac81ce50ad5adb079af6ca4e8c396aaece) - support for `/user/repo/issues` and `/user/repo/pulls` were added-->added support for fuzzy searching in `/user/repo/issues` and `/user/repo/pulls`.<!--description-->
- [PR](https://codeberg.org/forgejo/forgejo/pulls/4145)</a>: <!--number 4145 --><!--number--><!--description multine placeholder-->
- feat(perf): [commit](https://codeberg.org/forgejo/forgejo/commit/358cd67c4f316f2d4f1d3be6dcb891dc04a2ff07) reduce memory usage for chunked artifact uploads to S3.
- feat: [commit](https://codeberg.org/forgejo/forgejo/commit/b60e3ac7b4aeeb9b8760f43eea9576c0e23309e9) allow downloading draft releases assets.
- feat: [commit](https://codeberg.org/forgejo/forgejo/commit/1fca15529ac8fefb60d86b0c1f4bec8dae9a8566) API endpoints for managing tag protection.
- feat: [commit](https://codeberg.org/forgejo/forgejo/commit/4334c705b5f9388b16af23c7e75a69d027d07d5e) extract and display readme and comments for Composer packages.
- fix: [commit](https://codeberg.org/forgejo/forgejo/commit/364922c6e4f28264add9e2501a352c25ad6a0993) when a repository is adopted, its object format is not set in the database.
- fix: [commit](https://codeberg.org/forgejo/forgejo/commit/e7f332a55d6a48a3f3b4f2bfa43d18455ac00acc) during a migration from bitbucket, LFS downloads fail.<!--description-->
- [PR](https://codeberg.org/forgejo/forgejo/pulls/4143)</a>: <!--number 4143 --><!--number--><!--description a help overlay, triggered by "?" key can be displayed when viewing [asciinema](https://asciinema.org/) files (.cast extension) and [SGR color sequence](https://github.com/asciinema/avt/issues/9) are supported.-->a help overlay, triggered by "?" key can be displayed when viewing [asciinema](https://asciinema.org/) files (.cast extension) and [SGR color sequence](https://github.com/asciinema/avt/issues/9) are supported.<!--description-->
- [PR](https://codeberg.org/forgejo/forgejo/pulls/4136)</a>: <!--number 4136 --><!--number--><!--description - strikethrough in markdown can be achieved with [a single ~ in addition to ~~](https://github.github.com/gfm/#strikethrough-extension-)-->strikethrough in markdown can be achieved with [a single ~ in addition to ~~](https://github.github.com/gfm/#strikethrough-extension-).<!--description-->
- [PR](https://codeberg.org/forgejo/forgejo/pulls/4083)</a>: <!--number 4083 --><!--number--><!--description multine placeholder-->
- feat: add [Reviewed-on and Reviewed-by variables](https://codeberg.org/forgejo/forgejo/commit/4ddd9af50fbfcfb2ebf629697a803b3bce56c4af) to the merge template.
- feat(perf): [add the `[ui.csv].MAX_ROWS` setting](https://codeberg.org/forgejo/forgejo/commit/433b6c6910f8699dc41787ef8f5148b122b4677e) to avoid displaying a large number of lines (defaults to 2500).
- feat: [add a setting to override or add headers of all outgoing emails](https://codeberg.org/forgejo/forgejo/commit/1d4bff4f65d5e4a3969871ef91d3612daf272b45), for instance `Reply-To` or `In-Reply-To`.<!--description-->
- [PR](https://codeberg.org/forgejo/forgejo/pulls/4027)</a>: <!--number 4027 --><!--number--><!--description - Gitea/Forgejo webhook payload include additional fields (`html_url`, `additions`, `deletions`, `review_comments`...) for better compatbility with [OpenProject](https://www.openproject.org/), ported from [gitea#28435](https://github.com/go-gitea/gitea/pull/28435).-->the Gitea/Forgejo webhook payload includes additional fields (`html_url`, `additions`, `deletions`, `review_comments`...) for better compatbility with [OpenProject](https://www.openproject.org/).<!--description-->
- [PR](https://codeberg.org/forgejo/forgejo/pulls/4026)</a>: <!--number 4026 --><!--number--><!--description - when an OAuth grant request submitted to a Forgejo user is denied, the server from which the request originates is not notified that it has been denied-->when an OAuth grant request submitted to a Forgejo user is denied, the server from which the request originates is notified that it has been denied.<!--description-->
- [PR](https://codeberg.org/forgejo/forgejo/pulls/3989)</a>: <!--number 3989 --><!--number--><!--description multine placeholder-->
- feat: API endpoints that return a repository now [also include the topics](https://codeberg.org/forgejo/forgejo/commit/ee2247d77c0b13b0b45df704d7589b541db03899).
- feat: display an error when an issue comment is [edited simultaneously by two users](https://codeberg.org/forgejo/forgejo/commit/ca0921a95aa9a37d8820538458c15fd0a3b0c97c) instead of silently overriding one of them.
- feat: add [support for a credentials chain for minio](https://codeberg.org/forgejo/forgejo/commit/73706ae26d138684ef9da9e1164846a040fd4a7d).
- feat(perf): improve performances when [retrieving pull requests via the API](https://codeberg.org/forgejo/forgejo/commit/47a2102694c47bc30a2a7c673c328471839ef206).<!--description-->
- [PR](https://codeberg.org/forgejo/forgejo/pulls/3934)</a>: <!--number 3934 --><!--number--><!--description When installing Forgejo through the built-in installer, open (self-) registration is now disabled by default.-->when installing Forgejo through the built-in installer, open (self-) registration is now disabled by default.<!--description-->
- [PR](https://codeberg.org/forgejo/forgejo/pulls/3917)</a>: <!--number 3917 --><!--number--><!--description support [setting the default attribute of the issue template dropdown field](https://codeberg.org/forgejo/forgejo/commit/df15abd07264138fd07e003d0cf056f7da514b8f)-->support [setting the default attribute of the issue template dropdown field](https://codeberg.org/forgejo/forgejo/commit/df15abd07264138fd07e003d0cf056f7da514b8f)<!--description-->
- [PR](https://codeberg.org/forgejo/forgejo/pulls/3886)</a>: <!--number 3886 --><!--number--><!--description For federated-star we introduce a new repository setting to define following repositories. That is a workaround till we find a better way to express repository federation.-->For federated-star we introduce a new repository setting to define following repositories. That is a workaround till we find a better way to express repository federation.<!--description-->
- [PR](https://codeberg.org/forgejo/forgejo/pulls/3847)</a>: <!--number 3847 --><!--number--><!--description Basic wiki content search using git-grep. The search results include the first ten matched files. Only the first three matches per file are displayed.-->Basic wiki content search using git-grep. The search results include the first ten matched files. Only the first three matches per file are displayed.<!--description-->
- [PR](https://codeberg.org/forgejo/forgejo/pulls/3838)</a>: <!--number 3838 --><!--number--><!--description - [Support using label names when changing issue labels](https://codeberg.org/forgejo/forgejo/commit/8e1de85980f1e4ae05b240cafbf9eaf33c94a203)-->support using label names when changing issue labels.<!--description-->
- [PR](https://codeberg.org/forgejo/forgejo/pulls/3836)</a>: <!--number 3836 --><!--number--><!--description Parse prefix parameter from redis URI for queues and use that as prefix to keys-->parse prefix parameter from redis URI for queues and use that as prefix to keys.<!--description-->
- [PR](https://codeberg.org/forgejo/forgejo/pulls/3830)</a>: <!--number 3830 --><!--number--><!--description Neutralize delete runners' UUID to prevent collisions with new records-->neutralize delete runners' UUID to prevent collisions with new records.<!--description-->
- [PR](https://codeberg.org/forgejo/forgejo/pulls/3811)</a>: <!--number 3811 --><!--number--><!--description Implement a non-caching version of the [RubyGems compact API](https://guides.rubygems.org/rubygems-org-compact-index-api/) for bundler dependency resolution.-->implement a non-caching version of the [RubyGems compact API](https://guides.rubygems.org/rubygems-org-compact-index-api/) for bundler dependency resolution.<!--description-->
- [PR](https://codeberg.org/forgejo/forgejo/pulls/3808)</a>: <!--number 3808 --><!--number--><!--description - Add support for the [reddit](https://github.com/markbates/goth/pull/523) and [Hubspot](https://github.com/markbates/goth/pull/531) OAuth providers.-->add support for the [reddit](https://github.com/markbates/goth/pull/523) and [Hubspot](https://github.com/markbates/goth/pull/531) OAuth providers.<!--description-->
- [PR](https://codeberg.org/forgejo/forgejo/pulls/3791)</a>: <!--number 3791 --><!--number--><!--description - when parsing [incoming emails](https://forgejo.org/docs/v8.0/user/incoming/), [remove tspecials from type/subtype](https://github.com/jhillyerd/enmime/pull/317). According to the RFC, content type and subtype cannot contain special characters and any such character will fail parsing. Removing the characters from the type/subtype can help successfully parsing the content type that contains some extra garbage.-->when parsing [incoming emails](https://forgejo.org/docs/v8.0/user/incoming/), [remove tspecials from type/subtype](https://github.com/jhillyerd/enmime/pull/317). According to the RFC, content type and subtype cannot contain special characters and any such character will fail parsing. Removing the characters from the type/subtype can help successfully parsing the content type that contains some extra garbage.<!--description-->
- [PR](https://codeberg.org/forgejo/forgejo/pulls/3752)</a>: <!--number 3752 --><!--number--><!--description There are a couple of new configs to define the name of the instance. The more important is `APP_SLOGAN`. It permits to configure a slogan for the site and it is optional. The other is `APP_DISPLAY_NAME_FORMAT` and permits to customize the aspect of the full display name for the instance used in some parts of the UI as: (i) Title page, (ii) Homepage head title (ii) Open Graph site and title meta tags. Its default value is `APP_NAME: APP_SLOGAN`. The config `APP_DISPLAY_NAME_FORMAT` is used only if `APP_SLOGAN` is set otherwise the full display name shows only `APP_NAME` value.-->there are a couple of new configs to define the name of the instance. The more important is `APP_SLOGAN`. It permits to configure a slogan for the site and it is optional. The other is `APP_DISPLAY_NAME_FORMAT` and permits to customize the aspect of the full display name for the instance used in some parts of the UI as: (i) Title page, (ii) Homepage head title (ii) Open Graph site and title meta tags. Its default value is `APP_NAME: APP_SLOGAN`. The config `APP_DISPLAY_NAME_FORMAT` is used only if `APP_SLOGAN` is set otherwise the full display name shows only `APP_NAME` value.<!--description-->
- [PR](https://codeberg.org/forgejo/forgejo/pulls/3729)</a>: <!--number 3729 --><!--number--><!--description multine placeholder-->
- feat: [commit](https://codeberg.org/forgejo/forgejo/commit/7028fe0b4d89c045b64ae891d2716e89965bc012): add actions-artifacts to the [storage migrate CLI](https://forgejo.org/docs/v8.0/admin/command-line/#migrate).
- fix: [commit](https://codeberg.org/forgejo/forgejo/commit/8f0f6bf89cdcd12cd4daa761aa259fdba7e32b50): pull request search shows closed pull requests in the open tab.<!--description-->
- [PR](https://codeberg.org/forgejo/forgejo/pulls/3724)</a>: <!--number 3724 --><!--number--><!--description multine placeholder-->
- [CERT management was improved](https://codeberg.org/forgejo/forgejo/pulls/3724) when [`ENABLE_ACME=true`](https://forgejo.org/docs/v7.0/admin/config-cheat-sheet/#server-server)
- Draft support for draft-03 of [ACME Renewal Information (ARI)](https://datatracker.ietf.org/doc/draft-ietf-acme-ari/) which assists with deciding when to renew certificates. This augments CertMagic's already-advanced logic using cert lifetime and OCSP/revocation status.
- New [`ZeroSSLIssuer`](https://pkg.go.dev/github.com/caddyserver/certmagic@v0.21.0#ZeroSSLIssuer) uses the [ZeroSSL API](https://zerossl.com/documentation/api/) to get certificates. ZeroSSL also has an ACME endpoint, which can still be accesed using the existing ACMEIssuer, as always. Their proprietary API is paid, but has extra features like IP certificates, better reliability, and support.
- DNS challenges should be smoother in some cases as we've improved propagation checking.
- In the odd case your ACME account disappears from the ACME server, CertMagic will automatically retry with a new account. (This happens in some test/dev environments.)
- ACME accounts are identified only by their public keys, but CertMagic maps accounts by CA+email for practical/storage reasons. So now you can "pin" an account key to use by specifying your email and the account public key in your config, which is useful if you need to absolutely be sure to use a specific account (like if you get rate limit exemptions from a CA).<!--description-->
- [PR](https://codeberg.org/forgejo/forgejo/pulls/3723)</a>: <!--number 3723 --><!--number--><!--description multine placeholder-->
- With the go-enry upgrade to [v2.8.8](https://github.com/go-enry/go-enry/releases/tag/v2.8.8), language detection in the repository [now includes](https://github.com/github-linguist/linguist/releases/tag/v7.29.0):
- New languages
- [Roc](https://github.com/github-linguist/linguist/pull/6633)
- [BitBake](https://github.com/github-linguist/linguist/pull/6665) with `.bbappend`, `.bbclass` and `.inc` extensions
- [Glimmer TS](https://github.com/github-linguist/linguist/pull/6680)
- [Edge](https://github.com/github-linguist/linguist/pull/6695)
- [Pip Requirements](https://github.com/github-linguist/linguist/pull/6739)
- [Mojo](https://github.com/github-linguist/linguist/pull/6400)
- [Slint](https://github.com/github-linguist/linguist/pull/6750)
- [Oberon](https://github.com/github-linguist/linguist/pull/4645)
- New data formats
- [TextGrid](https://github.com/github-linguist/linguist/pull/6719)
- File names and extensions:
- The [rebornix.Ruby extension is deprecated in favor of Shopify.ruby-lsp](https://github.com/github-linguist/linguist/pull/6738)
- [Add .bicepparam to list of Bicep file extensions](https://github.com/github-linguist/linguist/pull/6664)
- [Add cs.pp extension to C#](https://github.com/github-linguist/linguist/pull/6679)
- [Add tmux.conf and .tmux.conf as shell filenames](https://github.com/github-linguist/linguist/pull/6726)
- [Add .env.sample as Dotenv filename](https://github.com/github-linguist/linguist/pull/6732)<!--description-->
- [PR](https://codeberg.org/forgejo/forgejo/pulls/3654)</a>: <!--number 3654 --><!--number--><!--description Code Search for non-default branches and tags when repository indexer is disabled-->support Code Search for non-default branches and tags when the repository indexer is disabled.<!--description-->
- [PR](https://codeberg.org/forgejo/forgejo/pulls/3615)</a>: <!--number 3615 --><!--number--><!--description -->add an immutable tarball link to archive download headers for Nix.<!--description-->
- [PR](https://codeberg.org/forgejo/forgejo/pulls/3414)</a>: <!--number 3414 --><!--number--><!--description Allow to customize the domain name used as a fallback when synchronizing sources from ldap [`ldap: default domain name`](https://codeberg.org/forgejo/forgejo/pulls/3414)-->allow to customize the domain name used as a fallback when synchronizing sources from ldap default domain name.<!--description-->
- [PR](https://codeberg.org/forgejo/forgejo/pulls/3383)</a>: <!--number 3383 --><!--number--><!--description The default config for `database.MAX_OPEN_CONNS` changed from 0 (unlimited) to 100 to avoid problems if it exceeds the limit by the database server. If you require high concurrency, try to increase this value for both Forgejo **and your database server**. [`Limit database max connections by default`](https://codeberg.org/forgejo/forgejo/pulls/3383)-->the default config for `database.MAX_OPEN_CONNS` changed from 0 (unlimited) to 100 to avoid problems if it exceeds the limit by the database server. If you require high concurrency, try to increase this value for both Forgejo **and your database server**.<!--description-->
- [PR](https://codeberg.org/forgejo/forgejo/pulls/3366)</a>: <!--number 3366 --><!--number--><!--description -->infer the `[email.incoming].PORT` setting from `.USE_TLS`.<!--description-->
- [PR](https://codeberg.org/forgejo/forgejo/pulls/3363)</a>: <!--number 3363 --><!--number--><!--description Reverted the rootless container image path in `GITEA_APP_INI` from `/etc/gitea/app.ini` to its default value of `/var/lib/gitea/custom/conf/app.ini`. This allows container users to not have to mount two separate volumes (one for the configuration data and one for the configuration `.ini` file). A warning is issued for users with the legacy configuration on how to update to the new path.-->reverted the rootless container image path in `GITEA_APP_INI` from `/etc/gitea/app.ini` to its default value of `/var/lib/gitea/custom/conf/app.ini`. This allows container users to not have to mount two separate volumes (one for the configuration data and one for the configuration `.ini` file). A warning is issued for users with the legacy configuration on how to update to the new path.<!--description-->
- [PR](https://codeberg.org/forgejo/forgejo/pulls/3334)</a>: <!--number 3334 --><!--number--><!--description Added support for the `workflow_dispatch` workflow trigger-->added support for the [`workflow_dispatch` trigger](https://forgejo.org/docs/v8.0/user/actions/#onworkflow_dispatch) in Forgejo Actions.<!--description-->
- [PR](https://codeberg.org/forgejo/forgejo/pulls/3307)</a>: <!--number 3307 --><!--number--><!--description Support [Proof Key for Code Exchange (PKCE - RFC7636)](https://www.rfc-editor.org/rfc/rfc7636) for external login using the OpenID Connect authentication source.-->support [Proof Key for Code Exchange (PKCE - RFC7636)](https://www.rfc-editor.org/rfc/rfc7636) for external login using the OpenID Connect authentication source.<!--description-->
- [PR](https://codeberg.org/forgejo/forgejo/pulls/3139)</a>: <!--number 3139 --><!--number--><!--description Allow hiding auto generated release archives-->allow hiding auto generated release archives.<!--description-->
- **Bug fixes**
- [PR](https://codeberg.org/forgejo/forgejo/pulls/4423)</a> ([backport](https://codeberg.org/forgejo/forgejo/pulls/4375)): <!--number 4423 --><!--number--><!--description the "View command line instructions" link in pull requests and the "Copy content" button in file editor are not accessible-->Fixed: the "View command line instructions" link in pull requests and the "Copy content" button in file editor are not accessible.<!--description-->
- [PR](https://codeberg.org/forgejo/forgejo/pulls/4288)</a> ([backport](https://codeberg.org/forgejo/forgejo/pulls/4253)): <!--number 4288 --><!--number--><!--description - unknown git push options are rejected instead of being ignored-->Fixed: unknown git push options are rejected instead of being ignored.<!--description-->
- [PR](https://codeberg.org/forgejo/forgejo/pulls/4240)</a>: <!--number 4240 --><!--number--><!--description - markdown `[*[a]*](b)` [is incorrectly rendered as `<p><a href="b"><em>[a]</em></a></p>`](https://github.com/yuin/goldmark/issues/457)-->Fixed: markdown `[*[a]*](b)` [is incorrectly rendered as `<p><a href="b"><em>[a]</em></a></p>`](https://github.com/yuin/goldmark/issues/457).<!--description-->
- [PR](https://codeberg.org/forgejo/forgejo/pulls/4222)</a>: <!--number 4222 --><!--number--><!--description - markdown files displayed in the UI that have an unescaped backtick in the image alt [could (accidentally) trigger an inline code](https://github.com/yuin/goldmark/issues/456)-->Fixed: markdown files displayed in the UI that have an unescaped backtick in the image alt [could (accidentally) trigger an inline code](https://github.com/yuin/goldmark/issues/456).<!--description-->
- [PR](https://codeberg.org/forgejo/forgejo/pulls/3562)</a>: <!--number 3562 --><!--number--><!--description -->Fixed: when the git repository is empty, it is not possible to unsubscribe from an issue.<!--description-->
- [PR](https://codeberg.org/forgejo/forgejo/pulls/3442)</a>: <!--number 3442 --><!--number--><!--description Save updated empty comments instead of skipping the update silently, [which prevented the removal of attachments of such comments](https://codeberg.org/forgejo/forgejo/issues/3424).-->Fixed: it is not possible to remove attachments from an empty comment.<!--description-->
- [PR](https://codeberg.org/forgejo/forgejo/pulls/3430)</a>: <!--number 3430 --><!--number--><!--description Fixed a bug where the `/api/v1/repos/{owner}/{repo}/wiki` API endpoints were using a hardcoded "master" branch for the wiki, rather than the branch they really use.-->Fixed: the `/api/v1/repos/{owner}/{repo}/wiki` API endpoints is using a hardcoded "master" branch for the wiki, rather than the branch they really use.<!--description-->
- [PR](https://codeberg.org/forgejo/forgejo/pulls/3379)</a>: <!--number 3379 --><!--number--><!--description -->Fixed: using the API to search for users, the results are not paged by default an the default paging limits are not respected.<!--description-->
- **Localization**
- [PR](https://codeberg.org/forgejo/forgejo/pulls/4445)</a> ([backport](https://codeberg.org/forgejo/forgejo/pulls/4330)): <!--number 4445 --><!--number--><!--description -->11 July updates<!--description-->
- [PR](https://codeberg.org/forgejo/forgejo/pulls/4316)</a> ([backport](https://codeberg.org/forgejo/forgejo/pulls/4251)): <!--number 4316 --><!--number--><!--description -->4 July updates<!--description-->
- [PR](https://codeberg.org/forgejo/forgejo/pulls/4168)</a>: <!--number 4168 --><!--number--><!--description -->18 June updates<!--description-->
- [PR](https://codeberg.org/forgejo/forgejo/pulls/4098)</a>: <!--number 4098 --><!--number--><!--description -->10 June updates<!--description-->
- [PR](https://codeberg.org/forgejo/forgejo/pulls/3992)</a>: <!--number 3992 --><!--number--><!--description -->2 June updates<!--description-->
- [PR](https://codeberg.org/forgejo/forgejo/pulls/3908)</a>: <!--number 3908 --><!--number--><!--description -->25 May updates<!--description-->
- [PR](https://codeberg.org/forgejo/forgejo/pulls/3851)</a>: <!--number 3851 --><!--number--><!--description -->20 May updates<!--description-->
- [PR](https://codeberg.org/forgejo/forgejo/pulls/3759)</a>: <!--number 3759 --><!--number--><!--description -->14 May updates<!--description-->
- [PR](https://codeberg.org/forgejo/forgejo/pulls/3637)</a>: <!--number 3637 --><!--number--><!--description -->5 May updates<!--description-->
- [PR](https://codeberg.org/forgejo/forgejo/pulls/3508)</a>: <!--number 3508 --><!--number--><!--description -->28 April updates<!--description-->
- [PR](https://codeberg.org/forgejo/forgejo/pulls/3359)</a>: <!--number 3359 --><!--number--><!--description -->22 April updates<!--description-->
- [PR](https://codeberg.org/forgejo/forgejo/pulls/3244)</a>: <!--number 3244 --><!--number--><!--description -->15 April updates<!--description-->
- [PR](https://codeberg.org/forgejo/forgejo/pulls/3138)</a>: <!--number 3138 --><!--number--><!--description -->10 April updates<!--description-->
- [PR](https://codeberg.org/forgejo/forgejo/pulls/3064)</a>: <!--number 3064 --><!--number--><!--description -->5 April updates<!--description-->
- [PR](https://codeberg.org/forgejo/forgejo/pulls/2982)</a>: <!--number 2982 --><!--number--><!--description -->3 April updates<!--description-->
- [PR](https://codeberg.org/forgejo/forgejo/pulls/2937)</a>: <!--number 2937 --><!--number--><!--description -->31 March updates<!--description-->
<!--end release-notes-assistant-->
## 7.0.5

View file

@ -20,11 +20,11 @@
},
"nixpkgs": {
"locked": {
"lastModified": 1717974879,
"narHash": "sha256-GTO3C88+5DX171F/gVS3Qga/hOs/eRMxPFpiHq2t+D8=",
"lastModified": 1720542800,
"narHash": "sha256-ZgnNHuKV6h2+fQ5LuqnUaqZey1Lqqt5dTUAiAnqH0QQ=",
"owner": "nixos",
"repo": "nixpkgs",
"rev": "c7b821ba2e1e635ba5a76d299af62821cbcb09f3",
"rev": "feb2849fdeb70028c70d73b848214b00d324a497",
"type": "github"
},
"original": {

View file

@ -31,6 +31,7 @@
# backend
go_1_22
gofumpt
sqlite
];
};
}

8
go.mod
View file

@ -49,7 +49,7 @@ require (
github.com/go-ldap/ldap/v3 v3.4.6
github.com/go-sql-driver/mysql v1.8.1
github.com/go-swagger/go-swagger v0.30.5
github.com/go-testfixtures/testfixtures/v3 v3.11.0
github.com/go-testfixtures/testfixtures/v3 v3.12.0
github.com/go-webauthn/webauthn v0.10.0
github.com/gobwas/glob v0.2.3
github.com/gogs/chardet v0.0.0-20211120154057-b7413eaefb8f
@ -77,7 +77,7 @@ require (
github.com/meilisearch/meilisearch-go v0.26.1
github.com/mholt/archiver/v3 v3.5.1
github.com/microcosm-cc/bluemonday v1.0.27
github.com/minio/minio-go/v7 v7.0.73
github.com/minio/minio-go/v7 v7.0.74
github.com/msteinert/pam v1.2.0
github.com/nektos/act v0.2.52
github.com/niklasfasching/go-org v1.7.0
@ -87,7 +87,7 @@ require (
github.com/pquerna/otp v1.4.0
github.com/prometheus/client_golang v1.18.0
github.com/quasoft/websspi v1.1.2
github.com/redis/go-redis/v9 v9.5.4
github.com/redis/go-redis/v9 v9.5.2
github.com/robfig/cron/v3 v3.0.1
github.com/santhosh-tekuri/jsonschema/v6 v6.0.1
github.com/sassoftware/go-rpmutils v0.2.1-0.20240124161140-277b154961dd
@ -127,7 +127,7 @@ require (
filippo.io/edwards25519 v1.1.0 // indirect
git.sr.ht/~mariusor/go-xsd-duration v0.0.0-20220703122237-02e73435a078 // indirect
github.com/ClickHouse/ch-go v0.61.5 // indirect
github.com/ClickHouse/clickhouse-go/v2 v2.24.0 // indirect
github.com/ClickHouse/clickhouse-go/v2 v2.26.0 // indirect
github.com/DataDog/zstd v1.5.5 // indirect
github.com/Masterminds/goutils v1.1.1 // indirect
github.com/Masterminds/semver/v3 v3.2.1 // indirect

16
go.sum
View file

@ -45,8 +45,8 @@ github.com/Azure/go-ntlmssp v0.0.0-20221128193559-754e69321358/go.mod h1:chxPXzS
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/ClickHouse/ch-go v0.61.5 h1:zwR8QbYI0tsMiEcze/uIMK+Tz1D3XZXLdNrlaOpeEI4=
github.com/ClickHouse/ch-go v0.61.5/go.mod h1:s1LJW/F/LcFs5HJnuogFMta50kKDO0lf9zzfrbl0RQg=
github.com/ClickHouse/clickhouse-go/v2 v2.24.0 h1:L/n/pVVpk95KtkHOiKuSnO7cu2ckeW4gICbbOh5qs74=
github.com/ClickHouse/clickhouse-go/v2 v2.24.0/go.mod h1:iDTViXk2Fgvf1jn2dbJd1ys+fBkdD1UMRnXlwmhijhQ=
github.com/ClickHouse/clickhouse-go/v2 v2.26.0 h1:j4/y6NYaCcFkJwN/TU700ebW+nmsIy34RmUAAcZKy9w=
github.com/ClickHouse/clickhouse-go/v2 v2.26.0/go.mod h1:iDTViXk2Fgvf1jn2dbJd1ys+fBkdD1UMRnXlwmhijhQ=
github.com/DataDog/zstd v1.4.5/go.mod h1:1jcaCB/ufaK+sKp1NBhlGmpz41jOoPQ35bpF36t7BBo=
github.com/DataDog/zstd v1.5.5 h1:oWf5W7GtOLgp6bciQYDmhHHjdhYkALu6S/5Ni9ZgSvQ=
github.com/DataDog/zstd v1.5.5/go.mod h1:g4AWEaM3yOg3HYfnJ3YIawPnVdXJh9QME85blwSAmyw=
@ -305,8 +305,8 @@ github.com/go-swagger/scan-repo-boundary v0.0.0-20180623220736-973b3573c013/go.m
github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE=
github.com/go-test/deep v1.1.0 h1:WOcxcdHcvdgThNXjw0t76K42FXTU7HpNQWHpA2HHNlg=
github.com/go-test/deep v1.1.0/go.mod h1:5C2ZWiW0ErCdrYzpqxLbTX7MG14M9iiw8DgHncVwcsE=
github.com/go-testfixtures/testfixtures/v3 v3.11.0 h1:XxQr8AnPORcZkyNd7go5UNLPD3dULN8ixYISlzrlfEQ=
github.com/go-testfixtures/testfixtures/v3 v3.11.0/go.mod h1:THmudHF1Ixq++J2/UodcJpxUphfyEd77m83TvDtryqE=
github.com/go-testfixtures/testfixtures/v3 v3.12.0 h1:Ew0+c2o1mXSUqMwjuNup3MK/vw1HkLS3ILljX5C6lVE=
github.com/go-testfixtures/testfixtures/v3 v3.12.0/go.mod h1:13F0m6/DtqqSDso9IAVuhbZ4I7AiRAHrolmDMu9v5vY=
github.com/go-webauthn/webauthn v0.10.0 h1:yuW2e1tXnRAwAvKrR4q4LQmc6XtCMH639/ypZGhZCwk=
github.com/go-webauthn/webauthn v0.10.0/go.mod h1:l0NiauXhL6usIKqNLCUM3Qir43GK7ORg8ggold0Uv/Y=
github.com/go-webauthn/x v0.1.6 h1:QNAX+AWeqRt9loE8mULeWJCqhVG5D/jvdmJ47fIWCkQ=
@ -524,8 +524,8 @@ github.com/miekg/dns v1.1.59 h1:C9EXc/UToRwKLhK5wKU/I4QVsBUc8kE6MkHBkeypWZs=
github.com/miekg/dns v1.1.59/go.mod h1:nZpewl5p6IvctfgrckopVx2OlSEHPRO/U4SYkRklrEk=
github.com/minio/md5-simd v1.1.2 h1:Gdi1DZK69+ZVMoNHRXJyNcxrMA4dSxoYHZSQbirFg34=
github.com/minio/md5-simd v1.1.2/go.mod h1:MzdKDxYpY2BT9XQFocsiZf/NKVtR7nkE4RoEpN+20RM=
github.com/minio/minio-go/v7 v7.0.73 h1:qr2vi96Qm7kZ4v7LLebjte+MQh621fFWnv93p12htEo=
github.com/minio/minio-go/v7 v7.0.73/go.mod h1:qydcVzV8Hqtj1VtEocfxbmVFa2siu6HGa+LDEPogjD8=
github.com/minio/minio-go/v7 v7.0.74 h1:fTo/XlPBTSpo3BAMshlwKL5RspXRv9us5UeHEGYCFe0=
github.com/minio/minio-go/v7 v7.0.74/go.mod h1:qydcVzV8Hqtj1VtEocfxbmVFa2siu6HGa+LDEPogjD8=
github.com/mitchellh/copystructure v1.0.0/go.mod h1:SNtv71yrdKgLRyLFxmLdkAbkKEFWgYaq1OVrnRcwhnw=
github.com/mitchellh/copystructure v1.2.0 h1:vpKXTN4ewci03Vljg/q9QvCGUDttBOGBIa15WveJJGw=
github.com/mitchellh/copystructure v1.2.0/go.mod h1:qLl+cE2AmVv+CoeAwDPye/v+N2HKCj9FbZEVFJRxO9s=
@ -608,8 +608,8 @@ github.com/prometheus/procfs v0.12.0 h1:jluTpSng7V9hY0O2R9DzzJHYb2xULk9VTR1V1R/k
github.com/prometheus/procfs v0.12.0/go.mod h1:pcuDEFsWDnvcgNzo4EEweacyhjeA9Zk3cnaOZAZEfOo=
github.com/quasoft/websspi v1.1.2 h1:/mA4w0LxWlE3novvsoEL6BBA1WnjJATbjkh1kFrTidw=
github.com/quasoft/websspi v1.1.2/go.mod h1:HmVdl939dQ0WIXZhyik+ARdI03M6bQzaSEKcgpFmewk=
github.com/redis/go-redis/v9 v9.5.4 h1:vOFYDKKVgrI5u++QvnMT7DksSMYg7Aw/Np4vLJLKLwY=
github.com/redis/go-redis/v9 v9.5.4/go.mod h1:hdY0cQFCN4fnSYT6TkisLufl/4W5UIXyv0b/CLO2V2M=
github.com/redis/go-redis/v9 v9.5.2 h1:L0L3fcSNReTRGyZ6AqAEN0K56wYeYAwapBIhkvh0f3E=
github.com/redis/go-redis/v9 v9.5.2/go.mod h1:hdY0cQFCN4fnSYT6TkisLufl/4W5UIXyv0b/CLO2V2M=
github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0 h1:OdAsTTz6OkFY5QxjkYwrChwuRruF69c169dPK26NUlk=
github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo=
github.com/rhysd/actionlint v1.6.27 h1:xxwe8YmveBcC8lydW6GoHMGmB6H/MTqUU60F2p10wjw=

View file

@ -22,6 +22,10 @@ func (specs SpecList) GetScheduleIDs() []int64 {
}
func (specs SpecList) LoadSchedules(ctx context.Context) error {
if len(specs) == 0 {
return nil
}
scheduleIDs := specs.GetScheduleIDs()
schedules, err := GetSchedulesMapByIDs(ctx, scheduleIDs)
if err != nil {
@ -50,6 +54,10 @@ func (specs SpecList) GetRepoIDs() []int64 {
}
func (specs SpecList) LoadRepos(ctx context.Context) error {
if len(specs) == 0 {
return nil
}
repoIDs := specs.GetRepoIDs()
repos, err := repo_model.GetRepositoriesMapByIDs(ctx, repoIDs)
if err != nil {

View file

@ -6,6 +6,7 @@ package db
import (
"fmt"
"strconv"
"strings"
"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/setting"
@ -25,7 +26,8 @@ func ConvertDatabaseTable() error {
return err
}
_, err = x.Exec(fmt.Sprintf("ALTER DATABASE `%s` CHARACTER SET utf8mb4 COLLATE %s", setting.Database.Name, r.ExpectedCollation))
databaseName := strings.SplitN(setting.Database.Name, "?", 2)[0]
_, err = x.Exec(fmt.Sprintf("ALTER DATABASE `%s` CHARACTER SET utf8mb4 COLLATE %s", databaseName, r.ExpectedCollation))
if err != nil {
return err
}

View file

@ -12,6 +12,7 @@ import (
"path"
"path/filepath"
"runtime"
"strings"
"testing"
"time"
@ -198,11 +199,13 @@ func deleteDB() error {
}
defer db.Close()
if _, err = db.Exec(fmt.Sprintf("DROP DATABASE IF EXISTS %s", setting.Database.Name)); err != nil {
databaseName := strings.SplitN(setting.Database.Name, "?", 2)[0]
if _, err = db.Exec(fmt.Sprintf("DROP DATABASE IF EXISTS %s", databaseName)); err != nil {
return err
}
if _, err = db.Exec(fmt.Sprintf("CREATE DATABASE IF NOT EXISTS %s", setting.Database.Name)); err != nil {
if _, err = db.Exec(fmt.Sprintf("CREATE DATABASE IF NOT EXISTS %s", databaseName)); err != nil {
return err
}
return nil

View file

@ -9,6 +9,7 @@ import (
"context"
"encoding/hex"
"fmt"
"net/mail"
"net/url"
"path/filepath"
"regexp"
@ -439,6 +440,33 @@ func (u *User) DisplayName() string {
return u.Name
}
var emailToReplacer = strings.NewReplacer(
"\n", "",
"\r", "",
"<", "",
">", "",
",", "",
":", "",
";", "",
)
// EmailTo returns a string suitable to be put into a e-mail `To:` header.
func (u *User) EmailTo() string {
sanitizedDisplayName := emailToReplacer.Replace(u.DisplayName())
// should be an edge case but nice to have
if sanitizedDisplayName == u.Email {
return u.Email
}
address, err := mail.ParseAddress(fmt.Sprintf("%s <%s>", sanitizedDisplayName, u.Email))
if err != nil {
return u.Email
}
return address.String()
}
// GetDisplayName returns full name if it's not empty and DEFAULT_SHOW_FULL_NAME is set,
// returns username otherwise.
func (u *User) GetDisplayName() string {

View file

@ -601,6 +601,32 @@ func Test_NormalizeUserFromEmail(t *testing.T) {
}
}
func TestEmailTo(t *testing.T) {
testCases := []struct {
fullName string
mail string
result string
}{
{"Awareness Hub", "awareness@hub.net", `"Awareness Hub" <awareness@hub.net>`},
{"name@example.com", "name@example.com", "name@example.com"},
{"Hi Its <Mee>", "ee@mail.box", `"Hi Its Mee" <ee@mail.box>`},
{"Sinéad.O'Connor", "sinead.oconnor@gmail.com", "=?utf-8?b?U2luw6lhZC5PJ0Nvbm5vcg==?= <sinead.oconnor@gmail.com>"},
{"Æsir", "aesir@gmx.de", "=?utf-8?q?=C3=86sir?= <aesir@gmx.de>"},
{"new😀user", "new.user@alo.com", "=?utf-8?q?new=F0=9F=98=80user?= <new.user@alo.com>"},
{`"quoted"`, "quoted@test.com", `"quoted" <quoted@test.com>`},
{`gusted`, "gusted@test.com", `"gusted" <gusted@test.com>`},
{`Joe Q. Public`, "john.q.public@example.com", `"Joe Q. Public" <john.q.public@example.com>`},
{`Who?`, "one@y.test", `"Who?" <one@y.test>`},
}
for _, testCase := range testCases {
t.Run(testCase.result, func(t *testing.T) {
testUser := &user_model.User{FullName: testCase.fullName, Email: testCase.mail}
assert.EqualValues(t, testCase.result, testUser.EmailTo())
})
}
}
func TestDisabledUserFeatures(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())

View file

@ -6,7 +6,6 @@ package base
import (
"crypto/sha1"
"fmt"
"os"
"testing"
"time"
@ -168,9 +167,9 @@ func TestInt64sToStrings(t *testing.T) {
// TODO: Test EntryIcon
func TestSetupGiteaRoot(t *testing.T) {
_ = os.Setenv("GITEA_ROOT", "test")
t.Setenv("GITEA_ROOT", "test")
assert.Equal(t, "test", SetupGiteaRoot())
_ = os.Setenv("GITEA_ROOT", "")
t.Setenv("GITEA_ROOT", "")
assert.NotEqual(t, "test", SetupGiteaRoot())
}

View file

@ -36,6 +36,10 @@ func (g *GitHubCalloutTransformer) Transform(node *ast.Document, reader text.Rea
switch v := n.(type) {
case *ast.Blockquote:
if v.ChildCount() == 0 {
return ast.WalkContinue, nil
}
// We only want attention blockquotes when the AST looks like:
// Text: "["
// Text: "!TYPE"

View file

@ -25,6 +25,10 @@ func (g *GitHubLegacyCalloutTransformer) Transform(node *ast.Document, reader te
switch v := n.(type) {
case *ast.Blockquote:
if v.ChildCount() == 0 {
return ast.WalkContinue, nil
}
// The first paragraph contains the callout type.
firstParagraph := v.FirstChild()
if firstParagraph.ChildCount() < 1 {

View file

@ -1342,3 +1342,17 @@ key: value
</tbody>
</table>`)
}
func TestCallout(t *testing.T) {
setting.AppURL = AppURL
test := func(input, expected string) {
buffer, err := markdown.RenderString(&markup.RenderContext{
Ctx: git.DefaultContext,
}, input)
assert.NoError(t, err)
assert.Equal(t, strings.TrimSpace(expected), strings.TrimSpace(string(buffer)))
}
test(">\n0", "<blockquote>\n</blockquote>\n<p>0</p>")
}

View file

@ -2058,413 +2058,6 @@ func (mr *MockUniversalClientMockRecorder) FCallRo(arg0, arg1, arg2 any, arg3 ..
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "FCallRo", reflect.TypeOf((*MockUniversalClient)(nil).FCallRo), varargs...)
}
// FTAggregate mocks base method.
func (m *MockUniversalClient) FTAggregate(arg0 context.Context, arg1, arg2 string) *redis.MapStringInterfaceCmd {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "FTAggregate", arg0, arg1, arg2)
ret0, _ := ret[0].(*redis.MapStringInterfaceCmd)
return ret0
}
// FTAggregate indicates an expected call of FTAggregate.
func (mr *MockUniversalClientMockRecorder) FTAggregate(arg0, arg1, arg2 any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "FTAggregate", reflect.TypeOf((*MockUniversalClient)(nil).FTAggregate), arg0, arg1, arg2)
}
// FTAggregateWithArgs mocks base method.
func (m *MockUniversalClient) FTAggregateWithArgs(arg0 context.Context, arg1, arg2 string, arg3 *redis.FTAggregateOptions) *redis.AggregateCmd {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "FTAggregateWithArgs", arg0, arg1, arg2, arg3)
ret0, _ := ret[0].(*redis.AggregateCmd)
return ret0
}
// FTAggregateWithArgs indicates an expected call of FTAggregateWithArgs.
func (mr *MockUniversalClientMockRecorder) FTAggregateWithArgs(arg0, arg1, arg2, arg3 any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "FTAggregateWithArgs", reflect.TypeOf((*MockUniversalClient)(nil).FTAggregateWithArgs), arg0, arg1, arg2, arg3)
}
// FTAliasAdd mocks base method.
func (m *MockUniversalClient) FTAliasAdd(arg0 context.Context, arg1, arg2 string) *redis.StatusCmd {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "FTAliasAdd", arg0, arg1, arg2)
ret0, _ := ret[0].(*redis.StatusCmd)
return ret0
}
// FTAliasAdd indicates an expected call of FTAliasAdd.
func (mr *MockUniversalClientMockRecorder) FTAliasAdd(arg0, arg1, arg2 any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "FTAliasAdd", reflect.TypeOf((*MockUniversalClient)(nil).FTAliasAdd), arg0, arg1, arg2)
}
// FTAliasDel mocks base method.
func (m *MockUniversalClient) FTAliasDel(arg0 context.Context, arg1 string) *redis.StatusCmd {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "FTAliasDel", arg0, arg1)
ret0, _ := ret[0].(*redis.StatusCmd)
return ret0
}
// FTAliasDel indicates an expected call of FTAliasDel.
func (mr *MockUniversalClientMockRecorder) FTAliasDel(arg0, arg1 any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "FTAliasDel", reflect.TypeOf((*MockUniversalClient)(nil).FTAliasDel), arg0, arg1)
}
// FTAliasUpdate mocks base method.
func (m *MockUniversalClient) FTAliasUpdate(arg0 context.Context, arg1, arg2 string) *redis.StatusCmd {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "FTAliasUpdate", arg0, arg1, arg2)
ret0, _ := ret[0].(*redis.StatusCmd)
return ret0
}
// FTAliasUpdate indicates an expected call of FTAliasUpdate.
func (mr *MockUniversalClientMockRecorder) FTAliasUpdate(arg0, arg1, arg2 any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "FTAliasUpdate", reflect.TypeOf((*MockUniversalClient)(nil).FTAliasUpdate), arg0, arg1, arg2)
}
// FTAlter mocks base method.
func (m *MockUniversalClient) FTAlter(arg0 context.Context, arg1 string, arg2 bool, arg3 []any) *redis.StatusCmd {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "FTAlter", arg0, arg1, arg2, arg3)
ret0, _ := ret[0].(*redis.StatusCmd)
return ret0
}
// FTAlter indicates an expected call of FTAlter.
func (mr *MockUniversalClientMockRecorder) FTAlter(arg0, arg1, arg2, arg3 any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "FTAlter", reflect.TypeOf((*MockUniversalClient)(nil).FTAlter), arg0, arg1, arg2, arg3)
}
// FTConfigGet mocks base method.
func (m *MockUniversalClient) FTConfigGet(arg0 context.Context, arg1 string) *redis.MapMapStringInterfaceCmd {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "FTConfigGet", arg0, arg1)
ret0, _ := ret[0].(*redis.MapMapStringInterfaceCmd)
return ret0
}
// FTConfigGet indicates an expected call of FTConfigGet.
func (mr *MockUniversalClientMockRecorder) FTConfigGet(arg0, arg1 any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "FTConfigGet", reflect.TypeOf((*MockUniversalClient)(nil).FTConfigGet), arg0, arg1)
}
// FTConfigSet mocks base method.
func (m *MockUniversalClient) FTConfigSet(arg0 context.Context, arg1 string, arg2 any) *redis.StatusCmd {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "FTConfigSet", arg0, arg1, arg2)
ret0, _ := ret[0].(*redis.StatusCmd)
return ret0
}
// FTConfigSet indicates an expected call of FTConfigSet.
func (mr *MockUniversalClientMockRecorder) FTConfigSet(arg0, arg1, arg2 any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "FTConfigSet", reflect.TypeOf((*MockUniversalClient)(nil).FTConfigSet), arg0, arg1, arg2)
}
// FTCreate mocks base method.
func (m *MockUniversalClient) FTCreate(arg0 context.Context, arg1 string, arg2 *redis.FTCreateOptions, arg3 ...*redis.FieldSchema) *redis.StatusCmd {
m.ctrl.T.Helper()
varargs := []any{arg0, arg1, arg2}
for _, a := range arg3 {
varargs = append(varargs, a)
}
ret := m.ctrl.Call(m, "FTCreate", varargs...)
ret0, _ := ret[0].(*redis.StatusCmd)
return ret0
}
// FTCreate indicates an expected call of FTCreate.
func (mr *MockUniversalClientMockRecorder) FTCreate(arg0, arg1, arg2 any, arg3 ...any) *gomock.Call {
mr.mock.ctrl.T.Helper()
varargs := append([]any{arg0, arg1, arg2}, arg3...)
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "FTCreate", reflect.TypeOf((*MockUniversalClient)(nil).FTCreate), varargs...)
}
// FTCursorDel mocks base method.
func (m *MockUniversalClient) FTCursorDel(arg0 context.Context, arg1 string, arg2 int) *redis.StatusCmd {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "FTCursorDel", arg0, arg1, arg2)
ret0, _ := ret[0].(*redis.StatusCmd)
return ret0
}
// FTCursorDel indicates an expected call of FTCursorDel.
func (mr *MockUniversalClientMockRecorder) FTCursorDel(arg0, arg1, arg2 any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "FTCursorDel", reflect.TypeOf((*MockUniversalClient)(nil).FTCursorDel), arg0, arg1, arg2)
}
// FTCursorRead mocks base method.
func (m *MockUniversalClient) FTCursorRead(arg0 context.Context, arg1 string, arg2, arg3 int) *redis.MapStringInterfaceCmd {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "FTCursorRead", arg0, arg1, arg2, arg3)
ret0, _ := ret[0].(*redis.MapStringInterfaceCmd)
return ret0
}
// FTCursorRead indicates an expected call of FTCursorRead.
func (mr *MockUniversalClientMockRecorder) FTCursorRead(arg0, arg1, arg2, arg3 any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "FTCursorRead", reflect.TypeOf((*MockUniversalClient)(nil).FTCursorRead), arg0, arg1, arg2, arg3)
}
// FTDictAdd mocks base method.
func (m *MockUniversalClient) FTDictAdd(arg0 context.Context, arg1 string, arg2 ...any) *redis.IntCmd {
m.ctrl.T.Helper()
varargs := []any{arg0, arg1}
for _, a := range arg2 {
varargs = append(varargs, a)
}
ret := m.ctrl.Call(m, "FTDictAdd", varargs...)
ret0, _ := ret[0].(*redis.IntCmd)
return ret0
}
// FTDictAdd indicates an expected call of FTDictAdd.
func (mr *MockUniversalClientMockRecorder) FTDictAdd(arg0, arg1 any, arg2 ...any) *gomock.Call {
mr.mock.ctrl.T.Helper()
varargs := append([]any{arg0, arg1}, arg2...)
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "FTDictAdd", reflect.TypeOf((*MockUniversalClient)(nil).FTDictAdd), varargs...)
}
// FTDictDel mocks base method.
func (m *MockUniversalClient) FTDictDel(arg0 context.Context, arg1 string, arg2 ...any) *redis.IntCmd {
m.ctrl.T.Helper()
varargs := []any{arg0, arg1}
for _, a := range arg2 {
varargs = append(varargs, a)
}
ret := m.ctrl.Call(m, "FTDictDel", varargs...)
ret0, _ := ret[0].(*redis.IntCmd)
return ret0
}
// FTDictDel indicates an expected call of FTDictDel.
func (mr *MockUniversalClientMockRecorder) FTDictDel(arg0, arg1 any, arg2 ...any) *gomock.Call {
mr.mock.ctrl.T.Helper()
varargs := append([]any{arg0, arg1}, arg2...)
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "FTDictDel", reflect.TypeOf((*MockUniversalClient)(nil).FTDictDel), varargs...)
}
// FTDictDump mocks base method.
func (m *MockUniversalClient) FTDictDump(arg0 context.Context, arg1 string) *redis.StringSliceCmd {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "FTDictDump", arg0, arg1)
ret0, _ := ret[0].(*redis.StringSliceCmd)
return ret0
}
// FTDictDump indicates an expected call of FTDictDump.
func (mr *MockUniversalClientMockRecorder) FTDictDump(arg0, arg1 any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "FTDictDump", reflect.TypeOf((*MockUniversalClient)(nil).FTDictDump), arg0, arg1)
}
// FTDropIndex mocks base method.
func (m *MockUniversalClient) FTDropIndex(arg0 context.Context, arg1 string) *redis.StatusCmd {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "FTDropIndex", arg0, arg1)
ret0, _ := ret[0].(*redis.StatusCmd)
return ret0
}
// FTDropIndex indicates an expected call of FTDropIndex.
func (mr *MockUniversalClientMockRecorder) FTDropIndex(arg0, arg1 any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "FTDropIndex", reflect.TypeOf((*MockUniversalClient)(nil).FTDropIndex), arg0, arg1)
}
// FTDropIndexWithArgs mocks base method.
func (m *MockUniversalClient) FTDropIndexWithArgs(arg0 context.Context, arg1 string, arg2 *redis.FTDropIndexOptions) *redis.StatusCmd {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "FTDropIndexWithArgs", arg0, arg1, arg2)
ret0, _ := ret[0].(*redis.StatusCmd)
return ret0
}
// FTDropIndexWithArgs indicates an expected call of FTDropIndexWithArgs.
func (mr *MockUniversalClientMockRecorder) FTDropIndexWithArgs(arg0, arg1, arg2 any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "FTDropIndexWithArgs", reflect.TypeOf((*MockUniversalClient)(nil).FTDropIndexWithArgs), arg0, arg1, arg2)
}
// FTExplain mocks base method.
func (m *MockUniversalClient) FTExplain(arg0 context.Context, arg1, arg2 string) *redis.StringCmd {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "FTExplain", arg0, arg1, arg2)
ret0, _ := ret[0].(*redis.StringCmd)
return ret0
}
// FTExplain indicates an expected call of FTExplain.
func (mr *MockUniversalClientMockRecorder) FTExplain(arg0, arg1, arg2 any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "FTExplain", reflect.TypeOf((*MockUniversalClient)(nil).FTExplain), arg0, arg1, arg2)
}
// FTExplainWithArgs mocks base method.
func (m *MockUniversalClient) FTExplainWithArgs(arg0 context.Context, arg1, arg2 string, arg3 *redis.FTExplainOptions) *redis.StringCmd {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "FTExplainWithArgs", arg0, arg1, arg2, arg3)
ret0, _ := ret[0].(*redis.StringCmd)
return ret0
}
// FTExplainWithArgs indicates an expected call of FTExplainWithArgs.
func (mr *MockUniversalClientMockRecorder) FTExplainWithArgs(arg0, arg1, arg2, arg3 any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "FTExplainWithArgs", reflect.TypeOf((*MockUniversalClient)(nil).FTExplainWithArgs), arg0, arg1, arg2, arg3)
}
// FTInfo mocks base method.
func (m *MockUniversalClient) FTInfo(arg0 context.Context, arg1 string) *redis.FTInfoCmd {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "FTInfo", arg0, arg1)
ret0, _ := ret[0].(*redis.FTInfoCmd)
return ret0
}
// FTInfo indicates an expected call of FTInfo.
func (mr *MockUniversalClientMockRecorder) FTInfo(arg0, arg1 any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "FTInfo", reflect.TypeOf((*MockUniversalClient)(nil).FTInfo), arg0, arg1)
}
// FTSearch mocks base method.
func (m *MockUniversalClient) FTSearch(arg0 context.Context, arg1, arg2 string) *redis.FTSearchCmd {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "FTSearch", arg0, arg1, arg2)
ret0, _ := ret[0].(*redis.FTSearchCmd)
return ret0
}
// FTSearch indicates an expected call of FTSearch.
func (mr *MockUniversalClientMockRecorder) FTSearch(arg0, arg1, arg2 any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "FTSearch", reflect.TypeOf((*MockUniversalClient)(nil).FTSearch), arg0, arg1, arg2)
}
// FTSearchWithArgs mocks base method.
func (m *MockUniversalClient) FTSearchWithArgs(arg0 context.Context, arg1, arg2 string, arg3 *redis.FTSearchOptions) *redis.FTSearchCmd {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "FTSearchWithArgs", arg0, arg1, arg2, arg3)
ret0, _ := ret[0].(*redis.FTSearchCmd)
return ret0
}
// FTSearchWithArgs indicates an expected call of FTSearchWithArgs.
func (mr *MockUniversalClientMockRecorder) FTSearchWithArgs(arg0, arg1, arg2, arg3 any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "FTSearchWithArgs", reflect.TypeOf((*MockUniversalClient)(nil).FTSearchWithArgs), arg0, arg1, arg2, arg3)
}
// FTSpellCheck mocks base method.
func (m *MockUniversalClient) FTSpellCheck(arg0 context.Context, arg1, arg2 string) *redis.FTSpellCheckCmd {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "FTSpellCheck", arg0, arg1, arg2)
ret0, _ := ret[0].(*redis.FTSpellCheckCmd)
return ret0
}
// FTSpellCheck indicates an expected call of FTSpellCheck.
func (mr *MockUniversalClientMockRecorder) FTSpellCheck(arg0, arg1, arg2 any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "FTSpellCheck", reflect.TypeOf((*MockUniversalClient)(nil).FTSpellCheck), arg0, arg1, arg2)
}
// FTSpellCheckWithArgs mocks base method.
func (m *MockUniversalClient) FTSpellCheckWithArgs(arg0 context.Context, arg1, arg2 string, arg3 *redis.FTSpellCheckOptions) *redis.FTSpellCheckCmd {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "FTSpellCheckWithArgs", arg0, arg1, arg2, arg3)
ret0, _ := ret[0].(*redis.FTSpellCheckCmd)
return ret0
}
// FTSpellCheckWithArgs indicates an expected call of FTSpellCheckWithArgs.
func (mr *MockUniversalClientMockRecorder) FTSpellCheckWithArgs(arg0, arg1, arg2, arg3 any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "FTSpellCheckWithArgs", reflect.TypeOf((*MockUniversalClient)(nil).FTSpellCheckWithArgs), arg0, arg1, arg2, arg3)
}
// FTSynDump mocks base method.
func (m *MockUniversalClient) FTSynDump(arg0 context.Context, arg1 string) *redis.FTSynDumpCmd {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "FTSynDump", arg0, arg1)
ret0, _ := ret[0].(*redis.FTSynDumpCmd)
return ret0
}
// FTSynDump indicates an expected call of FTSynDump.
func (mr *MockUniversalClientMockRecorder) FTSynDump(arg0, arg1 any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "FTSynDump", reflect.TypeOf((*MockUniversalClient)(nil).FTSynDump), arg0, arg1)
}
// FTSynUpdate mocks base method.
func (m *MockUniversalClient) FTSynUpdate(arg0 context.Context, arg1 string, arg2 any, arg3 []any) *redis.StatusCmd {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "FTSynUpdate", arg0, arg1, arg2, arg3)
ret0, _ := ret[0].(*redis.StatusCmd)
return ret0
}
// FTSynUpdate indicates an expected call of FTSynUpdate.
func (mr *MockUniversalClientMockRecorder) FTSynUpdate(arg0, arg1, arg2, arg3 any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "FTSynUpdate", reflect.TypeOf((*MockUniversalClient)(nil).FTSynUpdate), arg0, arg1, arg2, arg3)
}
// FTSynUpdateWithArgs mocks base method.
func (m *MockUniversalClient) FTSynUpdateWithArgs(arg0 context.Context, arg1 string, arg2 any, arg3 *redis.FTSynUpdateOptions, arg4 []any) *redis.StatusCmd {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "FTSynUpdateWithArgs", arg0, arg1, arg2, arg3, arg4)
ret0, _ := ret[0].(*redis.StatusCmd)
return ret0
}
// FTSynUpdateWithArgs indicates an expected call of FTSynUpdateWithArgs.
func (mr *MockUniversalClientMockRecorder) FTSynUpdateWithArgs(arg0, arg1, arg2, arg3, arg4 any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "FTSynUpdateWithArgs", reflect.TypeOf((*MockUniversalClient)(nil).FTSynUpdateWithArgs), arg0, arg1, arg2, arg3, arg4)
}
// FTTagVals mocks base method.
func (m *MockUniversalClient) FTTagVals(arg0 context.Context, arg1, arg2 string) *redis.StringSliceCmd {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "FTTagVals", arg0, arg1, arg2)
ret0, _ := ret[0].(*redis.StringSliceCmd)
return ret0
}
// FTTagVals indicates an expected call of FTTagVals.
func (mr *MockUniversalClientMockRecorder) FTTagVals(arg0, arg1, arg2 any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "FTTagVals", reflect.TypeOf((*MockUniversalClient)(nil).FTTagVals), arg0, arg1, arg2)
}
// FT_List mocks base method.
func (m *MockUniversalClient) FT_List(arg0 context.Context) *redis.StringSliceCmd {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "FT_List", arg0)
ret0, _ := ret[0].(*redis.StringSliceCmd)
return ret0
}
// FT_List indicates an expected call of FT_List.
func (mr *MockUniversalClientMockRecorder) FT_List(arg0 any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "FT_List", reflect.TypeOf((*MockUniversalClient)(nil).FT_List), arg0)
}
// FlushAll mocks base method.
func (m *MockUniversalClient) FlushAll(arg0 context.Context) *redis.StatusCmd {
m.ctrl.T.Helper()
@ -2947,101 +2540,6 @@ func (mr *MockUniversalClientMockRecorder) HExists(arg0, arg1, arg2 any) *gomock
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "HExists", reflect.TypeOf((*MockUniversalClient)(nil).HExists), arg0, arg1, arg2)
}
// HExpire mocks base method.
func (m *MockUniversalClient) HExpire(arg0 context.Context, arg1 string, arg2 time.Duration, arg3 ...string) *redis.IntSliceCmd {
m.ctrl.T.Helper()
varargs := []any{arg0, arg1, arg2}
for _, a := range arg3 {
varargs = append(varargs, a)
}
ret := m.ctrl.Call(m, "HExpire", varargs...)
ret0, _ := ret[0].(*redis.IntSliceCmd)
return ret0
}
// HExpire indicates an expected call of HExpire.
func (mr *MockUniversalClientMockRecorder) HExpire(arg0, arg1, arg2 any, arg3 ...any) *gomock.Call {
mr.mock.ctrl.T.Helper()
varargs := append([]any{arg0, arg1, arg2}, arg3...)
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "HExpire", reflect.TypeOf((*MockUniversalClient)(nil).HExpire), varargs...)
}
// HExpireAt mocks base method.
func (m *MockUniversalClient) HExpireAt(arg0 context.Context, arg1 string, arg2 time.Time, arg3 ...string) *redis.IntSliceCmd {
m.ctrl.T.Helper()
varargs := []any{arg0, arg1, arg2}
for _, a := range arg3 {
varargs = append(varargs, a)
}
ret := m.ctrl.Call(m, "HExpireAt", varargs...)
ret0, _ := ret[0].(*redis.IntSliceCmd)
return ret0
}
// HExpireAt indicates an expected call of HExpireAt.
func (mr *MockUniversalClientMockRecorder) HExpireAt(arg0, arg1, arg2 any, arg3 ...any) *gomock.Call {
mr.mock.ctrl.T.Helper()
varargs := append([]any{arg0, arg1, arg2}, arg3...)
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "HExpireAt", reflect.TypeOf((*MockUniversalClient)(nil).HExpireAt), varargs...)
}
// HExpireAtWithArgs mocks base method.
func (m *MockUniversalClient) HExpireAtWithArgs(arg0 context.Context, arg1 string, arg2 time.Time, arg3 redis.HExpireArgs, arg4 ...string) *redis.IntSliceCmd {
m.ctrl.T.Helper()
varargs := []any{arg0, arg1, arg2, arg3}
for _, a := range arg4 {
varargs = append(varargs, a)
}
ret := m.ctrl.Call(m, "HExpireAtWithArgs", varargs...)
ret0, _ := ret[0].(*redis.IntSliceCmd)
return ret0
}
// HExpireAtWithArgs indicates an expected call of HExpireAtWithArgs.
func (mr *MockUniversalClientMockRecorder) HExpireAtWithArgs(arg0, arg1, arg2, arg3 any, arg4 ...any) *gomock.Call {
mr.mock.ctrl.T.Helper()
varargs := append([]any{arg0, arg1, arg2, arg3}, arg4...)
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "HExpireAtWithArgs", reflect.TypeOf((*MockUniversalClient)(nil).HExpireAtWithArgs), varargs...)
}
// HExpireTime mocks base method.
func (m *MockUniversalClient) HExpireTime(arg0 context.Context, arg1 string, arg2 ...string) *redis.IntSliceCmd {
m.ctrl.T.Helper()
varargs := []any{arg0, arg1}
for _, a := range arg2 {
varargs = append(varargs, a)
}
ret := m.ctrl.Call(m, "HExpireTime", varargs...)
ret0, _ := ret[0].(*redis.IntSliceCmd)
return ret0
}
// HExpireTime indicates an expected call of HExpireTime.
func (mr *MockUniversalClientMockRecorder) HExpireTime(arg0, arg1 any, arg2 ...any) *gomock.Call {
mr.mock.ctrl.T.Helper()
varargs := append([]any{arg0, arg1}, arg2...)
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "HExpireTime", reflect.TypeOf((*MockUniversalClient)(nil).HExpireTime), varargs...)
}
// HExpireWithArgs mocks base method.
func (m *MockUniversalClient) HExpireWithArgs(arg0 context.Context, arg1 string, arg2 time.Duration, arg3 redis.HExpireArgs, arg4 ...string) *redis.IntSliceCmd {
m.ctrl.T.Helper()
varargs := []any{arg0, arg1, arg2, arg3}
for _, a := range arg4 {
varargs = append(varargs, a)
}
ret := m.ctrl.Call(m, "HExpireWithArgs", varargs...)
ret0, _ := ret[0].(*redis.IntSliceCmd)
return ret0
}
// HExpireWithArgs indicates an expected call of HExpireWithArgs.
func (mr *MockUniversalClientMockRecorder) HExpireWithArgs(arg0, arg1, arg2, arg3 any, arg4 ...any) *gomock.Call {
mr.mock.ctrl.T.Helper()
varargs := append([]any{arg0, arg1, arg2, arg3}, arg4...)
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "HExpireWithArgs", reflect.TypeOf((*MockUniversalClient)(nil).HExpireWithArgs), varargs...)
}
// HGet mocks base method.
func (m *MockUniversalClient) HGet(arg0 context.Context, arg1, arg2 string) *redis.StringCmd {
m.ctrl.T.Helper()
@ -3164,139 +2662,6 @@ func (mr *MockUniversalClientMockRecorder) HMSet(arg0, arg1 any, arg2 ...any) *g
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "HMSet", reflect.TypeOf((*MockUniversalClient)(nil).HMSet), varargs...)
}
// HPExpire mocks base method.
func (m *MockUniversalClient) HPExpire(arg0 context.Context, arg1 string, arg2 time.Duration, arg3 ...string) *redis.IntSliceCmd {
m.ctrl.T.Helper()
varargs := []any{arg0, arg1, arg2}
for _, a := range arg3 {
varargs = append(varargs, a)
}
ret := m.ctrl.Call(m, "HPExpire", varargs...)
ret0, _ := ret[0].(*redis.IntSliceCmd)
return ret0
}
// HPExpire indicates an expected call of HPExpire.
func (mr *MockUniversalClientMockRecorder) HPExpire(arg0, arg1, arg2 any, arg3 ...any) *gomock.Call {
mr.mock.ctrl.T.Helper()
varargs := append([]any{arg0, arg1, arg2}, arg3...)
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "HPExpire", reflect.TypeOf((*MockUniversalClient)(nil).HPExpire), varargs...)
}
// HPExpireAt mocks base method.
func (m *MockUniversalClient) HPExpireAt(arg0 context.Context, arg1 string, arg2 time.Time, arg3 ...string) *redis.IntSliceCmd {
m.ctrl.T.Helper()
varargs := []any{arg0, arg1, arg2}
for _, a := range arg3 {
varargs = append(varargs, a)
}
ret := m.ctrl.Call(m, "HPExpireAt", varargs...)
ret0, _ := ret[0].(*redis.IntSliceCmd)
return ret0
}
// HPExpireAt indicates an expected call of HPExpireAt.
func (mr *MockUniversalClientMockRecorder) HPExpireAt(arg0, arg1, arg2 any, arg3 ...any) *gomock.Call {
mr.mock.ctrl.T.Helper()
varargs := append([]any{arg0, arg1, arg2}, arg3...)
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "HPExpireAt", reflect.TypeOf((*MockUniversalClient)(nil).HPExpireAt), varargs...)
}
// HPExpireAtWithArgs mocks base method.
func (m *MockUniversalClient) HPExpireAtWithArgs(arg0 context.Context, arg1 string, arg2 time.Time, arg3 redis.HExpireArgs, arg4 ...string) *redis.IntSliceCmd {
m.ctrl.T.Helper()
varargs := []any{arg0, arg1, arg2, arg3}
for _, a := range arg4 {
varargs = append(varargs, a)
}
ret := m.ctrl.Call(m, "HPExpireAtWithArgs", varargs...)
ret0, _ := ret[0].(*redis.IntSliceCmd)
return ret0
}
// HPExpireAtWithArgs indicates an expected call of HPExpireAtWithArgs.
func (mr *MockUniversalClientMockRecorder) HPExpireAtWithArgs(arg0, arg1, arg2, arg3 any, arg4 ...any) *gomock.Call {
mr.mock.ctrl.T.Helper()
varargs := append([]any{arg0, arg1, arg2, arg3}, arg4...)
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "HPExpireAtWithArgs", reflect.TypeOf((*MockUniversalClient)(nil).HPExpireAtWithArgs), varargs...)
}
// HPExpireTime mocks base method.
func (m *MockUniversalClient) HPExpireTime(arg0 context.Context, arg1 string, arg2 ...string) *redis.IntSliceCmd {
m.ctrl.T.Helper()
varargs := []any{arg0, arg1}
for _, a := range arg2 {
varargs = append(varargs, a)
}
ret := m.ctrl.Call(m, "HPExpireTime", varargs...)
ret0, _ := ret[0].(*redis.IntSliceCmd)
return ret0
}
// HPExpireTime indicates an expected call of HPExpireTime.
func (mr *MockUniversalClientMockRecorder) HPExpireTime(arg0, arg1 any, arg2 ...any) *gomock.Call {
mr.mock.ctrl.T.Helper()
varargs := append([]any{arg0, arg1}, arg2...)
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "HPExpireTime", reflect.TypeOf((*MockUniversalClient)(nil).HPExpireTime), varargs...)
}
// HPExpireWithArgs mocks base method.
func (m *MockUniversalClient) HPExpireWithArgs(arg0 context.Context, arg1 string, arg2 time.Duration, arg3 redis.HExpireArgs, arg4 ...string) *redis.IntSliceCmd {
m.ctrl.T.Helper()
varargs := []any{arg0, arg1, arg2, arg3}
for _, a := range arg4 {
varargs = append(varargs, a)
}
ret := m.ctrl.Call(m, "HPExpireWithArgs", varargs...)
ret0, _ := ret[0].(*redis.IntSliceCmd)
return ret0
}
// HPExpireWithArgs indicates an expected call of HPExpireWithArgs.
func (mr *MockUniversalClientMockRecorder) HPExpireWithArgs(arg0, arg1, arg2, arg3 any, arg4 ...any) *gomock.Call {
mr.mock.ctrl.T.Helper()
varargs := append([]any{arg0, arg1, arg2, arg3}, arg4...)
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "HPExpireWithArgs", reflect.TypeOf((*MockUniversalClient)(nil).HPExpireWithArgs), varargs...)
}
// HPTTL mocks base method.
func (m *MockUniversalClient) HPTTL(arg0 context.Context, arg1 string, arg2 ...string) *redis.IntSliceCmd {
m.ctrl.T.Helper()
varargs := []any{arg0, arg1}
for _, a := range arg2 {
varargs = append(varargs, a)
}
ret := m.ctrl.Call(m, "HPTTL", varargs...)
ret0, _ := ret[0].(*redis.IntSliceCmd)
return ret0
}
// HPTTL indicates an expected call of HPTTL.
func (mr *MockUniversalClientMockRecorder) HPTTL(arg0, arg1 any, arg2 ...any) *gomock.Call {
mr.mock.ctrl.T.Helper()
varargs := append([]any{arg0, arg1}, arg2...)
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "HPTTL", reflect.TypeOf((*MockUniversalClient)(nil).HPTTL), varargs...)
}
// HPersist mocks base method.
func (m *MockUniversalClient) HPersist(arg0 context.Context, arg1 string, arg2 ...string) *redis.IntSliceCmd {
m.ctrl.T.Helper()
varargs := []any{arg0, arg1}
for _, a := range arg2 {
varargs = append(varargs, a)
}
ret := m.ctrl.Call(m, "HPersist", varargs...)
ret0, _ := ret[0].(*redis.IntSliceCmd)
return ret0
}
// HPersist indicates an expected call of HPersist.
func (mr *MockUniversalClientMockRecorder) HPersist(arg0, arg1 any, arg2 ...any) *gomock.Call {
mr.mock.ctrl.T.Helper()
varargs := append([]any{arg0, arg1}, arg2...)
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "HPersist", reflect.TypeOf((*MockUniversalClient)(nil).HPersist), varargs...)
}
// HRandField mocks base method.
func (m *MockUniversalClient) HRandField(arg0 context.Context, arg1 string, arg2 int) *redis.StringSliceCmd {
m.ctrl.T.Helper()
@ -3339,20 +2704,6 @@ func (mr *MockUniversalClientMockRecorder) HScan(arg0, arg1, arg2, arg3, arg4 an
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "HScan", reflect.TypeOf((*MockUniversalClient)(nil).HScan), arg0, arg1, arg2, arg3, arg4)
}
// HScanNoValues mocks base method.
func (m *MockUniversalClient) HScanNoValues(arg0 context.Context, arg1 string, arg2 uint64, arg3 string, arg4 int64) *redis.ScanCmd {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "HScanNoValues", arg0, arg1, arg2, arg3, arg4)
ret0, _ := ret[0].(*redis.ScanCmd)
return ret0
}
// HScanNoValues indicates an expected call of HScanNoValues.
func (mr *MockUniversalClientMockRecorder) HScanNoValues(arg0, arg1, arg2, arg3, arg4 any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "HScanNoValues", reflect.TypeOf((*MockUniversalClient)(nil).HScanNoValues), arg0, arg1, arg2, arg3, arg4)
}
// HSet mocks base method.
func (m *MockUniversalClient) HSet(arg0 context.Context, arg1 string, arg2 ...any) *redis.IntCmd {
m.ctrl.T.Helper()
@ -3386,25 +2737,6 @@ func (mr *MockUniversalClientMockRecorder) HSetNX(arg0, arg1, arg2, arg3 any) *g
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "HSetNX", reflect.TypeOf((*MockUniversalClient)(nil).HSetNX), arg0, arg1, arg2, arg3)
}
// HTTL mocks base method.
func (m *MockUniversalClient) HTTL(arg0 context.Context, arg1 string, arg2 ...string) *redis.IntSliceCmd {
m.ctrl.T.Helper()
varargs := []any{arg0, arg1}
for _, a := range arg2 {
varargs = append(varargs, a)
}
ret := m.ctrl.Call(m, "HTTL", varargs...)
ret0, _ := ret[0].(*redis.IntSliceCmd)
return ret0
}
// HTTL indicates an expected call of HTTL.
func (mr *MockUniversalClientMockRecorder) HTTL(arg0, arg1 any, arg2 ...any) *gomock.Call {
mr.mock.ctrl.T.Helper()
varargs := append([]any{arg0, arg1}, arg2...)
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "HTTL", reflect.TypeOf((*MockUniversalClient)(nil).HTTL), varargs...)
}
// HVals mocks base method.
func (m *MockUniversalClient) HVals(arg0 context.Context, arg1 string) *redis.StringSliceCmd {
m.ctrl.T.Helper()

View file

@ -4,7 +4,6 @@
package user
import (
"os"
"os/exec"
"runtime"
"strings"
@ -36,7 +35,7 @@ func TestCurrentUsername(t *testing.T) {
if user != whoami {
t.Errorf("expected %s as user, got: %s", whoami, user)
}
os.Setenv("USER", "spoofed")
t.Setenv("USER", "spoofed")
user = CurrentUsername()
if user != whoami {
t.Errorf("expected %s as user, got: %s", whoami, user)

View file

@ -1297,7 +1297,7 @@ issue.in_tree_path = В %s:
release.note = Бележка:
hi_user_x = Здравейте <b>%s</b>,
admin.new_user.user_info = Информация за потребителя
register_notify = Добре дошли във Forgejo
register_notify = Добре дошли във %s
issue.action.new = <b>@%[1]s</b> създаде #%[2]d.
issue.action.review = <b>@%[1]s</b> коментира в тази заявка за сливане.
issue.action.reopen = <b>@%[1]s</b> отвори наново #%[2]d.

View file

@ -487,7 +487,7 @@ activate_email=Ověřte vaši e-mailovou adresu
activate_email.title=%s, prosím ověřte vaši e-mailovou adresu
activate_email.text=Pro aktivaci vašeho účtu do <b>%s</b> klikněte na následující odkaz:
register_notify=Vítejte v Forgejo
register_notify=Vítejte v %s
register_notify.title=%[1]s vítejte v %[2]s
register_notify.text_1=toto je váš potvrzovací e-mail pro %s!
register_notify.text_2=Do svého účtu se můžete přihlásit svým uživatelským jménem: %s
@ -810,7 +810,7 @@ add_email_success=Nová e-mailová adresa byla přidána.
email_preference_set_success=Nastavení e-mailu bylo úspěšně nastaveno.
add_openid_success=Nová OpenID adresa byla přidána.
keep_email_private=Skrýt e-mailovou adresu
keep_email_private_popup=Toto skryje vaši e-mailovou adresu z vašeho profilu, stejně jako při vytvoření pull requestu nebo úpravě souboru pomocí webového rozhraní. Odeslané commity nebudou změněny. Použijte %s v commitech pro jejich přiřazení k vašemu účtu.
keep_email_private_popup=Tímto skryjete svou e-mailovou adresu ze svého profilu. Nebude již výchozí adresou pro commity provedené skrze webové rozhraní, jako nahrávání a úpravy souborů, a nebude použita pro slučovací commity. Místo toho můžete použít speciální adresu %s pro spojení commitů s vaším účtem. Změna této funkce nebude mít vliv na stávající commity.
openid_desc=OpenID vám umožní delegovat ověřování na externího poskytovatele.
manage_ssh_keys=Správa klíčů SSH
@ -1593,8 +1593,8 @@ issues.reopened_at=`znovu otevřel/a tento problém <a id="%[1]s" href="#%[1]s">
issues.commit_ref_at=`odkázal/a na tento problém z commitu <a id="%[1]s" href="#%[1]s">%[2]s</a>`
issues.ref_issue_from=`<a href="%[3]s">odkázal/a na tento problém %[4]s</a> <a id="%[1]s" href="#%[1]s">%[2]s</a>`
issues.ref_pull_from=`<a href="%[3]s">odkázal/a na tuto žádost o sloučení %[4]s</a> <a id="%[1]s" href="#%[1]s">%[2]s</a>`
issues.ref_closing_from=`<a href="%[3]s">odkazoval/a na žádost o sloučení %[4]s, která uzavře tento problém</a> <a id="%[1]s" href="#%[1]s">%[2]s</a>`
issues.ref_reopening_from=`<a href="%[3]s">odkazoval/a na žádost o sloučení %[4]s, která znovu otevře tento problém</a> <a id="%[1]s" href="#%[1]s">%[2]s</a>`
issues.ref_closing_from=`<a href="%[3]s">odkazoval/a na tento problém ze žádosti o sloučení %[4]s, která jej uzavře</a>, <a id="%[1]s" href="#%[1]s">%[2]s</a>`
issues.ref_reopening_from=`<a href="%[3]s">odkazoval/a na tento problém ze žádosti o sloučení %[4]s, která jej znovu otevře</a>, <a id="%[1]s" href="#%[1]s">%[2]s</a>`
issues.ref_closed_from=`<a href="%[3]s">uzavřel/a tento problém %[4]s</a> <a id="%[1]s" href="#%[1]s">%[2]s</a>`
issues.ref_reopened_from=`<a href="%[3]s">znovu otevřel/a tento problém %[4]s</a> <a id="%[1]s" href="#%[1]s">%[2]s</a>`
issues.ref_from=`z %[1]s`
@ -1903,7 +1903,7 @@ pulls.outdated_with_base_branch=Tato větev je zastaralá oproti základní vět
pulls.close=Zavřít žádost o sloučení
pulls.closed_at=`uzavřel/a tento požadavek na natažení <a id="%[1]s" href="#%[1]s">%[2]s</a>`
pulls.reopened_at=`znovuotevřel/a tento požadavek na natažení <a id="%[1]s" href="#%[1]s">%[2]s</a>`
pulls.cmd_instruction_hint=`Zobrazit instrukce příkazové řádky.`
pulls.cmd_instruction_hint=Zobrazit instrukce příkazové řádky
pulls.cmd_instruction_checkout_desc=Z vašeho repositáře projektu se podívejte na novou větev a vyzkoušejte změny.
pulls.cmd_instruction_merge_title=Sloučit
pulls.cmd_instruction_merge_desc=Slučte změny a aktualizujte je na Gitea.
@ -2652,7 +2652,7 @@ topic.done=Hotovo
topic.count_prompt=Nelze vybrat více než 25 témat
topic.format_prompt=Téma musí začínat písmenem nebo číslem, může obsahovat pomlčky („-“) a tečky („.“) a může být dlouhé až 35 znaků. Písmena musí být malá.
find_file.go_to_file=Přejít na soubor
find_file.go_to_file=Najít soubor
find_file.no_matching=Nebyl nalezen žádný odpovídající soubor
error.csv.too_large=Tento soubor nelze vykreslit, protože je příliš velký.
@ -3111,7 +3111,7 @@ orgs.new_orga=Nová organizace
repos.repo_manage_panel=Správa repozitářů
repos.unadopted=Nepřijaté repozitáře
repos.unadopted.no_more=Nebyly nalezeny žádné další nepřijaté repositáře
repos.unadopted.no_more=Nebyly nalezeny žádné nepřijaté repositáře.
repos.owner=Vlastník
repos.name=Název
repos.private=Soukromý
@ -3908,3 +3908,7 @@ gib = GiB
tib = TiB
pib = PiB
eib = EiB
[translation_meta]
test = ok

View file

@ -190,6 +190,8 @@ buttons.ref.tooltip=Issue oder Pull-Request referenzieren
buttons.switch_to_legacy.tooltip=Legacy-Editor verwenden
buttons.enable_monospace_font=Festbreitenschrift aktivieren
buttons.disable_monospace_font=Festbreitenschrift deaktivieren
buttons.indent.tooltip = Einträge um eine Ebene verschachteln
buttons.unindent.tooltip = Einträge um eine Ebene entschachteln
[filter]
string.asc=AZ
@ -462,6 +464,11 @@ change_unconfirmed_email = Wenn du bei der Anmeldung eine falsche E-Mail-Adresse
remember_me.compromised = Der Anmeldetoken ist nicht mehr gültig, dies könnte auf ein kompromittiertes Konto hindeuten. Bitte prüfe dein Konto auf ungewöhnliche Aktivitäten.
tab_signin = Anmelden
tab_signup = Registrieren
sign_up_button = Jetzt registrieren.
back_to_sign_in = Zurück zur Anmeldung
sign_in_openid = Mit OpenID fortfahren
hint_login = Hast du bereits ein Konto? <a href="%s">Jetzt anmelden!</a>
hint_register = Brauchst du ein Konto? <a href="%s">Jetzt registrieren.</a>
[mail]
view_it_on=Auf %s ansehen
@ -478,7 +485,7 @@ activate_email=Bestätige deine E-Mail-Adresse
activate_email.title=%s, bitte verifiziere deine E-Mail-Adresse
activate_email.text=Bitte klicke innerhalb von <b>%s</b> auf folgenden Link, um dein Konto zu aktivieren:
register_notify=Willkommen bei Forgejo
register_notify=Willkommen bei %s
register_notify.title=%[1]s, willkommen bei %[2]s
register_notify.text_1=dies ist deine Bestätigungs-E-Mail für %s!
register_notify.text_2=Du kannst dich mit dem Benutzernamen „%s“ anmelden.
@ -800,7 +807,7 @@ add_email_success=Die neue E-Mail-Addresse wurde hinzugefügt.
email_preference_set_success=E-Mail-Einstellungen wurden erfolgreich aktualisiert.
add_openid_success=Die neue OpenID-Adresse wurde hinzugefügt.
keep_email_private=E-Mail-Adresse verbergen
keep_email_private_popup=Dies wird deine E-Mail-Adresse nicht nur in deinem Profil ausblenden, sondern auch, wenn du einen Pull Request erstellst oder eine Datei über das Web-Interface bearbeitest. Gepushte Commits werden nicht geändert. Benutze %s in Commits, um sie mit deinem Konto zu assoziieren.
keep_email_private_popup=Dies wird deine E-Mail-Adresse in deinem Profil ausblenden. Sie wird nicht mehr der Standardwert für die Commits, die vom Web-Interface gemacht wurden, sein, z.B. Dateiuploads und -bearbeitungen, und sie wird nicht für Merge-Commits benutzt werden. Stattdessen kann eine besondere Adresse %s benutzt werden, um Commits mit deinem Konto zu assoziieren. Beachte, dass diese Option für existierende Commits keine Wirkung hat.
openid_desc=Mit OpenID kannst du dich über einen Drittanbieter authentifizieren.
manage_ssh_keys=SSH-Schlüssel verwalten
@ -1013,6 +1020,7 @@ pronouns = Pronomen
pronouns_custom = Eigene
pronouns_unspecified = Nicht spezifiziert
language.title = Standardsprache
keep_activity_private.description = Deine <a href="%s">öffentliche Aktivität</a> wird nur für dich selbst und den Instanzadminstratoren sichtbar sein.
[repo]
owner=Besitzer
@ -2682,7 +2690,7 @@ commits.browse_further = Weiter browsen
pulls.nothing_to_compare_have_tag = Der gewählte Branch/Tag ist gleich.
pulls.status_checks_hide_all = Alle Prüfungen verbergen
pulls.status_checks_show_all = Alle Prüfungen anzeigen
pulls.cmd_instruction_hint = `Anweisungen für die Kommandozeile betrachten.`
pulls.cmd_instruction_hint = Anweisungen für die Kommandozeile betrachten
pulls.cmd_instruction_checkout_title = Auschecken
wiki.cancel = Abbrechen
settings.wiki_globally_editable = Allen erlauben, das Wiki zu bearbeiten
@ -3762,7 +3770,7 @@ runs.all_workflows=Alle Workflows
runs.commit=Commit
runs.scheduled=Geplant
runs.pushed_by=gepusht von
runs.invalid_workflow_helper=Die Workflow-Konfigurationsdatei ist ungültig. Bitte überprüfe deine Konfigurationsdatei: %s
runs.invalid_workflow_helper=Die Arbeitsablauf-Konfigurationsdatei ist ungültig. Bitte überprüfe deine Konfigurationsdatei: %s
runs.actor=Initiator
runs.status=Status
runs.actors_no_select=Alle Initiatoren
@ -3798,7 +3806,7 @@ runs.no_workflows = Es existieren noch keine Workflows.
runs.no_workflows.documentation = Für weitere Informationen über Forgejo Actions, siehe <a target="_blank" rel="noopener noreferrer" href="%s">die Dokumentation</a>.
runs.empty_commit_message = (leere Commit-Nachricht)
variables.id_not_exist = Variable mit ID %d existiert nicht.
runs.workflow = Workflow
runs.workflow = Arbeitsablauf
runs.no_job_without_needs = Der Workflow muss mindestens einen Job ohne Abhängigkeiten enthalten.
runs.no_job = Der Workflow muss mindestens einen Job enthalten
workflow.dispatch.use_from = Workflow benutzen von
@ -3860,6 +3868,8 @@ exact = Exakt
exact_tooltip = Nur Ergebnisse einbinden, die auf den exakten Suchbegriff passen
issue_kind = Issues durchsuchen …
pull_kind = Pulls durchsuchen …
union = Vereinigungsmenge
union_tooltip = Ergebnisse, die auf ein beliebiges von den Whitespace getrennten Schlüsselwörtern passen, einbinden
[markup]
filepreview.line = Zeile %[1]d in %[2]s

View file

@ -478,7 +478,7 @@ activate_email=Επιβεβαιώστε τη διεύθυνση email σας
activate_email.title=%s, επαληθεύστε τη διεύθυνση email σας
activate_email.text=Για να επαληθεύσετε τη διεύθυνση email σας, παρακαλώ πατήστε τον ακόλουθο σύνδεσμο μέσα σε <b>%s</b>:
register_notify=Καλώς ήλθατε στο Forgejo
register_notify=Καλώς ήλθατε στο %s
register_notify.title=%[1]s, καλώς ήλθατε στο %[2]s
register_notify.text_1=αυτό είναι το email επιβεβαίωσης εγγραφής σας για το %s!
register_notify.text_2=Μπορείτε να συνδεθείτε χρησιμοποιώντας το όνομα χρήστη σας: %s

View file

@ -236,7 +236,7 @@ app_desc = A painless, self-hosted Git service
install = Easy to install
install_desc = Simply <a target="_blank" rel="noopener noreferrer" href="https://forgejo.org/download/#installation-from-binary">run the binary</a> for your platform, ship it with <a target="_blank" rel="noopener noreferrer" href="https://forgejo.org/download/#container-image">Docker</a>, or get it <a target="_blank" rel="noopener noreferrer" href="https://forgejo.org/download">packaged</a>.
platform = Cross-platform
platform_desc = Forgejo runs anywhere <a target="_blank" rel="noopener noreferrer" href="https://go.dev/">Go</a> can compile for: Windows, macOS, Linux, ARM, etc. Choose the one you love!
platform_desc = Forgejo is confirmed to run on libre operating systems like Linux and FreeBSD, as well as different CPU architectures. Choose the one you love!
lightweight = Lightweight
lightweight_desc = Forgejo has low minimal requirements and can run on an inexpensive Raspberry Pi. Save your machine energy!
license = Open Source
@ -418,8 +418,8 @@ allow_password_change = Require user to change password (recommended)
reset_password_mail_sent_prompt = A confirmation email has been sent to <b>%s</b>. Please check your inbox within the next %s to complete the account recovery process.
active_your_account = Activate your account
account_activated = Account has been activated
prohibit_login = Signing in is prohibited
prohibit_login_desc = Your account is prohibited from signing in, please contact your site administrator.
prohibit_login = Account is suspended
prohibit_login_desc = Your account has been suspended from interacting with the instance. Contact the instance administrator to regain access.
resent_limit_prompt = You have already requested an activation email recently. Please wait 3 minutes and try again.
has_unconfirmed_mail = Hi %s, you have an unconfirmed email address (<b>%s</b>). If you haven't received a confirmation email or need to resend a new one, please click on the button below.
change_unconfirmed_email_summary = Change the email address activation mail is sent to.
@ -492,7 +492,7 @@ admin.new_user.subject = New user %s just signed up
admin.new_user.user_info = User information
admin.new_user.text = Please <a href="%s">click here</a> to manage this user from the admin panel.
register_notify = Welcome to Forgejo
register_notify = Welcome to %s
register_notify.text_1 = this is your registration confirmation email for %s!
register_notify.text_2 = You can sign into your account using your username: %s
register_notify.text_3 = If someone else made this account for you, you will need to <a href="%s">set your password</a> first.
@ -741,6 +741,8 @@ continue = Continue
cancel = Cancel
language = Language
language.title = Default language
language.description = This language will be saved to your account and be used as the default after you log in.
language.localization_project = Help us translate Forgejo into your language! <a href="%s">Learn more</a>.
ui = Theme
hints = Hints
additional_repo_units_hint = Suggest to enable additional repository units
@ -2121,6 +2123,7 @@ activity.git_stats_addition_n = %d additions
activity.git_stats_and_deletions = and
activity.git_stats_deletion_1 = %d deletion
activity.git_stats_deletion_n = %d deletions
activity.commit = Commit activity
contributors.contribution_type.filter_label = Contribution type:
contributors.contribution_type.commits = Commits
@ -2835,13 +2838,13 @@ members.member = Member
members.remove = Remove
members.remove.detail = Remove %[1]s from %[2]s?
members.leave = Leave
members.leave.detail = Leave %s?
members.leave.detail = Are you sure you want to leave organization "%s"?
members.invite_desc = Add a new member to %s:
members.invite_now = Invite now
teams.join = Join
teams.leave = Leave
teams.leave.detail = Leave %s?
teams.leave.detail = Are you sure you want to leave team "%s"?
teams.can_create_org_repo = Create repositories
teams.can_create_org_repo_helper = Members can create new repositories in organization. Creator will get administrator access to the new repository.
teams.none_access = No access

View file

@ -427,7 +427,7 @@ active_your_account = Aktivigi vian konton
[mail]
activate_account.text_1 = Saluton <b>%[1]s</b>, dankon pro via registriĝo ĉe %[2]s!
release.title = Nomo: %s
register_notify = Bonvenon al Forgejo
register_notify = Bonvenon al %s
reply = aŭ respondu tiun ĉi retleteron rekte
issue.action.close = <b>@%[1]s</b> fermis #%[2]d.
register_notify.text_1 = jen estas via registriĝa konfirmletero por %s!

View file

@ -459,7 +459,7 @@ activate_email=Verifique su correo electrónico
activate_email.title=%s, por favor verifique su dirección de correo electrónico
activate_email.text=Por favor, haga clic en el siguiente enlace para verificar su dirección de correo electrónico dentro de <b>%s</b>:
register_notify=¡Bienvenido a Forgejo
register_notify=¡Bienvenido a %s
register_notify.title=%[1]s, bienvenido a %[2]s
register_notify.text_1=este es tu correo de confirmación de registro para %s!
register_notify.text_2=Ahora puede iniciar sesión vía nombre de usuario: %s.

View file

@ -365,7 +365,7 @@ activate_account=Ole hyvä ja aktivoi tilisi
activate_email=Vahvista sähköpostiosoitteesi
register_notify=Tervetuloa Forgejoan
register_notify=Tervetuloa %san
register_notify.text_2=Voit nyt kirjautua käyttäjätunnuksella: %s.
reset_password=Palauta käyttäjätili

View file

@ -38,7 +38,7 @@ powered_by = Pinapatakbo ng %s
explore = Tuklasin
help = Tulong
logo = Logo
sign_in = Mag-Sign In
sign_in = Mag-sign in
sign_in_with_provider = Mag-sign in gamit ang %s
sign_in_or = o
sign_out = Mag-Sign Out
@ -400,7 +400,7 @@ scratch_code = Scratch code
use_scratch_code = Gumamit ng scratch code
twofa_passcode_incorrect = Mali ang iyong passcode. Kung nawala mo ang iyong device, gamitin ang iyong scratch code para mag-sign in.
twofa_scratch_token_incorrect = Mali ang iyong scratch code.
login_userpass = Mag-Sign In
login_userpass = Mag-sign in
login_openid = OpenID
oauth_signup_tab = Mag-rehistro ng bagong account
oauth_signup_title = Kumpletuhin ang bagong account
@ -442,6 +442,11 @@ last_admin = Hindi mo matatanggal ang pinakahuling admin. Kailangan may hindi ba
tab_signin = Mag-sign In
tab_signup = Mag-sign Up
tab_openid = OpenID
hint_register = Kailangan ng account? <a href="%s">Magrehistro ngayon.</a>
sign_up_button = Magrehistro ngayon.
back_to_sign_in = Bumalik sa sign in
sign_in_openid = Magpatuloy gamit ang OpenID
hint_login = May account ka na? <a href="%s">Mag-sign in ngayon!</a>
[mail]
reply = o direktang tumugon sa email na ito
@ -457,7 +462,7 @@ activate_email = I-verify ang iyong email address
admin.new_user.subject = Nag-sign up lang ngayon ang user na si %s
admin.new_user.user_info = Impormasyon ng user
admin.new_user.text = Mangyaring <a href="%s">mag-click dito</a> para ipamahala ang user na ito sa admin panel.
register_notify = Maligayang Pagdating sa Forgejo
register_notify = Maligayang Pagdating sa %s
register_notify.title = %[1]s, maligayang pagdating sa %[2]s
register_notify.text_1 = ito ang iyong registration confirmation email para sa %s!
register_notify.text_2 = Maari kang mag-sign in sa iyong account gamit ng iyong username: %s
@ -729,7 +734,7 @@ ssh_key_deletion_desc = Ang pagtanggal ng SSH key ay matatanggihan ang pag-acces
no_activity = Walang kamakilang aktibidad
ssh_signonly = Kasalukuyang naka-disable ang SSH kaya magagamit lang ang mga key na ito para sa pagpapatunay ng commit signature.
gpg_desc = Ang mga pampublikong GPG key dito ay nauugnay sa iyong account at ginagamit para i-verify ang iyong mga commit. Panatilihing ligtas ang iyong mga pribadong key dahil pinapayagan nito ang pag-sign ng mga commit gamit ng iyong pagkakakilanlan.
keep_email_private_popup = Itatago nito ang iyong email address sa iyong profile, at kung gumawa ka ng pull request o mag-edit ng file sa pamamagitan ng web interface. Hindi babaguhin ang mga naka-push na commit. Gamitin ang %s sa mga commit para i-associate sila sa iyong account.
keep_email_private_popup = Itatago nito ang iyong email address sa iyong profile. Hindi na ito ang magiging default para sa mga commit na ginawa sa pamamagitan ng web interface, tulad ng pag-upload ng mga file at pagbabago. Sa halip gagamitin ang isang espeyal na address na %s para i-associate ang mga commit sa iyong account. Tandaan na ang pagbabago ng opsyon na ito ay hindi makakaapekto sa mga umiiral na commit.
gpg_key_id_used = Ang isang publikong GPG key na may katulad na ID ay umiiral na.
gpg_no_key_email_found = Ang GPG key na ito ay hindi tumutugma sa anumang email address na nauugnay sa iyong account. Madadagdag pa rin ito kapag i-sign mo ang ibinigay na token.
ssh_principal_deletion_success = Tinanggal na ang principal.
@ -956,6 +961,7 @@ pronouns_custom = Pasadya
pronouns_unspecified = Hindi natakda
pronouns = Mga panghalip
language.title = Default na wika
keep_activity_private.description = Makikita mo lang at mga tagapangasiwa ng instansya ang iyong <a href="%s">pampublikong aktibidad</a>.
[repo]
template_description = Ang mga template na repositoryo ay pinapayagan ang mga gumagamit na mag-generate ng mga bagong repositoryo na may magkatulad na istraktura ng direktoryo, mga file, at opsyonal na mga setting.
@ -1490,7 +1496,7 @@ settings.transfer_perform = Gawin ang paglipat
settings.transfer_abort = Ipagpaliban ang paglipat
settings.transfer_owner = Bagong may-ari
pulls.tab_conversation = Pag-uusap
pulls.tab_files = Nabagong mga file
pulls.tab_files = Mga nabagong file
settings.new_owner_blocked_doer = Hinarang ka ng bagong may-ari.
settings.transfer.rejected = Tinanggihan ang paglipat ng [repository].
settings.transfer.success = Matagumpay na inilipat ang [repository].
@ -1756,7 +1762,7 @@ pulls.close = Isara ang [pull request]
pulls.cmd_instruction_hint = `Tingnan ang mga panuto para sa linya ng utos.`
project = Mga proyekto
issues.content_history.deleted = binura
pulls.no_results = Walang nakitang mga resulta.
pulls.no_results = Walang mga nahanap na resulta.
pulls.closed = Sarado ang [pull request]
pulls.is_closed = Naisara na ang [pull request].
issues.ref_closing_from = `<a href="%[3]s">isinangguni ang hiling sa paghila %[4]s na magsasara sa isyung ito</a><a id="%[1]s" href="#%[1]s">%[2]s</a>`
@ -1813,7 +1819,7 @@ issues.dependency.remove = Tanggalin
pulls.edit.already_changed = Hindi maimbak ang mga pagbabago sa [pull request]. Mukhang nabago na ng ibang tagagamit ang nilalaman. Mangyaring i-refresh ang pahina at subukang baguhin muli upang maiwasang ma-overwrite ang kanilang pagbago
milestones.filter_sort.most_complete = Pinakakumpleto
settings.collaboration.owner = May-ari
pulls.showing_only_single_commit = Ipinapakita lamang ang mga pagbago ng [commit] %[1]s
pulls.showing_only_single_commit = Ipinapakita lamang ang mga pagbago ng commit na %[1]s
comments.edit.already_changed = Hindi maimbak ang mga pagbabago sa komento. Mukhang nabago na ng ibang tagagamit ang nilalaman. Mangyaring i-refresh ang pahina at subukang baguhin muli upang maiwasang ma-overwrite ang kanilang pagbago
milestones.completeness = <strong>%d%%</strong> nakumpleto
wiki.welcome = Maligayang pagdating sa Wiki.
@ -1865,7 +1871,7 @@ pulls.showing_specified_commit_range = Ipinapakita lamang ang mga pagbabago sa p
wiki.pages = Mga pahina
activity.unresolved_conv_label = Nakabukas
settings.pull_mirror_sync_in_progress = Inihatak ang mga pagbabago mula sa [malayuang] %s sa ngayon.
issues.dependency.setting = Paganahin ang mga [dependency] para sa mga isyu at mga hiling sa paghila
issues.dependency.setting = Paganahin ang mga dependency para sa mga isyu at mga hiling sa paghila
activity.navbar.pulse = Pulso
settings.protect_enable_merge_desc = Pinapayagan ang sinumang may [access] sa pagsulat upang isama ang mga hiling sa paghila sa [branch] na ito.
activity.git_stats_commit_1 = %d commit
@ -1874,6 +1880,24 @@ activity.git_stats_file_1 = %d file
pulls.desc = Paganahin ang mga hiling sa paghila at mga pagsuri sa [code].
activity.git_stats_exclude_merges = Maliban sa mga pagsali,
activity.active_prs_count_n = <strong>%d</strong> aktibong mga hiling sa paghila
issues.author.tooltip.issue = May-akda ng iysung ito ang user.
issues.author.tooltip.pr = May-akda ng hiling sa paghila na ito ang user na ito.
issues.dependency.add_error_dep_exists = Umiiral na and dependency.
issues.dependency.add_error_cannot_create_circular = Hindi ka maaring gumawa ng dependency na may dalawang isyu na humaharang ang isa't isa.
issues.dependency.add_error_same_issue = Hindi mo magagwang dumepende ang isyu sa sarili.
issues.dependency.add_error_dep_not_same_repo = Dapat nasa katulad na repositoryo ang mga isyu.
issues.dependency.add_error_dep_issue_not_exist = Hindi umiiral ang dumedependeng isyu.
issues.dependency.add_error_dep_not_exist = Hindi umiiral ang dependency.
pulls.compare_changes = Bagong hiling sa paghila
pulls.allow_edits_from_maintainers = Payagan ang mga pagbabago mula sa mga tagapagpanatili
pulls.show_all_commits = Ipakita ang lahat ng mga commit
pulls.show_changes_since_your_last_review = Ipakita ang mga pagbabago mula noong huli mong pagsusuri
issues.dependency.blocked_by_short = Dumedepende sa
issues.review.pending.tooltip = Kasalukuyang hindi visible ang komentong ito sa ibang mga user. Para i-submit ang iyong mga nakabinbin na komento, piliin ang "%s" -> "%s/%s/%s" sa itaas ng pahina.
pulls.tab_commits = Mga Commit
issues.dependency.issue_remove_text = Tatanggalin nito ang dependency sa isyu na ito. Magpatuloy?
issues.dependency.remove_header = Tanggalin ang Dependency
issues.dependency.pr_remove_text = Tatanggalin nito ang dependency sa hiling sa paghila na ito. Magpatuloy?
[search]
commit_kind = Maghanap ng mga commit...
@ -1900,6 +1924,8 @@ pull_kind = Maghanap ng mga paghila...
issue_kind = Maghanap ng mga isyu...
exact = Eksakto
exact_tooltip = Samahan lamang ang mga resulta na tutugma sa eksaktong search term
union = Kaugnay
union_tooltip = Isama ang mga resulta na tumutugma sa anumang mga nahiwalay ng whitespace na keyword
[admin]
auths.updated = Nabago
@ -2205,6 +2231,40 @@ notices.delete_selected = Burahin ang pinili
notices.view_detail_header = Mga detalye ng paunawa
notices.inverse_selection = Baliktarin ang pagpili
config.app_slogan = Slogan ng instansya
auths.oauth2_provider = Tagapagbigay ng OAuth2
auths.oauth2_tokenURL = URL ng token
auths.oauth2_authURL = URL ng Authorize
auths.oauth2_clientID = ID ng kliyente (Key)
auths.enable_ldap_groups = I-enable ang mga LDAP group
auths.oauth2_clientSecret = Sikreto ng Kliyente
auths.openIdConnectAutoDiscoveryURL = URL ng OpenID Connect Auto Discovery
auths.oauth2_use_custom_url = Gumamit ng mga custom URL sa halip ng mga default URL
auths.group_attribute_list_users = Group attribute na naglalaman ng listahan ng mga user
auths.user_attribute_in_group = User attribute na nakalista sa grupo
auths.oauth2_tenant = Tenant
auths.oauth2_scopes = Mga karagdagang scope
auths.oauth2_required_claim_name = Kinakailangang claim name
auths.pam_email_domain = Email domain ng PAM (opsyonal)
auths.oauth2_icon_url = URL ng icon
auths.oauth2_emailURL = URL ng email
auths.skip_local_two_fa = I-skip ang lokal na 2FA
auths.skip_tls_verify = I-skip ang pagpapatunay ng TLS
auths.force_smtps_helper = Palaging ginagagmit ang SMTPS sa port 465. Itakda ito para pilitin ang SMTPS sa mga ibang port. (Kung hindi, gagamitin ang STARTTLS sa mga ibang port kapag sinusuportahan ng host.)
auths.helo_hostname = Hostname ng HELO
auths.force_smtps = Pilitin ang SMTPS
auths.skip_local_two_fa_helper = Ang pag-iwan sa hindi nakatakda ay nangangahulugan na ang mga lokal na user na may 2FA ay kailangan pa ring pumasa sa 2FA upang mag-log on
auths.ms_ad_sa = Mga search attribute ng MS AD
auths.smtphost = Host ng SMTP
auths.allowed_domains_helper = Iwanang walang laman para payagan ang lahat ng mga domain. Ihiwalay ang mga maraming domain gamit ang kuwit (",").
auths.smtp_auth = Uri ng authentikasyon ng SMTP
auths.pam_service_name = Pangalan ng serbisyo ng PAM
auths.map_group_to_team = I-map ang mga LDAP group sa Mga koponan ng organisasyon (iwanang walang laman para i-skip)
auths.map_group_to_team_removal = Tanggalin ang mga user sa mga naka-synchronize na koponan kapag hindi kasama ang user sa katumbas na LDAP group
auths.smtpport = Port ng SMTP
auths.allowed_domains = Mga pinapayagang domain
auths.helo_hostname_helper = Hostname na pinapadala sa pamamagitan ng HELO. Iwanang walang laman para ipadala ang kasalukuyang hostname.
auths.disable_helo = I-disable ang HELO
auths.oauth2_profileURL = URL ng profile
[org]
repo_updated = Binago %s

View file

@ -191,6 +191,8 @@ buttons.ref.tooltip=Référencer un ticket ou demande dajout
buttons.switch_to_legacy.tooltip=Utiliser lancien éditeur à la place
buttons.enable_monospace_font=Activer la police à chasse fixe
buttons.disable_monospace_font=Désactiver la police à chasse fixe
buttons.indent.tooltip = Indenter les éléments d'un niveau
buttons.unindent.tooltip = Supprimer un niveau d'indentation
[filter]
string.asc=A - Z
@ -247,7 +249,7 @@ err_admin_name_is_invalid=Le nom d'utilisateur de l'administrateur est invalide
general_title=Configuration générale
app_name=Titre du site
app_name_helper=Entrez ici le nom de votre société.
app_name_helper=Entrez ici le nom de votre instance. Il sera affiché sur chaque page.
repo_path=Emplacement racine des dépôts
repo_path_helper=Les dépôts Git distants seront stockés dans ce répertoire.
lfs_path=Répertoire racine Git LFS
@ -464,6 +466,11 @@ last_admin = Vous ne pouvez pas supprimer le dernier compte administrateur. Il d
remember_me.compromised = Le jeton de login n'est plus valide ce qui pourrait indiquer une compromission de compte. Veuillez vérifier d'éventuelles activités inhabituelles.
tab_signup = Enregistrement
tab_signin = Connexion
hint_register = Besoin d'un compte? <a href="%s">Enregistrez vous.</a>
sign_up_button = Creation d'un compte.
hint_login = Vous avez déjà un compte? <a href="%s">Connectez vous maintenant!</a>
back_to_sign_in = Retour à la connexion
sign_in_openid = Continuer avec OpenID
[mail]
view_it_on=Voir sur %s
@ -480,7 +487,7 @@ activate_email=Veuillez vérifier votre adresse courriel
activate_email.title=%s, veuillez vérifier votre adresse courriel
activate_email.text=Veuillez cliquer sur le lien suivant pour vérifier votre adresse courriel dans <b>%s</b>:
register_notify=Bienvenue sur Forgejo
register_notify=Bienvenue sur %s
register_notify.title=%[1]s, bienvenue à %[2]s
register_notify.text_1=ceci est votre courriel de confirmation d'inscription pour %s!
register_notify.text_2=Vous pouvez maintenant vous connecter avec le nom d'utilisateur : %s
@ -673,14 +680,22 @@ form.name_pattern_not_allowed=Le motif « %s » nest pas autorisé dans un
form.name_chars_not_allowed=Le nom d'utilisateur "%s" contient des caractères non valides.
block_user = Bloquer un utilisateur
block_user.detail = Veuillez noter que bloquer un utilisateur a des conséquences. En particulier :
block_user.detail_1 = Vous ne suivez plus cet utilisateur.
block_user.detail_1 = Vous cesserez de vous suivre l'un et l'autre et ne pourrez plus vous suivre l'un et l'autre.
block_user.detail_2 = Cet utilisateur ne peut interagir avec vos dépôts, les tickets ou commentaires que vous avez créés.
block_user.detail_3 = Cet utilisateur ne peut pas vous ajouter en tant que collaborateur, et vous ne pouvez pas l'ajouter en tant que collaborateur.
block_user.detail_3 = Cet utilisateur ne peut pas vous ajouter l'un et l'autre en tant que collaborateur.
follow_blocked_user = Vous ne pouvez pas suivre cet utilisateur parce vous avez bloqué cet utilisateur ou bien cet utilisateur vous a bloqué.
block = Bloquer
unblock = Débloquer
following_one = Suit %d personnes
followers_one = %d abonné
public_activity.visibility_hint.self_public = Votre activité est visible de tous, a l'exception de vos interactions dans les espaces privés. <a href="%s">Configurer</a>.
public_activity.visibility_hint.admin_public = Cette activité est visible de tous mais, en tant qu'administrateur vous pouvez aussi voir les interactions dans les espaces privés.
public_activity.visibility_hint.self_private = Vous pouvez voir votre propre activité, ainsi que les administrateurs de l'instance. <a href="%s">Configurer</a>.
public_activity.visibility_hint.admin_private = Vous pouvez voir cette activité en tant qu'administrateur mais l'utilisateur veut qu'elle reste privée.
following.title.few = Following
followers.title.one = Follower
followers.title.few = Followers
following.title.one = Following
[settings]
profile=Profil
@ -795,7 +810,7 @@ add_email_success=La nouvelle adresse e-mail a été ajoutée.
email_preference_set_success=L'e-mail de préférence a été défini avec succès.
add_openid_success=La nouvelle adresse OpenID a été ajoutée.
keep_email_private=Cacher l'adresse courriel
keep_email_private_popup=Ceci masquera votre adresse e-mail de votre profil, de vos demandes d'ajout et des fichiers modifiés depuis l'interface Web. Les révisions déjà soumises ne seront pas modifiés. Utilisez %s dans les révisions pour les relier à votre compte.
keep_email_private_popup=Ceci masquera votre adresse courriel de votre profil. Elle ne sera plus la valeur par défaut pour les commits créés par l'interface web, tel que des ajouts de fichiers ou des éditions, et ne sera pas utilisée pour fusionner les commits. Un courriel special %s peut être utilisé pour établir la relation entre des commits et votre compte. Notez que changer cette option n'aura pas d'effet sur les commits existants.
openid_desc=OpenID vous permet de confier l'authentification à une tierce partie.
manage_ssh_keys=Gérer les clés SSH
@ -1008,6 +1023,7 @@ pronouns_custom = Personnalisés
pronouns = Pronoms
pronouns_unspecified = Non spécifiés
language.title = Langue par défaut
keep_activity_private.description = Vous seul pourrez voir votre <a href="%s">activité publique</a>, ainsi que les administrateurs de l'instance.
[repo]
new_repo_helper=Un dépôt contient tous les fichiers dun projet, ainsi que lhistorique de leurs modifications. Vous avez déjà ça ailleurs ? <a href="%s">Migrez-le ici.</a>
@ -2491,7 +2507,7 @@ settings.lfs_locks_no_locks=Pas de verrous
settings.lfs_lock_file_no_exist=Le fichier verrouillé n'existe pas dans la branche par défaut
settings.lfs_force_unlock=Forcer le déverrouillage
settings.lfs_pointers.found=%d pointeur(s) sur blob trouvés - %d associés, %d non associés (%d manquant dans le magasin)
settings.lfs_pointers.sha=SHA du Blob
settings.lfs_pointers.sha=SHA du blob
settings.lfs_pointers.oid=OID
settings.lfs_pointers.inRepo=Dans le dépôt
settings.lfs_pointers.exists=Existe en magasin
@ -2769,6 +2785,14 @@ subscribe.issue.guest.tooltip = Authentifiez vous pour vous abonner à ce ticket
subscribe.pull.guest.tooltip = Authentifiez vous pour suivre cette demande d'ajout.
n_release_one = %s publication
n_release_few = %s publications
issues.author.tooltip.pr = Cet utilisateur est l'auteur de cette pull request.
issues.author.tooltip.issue = Cet utilisateur est l'auteur de ce ticket.
issues.edit.already_changed = Impossible de sauvegarder les changements du ticket car son contenu a déjà été modifié par un autre utilisateur. Veuillez recharger la page et essayer de l'éditer à nouveau pour éviter d'écraser ses changements
pulls.edit.already_changed = Impossible de sauvegarder les changements de la pull request car son contenu a déjà été modifié par un autre utilisateur. Veuillez recharger la page et essayer de l'éditer à nouveau pour éviter d'écraser ses changements
settings.federation_following_repos = Les URL des dépôts suivis séparés par ";", sans espace. ; », pas d'espace.
settings.federation_not_enabled = La fédération n'est pas activée pour votre instance.
comments.edit.already_changed = Impossible de sauvegarder les changements du commentaire car son contenu a déjà été modifié par un autre utilisateur. Veuillez recharger la page et essayer de l'éditer à nouveau pour éviter d'écraser ses changements
settings.federation_apapiurl = URL de fédération de ce dépôt. A copier-coller dans les paramètres de fédérations d'un autre dépôt comme URL d'un dépôt à suivre.
[graphs]
component_loading=Chargement de %s…
@ -3291,7 +3315,7 @@ config.service_config=Configuration du service
config.register_email_confirm=Exiger la confirmation de l'e-mail lors de l'inscription
config.disable_register=Désactiver le formulaire d'inscription
config.allow_only_internal_registration=Autoriser l'inscription uniquement via Forgejo lui-même
config.allow_only_external_registration=N'autoriser l'inscription qu'à partir des services externes
config.allow_only_external_registration=N'autoriser l'inscription qu'à partir de services externes
config.enable_openid_signup=Activer l'inscription avec OpenID
config.enable_openid_signin=Activer la connexion avec OpenID
config.show_registration_button=Afficher le bouton d'enregistrement
@ -3454,6 +3478,10 @@ auths.tip.gitlab_new = Enregistrer une nouvelle application sur https://gitlab.c
auths.default_domain_name = Nom de domaine par défaut utilisé pour le courriel
config.open_with_editor_app_help = Les éditeurs du menu "Ouvrir avec". Si laissé vide, les valeurs par défaut seront utilisées. Ouvrir pour voir les valeurs par défaut.
config.app_slogan = Slogan de l'instance
config.cache_test_slow = Test du cache réussi, mais le temps de réponse est lent : %s.
config.cache_test_failed = Échec du contrôle du cache : %v.
config.cache_test = Tester le cache
config.cache_test_succeeded = Test du cache réussi, réponse obtenue en %s.
[action]
create_repo=a créé le dépôt <a href="%s">%s</a>
@ -3812,6 +3840,14 @@ runs.no_workflows.documentation = Pour plus dinformations sur Forgejo Actions
variables.id_not_exist = La variable numéro %d nexiste pas.
runs.workflow = Workflow
runs.no_job_without_needs = Le workflow doit contenir au moins une tâche sans dépendances.
workflow.dispatch.use_from = Utiliser un workflow depuis
runs.no_job = Le workflow doit au moins contenir une tâche
workflow.dispatch.trigger_found = Ce workflow a un déclencheur d'événement <c>workflow_dispatch</c>.
workflow.dispatch.run = Exécuter le workflow
workflow.dispatch.success = L'exécution du workflow a bien été demandée.
workflow.dispatch.input_required = Le champ "%s" est obligatoire.
workflow.dispatch.invalid_input_type = Type invalide pour le champ "%s".
workflow.dispatch.warn_input_limit = Affichage des %d premiers champs seulement.
[projects]
type-1.display_name=Projet personnel
@ -3864,6 +3900,9 @@ commit_kind = Chercher les commits...
exact = Exact
exact_tooltip = Inclure uniquement les résultats qui correspondent exactement au terme recherché
issue_kind = Rechercher dans les tickets...
union = Union
union_tooltip = Inclus les résultats contenant au moins un des mots clé séparés par des espaces
pull_kind = Rechercher dans les demande d'ajout...
[munits.data]

View file

@ -7,7 +7,7 @@ dashboard = Panel de Control
explore = Explorar
help = Axuda
logo = Logo
sign_in = Iniciar Sesión
sign_in = Iniciar sesión
sign_in_with_provider = Iniciar Sesión con %s
sign_in_or = ou
sign_out = Pechar Sesión
@ -142,6 +142,7 @@ filter.public = Publico
pin = Aproximada
filter.private = Privado
copy_generic = Copiar ao portapapeis
test = Test
[aria]
navbar = Barra de Navegación
@ -173,6 +174,8 @@ buttons.ref.tooltip = Referencia un problema ou pull request
[search]
search = Buscar...
type_tooltip = Tipo de busca
repo_kind = Buscar repositorios...
user_kind = Buscar usuarios...
[startpage]
platform = Multiplataforma

View file

@ -290,7 +290,7 @@ activate_account=Kérjük aktiválja a fiókját
activate_email=E-mail cím megerősítése
register_notify=A Forgejo üdvözli
register_notify=A %s üdvözli
reset_password=Fiókjának visszaállítása

View file

@ -212,7 +212,7 @@ activate_account=Silakan aktifkan akun anda
activate_email=Verifikasi alamat surel anda
register_notify=Selamat Datang di Forgejo
register_notify=Selamat Datang di %s
reset_password=Pulihkan akun Anda

View file

@ -302,7 +302,7 @@ activate_account.text_2=Vinsamlegast smelltu á eftirfarandi tengil til að virk
activate_email=Staðfestu netfangið þitt
activate_email.text=Vinsamlegast smelltu á eftirfarandi tengil til að staðfesta netfangið þitt innan <b>%s</b>:
register_notify=Velkomin(n) í Forgejo
register_notify=Velkomin(n) í %s
register_notify.title=%[1]s, velkomin(n) í %[2]s
register_notify.text_1=þetta er staðfestingarpóstur þinn fyrir skráningu á %s!
register_notify.text_2=Þú getur nú skráð þig inn með notandanafni: %s.

View file

@ -478,7 +478,7 @@ activate_account.text_2=Clicca sul seguente link per attivare il tuo account ent
activate_email=Verifica il tuo indirizzo e-mail
activate_email.text=Clicca sul seguente link per verificare il tuo indirizzo email entro <b>%s</b>:
register_notify=Benvenuto su Forgejo
register_notify=Benvenuto su %s
register_notify.title=%[1]s, benvenuto in %[2]s
register_notify.text_1=questa è la tua email di conferma di registrazione per %s!
register_notify.text_2=Puoi accedere al tuo profilo tramite il tuo nome utente: %s

View file

@ -477,7 +477,7 @@ activate_email=メール アドレスを確認します
activate_email.title=%s さん、メールアドレス確認をお願いします
activate_email.text=あなたのメールアドレスを確認するため、<b>%s</b>以内に次のリンクをクリックしてください:
register_notify=Forgejoへようこそ
register_notify=%sへようこそ
register_notify.title=%[1]s さん、%[2]s にようこそ
register_notify.text_1=これは %s への登録確認メールです!
register_notify.text_2=あなたはユーザー名 %s でログインできるようになりました。

View file

@ -379,12 +379,23 @@ activate_account=계정을 활성화하세요
activate_email=이메일 주소 확인
register_notify=Forgejo에 오신것을 환영합니다
register_notify=%s에 오신것을 환영합니다
reset_password=계정 복구
register_success=등록 완료
issue.action.close = <b>@%[1]s</b>님이 #%[2]d를 닫았습니다.
release.new.text = <b>@%[1]s</b>님이 %[2]s를 %[3]s에 출시함
issue.action.push_n = <b>@%[1]s</b>님이 %[3]d개의 커밋을 %[2]s에 푸시함
issue.action.reopen = <b>@%[1]s</b>님이 #%[2]d를 다시 열었습니다.
issue.action.approve = <b>@%[1]s</b>님이 이 풀 리퀘스트를 승인했습니다.
issue.action.review = <b>@%[1]s</b>님이 이 풀 리퀘스트에 커밋했습니다.
issue.action.ready_for_review = <b>@%[1]s</b>님이 이 풀 리퀘스트를 검토하기 적합하다 표시했습니다.
issue.action.push_1 = <b>@%[1]s</b>님이 %[3]d개의 커밋을 %[2]s에 푸시함
issue.action.merge = <b>@%[1]s</b>님이 #%[2]d를 %[3]s에 병합했습니다.
issue.action.review_dismissed = <b>@%[1]s</b>님이 이 풀 리퀘스트에 대한 %[2]s의 마지막 검토를 거부했습니다.
issue.action.reject = <b>@%[1]s</b>님이 이 풀 리퀘스트에 수정을 요청했습니다.
issue.action.new = <b>@%[1]s</b>님이 #%[2]d를 만들었습니다.
@ -862,7 +873,7 @@ issues.action_milestone=마일스톤
issues.action_milestone_no_select=마일스톤 없음
issues.action_assignee=담당자
issues.action_assignee_no_select=담당자 없음
issues.opened_by=<a href="%[2]s"> %[3]s</a>님이 %[1]s 오픈
issues.opened_by=<a href="%[2]s"> %[3]s</a>님이 %[1]s 오픈
issues.previous=이전
issues.next=다음
issues.open_title=오픈
@ -925,8 +936,8 @@ issues.due_date_form_add=마감일 추가
issues.due_date_form_edit=편집
issues.due_date_form_remove=삭제
issues.due_date_not_set=마감일이 설정되지 않았습니다.
issues.due_date_added=마감일 %s 를 추가 %s
issues.due_date_remove=%s %s 마감일이 삭제됨
issues.due_date_added=님이 마감일 %s을 %s 추가함
issues.due_date_remove=님이 마감일 %s를 %s 삭제함
issues.due_date_overdue="기한 초과"
issues.due_date_invalid=기한이 올바르지 않거나 범위를 벗어났습니다. "yyyy-mm-dd"형식을 사용해주십시오.
issues.dependency.title=전제조건
@ -946,7 +957,7 @@ issues.dependency.add_error_dep_exists=전제조건이 이미 존재합니다.
issues.dependency.add_error_dep_not_same_repo=두 이슈는 같은 저장소 안에 있어야 합니다.
issues.review.self.approval=자신의 풀 리퀘스트를 승인할 수 없습니다.
issues.review.self.rejection=자신의 풀 리퀘스트에 대한 변경을 요청할 수 없습니다.
issues.review.approve="이 변경사항을 승인하였습니다. %s"
issues.review.approve=이 변경사항을 승인함 %s
issues.review.comment=검토됨 %s
issues.review.pending=보류
issues.review.review=검토
@ -962,19 +973,19 @@ pulls.compare_compare=다음으로부터 풀
pulls.filter_branch=Filter Branch
pulls.no_results=결과를 찾을 수 없습니다.
pulls.create=풀 리퀘스트 생성
pulls.title_desc_few=<code>%[2]s</code> 에서 <code id="branch_target">%[3]s</code> 로 %[1]d개의 커밋들을 머지하려 합니다
pulls.merged_title_desc_few=<code>%[2]s</code> 에서 <code>%[3]s</code> 로 %[1]d commits 를 머지했습니다 %[4]s
pulls.title_desc_few=<code>%[2]s</code> 에서 <code id="branch_target">%[3]s</code> 로 %[1]d개의 커밋들을 병합하려함
pulls.merged_title_desc_few=님이 <code>%[2]s</code> 에서 <code>%[3]s</code> 로 %[1]d 커밋을 %[4]s 병합함
pulls.tab_conversation=대화
pulls.tab_commits=커밋
pulls.tab_files=파일 변경
pulls.reopen_to_merge=머지 작업을 수행하려면 이 풀 리퀘스트를 다시 열어주세요.
pulls.merged=병합
pulls.can_auto_merge_desc=이 풀리퀘스트는 자동적으로 머지될 수 있습니다.
pulls.cannot_auto_merge_helper=충돌을 해결하려면 수동으로 머지하십시오.
pulls.tab_files=파일 변경
pulls.reopen_to_merge=병합을 수행하려면 이 풀 리퀘스트를 다시 열어주세요.
pulls.merged=병합
pulls.can_auto_merge_desc=이 풀리퀘스트는 자동적으로 병합될 수 있습니다.
pulls.cannot_auto_merge_helper=충돌을 해결하려면 수동으로 병합하십시오.
pulls.no_merge_desc=모든 저장소 머지 옵션이 비활성화 되어있기 때문에 이 풀 리퀘스트를 머지할 수 없습니다.
pulls.no_merge_desc=모든 저장소 병합 옵션이 비활성화 되어있기 때문에 이 풀 리퀘스트를 병합할 수 없습니다.
pulls.invalid_merge_option=이 풀 리퀘스트에서 설정한 머지 옵션을 사용하실 수 없습니다.
pulls.invalid_merge_option=이 풀 리퀘스트에서 설정한 병합 옵션을 사용하실 수 없습니다.
@ -1042,7 +1053,7 @@ activity.title.user_1=%d 사용자
activity.title.user_n=%d 사용자
activity.title.prs_1=풀 리퀘스트 %d개
activity.title.prs_n=풀 리퀘스트 %d개
activity.title.prs_merged_by=%s 가 %s 로부터 머지 되었음
activity.title.prs_merged_by=%s 가 %s 로부터 병합되었음
activity.title.prs_opened_by=%s 가 %s 로 부터 제안됨
activity.merged_prs_label=병합됨
activity.opened_prs_label=제안중
@ -1208,7 +1219,7 @@ settings.protect_disable_push=푸시 끄기
settings.protect_enable_push=푸시 켜기
settings.protect_whitelist_search_users=사용자 찾기...
settings.protect_whitelist_search_teams=팀 찾기...
settings.protect_merge_whitelist_committers=머지 화이트리스트 활성화
settings.protect_merge_whitelist_committers=병합 화이트리스트 활성화
settings.protect_required_approvals=필요한 승인:
settings.protect_approvals_whitelist_users=화이트리스트된 리뷰어:
settings.add_protected_branch=보호 활성화
@ -1311,7 +1322,7 @@ pulls.blocked_by_official_review_requests = 이 풀 리퀘스트는 공식 검
watch_guest_user = 이 저장소를 주시하려면 로그인 해야합니다.
issues.closed_by_fake = %[2]s님이 %[1]s에 닫음
issues.new.closed_projects = 닫힌 프로젝트
pulls.merged_by_fake = %[2]s님이 %[1]s에 머지
pulls.merged_by_fake = %[2]s님이 %[1]s 병합
issues.closed_by = <a href="%[2]s">%[3]s</a>님이 %[1]s에 닫음
issues.closed_at = `<a id="%[1]s" href="#%[1]s">%[2]s</a>`에 이 이슈를 닫음
issues.filter_milestone_closed = 닫힌 마일스톤
@ -1338,6 +1349,22 @@ issues.dependency.pr_close_blocked = 병합하기 전에 이 풀 리퀘스트을
stars = 좋아요
stars_remove_warning = 이 작업은 이 저장소에 대한 모든 좋아요를 제거할것입니다.
star_guest_user = 로그인하여 이 저장소에 좋아요 하세요.
issues.author.tooltip.issue = 이 사용자는 이 이슈의 작성자 입니다.
issues.author.tooltip.pr = 이 사용자는 이 풀 리퀘스트의 작성자 입니다.
activity.git_stats_author_1 = %d명의 작성자
issues.filter_poster_no_select = 모든 작성자
pulls.blocked_by_user = 당신은 이 저장소의 소유자에게 차단당했기 떄문에 풀 리퀘스트를 만들 수 없습니다.
commits.search.tooltip = 키워드 앞에 접두사 "author:", "committer:", "after:", "before:"을 사용할 수 있습니다 (예: "revert author:Alice before:2019-01-13").
issues.filter_poster = 작성자
issues.author = 작성자
issues.role.owner_helper = 이 사용자는 이 저장소의 소유자 입니다.
activity.git_stats_author_n = %d명의 작성자
diff.review.self_reject = 풀 리퀘스트 작성자는 자신의 풀 리퀘스트에 수정을 요청할 수 없음
diff.review.self_approve = 풀 리퀘스트 작성자는 자신의 풀 리퀘스트를 승인할 수 없음
issues.blocked_by_user = 당신은 이 저장소의 소유자에게 차단당했기 떄문에 이슈를 만들 수 없습니다.
issues.comment.blocked_by_user = 당신은 이 저장소의 소유자 혹은 이 이슈의 작성자 에게 차단당했기 떄문에 이슈에 댓글을 달 수 없습니다.
author_search_tooltip = 최대 30명의 사용자를 표시함
pulls.merged_title_desc_one = 님이 <code>%[2]s</code> 에서 <code>%[3]s</code> 로 %[1]d 커밋을 %[4]s 병합함
@ -1772,6 +1799,7 @@ nuget.dependency.framework = 타겟 프레임워크
maven.download = 종속성을 다운로드하려면 명령줄을 통해 실행하세요:
dependency.id = ID
dependency.version = 버전
details.author = 작성자
[secrets]

View file

@ -439,7 +439,7 @@ activate_email=Apstipriniet savu e-pasta adresi
activate_email.title=%s, apstipriniet savu e-pasta adresi
activate_email.text=Nospiediet uz saites, lai apstiprinātu savu e-pasta adresi lapā <b>%s</b>:
register_notify=Laipni lūdzam Forgejo
register_notify=Laipni lūdzam %s
register_notify.title=%[1]s, esat reģistrējies %[2]s
register_notify.text_1=šis ir reģistrācijas apstiprinājuma e-pasts lapai %s!
register_notify.text_2=Tagad varat autorizēties ar lietotāja vārdu: %s.

View file

@ -158,6 +158,7 @@ filter.not_archived = Niet gearchiveerd
more_items = Meer items
invalid_data = Ongeldige data: %v
copy_generic = Kopieer naar klembord
test = Test
[aria]
navbar = Navigatiebalk
@ -274,20 +275,20 @@ register_confirm=E-mailbevestiging vereist bij registreren
mail_notify=Activeer e-mailnotificaties
server_service_title=Server en service-instellingen van derden
offline_mode=Lokale modus inschakelen
offline_mode.description=Schakel third-party content uit en gebruik alleen lokale middelen.
offline_mode.description=Schakel content delivery netwerken van derden uit en serveer alle middelen lokaal.
disable_gravatar=Gravatar uitschakelen
disable_gravatar.description=Gravatar en derden avatar bronnen uitschakelen. Een standaard avatar zal worden gebruikt, tenzij een gebruiker hun eigen avatar uploadt naar de instantie.
federated_avatar_lookup=Federated avatars toestaan
federated_avatar_lookup.description=Zoek avatars op met Libravatar.
disable_registration=Schakel zelf registratie uit
disable_registration.description=Schakel zelfregistratie uit, alleen admins kunnen accounts maken.
allow_only_external_registration.description=Registratie alleen via externe diensten toestaan
disable_registration.description=Alleen instantiebeheerders kunnen nieuwe gebruikersaccounts aanmaken. Het wordt sterk aangeraden om registratie uitgeschakeld te houden, tenzij je van plan bent om een publieke instantie voor iedereen te hosten en klaar bent om grote hoeveelheden spam-accounts te verwerken.
allow_only_external_registration.description=Gebruikers kunnen alleen nieuwe accounts aanmaken via geconfigureerde externe services.
openid_signin=OpenID-inloggen inschakelen
openid_signin.description=Gebruikerslogin via OpenID inschakelen.
openid_signin.description=Laat gebruikers zich aanmelden via OpenID.
openid_signup=OpenID zelf-registratie inschakelen
openid_signup.description=OpenID zelfregistratie inschakelen.
openid_signup.description=Sta gebruikers toe om accounts aan te maken via OpenID als zelfregistratie is ingeschakeld.
enable_captcha=Registratie CAPTCHA inschakelen
enable_captcha.description=Vereis captcha validatie voor zelf-registratie van gebruiker.
enable_captcha.description=Gebruikers verplichten om CAPTCHA te passeren om accounts aan te maken.
require_sign_in_view=Aanmelden vereist om inhoud van instantie te bekijken
admin_setting.description=Het creëren van een administrator-account is optioneel. De eerste geregistreerde gebruiker wordt automatisch de beheerder.
admin_title=Instellingen beheerdersaccount
@ -308,11 +309,11 @@ save_config_failed=Kan de configuratie niet opslaan: %v
invalid_admin_setting=Instelling van de administrator-account is ongeldig: %v
invalid_log_root_path=Ongeldig log-pad: %v
default_keep_email_private=Verberg standaard alle e-mailadressen
default_keep_email_private.description=Verberg standaard de email-adressen van nieuwe gebruikers.
default_keep_email_private.description=Schakel het verbergen van e-mailadressen standaard in voor nieuwe gebruikers, zodat deze informatie niet meteen na het aanmelden uitlekt.
default_allow_create_organization=Standaard toestaan om organisaties aan te maken
default_allow_create_organization.description=Standaard toestaan dat nieuwe gebruikers organisaties kunnen aanmaken.
default_allow_create_organization.description=Sta nieuwe gebruikers standaard toe om organisaties aan te maken. Als deze optie is uitgeschakeld, moet een beheerder nieuwe gebruikers toestemming geven om organisaties aan te maken.
default_enable_timetracking=Tijdregistratie standaard inschakelen
default_enable_timetracking.description=Tijdsregistratie voor nieuwe repositories standaard inschakelen.
default_enable_timetracking.description=Sta het gebruik van de tijd-tracking functie voor nieuwe repositories standaard toe.
no_reply_address=Verborgen e-maildomein
no_reply_address_helper=Domeinnaam voor gebruikers met een verborgen e-mailadres. Bijvoorbeeld zal de gebruikersnaam "joe" in Git worden geregistreerd als "joe@noreply.example.org" als het verborgen email domein is ingesteld op "noreply.example.org".
password_algorithm=Wachtwoord hash-algoritme
@ -324,7 +325,7 @@ enable_update_checker = Updatecontrole inschakelen
invalid_password_algorithm = Ongeldig wachtwoord hash-algoritme
password_algorithm_helper = Stel het hashing-algoritme voor wachtwoorden in. De algoritmes hebben verschillende vereisten en sterkte. Het argon2-algoritme is tamelijk veilig, maar gebruikt veel geheugen en kan ongeschikt zijn voor kleine systemen.
run_user_helper = De gebruikersnaam van het besturingssysteem waaronder Forgejo draait. Merk op dat deze gebruiker toegang moet hebben tot de hoofdmap van de repository.
require_sign_in_view.description = Beperk de toegang tot de pagina's tot ingelogde gebruikers. Bezoekers zien alleen de aanmeldings- en registratiepagina's.
require_sign_in_view.description = Beperk de inhoudstoegang tot aangemelde gebruikers. Bezoekers kunnen alleen de verificatiepagina's bezoeken.
enable_update_checker_helper_forgejo = Het zal periodiek controleren op nieuwe Forgejo-versies door een TXT DNS-record op release.forgejo.org te controleren.
smtp_from_invalid = Het adres "E-mails versturen als" is ongeldig
config_location_hint = Deze configuratieopties worden opgeslagen in:
@ -407,7 +408,7 @@ resent_limit_prompt=Sorry, je hebt te snel na elkaar een aanvraag gedaan voor ee
has_unconfirmed_mail=Beste %s, u heeft een onbevestigd e-mailadres (<b>%s</b>). Als u nog geen bevestiging heeft ontvangen, of u een nieuwe aanvraag wilt doen, klik dan op de onderstaande knop.
resend_mail=Klik hier om uw activatie mail nog een keer te verzenden
email_not_associate=Dit emailadres is niet gekoppeld aan een account.
send_reset_mail=Stuur account herstel e-mail
send_reset_mail=Verzend e-mail voor herstel
reset_password=Account herstel
invalid_code=Uw bevestigingscode is ongeldig of is verlopen.
reset_password_helper=Account herstellen
@ -475,7 +476,7 @@ activate_account.text_2=Klik op de volgende link om uw account te activeren binn
activate_email=Verifieer uw e-mailadres
activate_email.text=Klik op de volgende link om je e-mailadres te bevestigen in <b>%s</b>:
register_notify=Welkom bij Forgejo
register_notify=Welkom bij %s
register_notify.title=%[1]s, welkom bij %[2]s
register_notify.text_1=dit is uw registratie bevestigingsemail voor %s!
register_notify.text_2=U kunt zich aanmelden bij uw account met uw gebruikersnaam: %s
@ -659,10 +660,10 @@ user_bio=Biografie
disabled_public_activity=Deze gebruiker heeft de publieke zichtbaarheid van de activiteit uitgeschakeld.
block_user = Blokkeer gebruiker
joined_on = Geregistreerd op %s
block_user.detail_1 = Deze gebruiker zal u ontvolgen.
block_user.detail = Begrijp alsjeblieft dat als u deze gebruiker blokkeert, er andere acties worden genomen. Zoals:
block_user.detail_2 = Deze gebruiker kan geen interactie hebben met repositories, gecreëerde issues en reacties.
block_user.detail_3 = Deze gebruiker kunt u niet toevoegen als samenwerker, noch kunt u hen toevoegen als samenwerker.
block_user.detail_1 = Jullie zullen elkaar niet meer volgen en zullen elkaar niet meer kunnen volgen.
block_user.detail = Merk op dat het blokkeren van een gebruiker andere effecten heeft, zoals:
block_user.detail_2 = Deze gebruiker kan geen interactie hebben met de repositories waarvan jij de eigenaar bent, of met de issues en berichten die je hebt aangemaakt.
block_user.detail_3 = Je zult elkaar niet kunnen toevoegen als samenwerker.
follow_blocked_user = U kunt deze gebruiker niet volgen, omdat u hen geblokkeerd heeft en of deze gebruiker heeft u geblokkeerd.
block = Blokkeren
unblock = Deblokkeren
@ -692,11 +693,11 @@ avatar=Profielfoto
ssh_gpg_keys=SSH / GPG sleutels
social=Sociale netwerk-accounts
applications=Applicaties
orgs=Beheer organisaties
orgs=Organisaties
repos=Repositories
delete=Verwijder account
twofa=Twee-factor authenticatie (TOTP)
account_link=Gekoppelde Accounts
account_link=Gekoppelde accounts
organization=Organisaties
webauthn=Twee-factor authenticatie (Beveiligingssleutels)
@ -753,8 +754,8 @@ password_change_disabled=Niet-lokale gebruikers kunnen hun wachtwoord niet in de
emails=E-mailadressen
manage_emails=E-mailadressen beheren
manage_themes=Selecteer standaardthema
manage_openid=Beheer OpenID-adressen
manage_themes=Standaardthema
manage_openid=OpenID-adressen
theme_desc=Dit zal het standaardthema worden op de gehele site.
primary=Primair
activated=Geactiveerd
@ -846,7 +847,7 @@ token_state_desc=Dit token werd gebruikt in de laatste 7 dagen
principal_state_desc=Deze verantwoordelijke werd gebruikt in de laatste 7 dagen
show_openid=Tonen op profiel
hide_openid=Verbergen van profiel
ssh_disabled=SSH uitgeschakeld
ssh_disabled=SSH is uitgeschakeld
ssh_externally_managed=Deze SSH sleutel wordt extern beheerd voor deze gebruiker
manage_social=Beheer gekoppelde sociale accounts
unbind=Ontkoppelen
@ -2737,8 +2738,8 @@ settings.federation_following_repos = URLs van de volgende repositories. Geschei
settings.federation_settings = Federatie instellingen
settings.federation_apapiurl = Federatie URL van deze repository. Kopiër en plak dit in de federatie instellingen van een andere repository als een URL van de volgende repository.
settings.federation_not_enabled = Federatie is niet ingeschakeld voor deze instantie.
subscribe.issue.guest.tooltip = Log in om dit issue te volgen.
subscribe.pull.guest.tooltip = Log in om dit pull request te volgen.
subscribe.issue.guest.tooltip = Log in om deze issue te volgen.
subscribe.pull.guest.tooltip = Log in om deze pull request te volgen.
settings.transfer.modal.title = Eigendom overdragen
settings.transfer.button = Eigendom overdragen
settings.graphql_url = GraphQL URL

View file

@ -467,7 +467,7 @@ activate_account.text_2=Kliknij poniższy link, aby aktywować swoje konto w ci
activate_email=Potwierdź swój adres e-mail
activate_email.text=Aby zweryfikować swój adres e-mail, w ciągu następnych <b>%s</b> kliknij poniższy link:
register_notify=Witamy w Forgejo
register_notify=Witamy w %s
register_notify.title=%[1]s, witaj w %[2]s
register_notify.text_1=to jest Twój e-mail z potwierdzeniem rejestracji dla %s!
register_notify.text_2=Możesz teraz zalogować się za pomocą nazwy użytkownika: %s

View file

@ -24,7 +24,7 @@ signed_in_as=Sessão iniciada como
enable_javascript=Este site requer JavaScript.
toc=Índice
licenses=Licenças
return_to_forgejo=Volte para Forgejo
return_to_forgejo=Retornar ao Forgejo
username=Nome de usuário
email=Endereço de e-mail
@ -89,7 +89,7 @@ add=Adicionar
add_all=Adicionar todos
remove=Remover
remove_all=Excluir todos
remove_label_str=`Remover item "%s"`
remove_label_str=Remover item "%s"
edit=Editar
enabled=Habilitado
@ -157,7 +157,7 @@ filter.not_archived = Não arquivado
filter.not_fork = Sem forks
filter.not_mirror = Sem espelhos
filter.not_template = Sem modelos
copy_generic = Copiar para área de transferência
copy_generic = Copiar para a área de transferência
[aria]
navbar=Barra de navegação
@ -456,9 +456,9 @@ password_pwned=A senha que você escolheu faz parte de uma <a target="_blank" re
password_pwned_err=Não foi possível concluir a requisição ao HaveIBeenPwned
change_unconfirmed_email_error = Erro ao alterar o endereço de e-mail: %v
change_unconfirmed_email_summary = Alterar o endereço de e-mail que o e-mail de ativação será enviado para.
last_admin = Não é possível remover o último administrador. Deve haver ao menos um usuário administrador.
last_admin = Não é possível remover o último administrador. Deve existir ao menos um usuário administrador.
change_unconfirmed_email = Se você colocou o endereço de e-mail errado durante o cadastro, você pode alterá-lo abaixo, e uma confirmação será enviada para o novo endereço.
remember_me.compromised = O token de login foi invalidado, o que pode indicar que a sua conta foi comprometida. Verifique se não há atividades suspeitas em sua conta.
remember_me.compromised = O identificador de sessão foi invalidado, o que pode indicar que a sua conta foi comprometida. Verifique se não há atividades suspeitas em sua conta.
tab_signin = Iniciar sessão
tab_signup = Inscrever-se
@ -477,7 +477,7 @@ activate_email=Verifique seu endereço de e-mail
activate_email.title=%s, por favor verifique o seu endereço de e-mail
activate_email.text=Por favor clique no link a seguir para verificar o seu endereço de e-mail em <b>%s</b>:
register_notify=Bem-vindo ao Forgejo
register_notify=Bem-vindo ao %s
register_notify.title=%[1]s, bem-vindo(a) a %[2]s
register_notify.text_1=este é o seu e-mail de confirmação de registro para %s!
register_notify.text_2=Você pode fazer login em sua conta utilizando o usuário: %s
@ -631,7 +631,7 @@ target_branch_not_exist=O branch de destino não existe.
username_error_no_dots = ` pode conter apenas caracteres alfanuméricos ("0-9, "a-z", "A-Z"), hífens ("-") e traços inferiores ("_"). Não é permitido conter caracteres não alfanuméricos no início ou fim. Caracteres não alfanuméricos consecutivos também não são permitidos.`
admin_cannot_delete_self = Você não pode excluir a si mesmo quando você é um administrador. Por favor, remova suas permissões de administrador primeiro.
AccessToken = Token de acesso
To = Nome do Branch
To = Nome do ramo
Website = Site
Pronouns = Pronomes
Biography = Biografia
@ -671,7 +671,7 @@ block_user = Bloquear usuário
unblock = Desbloquear
block = Bloquear
block_user.detail_2 = Este usuário não poderá interagir com seus repositórios, questões criadas e comentários.
follow_blocked_user = Você não pode seguir este usuário, pois você o bloqueou ou foi bloqueado por ele.
follow_blocked_user = Você não pode seguir este usuário porque você o bloqueou ou foi bloqueado por ele.
block_user.detail_3 = Este(a) usuário(a) não poderá adicioná-lo(a) como colaborador(a), nem você poderá adicioná-lo(a) como colaborador(a).
block_user.detail = Por favor, entenda que se você bloquear este usuário, outras ações serão tomadas. Tais como:
followers_one = %d seguidor
@ -755,14 +755,14 @@ update_user_avatar_success=O avatar do usuário foi atualizado.
update_password=Modificar senha
old_password=Senha atual
new_password=Nova senha
retype_new_password=Confirmar nova senha
retype_new_password=Confirme a nova senha
password_incorrect=A senha atual está incorreta.
change_password_success=Sua senha foi atualizada. Acesse usando sua nova senha de agora em diante.
password_change_disabled=Contas não-locais não podem alterar sua senha através da interface web do Forgejo.
emails=Endereços de e-mail
manage_emails=Gerenciar endereços de e-mail
manage_themes=Tema Padrão
manage_themes=Tema padrão
manage_openid=Endereços OpenID
email_desc=Seu endereço de e-mail principal será usado para notificações, recuperação de senha e, desde que não esteja oculto, para operações do Git baseadas na Web.
theme_desc=Este será o seu tema padrão em todo o site.
@ -770,7 +770,7 @@ primary=Principal
activated=Ativado
requires_activation=Requer ativação
primary_email=Tornar primário
activate_email=Enviar ativação
activate_email=Enviar e-mail de ativação
activations_pending=Ativações pendentes
can_not_add_email_activations_pending=Há uma ativação pendente, tente novamente em alguns minutos se quiser adicionar um novo e-mail.
delete_email=Remover
@ -986,7 +986,7 @@ visibility.limited_tooltip=Visível apenas para usuários autenticados
visibility.private=Privada
visibility.private_tooltip=Visível apenas para membros das organizações às quais você se associou
blocked_users = Usuários bloqueados
blocked_since = Bloqueado desde %s
blocked_since = Bloqueado(a) desde %s
user_unblock_success = O usuário foi desbloqueado.
user_block_success = O usuário foi bloqueado.
twofa_recovery_tip = Caso perca o seu dispositivo, você poderá usar uma chave de uso único para recuperar o acesso à sua conta.
@ -1770,8 +1770,8 @@ pulls.nothing_to_compare=Estes branches são iguais. Não há nenhuma necessidad
pulls.nothing_to_compare_and_allow_empty_pr=Estes branches são iguais. Este PR ficará vazio.
pulls.has_pull_request=`Um pull request entre esses branches já existe: <a href="%[1]s">%[2]s#%[3]d</a>`
pulls.create=Criar pull request
pulls.title_desc_few=quer aplicar o merge de %[1]d commits de <code>%[2]s</code> em <code id="branch_target">%[3]s</code>
pulls.merged_title_desc_few=aplicou merge dos %[1]d commits de <code>%[2]s</code> em <code>%[3]s</code> %[4]s
pulls.title_desc_few=quer mesclar %[1]d commits de <code>%[2]s</code> em <code id="branch_target">%[3]s</code>
pulls.merged_title_desc_few=mesclou %[1]d commits de <code>%[2]s</code> em <code>%[3]s</code> %[4]s
pulls.change_target_branch_at=`mudou o branch de destino de <b>%s</b> para <b>%s</b> %s`
pulls.tab_conversation=Conversação
pulls.tab_commits=Commits
@ -2119,7 +2119,7 @@ settings.convert_fork_desc=Você pode converter este fork em um repositório nor
settings.convert_fork_notices_1=Esta operação irá converter o fork em um repositório normal e não pode ser desfeita.
settings.convert_fork_confirm=Converter repositório
settings.convert_fork_succeed=O fork foi convertido em um repositório normal.
settings.transfer.title=Transferir propriedade
settings.transfer.title=Transferir titularidade
settings.transfer.rejected=A transferência do repositório foi rejeitada.
settings.transfer.success=A transferência do repositório foi bem sucedida.
settings.transfer_abort=Cancelar transferência
@ -2592,13 +2592,13 @@ settings.unarchive.header = Desarquivar este repositório
diff.comment.add_line_comment = Adicionar comentário na linha
new_repo_helper = Um repositório contém todos os arquivos de projeto, incluindo o histórico de revisões. Já hospeda um repositório em outra plataforma? <a href="%s">Migrar repositório</a>
blame.ignore_revs.failed = Falha ao ignorar as revisões em <a href="%s">.git-blame-ignore-revs</a>.
migrate.forgejo.description = Migrar dados do codeberg.org ou outras instâncias Forgejo.
migrate.forgejo.description = Migrar dados do codeberg.org ou outras servidores Forgejo.
commits.browse_further = Ver mais
issues.role.first_time_contributor = Primeira vez contribuindo
issues.role.first_time_contributor_helper = Esta é a primeira contribuição deste usuário para o repositório.
issues.role.contributor = Contribuidor(a)
issues.role.member_helper = Este usuário é membro da organização proprietária deste repositório.
issues.role.collaborator_helper = Este usuário foi convidado para colaborar neste repositório.
issues.role.collaborator_helper = Este(a) usuário(a) foi convidado(a) para colaborar neste repositório.
pulls.cmd_instruction_checkout_title = Checkout
settings.wiki_globally_editable = Permitir que qualquer pessoa possa editar a wiki
settings.transfer_abort_success = A transferência de repositório para %s foi cancelada.
@ -2612,12 +2612,12 @@ admin.manage_flags = Gerenciar sinalizadores
admin.enabled_flags = Sinalizadores habilitados para o repositório:
admin.update_flags = Atualizar sinalizadores
admin.flags_replaced = Os sinalizadores do repositório foram substituídos
all_branches = Todas as branches
all_branches = Todos os ramos
fork_branch = Branch a ser clonada para o fork
object_format_helper = O formato utilizado para armazenar os objetos do repositório, sendo SHA1 o mais compatível. Esta ação é <strong>IRREVERSÍVEL</strong>.
object_format = Formato dos objetos
tree_path_not_found_branch = Caminho %[1]s não existe na branch %[2]s
tree_path_not_found_tag = Caminho %[1]s não existe na etiqueta %[2]s
tree_path_not_found_branch = O caminho %[1]s não existe no ramo %[2]s
tree_path_not_found_tag = O caminho %[1]s não existe na etiqueta %[2]s
commits.view_path = Ver neste ponto do histórico
commits.renamed_from = Renomeado de %s
admin.failed_to_replace_flags = Falha ao substituir os sinalizadores do repositório
@ -2639,7 +2639,7 @@ settings.units.units = Funcionalidades
vendored = Externo
issues.num_participants_one = %d participante
issues.archived_label_description = (arquivada) %s
n_branch_few = %s branches
n_branch_few = %s ramos
stars = Favoritos
n_commit_one = %s commit
n_tag_few = %s etiquetas
@ -3358,6 +3358,7 @@ dashboard.task.cancelled = Tarefa: %[1]s cancelada: %[3]s
dashboard.sync_branch.started = Sincronização de ramos iniciada
dashboard.sync_repo_branches = Sincronizar ramos perdidos do Git para o banco de dados
packages.cleanup.success = Os dados expirados foram limpos com sucesso
monitor.queue.activeworkers = Processos ativos
[action]
@ -3567,10 +3568,10 @@ settings.delete.notice=Você está prestes a excluir %s (%s). Esta operação é
settings.delete.success=O pacote foi excluído.
settings.delete.error=Falha ao excluir o pacote.
owner.settings.cargo.title=Índice do Registro Cargo
owner.settings.cargo.initialize=Iniciar Índice
owner.settings.cargo.initialize=Inicializar índice
owner.settings.cargo.initialize.error=Falha ao inicializar índice Cargo: %v
owner.settings.cargo.initialize.success=O índice Cargo foi criado com sucesso.
owner.settings.cargo.rebuild=Reconstruir Índice
owner.settings.cargo.rebuild=Reconstruir índice
owner.settings.cargo.rebuild.error=Falha ao reconstruir índice Cargo: %v
owner.settings.cargo.rebuild.success=O índice Cargo foi reconstruído com sucesso.
owner.settings.cleanuprules.title=Gerenciar Regras de Limpeza
@ -3613,7 +3614,7 @@ deletion=Excluir segredo
deletion.description=A exclusão de um segredo é permanente e não pode ser desfeita. Continuar?
deletion.success=O segredo foi excluído.
deletion.failed=Falha ao excluir segredo.
management=Gerenciamento de Segredos
management=Gerenciar segredos
[actions]
actions=Ações
@ -3649,7 +3650,7 @@ runners.task_list.repository=Repositório
runners.task_list.commit=Commit
runners.task_list.done_at=Realizada em
runners.edit_runner=Editar Runner
runners.update_runner=Atualizar as Alterações
runners.update_runner=Salvar alterações
runners.update_runner_success=Runner atualizado com sucesso
runners.update_runner_failed=Falha ao atualizar runner
runners.delete_runner=Deletar esse runner
@ -3741,8 +3742,8 @@ match_tooltip = Inclui apenas os resultados que correspondem exatamente aos term
repo_kind = Buscar repositórios...
type_tooltip = Tipo de busca
code_search_by_git_grep = Os resultados atuais da pesquisa de código são fornecidos por "git grep". Pode haver melhores resultados se o administrador do site ativar o indexador de código.
branch_kind = Pesquisar branches…
commit_kind = Pesquisar commits…
branch_kind = Buscar ramos…
commit_kind = Buscar commits…
runner_kind = Pesquisar runners...
code_search_unavailable = A pesquisa de código não está disponível no momento. Entre em contato com o administrador do site.

View file

@ -464,6 +464,11 @@ change_unconfirmed_email_summary = Mudar o endereço de email para onde a mensag
tab_signin = Iniciar sessão
tab_signup = Criar conta
change_unconfirmed_email_error = Não foi possível mudar o endereço de email: %v
hint_login = Já tem uma conta? <a href="%s">Inicie a sessão agora!</a>
hint_register = Precisa de uma conta? <a href="%s">Faça uma inscrição agora.</a>
sign_up_button = Faça uma inscrição agora.
back_to_sign_in = Voltar ao iniciar a sessão
sign_in_openid = Prosseguir com OpenID
[mail]
view_it_on=Ver em %s
@ -480,7 +485,7 @@ activate_email=Valide o seu endereço de email
activate_email.title=%s, por favor valide o seu endereço de email
activate_email.text=Por favor clique na seguinte ligação para validar o seu endereço de email dentro de <b>%s</b>:
register_notify=Bem-vindo(a) ao Forgejo
register_notify=Bem-vindo(a) ao %s
register_notify.title=%[1]s, bem-vindo(a) a %[2]s
register_notify.text_1=este é o seu email de confirmação de registo para %s!
register_notify.text_2=Pode iniciar a sessão usando o seu nome de utilizador: %s
@ -1015,6 +1020,7 @@ update_hints_success = As sugestões foram modificadas.
blocked_users_none = Não há utilizadores bloqueados.
user_unblock_success = O utilizador foi desbloqueado com sucesso.
language.title = Idioma predefinido
keep_activity_private.description = O seu <a href="%s">trabalho público</a> apenas estará visível para si e para os administradores da instância.
[repo]
new_repo_helper=Um repositório contém todos os ficheiros do trabalho, incluindo o histórico das revisões. Já tem um hospedado noutro sítio? <a href="%s">Migre o repositório</a>.
@ -3452,6 +3458,12 @@ config.cache_test = Testar a cache
config.cache_test_slow = O teste da cache foi bem sucedido, mas a resposta é lenta: %s.
config.cache_test_succeeded = O teste da cache foi bem sucedido, o tempo de resposta foi de %s.
config.cache_test_failed = Falhou a sondagem da cache: %v.
users.block.description = Impedir que este utilizador interaja com este serviço através da sua conta e proibi-lo de iniciar sessão.
users.admin.description = Atribuir acesso total a este utilizador a todos os recursos administrativos disponíveis através da interface web e da API.
users.local_import.description = Permitir a importação de repositórios a partir do sistema de ficheiros local do servidor. Isto poderá ser um problema de segurança.
users.organization_creation.description = Permitir a criação de novas organizações.
users.activated.description = Finalização da verificação do email. O proprietário de uma conta não habilitada não poderá iniciar a sessão enquanto a verificação do email não estiver finalizada.
users.restricted.description = Permitir que este/a utilizador/a interaja apenas com os repositórios e as organizações onde tenha sido adicionado/a como colaborador/a. Isto impede o acesso a repositórios públicos nesta instância.
[action]
create_repo=criou o repositório <a href="%s">%s</a>
@ -3854,6 +3866,8 @@ exact = Fiel
exact_tooltip = Incluir somente os resultados que correspondam rigorosamente ao termo de pesquisa
issue_kind = Procurar questões...
pull_kind = Procurar puxadas...
union = Palavras-chave
union_tooltip = Incluir resultados correspondentes a qualquer das palavras-chave separadas por espaços em branco
[munits.data]
kib = KiB
@ -3867,4 +3881,7 @@ b = B
[markup]
filepreview.lines = Linhas %[1]d até %[2]d em %[3]s
filepreview.line = Linha %[1]d em %[2]s
filepreview.truncated = A previsão foi truncada
filepreview.truncated = A previsão foi truncada
[translation_meta]
test = ok

View file

@ -338,7 +338,7 @@ app_slogan_helper = Укажите лозунг вашего сервера, л
[home]
uname_holder=Логин или адрес эл. почты
password_holder=Пароль
switch_dashboard_context=Переключить контекст панели управления
switch_dashboard_context=Сменить просматриваемое пространство
my_repos=Репозитории
show_more_repos=Показать больше репозиториев…
collaborative_repos=Совместные репозитории
@ -397,7 +397,7 @@ disable_register_mail=Подтверждение регистрации по э
manual_activation_only=Обратитесь к администратору сайта для завершения активации.
remember_me=Запомнить это устройство
remember_me.compromised=Токен входа более не действителен, что может указывать на компрометацию учётной записи. Пожалуйста, проверьте свою учётную запись на необычные действия.
forgot_password_title=Восстановить пароль
forgot_password_title=Восстановление пароля
forgot_password=Забыли пароль?
sign_up_now=Нужна учётная запись? Зарегистрируйтесь.
sign_up_successful=Учётная запись успешно создана. Добро пожаловать!
@ -405,7 +405,7 @@ confirmation_mail_sent_prompt=Новое письмо для подтвержд
must_change_password=Обновите пароль
allow_password_change=Требовать смену пароля пользователем (рекомендуется)
reset_password_mail_sent_prompt=Письмо с подтверждением отправлено на <b>%s</b>. Пожалуйста, проверьте входящую почту в течение %s, чтобы завершить процесс восстановления учётной записи.
active_your_account=Активируйте свою учётную запись
active_your_account=Активация учётной записи
account_activated=Учётная запись активирована
prohibit_login=Вход запрещён
prohibit_login_desc=Вход в вашу учётную запись запрещен. Свяжитесь с администратором сайта.
@ -413,7 +413,7 @@ resent_limit_prompt=Недавно вы уже запрашивали письм
has_unconfirmed_mail=Здравствуйте, %s! У вас есть неподтвержденный адрес эл. почты (<b>%s</b>). Если вам не приходило письмо с подтверждением или нужно выслать новое письмо, нажмите на кнопку ниже.
resend_mail=Нажмите здесь, чтобы отправить письмо для активации ещё раз
email_not_associate=Этот адрес эл. почты не связан ни с одной учётной записью.
send_reset_mail=Отправить письмо для восстановления учётной записи
send_reset_mail=Отправить восстановление пароля
reset_password=Восстановление учётной записи
invalid_code=Код подтверждения недействителен или истёк.
invalid_code_forgot_password=Ваш код подтверждения недействителен или истек. Нажмите <a href="%s">здесь</a> для начала новой сессии.
@ -435,7 +435,7 @@ tab_openid=OpenID
oauth_signup_tab=Зарегистрировать новую учётную запись
oauth_signup_title=Завершение регистрации учётной записи
oauth_signup_submit=Завершить регистрацию
oauth_signin_tab=Ссылка на существующую учётную запись
oauth_signin_tab=Привязать существующую уч. запись
oauth_signin_title=Войдите, чтобы авторизовать связанную учётную запись
oauth_signin_submit=Привязать учётную запись
oauth.signin.error=Произошла ошибка при обработке запроса авторизации. Если эта ошибка повторяется, обратитесь к администратору сайта.
@ -464,6 +464,11 @@ change_unconfirmed_email_summary = Измените адрес эл. почты,
change_unconfirmed_email_error = Невозможно изменить адрес почты: %v
last_admin = Невозможно удалить единственного администратора. Всегда должен оставаться хотя бы один администратор.
change_unconfirmed_email = Если при регистрации был введён неправильный адрес, его можно изменить ниже, и письмо с подтверждением будет выслано на исправленный адрес.
hint_register = Нет учётной записи? <a href="%s">Зарегистрируйтесь.</a>
sign_up_button = Зарегистрироваться.
back_to_sign_in = Назад ко входу
sign_in_openid = Продолжить с OpenID
hint_login = Уже есть учётная запись? <a href="%s">Войдите!</a>
[mail]
view_it_on=Посмотреть на %s
@ -480,7 +485,7 @@ activate_email=Подтвердите свой адрес эл. почты
activate_email.title=%s, пожалуйста, подтвердите свой адрес эл. почты
activate_email.text=Для подтверждения эл. почты перейдите по следующей ссылке в течение <b>%s</b>:
register_notify=Добро пожаловать в Forgejo
register_notify=Добро пожаловать в %s
register_notify.title=%[1]s, добро пожаловать в %[2]s
register_notify.text_1=это письмо с вашим подтверждением регистрации в %s!
register_notify.text_2=Теперь вы можете войти в учётную запись, используя логин: %s
@ -1015,6 +1020,7 @@ pronouns_custom = Другие
pronouns = Местоимения
pronouns_unspecified = Не указаны
language.title = Язык по умолчанию
keep_activity_private.description = Ваша <a href="%s">публичная активность</a> будет видна только вам и администраторам сервера.
[repo]
owner=Владелец
@ -1566,8 +1572,8 @@ issues.reopened_at=`задача была открыта снова <a id="%[1]s
issues.commit_ref_at=`упоминание этой задачи в коммите <a id="%[1]s" href="#%[1]s">%[2]s</a>`
issues.ref_issue_from=`<a href="%[3]s">упоминание этой задачи %[4]s</a> <a id="%[1]s" href="#%[1]s">%[2]s</a>`
issues.ref_pull_from=`<a href="%[3]s">упоминание этого запроса слияния %[4]s</a> <a id="%[1]s" href="#%[1]s">%[2]s</a>`
issues.ref_closing_from=`<a href="%[3]s">упоминание запроса слияния %[4]s, закрывающего эту задачу</a> <a id="%[1]s" href="#%[1]s">%[2]s</a>`
issues.ref_reopening_from=`<a href="%[3]s">упоминание запроса слияния %[4]s, повторно открывающего эту задачу</a> <a id="%[1]s" href="#%[1]s">%[2]s</a>`
issues.ref_closing_from=`<a href="%[3]s">упоминание из запроса на слияние %[4]s, который закроет эту задачу</a> <a id="%[1]s" href="#%[1]s">%[2]s</a>`
issues.ref_reopening_from=`<a href="%[3]s">упоминание из запроса на слияние %[4]s, который повторно откроет эту задачу</a> <a id="%[1]s" href="#%[1]s">%[2]s</a>`
issues.ref_closed_from=`<a href="%[3]s">закрыл этот запрос %[4]s</a> <a id="%[1]s" href="#%[1]s">%[2]s</a>`
issues.ref_reopened_from=`<a href="%[3]s">задача была открыта снова %[4]s</a> <a id="%[1]s" href="#%[1]s">%[2]s</a>`
issues.ref_from=`из %[1]s`
@ -1869,7 +1875,7 @@ pulls.outdated_with_base_branch=Эта ветка отстает от базов
pulls.close=Закрыть запрос на слияние
pulls.closed_at=`закрыл этот запрос на слияние <a id="%[1]s" href="#%[1]s">%[2]s</a>`
pulls.reopened_at=`переоткрыл этот запрос на слияние <a id="%[1]s" href="#%[1]s">%[2]s</a>`
pulls.cmd_instruction_hint=`Показать инструкции для командной строки.`
pulls.cmd_instruction_hint=Показать инструкции для командной строки
pulls.cmd_instruction_merge_title=Слейте изменения
pulls.cmd_instruction_merge_desc=Слейте изменения и отправьте их обратно.
pulls.clear_merge_message=Очистить сообщение о слиянии
@ -2614,7 +2620,7 @@ topic.done=Сохранить
topic.count_prompt=Нельзя выбрать более 25 тем
topic.format_prompt=Темы должны начинаться с буквы или цифры и могут содержать дефисы («-») и точки («.»). Длина темы не должна превышать 35 символов. Все буквы должны быть строчными.
find_file.go_to_file=Перейти к файлу
find_file.go_to_file=Найти файл
find_file.no_matching=Совпадающих файлов не найдено
error.csv.too_large=Не удается отобразить этот файл, потому что он слишком большой.
@ -3076,7 +3082,7 @@ orgs.new_orga=Новая организация
repos.repo_manage_panel=Управление репозиториями
repos.unadopted=Непринятые репозитории
repos.unadopted.no_more=Больше непринятых репозиториев не найдено
repos.unadopted.no_more=Непринятые репозитории не найдены.
repos.owner=Владелец
repos.name=Название
repos.private=Частный
@ -3848,7 +3854,7 @@ recent_commits.what = недавние коммиты
[search]
search = Поиск...
fuzzy_tooltip = Включать результаты, достаточно похожие на запрос
fuzzy_tooltip = Включает результаты, достаточно похожие на запрос, даже при наличии неточностей
type_tooltip = Тип поиска
fuzzy = Приблизительный
match = Точный
@ -3868,12 +3874,17 @@ code_search_unavailable = Поиск по коду сейчас недоступ
runner_kind = Поиск исполнителей...
code_search_by_git_grep = Эти результаты получены через «git grep». Результатов может быть больше, если администратор сервера включит индексатор кода.
exact = Точный
exact_tooltip = Включать только результаты, точно соответствующие запросу
exact_tooltip = Включает только результаты, в точности соответствующие запросу
issue_kind = Поиск задач...
pull_kind = Поиск слияний...
union_tooltip = Включает результаты с совпавшими ключевыми словами, разделёнными пробелами
union = Обычный
[markup]
filepreview.line = Строка %[1]d в %[2]s
filepreview.lines = Строки с %[1]d по %[2]d в %[3]s
filepreview.truncated = Предпросмотр был обрезан
filepreview.truncated = Предпросмотр был обрезан
[translation_meta]
test = хи-хи

View file

@ -425,7 +425,7 @@ activate_account.text_2=Pre aktiváciu vašeho účtu kliknite, prosím, na nasl
activate_email=Overte svoju e-mailovú adresu
activate_email.text=Pre overenie vašej e-mailovej adresy kliknite, prosím, na nasledovný odkaz do <b>%s</b>:
register_notify=Vitajte v Forgejo
register_notify=Vitajte v %s
register_notify.title=%[1]s, vitajte v %[2]s
register_notify.text_1=toto je e-mail potvrdzujúci vašu registráciu pre %s!
register_notify.text_2=Teraz sa môžete prihlásiť s používateľským menom: %s.

View file

@ -537,7 +537,7 @@ activate_account.text_1 = Pozdravljeni <b>%[1]s</b>, hvala za registracijo na %[
admin.new_user.subject = Prijavil se je nov uporabnik %s
admin.new_user.user_info = Informacije o uporabniku
admin.new_user.text = Prosimo, da <a href="%s">klikni tukaj</a> za upravljanje tega uporabnika iz upraviteljske plošče.
register_notify = Dobrodošli v Forgejo
register_notify = Dobrodošli v %s
register_notify.title = %[1]s, dobrodošli v %[2]s
register_notify.text_2 = V svoj račun se lahko prijavite z uporabniškim imenom: %s
register_notify.text_3 = Če je ta račun namesto vas ustvaril nekdo drug, boste morali najprej <a href="%s">nastaviti svoje geslo</a>.

View file

@ -305,7 +305,7 @@ activate_account=Vänligen aktivera ditt konto
activate_email=Verifiera din epostaddress
register_notify=Välkommen till Forgejo
register_notify=Välkommen till %s
reset_password=Återställ ditt konto

View file

@ -454,7 +454,7 @@ activate_email=E-posta adresinizi doğrulayın
activate_email.title=%s, lütfen e-posta adresinizi doğrulayın
activate_email.text=E posta adresinizi doğrulamak için lütfen <b>%s</b> içinde linke tıklayın:
register_notify=Forgejo'ya Hoş Geldiniz
register_notify=%s'ya Hoş Geldiniz
register_notify.title=%[1]s, %[2]s e hoşgeldiniz
register_notify.text_1=bu %s için kayıt onay e postanızdır!
register_notify.text_2=Artık %s kullanıcı adı ile oturum açabilirsiniz.

View file

@ -390,7 +390,7 @@ activate_account.text_2=Перейдіть за цим посиланням, щ
activate_email=Підтвердить вашу адресу електронної пошти
activate_email.text=Перейдіть за цим посиланням, щоб підтвердити вашу електронну адресу в <b>%s</b>:
register_notify=Ласкаво просимо у Forgejo
register_notify=Ласкаво просимо у %s
register_notify.title=%[1]s, ласкаво просимо до %[2]s
register_notify.text_1=це ваша е-пошта для підтвердження реєстрації для %s!
register_notify.text_2=Тепер ви можете увійти як: %s.

View file

@ -0,0 +1 @@

View file

@ -480,7 +480,7 @@ activate_email=请验证您的邮箱地址
activate_email.title=%s请验证您的邮箱
activate_email.text=请在 <b>%s</b> 时间内,点击以下链接,以验证你的电子邮件地址:
register_notify=欢迎来到 Forgejo
register_notify=欢迎来到 %s
register_notify.title=%[1]s欢迎来到 %[2]s
register_notify.text_1=这是您的 %s 注册确认电子邮件
register_notify.text_2=您现在可以以用户名 %s 登录

View file

@ -172,7 +172,7 @@ activate_account=請啟用您的帳戶
activate_email=請驗證您的郵箱地址
register_notify=歡迎來到 Forgejo
register_notify=歡迎來到 %s
register_success=註冊成功

View file

@ -473,7 +473,7 @@ activate_account.text_2=請在<b>%s</b>內點擊下列連結以啟用您的帳
activate_email=請驗證您的電子信箱
activate_email.text=請在<b>%s</b>內點擊下列連結以驗證您的電子信箱:
register_notify=歡迎來到 Forgejo
register_notify=歡迎來到 %s
register_notify.title=%[1]s歡迎來到 %[2]s
register_notify.text_1=這是您在 %s 的註冊確認信!
register_notify.text_2=您現在可以使用您的使用者名稱登入:%s

551
package-lock.json generated
View file

@ -7,14 +7,12 @@
"dependencies": {
"@citation-js/core": "0.7.11",
"@citation-js/plugin-bibtex": "0.7.11",
"@citation-js/plugin-csl": "0.7.11",
"@citation-js/plugin-software-formats": "0.6.1",
"@github/markdown-toolbar-element": "2.2.3",
"@github/relative-time-element": "4.4.2",
"@github/text-expander-element": "2.7.1",
"@mcaptcha/vanilla-glue": "0.1.0-alpha-3",
"@primer/octicons": "19.9.0",
"add-asset-webpack-plugin": "2.0.1",
"ansi_up": "6.0.2",
"asciinema-player": "3.8.0",
"chart.js": "4.4.2",
@ -22,17 +20,16 @@
"chartjs-plugin-zoom": "2.0.1",
"clippie": "4.1.1",
"css-loader": "7.0.0",
"dayjs": "1.11.11",
"dayjs": "1.11.12",
"dropzone": "6.0.0-beta.2",
"easymde": "2.18.0",
"esbuild-loader": "4.2.0",
"esbuild-loader": "4.2.2",
"escape-goat": "4.0.0",
"fast-glob": "3.3.2",
"htmx.org": "1.9.12",
"idiomorph": "0.3.0",
"jquery": "3.7.1",
"katex": "0.16.11",
"license-checker-webpack-plugin": "0.2.1",
"mermaid": "10.9.1",
"mini-css-extract-plugin": "2.9.0",
"minimatch": "9.0.5",
@ -45,7 +42,7 @@
"pretty-ms": "9.0.0",
"sortablejs": "1.15.2",
"swagger-ui-dist": "5.17.14",
"tailwindcss": "3.4.4",
"tailwindcss": "3.4.6",
"temporal-polyfill": "0.2.4",
"throttle-debounce": "5.0.0",
"tinycolor2": "1.6.0",
@ -54,8 +51,7 @@
"tributejs": "5.1.3",
"uint8-to-base64": "0.2.0",
"vanilla-colorful": "0.7.2",
"vue": "3.4.31",
"vue-bar-graph": "2.0.0",
"vue": "3.4.33",
"vue-chartjs": "5.3.1",
"vue-loader": "17.4.2",
"vue3-calendar-heatmap": "2.0.5",
@ -65,7 +61,7 @@
},
"devDependencies": {
"@eslint-community/eslint-plugin-eslint-comments": "4.3.0",
"@playwright/test": "1.45.1",
"@playwright/test": "1.45.2",
"@stoplight/spectral-cli": "6.11.1",
"@stylistic/eslint-plugin-js": "1.8.1",
"@stylistic/stylelint-plugin": "2.1.2",
@ -88,6 +84,7 @@
"eslint-plugin-vue-scoped-css": "2.8.1",
"eslint-plugin-wc": "2.1.0",
"happy-dom": "14.12.3",
"license-checker-rseidelsohn": "4.3.0",
"markdownlint-cli": "0.41.0",
"postcss-html": "1.7.0",
"stylelint": "16.7.0",
@ -377,22 +374,6 @@
"node": ">=14.0.0"
}
},
"node_modules/@citation-js/plugin-csl": {
"version": "0.7.11",
"resolved": "https://registry.npmjs.org/@citation-js/plugin-csl/-/plugin-csl-0.7.11.tgz",
"integrity": "sha512-4OGZ9wHZDfpgiPU2cOXWGuKt7P+ndGWAeLG95nOG+DXe5U+f9EEZTXfaM4C99x8Ri+g6JklR96A3kuYZxYLllg==",
"license": "MIT",
"dependencies": {
"@citation-js/date": "^0.5.0",
"citeproc": "^2.4.6"
},
"engines": {
"node": ">=16.0.0"
},
"peerDependencies": {
"@citation-js/core": "^0.7.0"
}
},
"node_modules/@citation-js/plugin-github": {
"version": "0.6.1",
"resolved": "https://registry.npmjs.org/@citation-js/plugin-github/-/plugin-github-0.6.1.tgz",
@ -1470,6 +1451,19 @@
"node": ">= 8"
}
},
"node_modules/@npmcli/fs": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/@npmcli/fs/-/fs-3.1.1.tgz",
"integrity": "sha512-q9CRWjpHCMIh5sVyefoD1cA7PkvILqCZsnSOEUUivORLjxCO/Irmue2DprETiNgEqktDBZaM1Bi+jrarx1XdCg==",
"dev": true,
"license": "ISC",
"dependencies": {
"semver": "^7.3.5"
},
"engines": {
"node": "^14.17.0 || ^16.13.0 || >=18.0.0"
}
},
"node_modules/@one-ini/wasm": {
"version": "0.1.1",
"resolved": "https://registry.npmjs.org/@one-ini/wasm/-/wasm-0.1.1.tgz",
@ -1501,13 +1495,13 @@
}
},
"node_modules/@playwright/test": {
"version": "1.45.1",
"resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.45.1.tgz",
"integrity": "sha512-Wo1bWTzQvGA7LyKGIZc8nFSTFf2TkthGIFBR+QVNilvwouGzFd4PYukZe3rvf5PSqjHi1+1NyKSDZKcQWETzaA==",
"version": "1.45.2",
"resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.45.2.tgz",
"integrity": "sha512-JxG9eq92ET75EbVi3s+4sYbcG7q72ECeZNbdBlaMkGcNbiDQ4cAi8U2QP5oKkOx+1gpaiL1LDStmzCaEM1Z6fQ==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
"playwright": "1.45.1"
"playwright": "1.45.2"
},
"bin": {
"playwright": "cli.js"
@ -2939,42 +2933,42 @@
}
},
"node_modules/@vue/compiler-core": {
"version": "3.4.31",
"resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.4.31.tgz",
"integrity": "sha512-skOiodXWTV3DxfDhB4rOf3OGalpITLlgCeOwb+Y9GJpfQ8ErigdBUHomBzvG78JoVE8MJoQsb+qhZiHfKeNeEg==",
"version": "3.4.33",
"resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.4.33.tgz",
"integrity": "sha512-MoIREbkdPQlnGfSKDMgzTqzqx5nmEjIc0ydLVYlTACGBsfvOJ4tHSbZXKVF536n6fB+0eZaGEOqsGThPpdvF5A==",
"license": "MIT",
"dependencies": {
"@babel/parser": "^7.24.7",
"@vue/shared": "3.4.31",
"@vue/shared": "3.4.33",
"entities": "^4.5.0",
"estree-walker": "^2.0.2",
"source-map-js": "^1.2.0"
}
},
"node_modules/@vue/compiler-dom": {
"version": "3.4.31",
"resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.4.31.tgz",
"integrity": "sha512-wK424WMXsG1IGMyDGyLqB+TbmEBFM78hIsOJ9QwUVLGrcSk0ak6zYty7Pj8ftm7nEtdU/DGQxAXp0/lM/2cEpQ==",
"version": "3.4.33",
"resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.4.33.tgz",
"integrity": "sha512-GzB8fxEHKw0gGet5BKlpfXEqoBnzSVWwMnT+dc25wE7pFEfrU/QsvjZMP9rD4iVXHBBoemTct8mN0GJEI6ZX5A==",
"license": "MIT",
"dependencies": {
"@vue/compiler-core": "3.4.31",
"@vue/shared": "3.4.31"
"@vue/compiler-core": "3.4.33",
"@vue/shared": "3.4.33"
}
},
"node_modules/@vue/compiler-sfc": {
"version": "3.4.31",
"resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.4.31.tgz",
"integrity": "sha512-einJxqEw8IIJxzmnxmJBuK2usI+lJonl53foq+9etB2HAzlPjAS/wa7r0uUpXw5ByX3/0uswVSrjNb17vJm1kQ==",
"version": "3.4.33",
"resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.4.33.tgz",
"integrity": "sha512-7rk7Vbkn21xMwIUpHQR4hCVejwE6nvhBOiDgoBcR03qvGqRKA7dCBSsHZhwhYUsmjlbJ7OtD5UFIyhP6BY+c8A==",
"license": "MIT",
"dependencies": {
"@babel/parser": "^7.24.7",
"@vue/compiler-core": "3.4.31",
"@vue/compiler-dom": "3.4.31",
"@vue/compiler-ssr": "3.4.31",
"@vue/shared": "3.4.31",
"@vue/compiler-core": "3.4.33",
"@vue/compiler-dom": "3.4.33",
"@vue/compiler-ssr": "3.4.33",
"@vue/shared": "3.4.33",
"estree-walker": "^2.0.2",
"magic-string": "^0.30.10",
"postcss": "^8.4.38",
"postcss": "^8.4.39",
"source-map-js": "^1.2.0"
}
},
@ -2987,64 +2981,92 @@
"@jridgewell/sourcemap-codec": "^1.4.15"
}
},
"node_modules/@vue/compiler-ssr": {
"version": "3.4.31",
"resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.4.31.tgz",
"integrity": "sha512-RtefmITAje3fJ8FSg1gwgDhdKhZVntIVbwupdyZDSifZTRMiWxWehAOTCc8/KZDnBOcYQ4/9VWxsTbd3wT0hAA==",
"node_modules/@vue/compiler-sfc/node_modules/postcss": {
"version": "8.4.39",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.39.tgz",
"integrity": "sha512-0vzE+lAiG7hZl1/9I8yzKLx3aR9Xbof3fBHKunvMfOCYAtMhrsnccJY2iTURb9EZd5+pLuiNV9/c/GZJOHsgIw==",
"funding": [
{
"type": "opencollective",
"url": "https://opencollective.com/postcss/"
},
{
"type": "tidelift",
"url": "https://tidelift.com/funding/github/npm/postcss"
},
{
"type": "github",
"url": "https://github.com/sponsors/ai"
}
],
"license": "MIT",
"dependencies": {
"@vue/compiler-dom": "3.4.31",
"@vue/shared": "3.4.31"
"nanoid": "^3.3.7",
"picocolors": "^1.0.1",
"source-map-js": "^1.2.0"
},
"engines": {
"node": "^10 || ^12 || >=14"
}
},
"node_modules/@vue/compiler-ssr": {
"version": "3.4.33",
"resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.4.33.tgz",
"integrity": "sha512-0WveC9Ai+eT/1b6LCV5IfsufBZ0HP7pSSTdDjcuW302tTEgoBw8rHVHKPbGUtzGReUFCRXbv6zQDDgucnV2WzQ==",
"license": "MIT",
"dependencies": {
"@vue/compiler-dom": "3.4.33",
"@vue/shared": "3.4.33"
}
},
"node_modules/@vue/reactivity": {
"version": "3.4.31",
"resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.4.31.tgz",
"integrity": "sha512-VGkTani8SOoVkZNds1PfJ/T1SlAIOf8E58PGAhIOUDYPC4GAmFA2u/E14TDAFcf3vVDKunc4QqCe/SHr8xC65Q==",
"version": "3.4.33",
"resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.4.33.tgz",
"integrity": "sha512-B24QIelahDbyHipBgbUItQblbd4w5HpG3KccL+YkGyo3maXyS253FzcTR3pSz739OTphmzlxP7JxEMWBpewilA==",
"license": "MIT",
"dependencies": {
"@vue/shared": "3.4.31"
"@vue/shared": "3.4.33"
}
},
"node_modules/@vue/runtime-core": {
"version": "3.4.31",
"resolved": "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.4.31.tgz",
"integrity": "sha512-LDkztxeUPazxG/p8c5JDDKPfkCDBkkiNLVNf7XZIUnJ+66GVGkP+TIh34+8LtPisZ+HMWl2zqhIw0xN5MwU1cw==",
"version": "3.4.33",
"resolved": "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.4.33.tgz",
"integrity": "sha512-6wavthExzT4iAxpe8q37/rDmf44nyOJGISJPxCi9YsQO+8w9v0gLCFLfH5TzD1V1AYrTAdiF4Y1cgUmP68jP6w==",
"license": "MIT",
"dependencies": {
"@vue/reactivity": "3.4.31",
"@vue/shared": "3.4.31"
"@vue/reactivity": "3.4.33",
"@vue/shared": "3.4.33"
}
},
"node_modules/@vue/runtime-dom": {
"version": "3.4.31",
"resolved": "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.4.31.tgz",
"integrity": "sha512-2Auws3mB7+lHhTFCg8E9ZWopA6Q6L455EcU7bzcQ4x6Dn4cCPuqj6S2oBZgN2a8vJRS/LSYYxwFFq2Hlx3Fsaw==",
"version": "3.4.33",
"resolved": "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.4.33.tgz",
"integrity": "sha512-iHsMCUSFJ+4z432Bn9kZzHX+zOXa6+iw36DaVRmKYZpPt9jW9riF32SxNwB124i61kp9+AZtheQ/mKoJLerAaQ==",
"license": "MIT",
"dependencies": {
"@vue/reactivity": "3.4.31",
"@vue/runtime-core": "3.4.31",
"@vue/shared": "3.4.31",
"@vue/reactivity": "3.4.33",
"@vue/runtime-core": "3.4.33",
"@vue/shared": "3.4.33",
"csstype": "^3.1.3"
}
},
"node_modules/@vue/server-renderer": {
"version": "3.4.31",
"resolved": "https://registry.npmjs.org/@vue/server-renderer/-/server-renderer-3.4.31.tgz",
"integrity": "sha512-D5BLbdvrlR9PE3by9GaUp1gQXlCNadIZytMIb8H2h3FMWJd4oUfkUTEH2wAr3qxoRz25uxbTcbqd3WKlm9EHQA==",
"version": "3.4.33",
"resolved": "https://registry.npmjs.org/@vue/server-renderer/-/server-renderer-3.4.33.tgz",
"integrity": "sha512-jTH0d6gQcaYideFP/k0WdEu8PpRS9MF8d0b6SfZzNi+ap972pZ0TNIeTaESwdOtdY0XPVj54XEJ6K0wXxir4fw==",
"license": "MIT",
"dependencies": {
"@vue/compiler-ssr": "3.4.31",
"@vue/shared": "3.4.31"
"@vue/compiler-ssr": "3.4.33",
"@vue/shared": "3.4.33"
},
"peerDependencies": {
"vue": "3.4.31"
"vue": "3.4.33"
}
},
"node_modules/@vue/shared": {
"version": "3.4.31",
"resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.4.31.tgz",
"integrity": "sha512-Yp3wtJk//8cO4NItOPpi3QkLExAr/aLBGZMmTtW9WpdwBCJpRM6zj9WgWktXAl8IDIozwNMByT45JP3tO3ACWA==",
"version": "3.4.33",
"resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.4.33.tgz",
"integrity": "sha512-aoRY0jQk3A/cuvdkodTrM4NMfxco8n55eG4H7ML/CRy7OryHfiqvug4xrCBBMbbN+dvXAetDDwZW9DXWWjBntA==",
"license": "MIT"
},
"node_modules/@vue/test-utils": {
@ -3327,21 +3349,6 @@
"node": ">=0.4.0"
}
},
"node_modules/add-asset-webpack-plugin": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/add-asset-webpack-plugin/-/add-asset-webpack-plugin-2.0.1.tgz",
"integrity": "sha512-Hx9EKnirCUfdh684y1yhx8QOFolpkIG2VRHHgNm8wFy1Cf7P3RGwS678hoN7Y1XvZRPpVXWa+6QnfL/2i0CMCA==",
"license": "MIT",
"engines": {
"node": ">=10.13.0"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
},
"peerDependencies": {
"webpack": ">=5"
}
},
"node_modules/ajv": {
"version": "8.17.1",
"resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz",
@ -3507,6 +3514,7 @@
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/array-find-index/-/array-find-index-1.0.2.tgz",
"integrity": "sha512-M1HQyIXcBGtVywBt8WVdim+lrNaK7VHp99Qt5pSNziXznKHViIBbXWtfRTpEFpF/c4FdfxNAsCCwPp5phBYJtw==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=0.10.0"
@ -4125,12 +4133,6 @@
"node": ">=8"
}
},
"node_modules/citeproc": {
"version": "2.4.63",
"resolved": "https://registry.npmjs.org/citeproc/-/citeproc-2.4.63.tgz",
"integrity": "sha512-68F95Bp4UbgZU/DBUGQn0qV3HDZLCdI9+Bb2ByrTaNJDL5VEm9LqaiNaxljsvoaExSLEXe1/r6n2Z06SCzW3/Q==",
"license": "CPAL-1.0 OR AGPL-1.0"
},
"node_modules/clean-regexp": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/clean-regexp/-/clean-regexp-1.0.0.tgz",
@ -4292,6 +4294,7 @@
"version": "0.0.1",
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
"integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==",
"dev": true,
"license": "MIT"
},
"node_modules/confbox": {
@ -5074,9 +5077,9 @@
}
},
"node_modules/dayjs": {
"version": "1.11.11",
"resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.11.tgz",
"integrity": "sha512-okzr3f11N6WuqYtZSvm+F776mB41wRZMhKP+hc34YdW+KmtYYK9iqvHSwo2k9FEH3fhGXvOPV6yz2IcSrfRUDg==",
"version": "1.11.12",
"resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.12.tgz",
"integrity": "sha512-Rt2g+nTbLlDWZTwwrIXjy9MeiZmSDI375FvZs72ngxx8PDC6YXOeR3q5LAuPzjZQxhiWdRKac7RKV+YyQYfYIg==",
"license": "MIT"
},
"node_modules/debug": {
@ -5778,9 +5781,9 @@
}
},
"node_modules/esbuild-loader": {
"version": "4.2.0",
"resolved": "https://registry.npmjs.org/esbuild-loader/-/esbuild-loader-4.2.0.tgz",
"integrity": "sha512-BhwHchuDknxIa69AqOPeZh2fIFqj2AzZKC1E3RBRvXSuyk5drsqMrwsgYZJufX41yrauLYjDM3KBmruoGl1NWQ==",
"version": "4.2.2",
"resolved": "https://registry.npmjs.org/esbuild-loader/-/esbuild-loader-4.2.2.tgz",
"integrity": "sha512-Mdq/A1L8p37hkibp8jGFwuQTDSWhDmlueAefsrCPRwNWThEOlQmIglV7Gd6GE2mO5bt7ksfxKOMwkuY7jjVTXg==",
"license": "MIT",
"dependencies": {
"esbuild": "^0.21.0",
@ -6935,6 +6938,7 @@
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
"integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==",
"dev": true,
"license": "ISC"
},
"node_modules/fsevents": {
@ -7123,6 +7127,7 @@
"resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz",
"integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==",
"deprecated": "Glob versions prior to v9 are no longer supported",
"dev": true,
"license": "ISC",
"dependencies": {
"fs.realpath": "^1.0.0",
@ -7161,6 +7166,7 @@
"version": "1.1.11",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
"integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
"dev": true,
"license": "MIT",
"dependencies": {
"balanced-match": "^1.0.0",
@ -7171,6 +7177,7 @@
"version": "3.1.2",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
"integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
"dev": true,
"license": "ISC",
"dependencies": {
"brace-expansion": "^1.1.7"
@ -7307,12 +7314,6 @@
"dev": true,
"license": "MIT"
},
"node_modules/gsap": {
"version": "3.12.5",
"resolved": "https://registry.npmjs.org/gsap/-/gsap-3.12.5.tgz",
"integrity": "sha512-srBfnk4n+Oe/ZnMIOXt3gT605BX9x5+rh/prT2F1SsNJsU1XuMiP0E2aptW481OnonOGACZWBqseH5Z7csHxhQ==",
"license": "Standard 'no charge' license: https://gsap.com/standard-license. Club GSAP members get more: https://gsap.com/licensing/. Why GreenSock doesn't employ an MIT license: https://gsap.com/why-license/"
},
"node_modules/hammerjs": {
"version": "2.0.8",
"resolved": "https://registry.npmjs.org/hammerjs/-/hammerjs-2.0.8.tgz",
@ -7633,6 +7634,7 @@
"resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
"integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==",
"deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.",
"dev": true,
"license": "ISC",
"dependencies": {
"once": "^1.3.0",
@ -7643,6 +7645,7 @@
"version": "2.0.4",
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
"integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
"dev": true,
"license": "ISC"
},
"node_modules/ini": {
@ -8692,69 +8695,44 @@
"node": ">= 0.8.0"
}
},
"node_modules/license-checker-webpack-plugin": {
"version": "0.2.1",
"resolved": "https://registry.npmjs.org/license-checker-webpack-plugin/-/license-checker-webpack-plugin-0.2.1.tgz",
"integrity": "sha512-rX8B+mH6fk1vxbnIu/UztqTEonQw95xwOkoRjX3TSrRZA/pbG9CWa3wnSo89KY/ej379JQoq050fsuthy6AU+A==",
"license": "MIT",
"node_modules/license-checker-rseidelsohn": {
"version": "4.3.0",
"resolved": "https://registry.npmjs.org/license-checker-rseidelsohn/-/license-checker-rseidelsohn-4.3.0.tgz",
"integrity": "sha512-A2LQ+3kUIG1hCJ/hh4WUvPsyhooT7o5mFhNyTean0cqH3rZeB1ZUCthxlcdgWESSqx+3DLC6J/8ghbiWRYKdUA==",
"dev": true,
"license": "BSD-3-Clause",
"dependencies": {
"glob": "^7.1.6",
"lodash.template": "^4.5.0",
"minimatch": "^3.0.4",
"semver": "^6.3.0",
"spdx-expression-validate": "^2.0.0",
"spdx-satisfies": "^5.0.0",
"superstruct": "^0.10.12",
"webpack-sources": "^1.4.3",
"wrap-ansi": "^6.1.0"
"chalk": "4.1.2",
"debug": "^4.3.4",
"lodash.clonedeep": "^4.5.0",
"mkdirp": "^1.0.4",
"nopt": "^7.2.0",
"read-installed-packages": "^2.0.1",
"semver": "^7.3.5",
"spdx-correct": "^3.1.1",
"spdx-expression-parse": "^3.0.1",
"spdx-satisfies": "^5.0.1",
"treeify": "^1.1.0"
},
"peerDependencies": {
"webpack": "^4.4.0 || ^5.4.0"
}
},
"node_modules/license-checker-webpack-plugin/node_modules/brace-expansion": {
"version": "1.1.11",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
"integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
"license": "MIT",
"dependencies": {
"balanced-match": "^1.0.0",
"concat-map": "0.0.1"
}
},
"node_modules/license-checker-webpack-plugin/node_modules/minimatch": {
"version": "3.1.2",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
"integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
"license": "ISC",
"dependencies": {
"brace-expansion": "^1.1.7"
},
"engines": {
"node": "*"
}
},
"node_modules/license-checker-webpack-plugin/node_modules/semver": {
"version": "6.3.1",
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
"integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
"license": "ISC",
"bin": {
"semver": "bin/semver.js"
}
},
"node_modules/license-checker-webpack-plugin/node_modules/wrap-ansi": {
"version": "6.2.0",
"resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz",
"integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==",
"license": "MIT",
"dependencies": {
"ansi-styles": "^4.0.0",
"string-width": "^4.1.0",
"strip-ansi": "^6.0.0"
"license-checker-rseidelsohn": "bin/license-checker-rseidelsohn"
},
"engines": {
"node": ">=8"
"node": ">=18",
"npm": ">=8"
}
},
"node_modules/license-checker-rseidelsohn/node_modules/mkdirp": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz",
"integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==",
"dev": true,
"license": "MIT",
"bin": {
"mkdirp": "bin/cmd.js"
},
"engines": {
"node": ">=10"
}
},
"node_modules/lilconfig": {
@ -8851,12 +8829,6 @@
"integrity": "sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==",
"license": "MIT"
},
"node_modules/lodash._reinterpolate": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz",
"integrity": "sha512-xYHt68QRoYGjeeM/XOE1uJtvXQAgvszfBhjV4yvsQH0u2i9I6cI6c6/eG4Hh3UAOVn0y/xAXwmTzEay49Q//HA==",
"license": "MIT"
},
"node_modules/lodash.camelcase": {
"version": "4.3.0",
"resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz",
@ -8864,6 +8836,13 @@
"dev": true,
"license": "MIT"
},
"node_modules/lodash.clonedeep": {
"version": "4.5.0",
"resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz",
"integrity": "sha512-H5ZhCF25riFd9uB5UCkVKo61m3S/xZk1x4wA6yp/L3RFP6Z/eHH1ymQcGLo7J3GMPfm0V/7m1tryHuGVxpqEBQ==",
"dev": true,
"license": "MIT"
},
"node_modules/lodash.kebabcase": {
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/lodash.kebabcase/-/lodash.kebabcase-4.1.1.tgz",
@ -8892,25 +8871,6 @@
"dev": true,
"license": "MIT"
},
"node_modules/lodash.template": {
"version": "4.5.0",
"resolved": "https://registry.npmjs.org/lodash.template/-/lodash.template-4.5.0.tgz",
"integrity": "sha512-84vYFxIkmidUiFxidA/KjjH9pAycqW+h980j7Fuz5qxRtO9pgB7MDFTdys1N7A5mcucRiDyEq4fusljItR1T/A==",
"license": "MIT",
"dependencies": {
"lodash._reinterpolate": "^3.0.0",
"lodash.templatesettings": "^4.0.0"
}
},
"node_modules/lodash.templatesettings": {
"version": "4.2.0",
"resolved": "https://registry.npmjs.org/lodash.templatesettings/-/lodash.templatesettings-4.2.0.tgz",
"integrity": "sha512-stgLz+i3Aa9mZgnjr/O+v9ruKZsPsndy7qPZOchbqk2cnTU1ZaldKK+v7m54WoKIyxiuMZTKT2H81F8BeAc3ZQ==",
"license": "MIT",
"dependencies": {
"lodash._reinterpolate": "^3.0.0"
}
},
"node_modules/lodash.topath": {
"version": "4.5.2",
"resolved": "https://registry.npmjs.org/lodash.topath/-/lodash.topath-4.5.2.tgz",
@ -10196,6 +10156,7 @@
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
"integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==",
"dev": true,
"license": "ISC",
"dependencies": {
"wrappy": "1"
@ -10337,6 +10298,7 @@
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
"integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=0.10.0"
@ -10519,13 +10481,13 @@
}
},
"node_modules/playwright": {
"version": "1.45.1",
"resolved": "https://registry.npmjs.org/playwright/-/playwright-1.45.1.tgz",
"integrity": "sha512-Hjrgae4kpSQBr98nhCj3IScxVeVUixqj+5oyif8TdIn2opTCPEzqAqNMeK42i3cWDCVu9MI+ZsGWw+gVR4ISBg==",
"version": "1.45.2",
"resolved": "https://registry.npmjs.org/playwright/-/playwright-1.45.2.tgz",
"integrity": "sha512-ReywF2t/0teRvNBpfIgh5e4wnrI/8Su8ssdo5XsQKpjxJj+jspm00jSoz9BTg91TT0c9HRjXO7LBNVrgYj9X0g==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
"playwright-core": "1.45.1"
"playwright-core": "1.45.2"
},
"bin": {
"playwright": "cli.js"
@ -10538,9 +10500,9 @@
}
},
"node_modules/playwright-core": {
"version": "1.45.1",
"resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.45.1.tgz",
"integrity": "sha512-LF4CUUtrUu2TCpDw4mcrAIuYrEjVDfT1cHbJMfwnE2+1b8PZcFzPNgvZCvq2JfQ4aTjRCCHw5EJ2tmr2NSzdPg==",
"version": "1.45.2",
"resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.45.2.tgz",
"integrity": "sha512-ha175tAWb0dTK0X4orvBIqi3jGEt701SMxMhyujxNrgd8K0Uy5wMSwwcQHtyB4om7INUkfndx02XnQ2p6dvLDw==",
"dev": true,
"license": "Apache-2.0",
"bin": {
@ -11103,6 +11065,123 @@
"pify": "^2.3.0"
}
},
"node_modules/read-installed-packages": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/read-installed-packages/-/read-installed-packages-2.0.1.tgz",
"integrity": "sha512-t+fJOFOYaZIjBpTVxiV8Mkt7yQyy4E6MSrrnt5FmPd4enYvpU/9DYGirDmN1XQwkfeuWIhM/iu0t2rm6iSr0CA==",
"dev": true,
"license": "ISC",
"dependencies": {
"@npmcli/fs": "^3.1.0",
"debug": "^4.3.4",
"read-package-json": "^6.0.0",
"semver": "2 || 3 || 4 || 5 || 6 || 7",
"slide": "~1.1.3"
},
"engines": {
"node": "^14.17.0 || ^16.13.0 || >=18.0.0"
},
"optionalDependencies": {
"graceful-fs": "^4.1.2"
}
},
"node_modules/read-installed-packages/node_modules/glob": {
"version": "10.4.5",
"resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz",
"integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==",
"dev": true,
"license": "ISC",
"dependencies": {
"foreground-child": "^3.1.0",
"jackspeak": "^3.1.2",
"minimatch": "^9.0.4",
"minipass": "^7.1.2",
"package-json-from-dist": "^1.0.0",
"path-scurry": "^1.11.1"
},
"bin": {
"glob": "dist/esm/bin.mjs"
},
"funding": {
"url": "https://github.com/sponsors/isaacs"
}
},
"node_modules/read-installed-packages/node_modules/hosted-git-info": {
"version": "6.1.1",
"resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-6.1.1.tgz",
"integrity": "sha512-r0EI+HBMcXadMrugk0GCQ+6BQV39PiWAZVfq7oIckeGiN7sjRGyQxPdft3nQekFTCQbYxLBH+/axZMeH8UX6+w==",
"dev": true,
"license": "ISC",
"dependencies": {
"lru-cache": "^7.5.1"
},
"engines": {
"node": "^14.17.0 || ^16.13.0 || >=18.0.0"
}
},
"node_modules/read-installed-packages/node_modules/json-parse-even-better-errors": {
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-3.0.2.tgz",
"integrity": "sha512-fi0NG4bPjCHunUJffmLd0gxssIgkNmArMvis4iNah6Owg1MCJjWhEcDLmsK6iGkJq3tHwbDkTlce70/tmXN4cQ==",
"dev": true,
"license": "MIT",
"engines": {
"node": "^14.17.0 || ^16.13.0 || >=18.0.0"
}
},
"node_modules/read-installed-packages/node_modules/lru-cache": {
"version": "7.18.3",
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz",
"integrity": "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==",
"dev": true,
"license": "ISC",
"engines": {
"node": ">=12"
}
},
"node_modules/read-installed-packages/node_modules/normalize-package-data": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-5.0.0.tgz",
"integrity": "sha512-h9iPVIfrVZ9wVYQnxFgtw1ugSvGEMOlyPWWtm8BMJhnwyEL/FLbYbTY3V3PpjI/BUK67n9PEWDu6eHzu1fB15Q==",
"dev": true,
"license": "BSD-2-Clause",
"dependencies": {
"hosted-git-info": "^6.0.0",
"is-core-module": "^2.8.1",
"semver": "^7.3.5",
"validate-npm-package-license": "^3.0.4"
},
"engines": {
"node": "^14.17.0 || ^16.13.0 || >=18.0.0"
}
},
"node_modules/read-installed-packages/node_modules/npm-normalize-package-bin": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/npm-normalize-package-bin/-/npm-normalize-package-bin-3.0.1.tgz",
"integrity": "sha512-dMxCf+zZ+3zeQZXKxmyuCKlIDPGuv8EF940xbkC4kQVDTtqoh6rJFO+JTKSA6/Rwi0getWmtuy4Itup0AMcaDQ==",
"dev": true,
"license": "ISC",
"engines": {
"node": "^14.17.0 || ^16.13.0 || >=18.0.0"
}
},
"node_modules/read-installed-packages/node_modules/read-package-json": {
"version": "6.0.4",
"resolved": "https://registry.npmjs.org/read-package-json/-/read-package-json-6.0.4.tgz",
"integrity": "sha512-AEtWXYfopBj2z5N5PbkAOeNHRPUg5q+Nen7QLxV8M2zJq1ym6/lCz3fYNTCXe19puu2d06jfHhrP7v/S2PtMMw==",
"deprecated": "This package is no longer supported. Please use @npmcli/package-json instead.",
"dev": true,
"license": "ISC",
"dependencies": {
"glob": "^10.2.2",
"json-parse-even-better-errors": "^3.0.0",
"normalize-package-data": "^5.0.0",
"npm-normalize-package-bin": "^3.0.0"
},
"engines": {
"node": "^14.17.0 || ^16.13.0 || >=18.0.0"
}
},
"node_modules/read-pkg": {
"version": "5.2.0",
"resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz",
@ -11842,6 +11921,16 @@
"url": "https://github.com/chalk/slice-ansi?sponsor=1"
}
},
"node_modules/slide": {
"version": "1.1.6",
"resolved": "https://registry.npmjs.org/slide/-/slide-1.1.6.tgz",
"integrity": "sha512-NwrtjCg+lZoqhFU8fOwl4ay2ei8PaqCBOUV3/ektPY9trO1yQ1oXEfmHAhKArUVUr/hOHvy5f6AdP17dCM0zMw==",
"dev": true,
"license": "ISC",
"engines": {
"node": "*"
}
},
"node_modules/smol-toml": {
"version": "1.2.2",
"resolved": "https://registry.npmjs.org/smol-toml/-/smol-toml-1.2.2.tgz",
@ -11927,6 +12016,7 @@
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/spdx-compare/-/spdx-compare-1.0.0.tgz",
"integrity": "sha512-C1mDZOX0hnu0ep9dfmuoi03+eOdDoz2yvK79RxbcrVEG1NO1Ph35yW102DHWKN4pk80nwCgeMmSY5L25VE4D9A==",
"dev": true,
"license": "MIT",
"dependencies": {
"array-find-index": "^1.0.2",
@ -11949,43 +12039,39 @@
"version": "2.5.0",
"resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.5.0.tgz",
"integrity": "sha512-PiU42r+xO4UbUS1buo3LPJkjlO7430Xn5SVAhdpzzsPHsjbYVflnnFdATgabnLude+Cqu25p6N+g2lw/PFsa4w==",
"dev": true,
"license": "CC-BY-3.0"
},
"node_modules/spdx-expression-parse": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz",
"integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==",
"dev": true,
"license": "MIT",
"dependencies": {
"spdx-exceptions": "^2.1.0",
"spdx-license-ids": "^3.0.0"
}
},
"node_modules/spdx-expression-validate": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/spdx-expression-validate/-/spdx-expression-validate-2.0.0.tgz",
"integrity": "sha512-b3wydZLM+Tc6CFvaRDBOF9d76oGIHNCLYFeHbftFXUWjnfZWganmDmvtM5sm1cRwJc/VDBMLyGGrsLFd1vOxbg==",
"license": "(MIT AND CC-BY-3.0)",
"dependencies": {
"spdx-expression-parse": "^3.0.0"
}
},
"node_modules/spdx-license-ids": {
"version": "3.0.18",
"resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.18.tgz",
"integrity": "sha512-xxRs31BqRYHwiMzudOrpSiHtZ8i/GeionCBDSilhYRj+9gIcI8wCZTlXZKu9vZIVqViP3dcp9qE5G6AlIaD+TQ==",
"dev": true,
"license": "CC0-1.0"
},
"node_modules/spdx-ranges": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/spdx-ranges/-/spdx-ranges-2.1.1.tgz",
"integrity": "sha512-mcdpQFV7UDAgLpXEE/jOMqvK4LBoO0uTQg0uvXUewmEFhpiZx5yJSZITHB8w1ZahKdhfZqP5GPEOKLyEq5p8XA==",
"dev": true,
"license": "(MIT AND CC-BY-3.0)"
},
"node_modules/spdx-satisfies": {
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/spdx-satisfies/-/spdx-satisfies-5.0.1.tgz",
"integrity": "sha512-Nwor6W6gzFp8XX4neaKQ7ChV4wmpSh2sSDemMFSzHxpTw460jxFYeOn+jq4ybnSSw/5sc3pjka9MQPouksQNpw==",
"dev": true,
"license": "MIT",
"dependencies": {
"spdx-compare": "^1.0.0",
@ -12553,12 +12639,6 @@
"url": "https://github.com/sponsors/isaacs"
}
},
"node_modules/superstruct": {
"version": "0.10.13",
"resolved": "https://registry.npmjs.org/superstruct/-/superstruct-0.10.13.tgz",
"integrity": "sha512-W4SitSZ9MOyMPbHreoZVEneSZyPEeNGbdfJo/7FkJyRs/M3wQRFzq+t3S/NBwlrFSWdx1ONLjLb9pB+UKe4IqQ==",
"license": "MIT"
},
"node_modules/supports-color": {
"version": "7.2.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
@ -12704,9 +12784,9 @@
}
},
"node_modules/tailwindcss": {
"version": "3.4.4",
"resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.4.4.tgz",
"integrity": "sha512-ZoyXOdJjISB7/BcLTR6SEsLgKtDStYyYZVLsUtWChO4Ps20CBad7lfJKVDiejocV4ME1hLmyY0WJE3hSDcmQ2A==",
"version": "3.4.6",
"resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.4.6.tgz",
"integrity": "sha512-1uRHzPB+Vzu57ocybfZ4jh5Q3SdlH7XW23J5sQoM9LhE9eIOlzxer/3XPSsycvih3rboRsvt0QCmzSrqyOYUIA==",
"license": "MIT",
"dependencies": {
"@alloc/quick-lru": "^5.2.0",
@ -13023,6 +13103,16 @@
"integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==",
"license": "MIT"
},
"node_modules/treeify": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/treeify/-/treeify-1.1.0.tgz",
"integrity": "sha512-1m4RA7xVAJrSGrrXGs0L3YTwyvBs2S8PbRHaLZAkFw7JR8oIFwYtysxlBZhYIa7xSyiYJKZ3iGrrk55cGA3i9A==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=0.6"
}
},
"node_modules/tributejs": {
"version": "5.1.3",
"resolved": "https://registry.npmjs.org/tributejs/-/tributejs-5.1.3.tgz",
@ -13659,16 +13749,16 @@
}
},
"node_modules/vue": {
"version": "3.4.31",
"resolved": "https://registry.npmjs.org/vue/-/vue-3.4.31.tgz",
"integrity": "sha512-njqRrOy7W3YLAlVqSKpBebtZpDVg21FPoaq1I7f/+qqBThK9ChAIjkRWgeP6Eat+8C+iia4P3OYqpATP21BCoQ==",
"version": "3.4.33",
"resolved": "https://registry.npmjs.org/vue/-/vue-3.4.33.tgz",
"integrity": "sha512-VdMCWQOummbhctl4QFMcW6eNtXHsFyDlX60O/tsSQuCcuDOnJ1qPOhhVla65Niece7xq/P2zyZReIO5mP+LGTQ==",
"license": "MIT",
"dependencies": {
"@vue/compiler-dom": "3.4.31",
"@vue/compiler-sfc": "3.4.31",
"@vue/runtime-dom": "3.4.31",
"@vue/server-renderer": "3.4.31",
"@vue/shared": "3.4.31"
"@vue/compiler-dom": "3.4.33",
"@vue/compiler-sfc": "3.4.33",
"@vue/runtime-dom": "3.4.33",
"@vue/server-renderer": "3.4.33",
"@vue/shared": "3.4.33"
},
"peerDependencies": {
"typescript": "*"
@ -13679,16 +13769,6 @@
}
}
},
"node_modules/vue-bar-graph": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/vue-bar-graph/-/vue-bar-graph-2.0.0.tgz",
"integrity": "sha512-IoYP+r5Ggjys6QdUNYFPh7qD41wi/uDOJj9nMawvDgvV6niOz3Dw8O2/98ZnUgjTpcgcGFDaaAaK6qa9x1jgpw==",
"license": "MIT",
"dependencies": {
"gsap": "^3.10.4",
"vue": "^3.2.37"
}
},
"node_modules/vue-chartjs": {
"version": "5.3.1",
"resolved": "https://registry.npmjs.org/vue-chartjs/-/vue-chartjs-5.3.1.tgz",
@ -14255,6 +14335,7 @@
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
"integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==",
"dev": true,
"license": "ISC"
},
"node_modules/write-file-atomic": {

View file

@ -6,14 +6,12 @@
"dependencies": {
"@citation-js/core": "0.7.11",
"@citation-js/plugin-bibtex": "0.7.11",
"@citation-js/plugin-csl": "0.7.11",
"@citation-js/plugin-software-formats": "0.6.1",
"@github/markdown-toolbar-element": "2.2.3",
"@github/relative-time-element": "4.4.2",
"@github/text-expander-element": "2.7.1",
"@mcaptcha/vanilla-glue": "0.1.0-alpha-3",
"@primer/octicons": "19.9.0",
"add-asset-webpack-plugin": "2.0.1",
"ansi_up": "6.0.2",
"asciinema-player": "3.8.0",
"chart.js": "4.4.2",
@ -21,17 +19,16 @@
"chartjs-plugin-zoom": "2.0.1",
"clippie": "4.1.1",
"css-loader": "7.0.0",
"dayjs": "1.11.11",
"dayjs": "1.11.12",
"dropzone": "6.0.0-beta.2",
"easymde": "2.18.0",
"esbuild-loader": "4.2.0",
"esbuild-loader": "4.2.2",
"escape-goat": "4.0.0",
"fast-glob": "3.3.2",
"htmx.org": "1.9.12",
"idiomorph": "0.3.0",
"jquery": "3.7.1",
"katex": "0.16.11",
"license-checker-webpack-plugin": "0.2.1",
"mermaid": "10.9.1",
"mini-css-extract-plugin": "2.9.0",
"minimatch": "9.0.5",
@ -44,7 +41,7 @@
"pretty-ms": "9.0.0",
"sortablejs": "1.15.2",
"swagger-ui-dist": "5.17.14",
"tailwindcss": "3.4.4",
"tailwindcss": "3.4.6",
"temporal-polyfill": "0.2.4",
"throttle-debounce": "5.0.0",
"tinycolor2": "1.6.0",
@ -53,8 +50,7 @@
"tributejs": "5.1.3",
"uint8-to-base64": "0.2.0",
"vanilla-colorful": "0.7.2",
"vue": "3.4.31",
"vue-bar-graph": "2.0.0",
"vue": "3.4.33",
"vue-chartjs": "5.3.1",
"vue-loader": "17.4.2",
"vue3-calendar-heatmap": "2.0.5",
@ -64,7 +60,7 @@
},
"devDependencies": {
"@eslint-community/eslint-plugin-eslint-comments": "4.3.0",
"@playwright/test": "1.45.1",
"@playwright/test": "1.45.2",
"@stoplight/spectral-cli": "6.11.1",
"@stylistic/eslint-plugin-js": "1.8.1",
"@stylistic/stylelint-plugin": "2.1.2",
@ -87,6 +83,7 @@
"eslint-plugin-vue-scoped-css": "2.8.1",
"eslint-plugin-wc": "2.1.0",
"happy-dom": "14.12.3",
"license-checker-rseidelsohn": "4.3.0",
"markdownlint-cli": "0.41.0",
"postcss-html": "1.7.0",
"stylelint": "16.7.0",
@ -97,5 +94,7 @@
"vite-string-plugin": "1.3.4",
"vitest": "1.6.0"
},
"browserslist": ["defaults"]
"browserslist": [
"defaults"
]
}

1
release-notes/4547.md Normal file
View file

@ -0,0 +1 @@
The milestone section in the sidebar on the issue and pull request page now uses HTMX. If you update the milestone of a issue or pull request it will no longer reload the whole page and instead update the current page with the new information about the milestone update. This should provide a smoother user experience.

View file

@ -120,7 +120,7 @@ func GetRepositoryFile(ctx *context.Context) {
ctx,
pv,
&packages_service.PackageFileInfo{
Filename: alpine_service.IndexFilename,
Filename: alpine_service.IndexArchiveFilename,
CompositeKey: fmt.Sprintf("%s|%s|%s", ctx.Params("branch"), ctx.Params("repository"), ctx.Params("architecture")),
},
)
@ -217,17 +217,23 @@ func UploadPackageFile(ctx *context.Context) {
}
func DownloadPackageFile(ctx *context.Context) {
pfs, _, err := packages_model.SearchFiles(ctx, &packages_model.PackageFileSearchOptions{
branch := ctx.Params("branch")
repository := ctx.Params("repository")
architecture := ctx.Params("architecture")
opts := &packages_model.PackageFileSearchOptions{
OwnerID: ctx.Package.Owner.ID,
PackageType: packages_model.TypeAlpine,
Query: ctx.Params("filename"),
CompositeKey: fmt.Sprintf("%s|%s|%s", ctx.Params("branch"), ctx.Params("repository"), ctx.Params("architecture")),
})
CompositeKey: fmt.Sprintf("%s|%s|%s", branch, repository, architecture),
}
pfs, _, err := packages_model.SearchFiles(ctx, opts)
if err != nil {
apiError(ctx, http.StatusInternalServerError, err)
return
}
if len(pfs) != 1 {
if len(pfs) == 0 {
apiError(ctx, http.StatusNotFound, nil)
return
}

View file

@ -462,6 +462,11 @@ func GetIssueComment(ctx *context.APIContext) {
return
}
if err := comment.LoadAttachments(ctx); err != nil {
ctx.Error(http.StatusInternalServerError, "LoadAttachments", err)
return
}
ctx.JSON(http.StatusOK, convert.ToAPIComment(ctx, ctx.Repo.Repository, comment))
}

View file

@ -242,6 +242,12 @@ func FileHistory(ctx *context.Context) {
ctx.ServerError("CommitsByFileAndRange", err)
return
}
if len(commits) == 0 {
ctx.NotFound("CommitsByFileAndRange", nil)
return
}
oldestCommit := commits[len(commits)-1]
renamedFiles, err := git.GetCommitFileRenames(ctx, ctx.Repo.GitRepo.Path, oldestCommit.ID.String())

View file

@ -1370,6 +1370,22 @@ func getBranchData(ctx *context.Context, issue *issues_model.Issue) {
}
}
func prepareHiddenCommentType(ctx *context.Context) {
var hiddenCommentTypes *big.Int
if ctx.IsSigned {
val, err := user_model.GetUserSetting(ctx, ctx.Doer.ID, user_model.SettingsKeyHiddenCommentTypes)
if err != nil {
ctx.ServerError("GetUserSetting", err)
return
}
hiddenCommentTypes, _ = new(big.Int).SetString(val, 10) // we can safely ignore the failed conversion here
}
ctx.Data["ShouldShowCommentType"] = func(commentType issues_model.CommentType) bool {
return hiddenCommentTypes == nil || hiddenCommentTypes.Bit(int(commentType)) == 0
}
}
// ViewIssue render issue view page
func ViewIssue(ctx *context.Context) {
if ctx.Params(":type") == "issues" {
@ -2019,21 +2035,13 @@ func ViewIssue(ctx *context.Context) {
ctx.Data["NewPinAllowed"] = pinAllowed
ctx.Data["PinEnabled"] = setting.Repository.Issue.MaxPinned != 0
var hiddenCommentTypes *big.Int
if ctx.IsSigned {
val, err := user_model.GetUserSetting(ctx, ctx.Doer.ID, user_model.SettingsKeyHiddenCommentTypes)
if err != nil {
ctx.ServerError("GetUserSetting", err)
return
}
hiddenCommentTypes, _ = new(big.Int).SetString(val, 10) // we can safely ignore the failed conversion here
}
ctx.Data["ShouldShowCommentType"] = func(commentType issues_model.CommentType) bool {
return hiddenCommentTypes == nil || hiddenCommentTypes.Bit(int(commentType)) == 0
prepareHiddenCommentType(ctx)
if ctx.Written() {
return
}
// For sidebar
PrepareBranchList(ctx)
if ctx.Written() {
return
}
@ -2342,7 +2350,49 @@ func UpdateIssueMilestone(ctx *context.Context) {
}
}
ctx.JSONOK()
if ctx.FormBool("htmx") {
renderMilestones(ctx)
if ctx.Written() {
return
}
prepareHiddenCommentType(ctx)
if ctx.Written() {
return
}
issue := issues[0]
var err error
if issue.MilestoneID > 0 {
issue.Milestone, err = issues_model.GetMilestoneByRepoID(ctx, ctx.Repo.Repository.ID, issue.MilestoneID)
if err != nil {
ctx.ServerError("GetMilestoneByRepoID", err)
return
}
} else {
issue.Milestone = nil
}
comment := &issues_model.Comment{}
has, err := db.GetEngine(ctx).Where("issue_id = ? AND type = ?", issue.ID, issues_model.CommentTypeMilestone).OrderBy("id DESC").Limit(1).Get(comment)
if !has || err != nil {
ctx.ServerError("GetLatestMilestoneComment", err)
}
if err := comment.LoadMilestone(ctx); err != nil {
ctx.ServerError("LoadMilestone", err)
return
}
if err := comment.LoadPoster(ctx); err != nil {
ctx.ServerError("LoadPoster", err)
return
}
issue.Comments = issues_model.CommentList{comment}
ctx.Data["Issue"] = issue
ctx.Data["HasIssuesOrPullsWritePermission"] = ctx.Repo.CanWriteIssuesOrPulls(issue.IsPull)
ctx.HTML(http.StatusOK, "htmx/milestone_sidebar")
} else {
ctx.JSONOK()
}
}
// UpdateIssueAssignee change issue's or pull's assignee

View file

@ -231,6 +231,8 @@ func CreatePost(ctx *context.Context) {
ctx.Data["CanCreateRepo"] = ctx.Doer.CanCreateRepo()
ctx.Data["MaxCreationLimit"] = ctx.Doer.MaxCreationLimit()
ctx.Data["SupportedObjectFormats"] = git.SupportedObjectFormats
ctx.Data["DefaultObjectFormat"] = git.Sha1ObjectFormat
ctxUser := checkContextUser(ctx, form.UID)
if ctx.Written() {

View file

@ -341,7 +341,6 @@ func prepareUserProfileTabData(ctx *context.Context, showPrivate bool, profileDb
// Action response for follow/unfollow user request
func Action(ctx *context.Context) {
var err error
var redirectViaJSON bool
action := ctx.FormString("action")
if ctx.ContextUser.IsOrganization() && (action == "block" || action == "unblock") {
@ -357,10 +356,8 @@ func Action(ctx *context.Context) {
err = user_model.UnfollowUser(ctx, ctx.Doer.ID, ctx.ContextUser.ID)
case "block":
err = user_service.BlockUser(ctx, ctx.Doer.ID, ctx.ContextUser.ID)
redirectViaJSON = true
case "unblock":
err = user_model.UnblockUser(ctx, ctx.Doer.ID, ctx.ContextUser.ID)
redirectViaJSON = true
}
if err != nil {
@ -371,21 +368,15 @@ func Action(ctx *context.Context) {
}
if ctx.ContextUser.IsOrganization() {
ctx.Flash.Error(ctx.Tr("org.follow_blocked_user"))
ctx.Flash.Error(ctx.Tr("org.follow_blocked_user"), true)
} else {
ctx.Flash.Error(ctx.Tr("user.follow_blocked_user"))
ctx.Flash.Error(ctx.Tr("user.follow_blocked_user"), true)
}
}
if redirectViaJSON {
ctx.JSON(http.StatusOK, map[string]any{
"redirect": ctx.ContextUser.HomeLink(),
})
return
}
if ctx.ContextUser.IsIndividual() {
shared_user.PrepareContextForProfileBigAvatar(ctx)
ctx.Data["IsHTMX"] = true
ctx.HTML(http.StatusOK, tplProfileBigAvatar)
return
} else if ctx.ContextUser.IsOrganization() {

View file

@ -62,7 +62,7 @@ func (f *UpdateOrgSettingForm) Validate(req *http.Request, errs binding.Errors)
// CreateTeamForm form for creating team
type CreateTeamForm struct {
TeamName string `binding:"Required;AlphaDashDot;MaxSize(30)"`
TeamName string `binding:"Required;AlphaDashDot;MaxSize(255)"`
Description string `binding:"MaxSize(255)"`
Permission string
RepoAccess string

View file

@ -82,7 +82,7 @@ func sendUserMail(language string, u *user_model.User, tpl base.TplName, code, s
return
}
msg := NewMessage(u.Email, subject, content.String())
msg := NewMessage(u.EmailTo(), subject, content.String())
msg.Info = fmt.Sprintf("UID: %d, %s", u.ID, info)
SendAsync(msg)
@ -158,7 +158,7 @@ func SendRegisterNotifyMail(u *user_model.User) {
return
}
msg := NewMessage(u.Email, locale.TrString("mail.register_notify"), content.String())
msg := NewMessage(u.EmailTo(), locale.TrString("mail.register_notify", setting.AppName), content.String())
msg.Info = fmt.Sprintf("UID: %d, registration notify", u.ID)
SendAsync(msg)
@ -189,7 +189,7 @@ func SendCollaboratorMail(u, doer *user_model.User, repo *repo_model.Repository)
return
}
msg := NewMessage(u.Email, subject, content.String())
msg := NewMessage(u.EmailTo(), subject, content.String())
msg.Info = fmt.Sprintf("UID: %d, add collaborator", u.ID)
SendAsync(msg)

View file

@ -40,10 +40,10 @@ func MailNewRelease(ctx context.Context, rel *repo_model.Release) {
return
}
langMap := make(map[string][]string)
langMap := make(map[string][]*user_model.User)
for _, user := range recipients {
if user.ID != rel.PublisherID {
langMap[user.Language] = append(langMap[user.Language], user.Email)
langMap[user.Language] = append(langMap[user.Language], user)
}
}
@ -52,7 +52,7 @@ func MailNewRelease(ctx context.Context, rel *repo_model.Release) {
}
}
func mailNewRelease(ctx context.Context, lang string, tos []string, rel *repo_model.Release) {
func mailNewRelease(ctx context.Context, lang string, tos []*user_model.User, rel *repo_model.Release) {
locale := translation.NewLocale(lang)
var err error
@ -88,7 +88,7 @@ func mailNewRelease(ctx context.Context, lang string, tos []string, rel *repo_mo
publisherName := rel.Publisher.DisplayName()
msgID := createMessageIDForRelease(rel)
for _, to := range tos {
msg := NewMessageFrom(to, publisherName, setting.MailService.FromEmail, subject, mailBody.String())
msg := NewMessageFrom(to.EmailTo(), publisherName, setting.MailService.FromEmail, subject, mailBody.String())
msg.Info = subject
msg.SetHeader("Message-ID", msgID)
msgs = append(msgs, msg)

View file

@ -28,13 +28,13 @@ func SendRepoTransferNotifyMail(ctx context.Context, doer, newOwner *user_model.
return err
}
langMap := make(map[string][]string)
langMap := make(map[string][]*user_model.User)
for _, user := range users {
if !user.IsActive {
// don't send emails to inactive users
continue
}
langMap[user.Language] = append(langMap[user.Language], user.Email)
langMap[user.Language] = append(langMap[user.Language], user)
}
for lang, tos := range langMap {
@ -46,11 +46,11 @@ func SendRepoTransferNotifyMail(ctx context.Context, doer, newOwner *user_model.
return nil
}
return sendRepoTransferNotifyMailPerLang(newOwner.Language, newOwner, doer, []string{newOwner.Email}, repo)
return sendRepoTransferNotifyMailPerLang(newOwner.Language, newOwner, doer, []*user_model.User{newOwner}, repo)
}
// sendRepoTransferNotifyMail triggers a notification e-mail when a pending repository transfer was created for each language
func sendRepoTransferNotifyMailPerLang(lang string, newOwner, doer *user_model.User, emails []string, repo *repo_model.Repository) error {
func sendRepoTransferNotifyMailPerLang(lang string, newOwner, doer *user_model.User, emailTos []*user_model.User, repo *repo_model.Repository) error {
var (
locale = translation.NewLocale(lang)
content bytes.Buffer
@ -78,8 +78,8 @@ func sendRepoTransferNotifyMailPerLang(lang string, newOwner, doer *user_model.U
return err
}
for _, to := range emails {
msg := NewMessage(to, subject, content.String())
for _, to := range emailTos {
msg := NewMessage(to.EmailTo(), subject, content.String())
msg.Info = fmt.Sprintf("UID: %d, repository pending transfer notification", newOwner.ID)
SendAsync(msg)

View file

@ -30,7 +30,10 @@ import (
packages_service "code.gitea.io/gitea/services/packages"
)
const IndexFilename = "APKINDEX.tar.gz"
const (
IndexFilename = "APKINDEX"
IndexArchiveFilename = IndexFilename + ".tar.gz"
)
// GetOrCreateRepositoryVersion gets or creates the internal repository package
// The Alpine registry needs multiple index files which are stored in this package.
@ -151,7 +154,7 @@ func buildPackagesIndex(ctx context.Context, ownerID int64, repoVersion *package
// Delete the package indices if there are no packages
if len(pfs) == 0 {
pf, err := packages_model.GetFileForVersionByName(ctx, repoVersion.ID, IndexFilename, fmt.Sprintf("%s|%s|%s", branch, repository, architecture))
pf, err := packages_model.GetFileForVersionByName(ctx, repoVersion.ID, IndexArchiveFilename, fmt.Sprintf("%s|%s|%s", branch, repository, architecture))
if err != nil && !errors.Is(err, util.ErrNotExist) {
return err
} else if pf == nil {
@ -244,7 +247,7 @@ func buildPackagesIndex(ctx context.Context, ownerID int64, repoVersion *package
h := sha1.New()
if err := writeGzipStream(io.MultiWriter(unsignedIndexContent, h), "APKINDEX", buf.Bytes(), true); err != nil {
if err := writeGzipStream(io.MultiWriter(unsignedIndexContent, h), IndexFilename, buf.Bytes(), true); err != nil {
return err
}
@ -299,7 +302,7 @@ func buildPackagesIndex(ctx context.Context, ownerID int64, repoVersion *package
repoVersion,
&packages_service.PackageFileCreationInfo{
PackageFileInfo: packages_service.PackageFileInfo{
Filename: IndexFilename,
Filename: IndexArchiveFilename,
CompositeKey: fmt.Sprintf("%s|%s|%s", branch, repository, architecture),
},
Creator: user_model.NewGhostUser(),

View file

@ -12,6 +12,7 @@ import (
"path"
"path/filepath"
"regexp"
"strconv"
"strings"
"time"
@ -54,7 +55,12 @@ var defaultTransformers = []transformer{
}
func generateExpansion(src string, templateRepo, generateRepo *repo_model.Repository, sanitizeFileName bool) string {
year, month, day := time.Now().Date()
expansions := []expansion{
{Name: "YEAR", Value: strconv.Itoa(year), Transformers: nil},
{Name: "MONTH", Value: fmt.Sprintf("%02d", int(month)), Transformers: nil},
{Name: "MONTH_ENGLISH", Value: month.String(), Transformers: defaultTransformers},
{Name: "DAY", Value: fmt.Sprintf("%02d", day), Transformers: nil},
{Name: "REPO_NAME", Value: generateRepo.Name, Transformers: defaultTransformers},
{Name: "TEMPLATE_NAME", Value: templateRepo.Name, Transformers: defaultTransformers},
{Name: "REPO_DESCRIPTION", Value: generateRepo.Description, Transformers: nil},

View file

@ -1,20 +1,23 @@
{{if .Flash.ErrorMsg}}
<div class="ui negative message flash-message flash-error">
<div id="flash-message" class="ui negative message flash-message flash-error" hx-swap-oob="true">
<p>{{.Flash.ErrorMsg | SanitizeHTML}}</p>
</div>
{{end}}
{{if .Flash.SuccessMsg}}
<div class="ui positive message flash-message flash-success">
<div id="flash-message" class="ui positive message flash-message flash-success" hx-swap-oob="true">
<p>{{.Flash.SuccessMsg | SanitizeHTML}}</p>
</div>
{{end}}
{{if .Flash.InfoMsg}}
<div class="ui info message flash-message flash-info">
<div id="flash-message" class="ui info message flash-message flash-info" hx-swap-oob="true">
<p>{{.Flash.InfoMsg | SanitizeHTML}}</p>
</div>
{{end}}
{{if .Flash.WarningMsg}}
<div class="ui warning message flash-message flash-warning">
<div id="flash-message" class="ui warning message flash-message flash-warning" hx-swap-oob="true">
<p>{{.Flash.WarningMsg | SanitizeHTML}}</p>
</div>
{{end}}
{{if and (not .Flash.ErrorMsg) (not .Flash.SuccessMsg) (not .Flash.InfoMsg) (not .Flash.WarningMsg) (not .IsHTMX)}}
<div id="flash-message" hx-swap-oob="true"></div>
{{end}}

View file

@ -0,0 +1,4 @@
<div id="insert-timeline" hx-swap-oob="beforebegin">
{{template "repo/issue/view_content/comments" .}}
</div>
{{template "repo/issue/view_content/sidebar/milestones" .}}

View file

@ -138,7 +138,9 @@
{{if .LatestPullRequest.HasMerged}}
<a href="{{.LatestPullRequest.Issue.Link}}" class="ui purple large label">{{svg "octicon-git-merge" 16 "tw-mr-1"}}{{ctx.Locale.Tr "repo.pulls.merged"}}</a>
{{else if .LatestPullRequest.Issue.IsClosed}}
<a href="{{.LatestPullRequest.Issue.Link}}" class="ui red large label">{{svg "octicon-git-pull-request" 16 "tw-mr-1"}}{{ctx.Locale.Tr "repo.issues.closed_title"}}</a>
<a href="{{.LatestPullRequest.Issue.Link}}" class="ui red large label">{{svg "octicon-git-pull-request-closed" 16 "tw-mr-1"}}{{ctx.Locale.Tr "repo.issues.closed_title"}}</a>
{{else if .LatestPullRequest.IsWorkInProgress ctx}}
<a href="{{.LatestPullRequest.Issue.Link}}" class="ui grey large label">{{svg "octicon-git-pull-request-draft" 16 "tw-mr-1"}}{{ctx.Locale.Tr "repo.issues.draft_title"}}</a>
{{else}}
<a href="{{.LatestPullRequest.Issue.Link}}" class="ui green large label">{{svg "octicon-git-pull-request" 16 "tw-mr-1"}}{{ctx.Locale.Tr "repo.issues.open_title"}}</a>
{{end}}

View file

@ -1,9 +1,6 @@
<button class="ui citation button" id="citation-copy-apa" data-text="">
APA
</button>
<button class="ui citation button" id="citation-copy-bibtex" data-text="">
<span class="ui citation label primary" id="citation-copy-bibtex" data-text="">
BibTeX
</button>
</span>
<!-- the value will be updated by initCitationFileCopyContent, the code below is used to avoid UI flicking -->
<input id="citation-copy-content" value="" size="1" readonly>
<button class="ui icon button" id="citation-clipboard-btn" data-tooltip-content="{{ctx.Locale.Tr "copy"}}" data-clipboard-target="#citation-copy-content">

View file

@ -69,7 +69,7 @@
<div class="inline field">
<label>{{ctx.Locale.Tr "repo.template"}}</label>
<div id="repo_template_search" class="ui search selection dropdown">
<input type="hidden" id="repo_template" name="repo_template" value="{{.repo_template}}">
<input type="hidden" id="repo_template" name="repo_template" value="{{if ne .repo_template 0}}{{.repo_template}}{{end}}">
<div class="default text">{{.repo_template_name}}</div>
<div class="menu">
</div>

View file

@ -1,4 +1,4 @@
{{if .item.Attributes.label}}
{{if and (.item.Attributes.label) (not .item.Attributes.hide_label)}}
<h3>{{.item.Attributes.label}}{{if .item.Validations.required}}<label class="required"></label>{{end}}</h3>
{{end}}
{{if .item.Attributes.description}}

View file

@ -5,11 +5,11 @@
{{svg "octicon-gear" 16 "tw-ml-1"}}
{{end}}
</span>
<div class="filter menu" {{if .Issue}}data-action="update" data-issue-id="{{$.Issue.ID}}" data-update-url="{{$.RepoLink}}/issues/labels"{{else}}data-id="#label_ids"{{end}}>
<div class="filter menu ugc-labels" {{if .Issue}}data-action="update" data-issue-id="{{$.Issue.ID}}" data-update-url="{{$.RepoLink}}/issues/labels"{{else}}data-id="#label_ids"{{end}}>
{{if or .Labels .OrgLabels}}
<div class="ui icon search input">
<i class="icon">{{svg "octicon-search" 16}}</i>
<input type="text" placeholder="{{ctx.Locale.Tr "repo.issues.filter_labels"}}">
<input class="tw-w-auto" type="text" placeholder="{{ctx.Locale.Tr "repo.issues.filter_labels"}}">
</div>
{{end}}
<a class="no-select item" href="#">{{ctx.Locale.Tr "repo.issues.new.clear_labels"}}</a>

View file

@ -1,13 +1,11 @@
<div class="ui labels list">
<span class="no-select item {{if .root.HasSelectedLabel}}tw-hidden{{end}}">{{ctx.Locale.Tr "repo.issues.new.no_label"}}</span>
{{if .root.HasSelectedLabel}}
<span class="labels-list">
{{range .root.Labels}}
{{template "repo/issue/labels/label" dict "root" $.root "label" .}}
{{end}}
{{range .root.OrgLabels}}
{{template "repo/issue/labels/label" dict "root" $.root "label" .}}
{{end}}
</span>
{{end}}
<span class="no-select {{if .root.HasSelectedLabel}}tw-hidden{{end}}">{{ctx.Locale.Tr "repo.issues.new.no_label"}}</span>
<span class="labels-list ugc-labels">
{{range .root.Labels}}
{{template "repo/issue/labels/label" dict "root" $.root "label" .}}
{{end}}
{{range .root.OrgLabels}}
{{template "repo/issue/labels/label" dict "root" $.root "label" .}}
{{end}}
</span>
</div>

View file

@ -5,7 +5,7 @@
</div>
<div class="divider"></div>
{{end}}
<div class="no-select item">{{ctx.Locale.Tr "repo.issues.new.clear_milestone"}}</div>
<div class="no-select item" hx-post="{{$.RepoLink}}/issues/milestone?issue_ids={{$.Issue.ID}}&htmx=true">{{ctx.Locale.Tr "repo.issues.new.clear_milestone"}}</div>
{{if and (not .OpenMilestones) (not .ClosedMilestones)}}
<div class="disabled item">
{{ctx.Locale.Tr "repo.issues.new.no_items"}}
@ -17,7 +17,7 @@
{{ctx.Locale.Tr "repo.issues.new.open_milestone"}}
</div>
{{range .OpenMilestones}}
<a class="item" data-id="{{.ID}}" data-href="{{$.RepoLink}}/issues?milestone={{.ID}}">
<a class="item" hx-post="{{$.RepoLink}}/issues/milestone?id={{.ID}}&issue_ids={{$.Issue.ID}}&htmx=true">
{{svg "octicon-milestone" 16 "tw-mr-1"}}
{{.Name}}
</a>
@ -29,7 +29,7 @@
{{ctx.Locale.Tr "repo.issues.new.closed_milestone"}}
</div>
{{range .ClosedMilestones}}
<a class="item" data-id="{{.ID}}" data-href="{{$.RepoLink}}/issues?milestone={{.ID}}">
<a class="item" hx-post="{{$.RepoLink}}/issues/milestone?id={{.ID}}&issue_ids={{$.Issue.ID}}&htmx=true">
{{svg "octicon-milestone" 16 "tw-mr-1"}}
{{.Name}}
</a>

View file

@ -72,7 +72,8 @@
</div>
</div>
{{template "repo/issue/view_content/comments" .}}
{{template "repo/issue/view_content/comments" .}}
<div id="insert-timeline"></div>
{{if and .Issue.IsPull (not $.Repository.IsArchived)}}
{{template "repo/issue/view_content/pull".}}

View file

@ -1,22 +1,24 @@
<div class="ui {{if or (not .HasIssuesOrPullsWritePermission) .Repository.IsArchived}}disabled{{end}} floating jump select-milestone dropdown">
<a class="text muted flex-text-block">
<strong>{{ctx.Locale.Tr "repo.issues.new.milestone"}}</strong>
{{if and .HasIssuesOrPullsWritePermission (not .Repository.IsArchived)}}
{{svg "octicon-gear" 16 "tw-ml-1"}}
{{end}}
</a>
<div class="menu" data-action="update" data-issue-id="{{$.Issue.ID}}" data-update-url="{{$.RepoLink}}/issues/milestone">
{{template "repo/issue/milestone/select_menu" .}}
</div>
</div>
<div class="ui select-milestone list">
<span class="no-select item {{if .Issue.Milestone}}tw-hidden{{end}}">{{ctx.Locale.Tr "repo.issues.new.no_milestone"}}</span>
<div class="selected">
{{if .Issue.Milestone}}
<a class="item muted sidebar-item-link" href="{{.RepoLink}}/milestone/{{.Issue.Milestone.ID}}">
{{svg "octicon-milestone" 18 "tw-mr-2"}}
{{.Issue.Milestone.Name}}
</a>
{{end}}
<div id="milestone-section" hx-swap="morph" hx-target="this" hx-indicator="this">
<div class="ui {{if or (not .HasIssuesOrPullsWritePermission) .Repository.IsArchived}}disabled{{end}} floating jump select-milestone dropdown">
<a class="text muted flex-text-block">
<strong>{{ctx.Locale.Tr "repo.issues.new.milestone"}}</strong>
{{if and .HasIssuesOrPullsWritePermission (not .Repository.IsArchived)}}
{{svg "octicon-gear" 16 "tw-ml-1"}}
{{end}}
</a>
<div class="menu">
{{template "repo/issue/milestone/select_menu" .}}
</div>
</div>
<div class="ui select-milestone list">
<span class="no-select item {{if .Issue.Milestone}}tw-hidden{{end}}">{{ctx.Locale.Tr "repo.issues.new.no_milestone"}}</span>
<div class="selected">
{{if .Issue.Milestone}}
<a class="item muted sidebar-item-link" href="{{.RepoLink}}/milestone/{{.Issue.Milestone.ID}}">
{{svg "octicon-milestone" 18 "tw-mr-2"}}
{{.Issue.Milestone.Name}}
</a>
{{end}}
</div>
</div>
</div>

View file

@ -37,7 +37,7 @@
{{if .HasMerged}}
<div class="ui purple label issue-state-label">{{svg "octicon-git-merge" 16 "tw-mr-1"}} {{if eq .Issue.PullRequest.Status 3}}{{ctx.Locale.Tr "repo.pulls.manually_merged"}}{{else}}{{ctx.Locale.Tr "repo.pulls.merged"}}{{end}}</div>
{{else if .Issue.IsClosed}}
<div class="ui red label issue-state-label">{{if .Issue.IsPull}}{{svg "octicon-git-pull-request"}}{{else}}{{svg "octicon-issue-closed"}}{{end}} {{ctx.Locale.Tr "repo.issues.closed_title"}}</div>
<div class="ui red label issue-state-label">{{if .Issue.IsPull}}{{svg "octicon-git-pull-request-closed"}}{{else}}{{svg "octicon-issue-closed"}}{{end}} {{ctx.Locale.Tr "repo.issues.closed_title"}}</div>
{{else if .Issue.IsPull}}
{{if .IsPullWorkInProgress}}
<div class="ui grey label issue-state-label">{{svg "octicon-git-pull-request-draft"}} {{ctx.Locale.Tr "repo.issues.draft_title"}}</div>

View file

@ -105,7 +105,7 @@
<strong class="text red">{{ctx.Locale.TrN .Activity.Code.Deletions "repo.activity.git_stats_deletion_1" "repo.activity.git_stats_deletion_n" .Activity.Code.Deletions}}</strong>.
</div>
<div class="ui attached segment">
<div id="repo-activity-top-authors-chart"></div>
<div id="repo-activity-top-authors-chart" data-locale-commit-activity="{{ctx.Locale.Tr "repo.activity.commit"}}"></div>
</div>
</div>
{{end}}

View file

@ -6,7 +6,7 @@
{{if .PullRequest.HasMerged}}
{{svg "octicon-git-merge" 16 "text purple"}}
{{else}}
{{svg "octicon-git-pull-request" 16 "text red"}}
{{svg "octicon-git-pull-request-closed" 16 "text red"}}
{{end}}
{{else}}
{{if .PullRequest.IsWorkInProgress ctx}}

View file

@ -1,4 +1,7 @@
<div id="profile-avatar-card" class="ui card">
{{if .IsHTMX}}
{{template "base/alert" .}}
{{end}}
<div id="profile-avatar-card" class="ui card" hx-swap="morph">
<div id="profile-avatar" class="content tw-flex">
{{if eq .SignedUserID .ContextUser.ID}}
<a class="image" href="{{AppSubUrl}}/user/settings" data-tooltip-content="{{ctx.Locale.Tr "user.change_avatar"}}">
@ -98,7 +101,7 @@
</li>
{{end}}
{{if and .IsSigned (ne .SignedUserID .ContextUser.ID)}}
<li class="follow" hx-target="#profile-avatar-card" hx-indicator="#profile-avatar-card" >
<li class="follow" hx-target="#profile-avatar-card" hx-indicator="#profile-avatar-card">
{{if $.IsFollowing}}
<button hx-post="{{.ContextUser.HomeLink}}?action=unfollow" class="ui basic red button">
{{svg "octicon-person"}} {{ctx.Locale.Tr "user.unfollow"}}
@ -109,14 +112,13 @@
</button>
{{end}}
</li>
<li class="block">
<li class="block" hx-target="#profile-avatar-card" hx-indicator="#profile-avatar-card">
{{if $.IsBlocked}}
<button class="ui basic red button link-action" data-url="{{.ContextUser.HomeLink}}?action=unblock&redirect_to={{$.Link}}">
<button class="ui basic red button" hx-post="{{.ContextUser.HomeLink}}?action=unblock">
{{svg "octicon-person"}} {{ctx.Locale.Tr "user.unblock"}}
</button>
{{else}}
<button type="submit" class="ui basic orange button delete-button"
data-modal-id="block-user" data-url="{{.ContextUser.HomeLink}}?action=block">
<button type="submit" class="ui basic orange button" data-modal-id="block-user" hx-post="{{.ContextUser.HomeLink}}?action=block" hx-confirm="-">
{{svg "octicon-blocked"}} {{ctx.Locale.Tr "user.block"}}
</button>
{{end}}

View file

@ -47,6 +47,9 @@
</h4>
<div class="ui attached segment">
<form class="ui form" action="{{.Link}}/language" method="post">
<div class="tw-mb-4">
{{ctx.Locale.Tr "settings.language.description"}}
</div>
{{.CsrfTokenHtml}}
<div class="field">
<div class="ui language selection dropdown" id="language">
@ -60,6 +63,9 @@
</div>
</div>
</div>
<div class="tw-mb-4">
{{ctx.Locale.Tr "settings.language.localization_project" "https://forgejo.org/docs/latest/developer/localization/"}}
</div>
<div class="field">
<button class="ui primary button">{{ctx.Locale.Tr "settings.update_language"}}</button>
</div>

View file

@ -100,8 +100,20 @@ TEST_MYSQL_HOST=localhost:1433 TEST_MYSQL_DBNAME=test TEST_MYSQL_USERNAME=sa TES
Although the main goal of e2e is assertion testing, we have added a framework for visual regress testing. If you are working on front-end features, please use the following:
- Check out `main`, `make clean frontend`, and run e2e tests with `VISUAL_TEST=1` to generate outputs. This will initially fail, as no screenshots exist. You can run the e2e tests again to assert it passes.
- Check out your branch, `make clean frontend`, and run e2e tests with `VISUAL_TEST=1`. You should be able to assert you front-end changes don't break any other tests unintentionally.
- Check out your branch, `make clean frontend`, and run e2e tests with `VISUAL_TEST=1`. You should be able to assert you front-end changes don't break any other tests unintentionally.
VISUAL_TEST=1 will create screenshots in tests/e2e/test-snapshots. The test will fail the first time this is enabled (until we get visual test image persistence figured out), because it will be testing against an empty screenshot folder.
VISUAL_TEST=1 will create screenshots in tests/e2e/test-snapshots. The test will fail the first time this is enabled (until we get visual test image persistence figured out), because it will be testing against an empty screenshot folder.
ACCEPT_VISUAL=1 will overwrite the snapshot images with new images.
## With VSCodium or VSCode
To debug a test, you can use "Playwright Test" for
[VScodium](https://open-vsx.org/extension/ms-playwright/playwright)
or [VSCode](https://marketplace.visualstudio.com/items?itemName=ms-playwright.playwright).
Before doing that you will need to manually start a Forgejo instance and populate it
with data from `models/fixtures` by running:
```sh
make TAGS='sqlite sqlite_unlock_notify' 'test-e2e-debugserver'
```

View file

@ -84,3 +84,27 @@ test('Issue: Labels', async ({browser}, workerInfo) => {
await expect(labelList.filter({hasText: 'label2'})).not.toBeVisible();
await expect(labelList.filter({hasText: 'label1'})).toBeVisible();
});
test('Issue: Milestone', async ({browser}, workerInfo) => {
test.skip(workerInfo.project.name === 'Mobile Safari', 'Unable to get tests working on Safari Mobile, see https://codeberg.org/forgejo/forgejo/pulls/3445#issuecomment-1789636');
const page = await login({browser}, workerInfo);
const response = await page.goto('/user2/repo1/issues/1');
await expect(response?.status()).toBe(200);
const selectedMilestone = page.locator('.issue-content-right .select-milestone.list');
const milestoneDropdown = page.locator('.issue-content-right .select-milestone.dropdown');
await expect(selectedMilestone).toContainText('No milestone');
// Add milestone.
await milestoneDropdown.click();
await page.getByRole('option', {name: 'milestone1'}).click();
await expect(selectedMilestone).toContainText('milestone1');
await expect(page.locator('.timeline-item.event').last()).toContainText('user2 added this to the milestone1 milestone');
// Clear milestone.
await milestoneDropdown.click();
await page.getByText('Clear milestone', {exact: true}).click();
await expect(selectedMilestone).toContainText('No milestone');
await expect(page.locator('.timeline-item.event').last()).toContainText('user2 removed this from the milestone1 milestone');
});

View file

@ -0,0 +1,41 @@
// @ts-check
import {test, expect} from '@playwright/test';
import {login_user, load_logged_in_context} from './utils_e2e.js';
test('Follow actions', async ({browser}, workerInfo) => {
await login_user(browser, workerInfo, 'user2');
const context = await load_logged_in_context(browser, workerInfo, 'user2');
const page = await context.newPage();
await page.goto('/user1');
await page.waitForLoadState('networkidle');
// Check if following and then unfollowing works.
// This checks that the event listeners of
// the buttons aren't dissapearing.
const followButton = page.locator('.follow');
await expect(followButton).toContainText('Follow');
await followButton.click();
await expect(followButton).toContainText('Unfollow');
await followButton.click();
await expect(followButton).toContainText('Follow');
// Simple block interaction.
await expect(page.locator('.block')).toContainText('Block');
await page.locator('.block').click();
await expect(page.locator('#block-user')).toBeVisible();
await page.locator('#block-user .ok').click();
await expect(page.locator('.block')).toContainText('Unblock');
await expect(page.locator('#block-user')).not.toBeVisible();
// Check that following the user yields in a error being shown.
await followButton.click();
const flashMessage = page.locator('#flash-message');
await expect(flashMessage).toBeVisible();
await expect(flashMessage).toContainText('You cannot follow this user because you have blocked this user or this user has blocked you.');
// Unblock interaction.
await page.locator('.block').click();
await expect(page.locator('.block')).toContainText('Block');
});

View file

@ -46,12 +46,19 @@ func TestAPIGetCommentAttachment(t *testing.T) {
session := loginUser(t, repoOwner.Name)
token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeReadIssue)
req := NewRequestf(t, "GET", "/api/v1/repos/%s/%s/issues/comments/%d/assets/%d", repoOwner.Name, repo.Name, comment.ID, attachment.ID).
req := NewRequestf(t, "GET", "/api/v1/repos/%s/%s/issues/comments/%d", repoOwner.Name, repo.Name, comment.ID).
AddTokenAuth(token)
resp := session.MakeRequest(t, req, http.StatusOK)
var apiComment api.Comment
DecodeJSON(t, resp, &apiComment)
assert.NotEmpty(t, apiComment.Attachments)
req = NewRequestf(t, "GET", "/api/v1/repos/%s/%s/issues/comments/%d/assets/%d", repoOwner.Name, repo.Name, comment.ID, attachment.ID).
AddTokenAuth(token)
session.MakeRequest(t, req, http.StatusOK)
req = NewRequestf(t, "GET", "/api/v1/repos/%s/%s/issues/comments/%d/assets/%d", repoOwner.Name, repo.Name, comment.ID, attachment.ID).
AddTokenAuth(token)
resp := session.MakeRequest(t, req, http.StatusOK)
resp = session.MakeRequest(t, req, http.StatusOK)
var apiAttachment api.Attachment
DecodeJSON(t, resp, &apiAttachment)

View file

@ -19,6 +19,7 @@ import (
"code.gitea.io/gitea/models/unittest"
user_model "code.gitea.io/gitea/models/user"
alpine_module "code.gitea.io/gitea/modules/packages/alpine"
alpine_service "code.gitea.io/gitea/services/packages/alpine"
"code.gitea.io/gitea/tests"
"github.com/stretchr/testify/assert"
@ -139,6 +140,49 @@ Djfa/2q5bH4699v++uMAAAAAAAAAAAAAAAAAAAAAAHbgA/eXQh8AKAAA`
})
})
readIndexContent := func(r io.Reader) (string, error) {
br := bufio.NewReader(r)
gzr, err := gzip.NewReader(br)
if err != nil {
return "", err
}
for {
gzr.Multistream(false)
tr := tar.NewReader(gzr)
for {
hd, err := tr.Next()
if err == io.EOF {
break
}
if err != nil {
return "", err
}
if hd.Name == alpine_service.IndexFilename {
buf, err := io.ReadAll(tr)
if err != nil {
return "", err
}
return string(buf), nil
}
}
err = gzr.Reset(br)
if err == io.EOF {
break
}
if err != nil {
return "", err
}
}
return "", io.EOF
}
t.Run("Index", func(t *testing.T) {
defer tests.PrintCurrentTest(t)()
@ -147,55 +191,22 @@ Djfa/2q5bH4699v++uMAAAAAAAAAAAAAAAAAAAAAAHbgA/eXQh8AKAAA`
req := NewRequest(t, "GET", url)
resp := MakeRequest(t, req, http.StatusOK)
assert.Condition(t, func() bool {
br := bufio.NewReader(resp.Body)
content, err := readIndexContent(resp.Body)
assert.NoError(t, err)
gzr, err := gzip.NewReader(br)
assert.NoError(t, err)
for {
gzr.Multistream(false)
tr := tar.NewReader(gzr)
for {
hd, err := tr.Next()
if err == io.EOF {
break
}
assert.NoError(t, err)
if hd.Name == "APKINDEX" {
buf, err := io.ReadAll(tr)
assert.NoError(t, err)
s := string(buf)
assert.Contains(t, s, "C:Q1/se1PjO94hYXbfpNR1/61hVORIc=\n")
assert.Contains(t, s, "P:"+packageName+"\n")
assert.Contains(t, s, "V:"+packageVersion+"\n")
assert.Contains(t, s, "A:x86_64\n")
assert.Contains(t, s, "T:Gitea Test Package\n")
assert.Contains(t, s, "U:https://gitea.io/\n")
assert.Contains(t, s, "L:MIT\n")
assert.Contains(t, s, "S:1353\n")
assert.Contains(t, s, "I:4096\n")
assert.Contains(t, s, "o:gitea-test\n")
assert.Contains(t, s, "m:KN4CK3R <kn4ck3r@gitea.io>\n")
assert.Contains(t, s, "t:1679498030\n")
return true
}
}
err = gzr.Reset(br)
if err == io.EOF {
break
}
assert.NoError(t, err)
}
return false
})
assert.Contains(t, content, "C:Q1/se1PjO94hYXbfpNR1/61hVORIc=\n")
assert.Contains(t, content, "P:"+packageName+"\n")
assert.Contains(t, content, "V:"+packageVersion+"\n")
assert.Contains(t, content, "A:x86_64\n")
assert.NotContains(t, content, "A:noarch\n")
assert.Contains(t, content, "T:Gitea Test Package\n")
assert.Contains(t, content, "U:https://gitea.io/\n")
assert.Contains(t, content, "L:MIT\n")
assert.Contains(t, content, "S:1353\n")
assert.Contains(t, content, "I:4096\n")
assert.Contains(t, content, "o:gitea-test\n")
assert.Contains(t, content, "m:KN4CK3R <kn4ck3r@gitea.io>\n")
assert.Contains(t, content, "t:1679498030\n")
})
t.Run("Download", func(t *testing.T) {

View file

@ -34,15 +34,8 @@ func BlockUser(t *testing.T, doer, blockedUser *user_model.User) {
"_csrf": GetCSRF(t, session, "/"+blockedUser.Name),
"action": "block",
})
resp := session.MakeRequest(t, req, http.StatusOK)
session.MakeRequest(t, req, http.StatusOK)
type redirect struct {
Redirect string `json:"redirect"`
}
var respBody redirect
DecodeJSON(t, resp, &respBody)
assert.EqualValues(t, "/"+blockedUser.Name, respBody.Redirect)
assert.True(t, unittest.BeanExists(t, &user_model.BlockedUser{BlockID: blockedUser.ID, UserID: doer.ID}))
}
@ -303,11 +296,10 @@ func TestBlockActions(t *testing.T) {
"_csrf": GetCSRF(t, session, "/"+blockedUser.Name),
"action": "follow",
})
session.MakeRequest(t, req, http.StatusOK)
resp := session.MakeRequest(t, req, http.StatusOK)
flashCookie := session.GetCookie(forgejo_context.CookieNameFlash)
assert.NotNil(t, flashCookie)
assert.EqualValues(t, "error%3DYou%2Bcannot%2Bfollow%2Bthis%2Buser%2Bbecause%2Byou%2Bhave%2Bblocked%2Bthis%2Buser%2Bor%2Bthis%2Buser%2Bhas%2Bblocked%2Byou.", flashCookie.Value)
htmlDoc := NewHTMLParser(t, resp.Body)
assert.Contains(t, htmlDoc.Find("#flash-message").Text(), "You cannot follow this user because you have blocked this user or this user has blocked you.")
// Assert it still doesn't exist.
unittest.AssertNotExistsBean(t, &user_model.Follow{UserID: doer.ID, FollowID: blockedUser.ID})
@ -323,11 +315,10 @@ func TestBlockActions(t *testing.T) {
"_csrf": GetCSRF(t, session, "/"+doer.Name),
"action": "follow",
})
session.MakeRequest(t, req, http.StatusOK)
resp := session.MakeRequest(t, req, http.StatusOK)
flashCookie := session.GetCookie(forgejo_context.CookieNameFlash)
assert.NotNil(t, flashCookie)
assert.EqualValues(t, "error%3DYou%2Bcannot%2Bfollow%2Bthis%2Buser%2Bbecause%2Byou%2Bhave%2Bblocked%2Bthis%2Buser%2Bor%2Bthis%2Buser%2Bhas%2Bblocked%2Byou.", flashCookie.Value)
htmlDoc := NewHTMLParser(t, resp.Body)
assert.Contains(t, htmlDoc.Find("#flash-message").Text(), "You cannot follow this user because you have blocked this user or this user has blocked you.")
unittest.AssertNotExistsBean(t, &user_model.Follow{UserID: blockedUser.ID, FollowID: doer.ID})
})

View file

@ -40,10 +40,10 @@ func withKeyFile(t *testing.T, keyname string, callback func(string)) {
assert.NoError(t, err)
// Setup ssh wrapper
os.Setenv("GIT_SSH", path.Join(tmpDir, "ssh"))
os.Setenv("GIT_SSH_COMMAND",
t.Setenv("GIT_SSH", path.Join(tmpDir, "ssh"))
t.Setenv("GIT_SSH_COMMAND",
"ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -o IdentitiesOnly=yes -i \""+keyFile+"\"")
os.Setenv("GIT_SSH_VARIANT", "ssh")
t.Setenv("GIT_SSH_VARIANT", "ssh")
callback(keyFile)
}

View file

@ -30,10 +30,8 @@ func TestGPGGit(t *testing.T) {
err := os.Chmod(tmpDir, 0o700)
assert.NoError(t, err)
oldGNUPGHome := os.Getenv("GNUPGHOME")
err = os.Setenv("GNUPGHOME", tmpDir)
t.Setenv("GNUPGHOME", tmpDir)
assert.NoError(t, err)
defer os.Setenv("GNUPGHOME", oldGNUPGHome)
// Need to create a root key
rootKeyPair, err := importTestingKey()

View file

@ -5,6 +5,7 @@ package integration
import (
"bytes"
"fmt"
"testing"
"github.com/PuerkitoBio/goquery"
@ -36,6 +37,37 @@ func (doc *HTMLDoc) GetInputValueByName(name string) string {
return text
}
func (doc *HTMLDoc) AssertDropdown(t testing.TB, name string) *goquery.Selection {
t.Helper()
dropdownGroup := doc.Find(fmt.Sprintf(".dropdown:has(input[name='%s'])", name))
assert.Equal(t, dropdownGroup.Length(), 1, fmt.Sprintf("%s dropdown does not exist", name))
return dropdownGroup
}
// Assert that a dropdown has at least one non-empty option
func (doc *HTMLDoc) AssertDropdownHasOptions(t testing.TB, dropdownName string) {
t.Helper()
options := doc.AssertDropdown(t, dropdownName).Find(".menu [data-value]:not([data-value=''])")
assert.Greater(t, options.Length(), 0, fmt.Sprintf("%s dropdown has no options", dropdownName))
}
func (doc *HTMLDoc) AssertDropdownHasSelectedOption(t testing.TB, dropdownName, expectedValue string) {
t.Helper()
dropdownGroup := doc.AssertDropdown(t, dropdownName)
selectedValue, _ := dropdownGroup.Find(fmt.Sprintf("input[name='%s']", dropdownName)).Attr("value")
assert.Equal(t, expectedValue, selectedValue, fmt.Sprintf("%s dropdown doesn't have expected value selected", dropdownName))
dropdownValues := dropdownGroup.Find(".menu [data-value]").Map(func(i int, s *goquery.Selection) string {
value, _ := s.Attr("data-value")
return value
})
assert.Contains(t, dropdownValues, expectedValue, fmt.Sprintf("%s dropdown doesn't have an option with expected value", dropdownName))
}
// Find gets the descendants of each element in the current set of
// matched elements, filtered by a selector. It returns a new Selection
// object containing these matched elements.

View file

@ -1129,10 +1129,11 @@ func TestIssueUnsubscription(t *testing.T) {
func TestIssueLabelList(t *testing.T) {
defer tests.PrepareTestEnv(t)()
// The label list should always be present. When no labels are selected, .no-select is visible, otherwise hidden.
labelListSelector := ".labels.list .labels-list"
hiddenClass := "tw-hidden"
t.Run("Show label list", func(t *testing.T) {
t.Run("Test label list", func(t *testing.T) {
defer tests.PrintCurrentTest(t)()
req := NewRequest(t, "GET", "/user2/repo1/issues/1")
@ -1140,18 +1141,6 @@ func TestIssueLabelList(t *testing.T) {
htmlDoc := NewHTMLParser(t, resp.Body)
htmlDoc.AssertElement(t, labelListSelector, true)
htmlDoc.AssertElement(t, ".labels.list .no-select.item."+hiddenClass, true)
})
t.Run("Show no label list", func(t *testing.T) {
defer tests.PrintCurrentTest(t)()
session := loginUser(t, "user2")
req := NewRequest(t, "GET", "/user2/repo2/issues/1")
resp := session.MakeRequest(t, req, http.StatusOK)
htmlDoc := NewHTMLParser(t, resp.Body)
htmlDoc.AssertElement(t, labelListSelector, false)
htmlDoc.AssertElement(t, ".labels.list .no-select.item:not([class*='"+hiddenClass+"'])", true)
htmlDoc.AssertElement(t, ".labels.list .no-select."+hiddenClass, true)
})
}

View file

@ -14,6 +14,7 @@ import (
"path/filepath"
"regexp"
"sort"
"strings"
"testing"
"code.gitea.io/gitea/models/db"
@ -174,14 +175,16 @@ func restoreOldDB(t *testing.T, version string) bool {
assert.NoError(t, err)
defer db.Close()
_, err = db.Exec(fmt.Sprintf("DROP DATABASE IF EXISTS %s", setting.Database.Name))
databaseName := strings.SplitN(setting.Database.Name, "?", 2)[0]
_, err = db.Exec(fmt.Sprintf("DROP DATABASE IF EXISTS %s", databaseName))
assert.NoError(t, err)
_, err = db.Exec(fmt.Sprintf("CREATE DATABASE IF NOT EXISTS %s", setting.Database.Name))
_, err = db.Exec(fmt.Sprintf("CREATE DATABASE IF NOT EXISTS %s", databaseName))
assert.NoError(t, err)
db.Close()
db, err = sql.Open("mysql", fmt.Sprintf("%s:%s@tcp(%s)/%s?multiStatements=true",
db, err = sql.Open("mysql", fmt.Sprintf("%s:%s@tcp(%s)/%s",
setting.Database.User, setting.Database.Passwd, setting.Database.Host, setting.Database.Name))
assert.NoError(t, err)
defer db.Close()

View file

@ -6,7 +6,7 @@ package integration
import (
"fmt"
"net/http"
"net/http/httptest"
"strconv"
"strings"
"testing"
@ -18,11 +18,23 @@ import (
"github.com/stretchr/testify/assert"
)
func testRepoGenerate(t *testing.T, session *TestSession, templateID, templateOwnerName, templateRepoName, generateOwnerName, generateRepoName string) *httptest.ResponseRecorder {
generateOwner := unittest.AssertExistsAndLoadBean(t, &user_model.User{Name: generateOwnerName})
func assertRepoCreateForm(t *testing.T, htmlDoc *HTMLDoc, owner *user_model.User, templateID string) {
_, exists := htmlDoc.doc.Find("form.ui.form[action^='/repo/create']").Attr("action")
assert.True(t, exists, "Expected the repo creation form")
htmlDoc.AssertDropdownHasSelectedOption(t, "uid", strconv.FormatInt(owner.ID, 10))
// the template menu is loaded client-side, so don't assert the option exists
assert.Equal(t, templateID, htmlDoc.GetInputValueByName("repo_template"), "Unexpected repo_template selection")
for _, name := range []string{"issue_labels", "gitignores", "license", "readme", "object_format_name"} {
htmlDoc.AssertDropdownHasOptions(t, name)
}
}
func testRepoGenerate(t *testing.T, session *TestSession, templateID, templateOwnerName, templateRepoName string, user, generateOwner *user_model.User, generateRepoName string) {
// Step0: check the existence of the generated repo
req := NewRequestf(t, "GET", "/%s/%s", generateOwnerName, generateRepoName)
req := NewRequestf(t, "GET", "/%s/%s", generateOwner.Name, generateRepoName)
session.MakeRequest(t, req, http.StatusNotFound)
// Step1: go to the main page of template repo
@ -36,12 +48,9 @@ func testRepoGenerate(t *testing.T, session *TestSession, templateID, templateOw
req = NewRequest(t, "GET", link)
resp = session.MakeRequest(t, req, http.StatusOK)
// Step3: fill the form of the create
// Step3: test and submit form
htmlDoc = NewHTMLParser(t, resp.Body)
link, exists = htmlDoc.doc.Find("form.ui.form[action^=\"/repo/create\"]").Attr("action")
assert.True(t, exists, "The template has changed")
_, exists = htmlDoc.doc.Find(fmt.Sprintf(".owner.dropdown .item[data-value=\"%d\"]", generateOwner.ID)).Attr("data-value")
assert.True(t, exists, fmt.Sprintf("Generate owner '%s' is not present in select box", generateOwnerName))
assertRepoCreateForm(t, htmlDoc, user, templateID)
req = NewRequestWithValues(t, "POST", link, map[string]string{
"_csrf": htmlDoc.GetCSRF(),
"uid": fmt.Sprintf("%d", generateOwner.ID),
@ -52,41 +61,66 @@ func testRepoGenerate(t *testing.T, session *TestSession, templateID, templateOw
session.MakeRequest(t, req, http.StatusSeeOther)
// Step4: check the existence of the generated repo
req = NewRequestf(t, "GET", "/%s/%s", generateOwnerName, generateRepoName)
req = NewRequestf(t, "GET", "/%s/%s", generateOwner.Name, generateRepoName)
session.MakeRequest(t, req, http.StatusOK)
// Step5: check substituted values in Readme
req = NewRequestf(t, "GET", "/%s/%s/raw/branch/master/README.md", generateOwnerName, generateRepoName)
req = NewRequestf(t, "GET", "/%s/%s/raw/branch/master/README.md", generateOwner.Name, generateRepoName)
resp = session.MakeRequest(t, req, http.StatusOK)
body := fmt.Sprintf(`# %s Readme
Owner: %s
Link: /%s/%s
Clone URL: %s%s/%s.git`,
generateRepoName,
strings.ToUpper(generateOwnerName),
generateOwnerName,
strings.ToUpper(generateOwner.Name),
generateOwner.Name,
generateRepoName,
setting.AppURL,
generateOwnerName,
generateOwner.Name,
generateRepoName)
assert.Equal(t, body, resp.Body.String())
// Step6: check substituted values in substituted file path ${REPO_NAME}
req = NewRequestf(t, "GET", "/%s/%s/raw/branch/master/%s.log", generateOwnerName, generateRepoName, generateRepoName)
req = NewRequestf(t, "GET", "/%s/%s/raw/branch/master/%s.log", generateOwner.Name, generateRepoName, generateRepoName)
resp = session.MakeRequest(t, req, http.StatusOK)
assert.Equal(t, generateRepoName, resp.Body.String())
}
return resp
// test form elements before and after POST error response
func TestRepoCreateForm(t *testing.T) {
defer tests.PrepareTestEnv(t)()
userName := "user1"
session := loginUser(t, userName)
user := unittest.AssertExistsAndLoadBean(t, &user_model.User{Name: userName})
req := NewRequest(t, "GET", "/repo/create")
resp := session.MakeRequest(t, req, http.StatusOK)
htmlDoc := NewHTMLParser(t, resp.Body)
assertRepoCreateForm(t, htmlDoc, user, "")
req = NewRequestWithValues(t, "POST", "/repo/create", map[string]string{
"_csrf": htmlDoc.GetCSRF(),
})
resp = session.MakeRequest(t, req, http.StatusOK)
htmlDoc = NewHTMLParser(t, resp.Body)
assertRepoCreateForm(t, htmlDoc, user, "")
}
func TestRepoGenerate(t *testing.T) {
defer tests.PrepareTestEnv(t)()
session := loginUser(t, "user1")
testRepoGenerate(t, session, "44", "user27", "template1", "user1", "generated1")
userName := "user1"
session := loginUser(t, userName)
user := unittest.AssertExistsAndLoadBean(t, &user_model.User{Name: userName})
testRepoGenerate(t, session, "44", "user27", "template1", user, user, "generated1")
}
func TestRepoGenerateToOrg(t *testing.T) {
defer tests.PrepareTestEnv(t)()
session := loginUser(t, "user2")
testRepoGenerate(t, session, "44", "user27", "template1", "user2", "generated2")
userName := "user2"
session := loginUser(t, userName)
user := unittest.AssertExistsAndLoadBean(t, &user_model.User{Name: userName})
org := unittest.AssertExistsAndLoadBean(t, &user_model.User{Name: "org3"})
testRepoGenerate(t, session, "44", "user27", "template1", user, org, "generated2")
}

View file

@ -1022,3 +1022,21 @@ func TestRepoCodeSearchForm(t *testing.T) {
testSearchForm(t, true)
})
}
func TestFileHistoryPager(t *testing.T) {
defer tests.PrepareTestEnv(t)()
t.Run("Normal page number", func(t *testing.T) {
defer tests.PrintCurrentTest(t)()
req := NewRequest(t, "GET", "/user2/repo1/commits/branch/master/README.md?page=1")
MakeRequest(t, req, http.StatusOK)
})
t.Run("Too high page number", func(t *testing.T) {
defer tests.PrintCurrentTest(t)()
req := NewRequest(t, "GET", "/user2/repo1/commits/branch/master/README.md?page=9999")
MakeRequest(t, req, http.StatusNotFound)
})
}

View file

@ -380,6 +380,9 @@ func TestUserHints(t *testing.T) {
_, hintChecked := htmlDoc.Find(`input[name="enable_repo_unit_hints"]`).Attr("checked")
assert.Equal(t, enabled, hintChecked)
link, _ := htmlDoc.Find("form[action='/user/settings/appearance/language'] a").Attr("href")
assert.EqualValues(t, "https://forgejo.org/docs/latest/developer/localization/", link)
}
t.Run("view", func(t *testing.T) {

View file

@ -12,6 +12,7 @@ import (
"path"
"path/filepath"
"runtime"
"strings"
"testing"
"time"
@ -106,7 +107,7 @@ func InitTest(requireGitea bool) {
if err != nil {
log.Fatal("sql.Open: %v", err)
}
if _, err = db.Exec(fmt.Sprintf("CREATE DATABASE IF NOT EXISTS %s", setting.Database.Name)); err != nil {
if _, err = db.Exec(fmt.Sprintf("CREATE DATABASE IF NOT EXISTS %s", strings.SplitN(setting.Database.Name, "?", 2)[0])); err != nil {
log.Fatal("db.Exec: %v", err)
}
case setting.Database.Type.IsPostgreSQL():

Some files were not shown because too many files have changed in this diff Show more