diff --git a/.deadcode-out b/.deadcode-out index cf5f7c479b..dc4aa0e498 100644 --- a/.deadcode-out +++ b/.deadcode-out @@ -84,7 +84,6 @@ package "code.gitea.io/gitea/models/repo" func (*releaseSorter).Swap func SortReleases func FindReposMapByIDs - func RepositoryListOfMap func (SearchOrderBy).String func IsErrTopicNotExist func (ErrTopicNotExist).Error @@ -178,6 +177,7 @@ package "code.gitea.io/gitea/modules/git" func (ErrExecTimeout).Error func (ErrUnsupportedVersion).Error func SetUpdateHook + func GetObjectFormatOfRepo func openRepositoryWithDefaultContext func IsTagExist func ToEntryMode @@ -189,6 +189,7 @@ package "code.gitea.io/gitea/modules/gitgraph" package "code.gitea.io/gitea/modules/gitrepo" func GetBranchCommitID + func GetWikiDefaultBranch package "code.gitea.io/gitea/modules/graceful" func (*Manager).TerminateContext @@ -221,7 +222,6 @@ package "code.gitea.io/gitea/modules/markup/markdown" func IsSummary func IsTaskCheckBoxListItem func IsIcon - func IsColorPreview func RenderRawString package "code.gitea.io/gitea/modules/markup/markdown/math" @@ -291,9 +291,6 @@ package "code.gitea.io/gitea/modules/translation" func (MockLocale).TrN func (MockLocale).PrettyNumber -package "code.gitea.io/gitea/modules/util" - func UnsafeStringToBytes - package "code.gitea.io/gitea/modules/util/filebuffer" func CreateFromReader diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index 9e290fb6a5..8563aafd04 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -8,7 +8,9 @@ }, "ghcr.io/devcontainers/features/git-lfs:1.1.0": {}, "ghcr.io/devcontainers-contrib/features/poetry:2": {}, - "ghcr.io/devcontainers/features/python:1": {} + "ghcr.io/devcontainers/features/python:1": { + "version": "3.12" + } }, "customizations": { "vscode": { diff --git a/.eslintrc.yaml b/.eslintrc.yaml index e9991c02ba..b62b13cefe 100644 --- a/.eslintrc.yaml +++ b/.eslintrc.yaml @@ -283,7 +283,7 @@ rules: i/unambiguous: [0] init-declarations: [0] jquery/no-ajax-events: [2] - jquery/no-ajax: [0] + jquery/no-ajax: [2] jquery/no-animate: [2] jquery/no-attr: [0] jquery/no-bind: [2] @@ -315,7 +315,7 @@ rules: jquery/no-parent: [0] jquery/no-parents: [0] jquery/no-parse-html: [2] - jquery/no-prop: [0] + jquery/no-prop: [2] jquery/no-proxy: [2] jquery/no-ready: [2] jquery/no-serialize: [2] @@ -396,11 +396,11 @@ rules: no-irregular-whitespace: [2] no-iterator: [2] no-jquery/no-ajax-events: [2] - no-jquery/no-ajax: [0] + no-jquery/no-ajax: [2] no-jquery/no-and-self: [2] no-jquery/no-animate-toggle: [2] no-jquery/no-animate: [2] - no-jquery/no-append-html: [0] + no-jquery/no-append-html: [2] no-jquery/no-attr: [0] no-jquery/no-bind: [2] no-jquery/no-box-model: [2] @@ -466,7 +466,7 @@ rules: no-jquery/no-parse-html: [2] no-jquery/no-parse-json: [2] no-jquery/no-parse-xml: [2] - no-jquery/no-prop: [0] + no-jquery/no-prop: [2] no-jquery/no-proxy: [2] no-jquery/no-ready-shorthand: [2] no-jquery/no-ready: [2] @@ -487,7 +487,7 @@ rules: no-jquery/no-visibility: [2] no-jquery/no-when: [2] no-jquery/no-wrap: [2] - no-jquery/variable-pattern: [0] + no-jquery/variable-pattern: [2] no-label-var: [2] no-labels: [0] # handled by no-restricted-syntax no-lone-blocks: [2] diff --git a/.forgejo/cascading-pr-end-to-end b/.forgejo/cascading-pr-end-to-end index 2350394f2c..d7a6b46b48 100755 --- a/.forgejo/cascading-pr-end-to-end +++ b/.forgejo/cascading-pr-end-to-end @@ -9,9 +9,15 @@ forgejo_pr_or_ref=$4 cd $forgejo full_version=$(make show-version-full) -major_version=$(make show-version-major) +minor_version=$(make show-version-minor) cd $end_to_end + +if ! test -f forgejo/sources/$minor_version ; then + echo "FAIL: forgejo/sources/$minor_version does not exist in the end-to-end repository" + false +fi + date > last-upgrade if test -f "$forgejo_pr_or_ref" ; then @@ -20,11 +26,8 @@ if test -f "$forgejo_pr_or_ref" ; then test "$head_url" != null branch=$(jq --raw-output .head.ref < $forgejo_pr) test "$branch" != null - echo $head_url $branch $full_version > forgejo/sources/$major_version + echo $head_url $branch $full_version > forgejo/sources/$minor_version else forgejo_ref=$forgejo_pr_or_ref - echo $GITHUB_SERVER_URL/$GITHUB_REPOSITORY ${forgejo_ref#refs/heads/} $full_version > forgejo/sources/$major_version + echo $GITHUB_SERVER_URL/$GITHUB_REPOSITORY ${forgejo_ref#refs/heads/} $full_version > forgejo/sources/$minor_version fi - -test "$GITHUB_RUN_NUMBER" -echo $GITHUB_SERVER_URL/$GITHUB_REPOSITORY/actions/runs/$GITHUB_RUN_NUMBER/artifacts/forgejo > forgejo/binary-url diff --git a/.forgejo/cascading-release-end-to-end b/.forgejo/cascading-release-end-to-end index 7b43c89ed8..08ad8a4431 100755 --- a/.forgejo/cascading-release-end-to-end +++ b/.forgejo/cascading-release-end-to-end @@ -9,4 +9,14 @@ forgejo_ref=$4 cd $end_to_end date > last-upgrade -echo $FORGEJO_BINARY > forgejo/binary-url +organizations=lib/ORGANIZATIONS +if ! test -f $organizations ; then + echo "$organizations file not found" + false +fi +# +# do not include forgejo-experimental so that 7.0-test is found +# in forgejo-integration where it was just built instead of +# forgejo-experimental which was published by the previous build +# +echo forgejo forgejo-integration > $organizations diff --git a/.forgejo/workflows/backport.yml b/.forgejo/workflows/backport.yml new file mode 100644 index 0000000000..59d953ebeb --- /dev/null +++ b/.forgejo/workflows/backport.yml @@ -0,0 +1,81 @@ +# Copyright 2024 The Forgejo Authors +# SPDX-License-Identifier: MIT +# +# To modify this workflow: +# +# - change pull_request_target: to pull_request: +# so that it runs from a pull request instead of the default branch +# +# - push it to the wip-ci-backport branch on the forgejo repository +# otherwise it will not have access to the secrets required to push +# the PR +# +# - open a pull request targetting wip-ci-backport that includes a change +# that can be backported without conflict in v1.21 and set the +# `backport/v1.21` label. +# +# - once it works, open a pull request for the sake of keeping track +# of the change even if the PR won't run it because it will use +# whatever is in the default branch instead +# +# - after it is merged, double check it works by setting a +# `backport/v1.21` label on a merged pull request that can be backported +# without conflict. +# +on: + pull_request_target: + types: + - closed + - labeled + +jobs: + backporting: + if: > + !startsWith(vars.ROLE, 'forgejo-') && ( + github.event.pull_request.merged + && ( + github.event.action == 'closed' + || ( + github.event.action == 'labeled' + && contains(github.event.label.name, 'backport/') + ) + ) + ) + runs-on: docker + container: + image: 'docker.io/node:20-bookworm' + steps: + - name: Fetch labels + id: fetch-labels + shell: bash + run: | + set -x + echo "Labels retrieved below" + export DEBIAN_FRONTEND=noninteractive + apt-get update -qq + apt-get -q install -qq -y jq + filtered_labels=$(echo "$LABELS" | jq -c 'map(select(.name | startswith("backport/")))') + echo "FILTERED_LABELS=${filtered_labels}" >> $GITHUB_ENV + env: + LABELS: ${{ toJSON(github.event.pull_request.labels) }} + - name: Extract targets + id: extract-targets + shell: bash + run: | + set -x + targets="$(echo $FILTERED_LABELS | jq -c '[.[] | .name | sub("backport/"; "")]')" + echo "targets=$(echo $targets)" >> $GITHUB_OUTPUT + + - name: Printing info + shell: bash + run: | + echo "targets: ${{ steps.extract-targets.outputs.targets }}" + echo "target-branch: ${{ fromJSON(steps.extract-targets.outputs.targets)[0] }}" + echo "pull-request: ${{ github.event.pull_request.url }}" + + - uses: https://code.forgejo.org/actions/git-backporting@v4.5.2 + with: + target-branch: ${{ fromJSON(steps.extract-targets.outputs.targets)[0] }}/forgejo + no-squash: true + auth: ${{ secrets.BACKPORT_TOKEN }} + pull-request: ${{ github.event.pull_request.url }} diff --git a/.forgejo/workflows/build-release.yml b/.forgejo/workflows/build-release.yml index c012991b3a..19423205af 100644 --- a/.forgejo/workflows/build-release.yml +++ b/.forgejo/workflows/build-release.yml @@ -203,11 +203,9 @@ jobs: destination-url: https://code.forgejo.org destination-fork-repo: ${{ vars.CASCADE_DESTINATION_DOER }}/end-to-end destination-repo: forgejo/end-to-end - destination-branch: forgejo-pr + destination-branch: main destination-token: ${{ secrets.CASCADE_DESTINATION_TOKEN }} update: .forgejo/cascading-release-end-to-end - env: - FORGEJO_BINARY: "${{ env.GITHUB_SERVER_URL }}/${{ github.repository }}/releases/download/v${{ steps.release-info.outputs.version }}/forgejo-${{ steps.release-info.outputs.version }}-linux-amd64" - name: copy to experimental if: vars.ROLE == 'forgejo-integration' && secrets.TOKEN != '' diff --git a/.forgejo/workflows/cascade-setup-end-to-end.yml b/.forgejo/workflows/cascade-setup-end-to-end.yml index 85871ec31d..dcca2404d9 100644 --- a/.forgejo/workflows/cascade-setup-end-to-end.yml +++ b/.forgejo/workflows/cascade-setup-end-to-end.yml @@ -42,45 +42,6 @@ jobs: ${{ toJSON(github.event) }} EOF - build: - if: > - !startsWith(vars.ROLE, 'forgejo-') && ( - github.event_name == 'push' || - ( - github.event.action == 'label_updated' && contains(github.event.pull_request.labels.*.name, 'run-end-to-end-tests') - ) - ) - runs-on: docker - container: - image: 'docker.io/node:20-bookworm' - steps: - - uses: https://code.forgejo.org/actions/checkout@v3 - with: - fetch-depth: '0' - show-progress: 'false' - - name: adduser forgejo - run: | - git config --add safe.directory '*' - git config user.email "you@example.com" - git config user.name "Your Name" - adduser --quiet --comment forgejo --disabled-password forgejo - chown -R forgejo:forgejo . - - uses: https://code.forgejo.org/actions/setup-go@v4 - with: - go-version: "1.21" - - name: make deps-backend - run: | - su forgejo -c 'make deps-backend' - - name: make forgejo - run: | - su forgejo -c 'make generate-backend static-executable && ln gitea forgejo' - env: - TAGS: bindata sqlite sqlite_unlock_notify - - uses: actions/upload-artifact@v3 - with: - name: forgejo - path: forgejo - cascade: if: > !startsWith(vars.ROLE, 'forgejo-') && ( @@ -89,7 +50,6 @@ jobs: github.event.action == 'label_updated' && contains(github.event.pull_request.labels.*.name, 'run-end-to-end-tests') ) ) - needs: [build] runs-on: docker container: image: node:20-bookworm @@ -108,7 +68,7 @@ jobs: destination-url: https://code.forgejo.org destination-fork-repo: cascading-pr/end-to-end destination-repo: forgejo/end-to-end - destination-branch: forgejo-pr + destination-branch: main destination-token: ${{ secrets.END_TO_END_CASCADING_PR_DESTINATION }} close-merge: true update: .forgejo/cascading-pr-end-to-end diff --git a/.forgejo/workflows/testing.yml b/.forgejo/workflows/testing.yml index 80fd87152e..85d7691cd1 100644 --- a/.forgejo/workflows/testing.yml +++ b/.forgejo/workflows/testing.yml @@ -21,8 +21,6 @@ jobs: check-latest: true - run: make deps-backend deps-tools - run: make --always-make -j$(nproc) lint-backend checks-backend # ensure the "go-licenses" make target runs - env: - TAGS: bindata sqlite sqlite_unlock_notify frontend-checks: if: ${{ !startsWith(vars.ROLE, 'forgejo-') }} runs-on: docker @@ -43,8 +41,11 @@ jobs: image: 'docker.io/node:20-bookworm' services: minio: - image: 'docker.io/bitnami/minio:2023.8.31' + image: bitnami/minio:2024.2.26 + options: >- + --hostname gitea.minio env: + MINIO_DOMAIN: minio MINIO_ROOT_USER: 123456 MINIO_ROOT_PASSWORD: 12345678 steps: @@ -130,10 +131,10 @@ jobs: image: 'docker.io/node:20-bookworm' services: minio: - image: bitnami/minio:2021.3.17 + image: bitnami/minio:2024.2.26 env: - MINIO_ACCESS_KEY: 123456 - MINIO_SECRET_KEY: 12345678 + MINIO_ROOT_USER: 123456 + MINIO_ROOT_PASSWORD: 12345678 pgsql: image: 'docker.io/postgres:15' env: diff --git a/Makefile b/Makefile index bc3837f065..6735ffd1a5 100644 --- a/Makefile +++ b/Makefile @@ -91,9 +91,11 @@ STORED_VERSION=$(shell cat $(STORED_VERSION_FILE) 2>/dev/null) ifneq ($(STORED_VERSION),) FORGEJO_VERSION ?= $(STORED_VERSION) else - FORGEJO_VERSION ?= $(shell git describe --exclude '*-test' --tags --always | sed 's/^v//')+${GITEA_COMPATIBILITY} + # drop the "g" prefix prepended by git describe to the commit hash + FORGEJO_VERSION ?= $(shell git describe --exclude '*-test' --tags --always | sed 's/^v//' | sed 's/\-g/-/')+${GITEA_COMPATIBILITY} endif FORGEJO_VERSION_MAJOR=$(shell echo $(FORGEJO_VERSION) | sed -e 's/\..*//') +FORGEJO_VERSION_MINOR=$(shell echo $(FORGEJO_VERSION) | sed -E -e 's/^([0-9]+\.[0-9]+).*/\1/') show-version-full: @echo ${FORGEJO_VERSION} @@ -101,6 +103,9 @@ show-version-full: show-version-major: @echo ${FORGEJO_VERSION_MAJOR} +show-version-minor: + @echo ${FORGEJO_VERSION_MINOR} + RELEASE_VERSION ?= ${FORGEJO_VERSION} VERSION ?= ${RELEASE_VERSION} @@ -313,12 +318,8 @@ fmt: .PHONY: fmt-check fmt-check: fmt - @diff=$$(git diff --color=always $(GO_SOURCES) templates $(WEB_DIRS)); \ - if [ -n "$$diff" ]; then \ - echo "Please run 'make fmt' and commit the result:"; \ - echo "$${diff}"; \ - exit 1; \ - fi + @git diff --exit-code --color=always $(GO_SOURCES) templates $(WEB_DIRS) \ + || (code=$$?; echo "Please run 'make fmt' and commit the result"; exit $${code}) .PHONY: $(TAGS_EVIDENCE) $(TAGS_EVIDENCE): @@ -339,12 +340,8 @@ generate-forgejo-api: $(FORGEJO_API_SPEC) .PHONY: forgejo-api-check forgejo-api-check: generate-forgejo-api - @diff=$$(git diff $(FORGEJO_API_SERVER) ; \ - if [ -n "$$diff" ]; then \ - echo "Please run 'make generate-forgejo-api' and commit the result:"; \ - echo "$${diff}"; \ - exit 1; \ - fi + @git diff --exit-code --color=always $(FORGEJO_API_SERVER) \ + || (code=$$?; echo "Please run 'make generate-forgejo-api' and commit the result"; exit $${code}) .PHONY: forgejo-api-validate forgejo-api-validate: @@ -361,12 +358,8 @@ $(SWAGGER_SPEC): $(GO_SOURCES_NO_BINDATA) .PHONY: swagger-check swagger-check: generate-swagger - @diff=$$(git diff --color=always '$(SWAGGER_SPEC)'); \ - if [ -n "$$diff" ]; then \ - echo "Please run 'make generate-swagger' and commit the result:"; \ - echo "$${diff}"; \ - exit 1; \ - fi + @git diff --exit-code --color=always '$(SWAGGER_SPEC)' \ + || (code=$$?; echo "Please run 'make generate-swagger' and commit the result"; exit $${code}) .PHONY: swagger-validate swagger-validate: @@ -437,11 +430,8 @@ lint-spell-fix: lint-go: $(GO) run $(GOLANGCI_LINT_PACKAGE) run $(GOLANGCI_LINT_ARGS) $(GO) run $(DEADCODE_PACKAGE) -generated=false -test code.gitea.io/gitea > .cur-deadcode-out - @$(DIFF) .deadcode-out .cur-deadcode-out; \ - if [ $$? -eq 1 ]; then \ - echo "Please run 'make lint-go-fix' and commit the result"; \ - exit 1; \ - fi + @$(DIFF) .deadcode-out .cur-deadcode-out \ + || (code=$$?; echo "Please run 'make lint-go-fix' and commit the result"; exit $${code}) .PHONY: lint-go-fix lint-go-fix: @@ -541,12 +531,8 @@ vendor: go.mod go.sum .PHONY: tidy-check tidy-check: tidy - @diff=$$(git diff --color=always go.mod go.sum $(GO_LICENSE_FILE)); \ - if [ -n "$$diff" ]; then \ - echo "Please run 'make tidy' and commit the result:"; \ - echo "$${diff}"; \ - exit 1; \ - fi + @git diff --exit-code --color=always go.mod go.sum $(GO_LICENSE_FILE) \ + || (code=$$?; echo "Please run 'make tidy' and commit the result"; exit $${code}) .PHONY: go-licenses go-licenses: $(GO_LICENSE_FILE) @@ -899,10 +885,6 @@ release-sources: | $(DIST_DIRS) release-docs: | $(DIST_DIRS) docs tar -czf $(DIST)/release/gitea-docs-$(VERSION).tar.gz -C ./docs . -.PHONY: docs -docs: - cd docs; bash scripts/trans-copy.sh; - .PHONY: deps deps: deps-frontend deps-backend deps-tools deps-py @@ -961,6 +943,7 @@ fomantic: cd $(FOMANTIC_WORK_DIR) && npm install --no-save cp -f $(FOMANTIC_WORK_DIR)/theme.config.less $(FOMANTIC_WORK_DIR)/node_modules/fomantic-ui/src/theme.config cp -rf $(FOMANTIC_WORK_DIR)/_site $(FOMANTIC_WORK_DIR)/node_modules/fomantic-ui/src/ + $(SED_INPLACE) -e 's/ overrideBrowserslist\r/ overrideBrowserslist: ["defaults"]\r/g' $(FOMANTIC_WORK_DIR)/node_modules/fomantic-ui/tasks/config/tasks.js cd $(FOMANTIC_WORK_DIR) && npx gulp -f node_modules/fomantic-ui/gulpfile.js build # fomantic uses "touchstart" as click event for some browsers, it's not ideal, so we force fomantic to always use "click" as click event $(SED_INPLACE) -e 's/clickEvent[ \t]*=/clickEvent = "click", unstableClickEvent =/g' $(FOMANTIC_WORK_DIR)/build/semantic.js @@ -984,23 +967,14 @@ svg: node-check | node_modules .PHONY: svg-check svg-check: svg @git add $(SVG_DEST_DIR) - @diff=$$(git diff --color=always --cached $(SVG_DEST_DIR)); \ - if [ -n "$$diff" ]; then \ - echo "Please run 'make svg' and 'git add $(SVG_DEST_DIR)' and commit the result:"; \ - echo "$${diff}"; \ - exit 1; \ - fi + @git diff --exit-code --color=always --cached $(SVG_DEST_DIR) \ + || (code=$$?; echo "Please run 'make svg' and commit the result"; exit $${code}) .PHONY: lockfile-check lockfile-check: npm install --package-lock-only - @diff=$$(git diff --color=always package-lock.json); \ - if [ -n "$$diff" ]; then \ - echo "package-lock.json is inconsistent with package.json"; \ - echo "Please run 'npm install --package-lock-only' and commit the result:"; \ - echo "$${diff}"; \ - exit 1; \ - fi + @git diff --exit-code --color=always package-lock.json \ + || (code=$$?; echo "Please run 'npm install --package-lock-only' and commit the result"; exit $${code}) .PHONY: update-translations update-translations: diff --git a/RELEASE-NOTES.md b/RELEASE-NOTES.md index 4e87078811..228511989a 100644 --- a/RELEASE-NOTES.md +++ b/RELEASE-NOTES.md @@ -4,6 +4,40 @@ A Forgejo release is published shortly after a Gitea release is published and th The Forgejo admin should carefully read the required manual actions before upgrading. A point release (e.g. v1.21.1-0 or v1.21.2-0) does not require manual actions but others might (e.g. v1.20, v1.21). +## 1.21.8-0 + +The [complete list of commits](https://codeberg.org/forgejo/forgejo/commits/branch/v1.21/forgejo) included in the `Forgejo v1.21.8-0` release can be reviewed from the command line with: + +```shell +$ git clone https://codeberg.org/forgejo/forgejo/ +$ git -C forgejo log --oneline --no-merges v1.21.7-0..v1.21.8-0 +``` + +This stable release contains bug fixes. + +* Recommended Action + + We recommend that all Forgejo installations are [upgraded](https://forgejo.org/docs/v1.21/admin/upgrade/) to the latest version. + +* [Forgejo Semantic Version](https://forgejo.org/docs/v1.21/user/semver/) + + The semantic version was updated to `6.0.8+0-gitea-1.21.8` + +* Bug fixes + + The most prominent ones are described here, others can be found in the list of commits included in the release as described above. + + * [Fix `/api/v1/{owner}/{repo}/issue_templates`](https://codeberg.org/forgejo/forgejo/commit/969d3f44101402afd9dd848e79dd5823d547a00d) which was always failing with a 500 error. + * [Prevent error 500 on /user/settings/security when SignedUser has a linked account from a deactivated authentication source](https://codeberg.org/forgejo/forgejo/commit/d9418651af8c8a3276ebc40a516109c0f33139b0). + * [Fix error 500 when pushing release to an empty repo](https://codeberg.org/forgejo/forgejo/commit/b76f370a3f8993638cad91547491b46631776f59). + * [Fix incorrect rendering csv file when file size is larger than UI.CSV.MaxFileSize](https://codeberg.org/forgejo/forgejo/commit/e151e0467341bd25a2465ca15e81ebc0c8fa3fc4). + * [Fix error 500 when deleting account with incorrect password or unsupported login type](https://codeberg.org/forgejo/forgejo/commit/66061d28286ee3adf69747c284d40121e2e4b280). + * [handle user-defined `name` anchors like `[Link](#link)` linking to `Link`](https://codeberg.org/forgejo/forgejo/commit/03caefbb02854d5c98a26d889e0e30c910651395). + * [Use correct head commit for CODEOWNER](https://codeberg.org/forgejo/forgejo/commit/d1cebb0e884a88941e27e2280e117cc04d2665fe). + * [Fix manual merge button](https://codeberg.org/forgejo/forgejo/commit/c70719c59c410e5378c04926c66461d7b9f72884). + * [Make meilisearch do exact search for issues](https://codeberg.org/forgejo/forgejo/commit/a876ac2c7934fa0f8a66424e178b501e4a341e0f). + * [Fix PR creation via api between branches of same repo with head field namespaced](https://codeberg.org/forgejo/forgejo/commit/120a173e24fd359b0b57f2bd1021168645fab5a8). + ## 1.21.7-0 The [complete list of commits](https://codeberg.org/forgejo/forgejo/commits/branch/v1.21/forgejo) included in the `Forgejo v1.21.7-0` release can be reviewed from the command line with: diff --git a/assets/go-licenses.json b/assets/go-licenses.json index 2aab21595b..ad3ab6c4c1 100644 --- a/assets/go-licenses.json +++ b/assets/go-licenses.json @@ -34,6 +34,11 @@ "path": "dario.cat/mergo/LICENSE", "licenseText": "Copyright (c) 2013 Dario Castañé. All rights reserved.\nCopyright (c) 2012 The Go Authors. All rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are\nmet:\n\n * Redistributions of source code must retain the above copyright\nnotice, this list of conditions and the following disclaimer.\n * Redistributions in binary form must reproduce the above\ncopyright notice, this list of conditions and the following disclaimer\nin the documentation and/or other materials provided with the\ndistribution.\n * Neither the name of Google Inc. nor the names of its\ncontributors may be used to endorse or promote products derived from\nthis software without specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n\"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\nLIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\nA PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\nOWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\nSPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\nLIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\nDATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\nTHEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\nOF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n" }, + { + "name": "filippo.io/edwards25519", + "path": "filippo.io/edwards25519/LICENSE", + "licenseText": "Copyright (c) 2009 The Go Authors. All rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are\nmet:\n\n * Redistributions of source code must retain the above copyright\nnotice, this list of conditions and the following disclaimer.\n * Redistributions in binary form must reproduce the above\ncopyright notice, this list of conditions and the following disclaimer\nin the documentation and/or other materials provided with the\ndistribution.\n * Neither the name of Google Inc. nor the names of its\ncontributors may be used to endorse or promote products derived from\nthis software without specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n\"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\nLIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\nA PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\nOWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\nSPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\nLIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\nDATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\nTHEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\nOF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n" + }, { "name": "git.sr.ht/~mariusor/go-xsd-duration", "path": "git.sr.ht/~mariusor/go-xsd-duration/LICENSE", diff --git a/cmd/admin_user_create.go b/cmd/admin_user_create.go index a257ce21c8..10965c7e8f 100644 --- a/cmd/admin_user_create.go +++ b/cmd/admin_user_create.go @@ -47,7 +47,8 @@ var microcmdUserCreate = &cli.Command{ }, &cli.BoolFlag{ Name: "must-change-password", - Usage: "Set this option to false to prevent forcing the user to change their password after initial login, (Default: true)", + Usage: "Set this option to false to prevent forcing the user to change their password after initial login", + Value: true, }, &cli.IntFlag{ Name: "random-password-length", @@ -110,8 +111,7 @@ func runCreateUser(c *cli.Context) error { return errors.New("must set either password or random-password flag") } - // always default to true - changePassword := true + changePassword := c.Bool("must-change-password") // If this is the first user being created. // Take it as the admin and don't force a password update. @@ -119,10 +119,6 @@ func runCreateUser(c *cli.Context) error { changePassword = false } - if c.IsSet("must-change-password") { - changePassword = c.Bool("must-change-password") - } - restricted := optional.None[bool]() if c.IsSet("restricted") { diff --git a/custom/conf/app.example.ini b/custom/conf/app.example.ini index 4d077643f5..9853a8e050 100644 --- a/custom/conf/app.example.ini +++ b/custom/conf/app.example.ini @@ -1496,10 +1496,11 @@ LEVEL = Info ;; ;; Default configuration for email notifications for users (user configurable). Options: enabled, onmention, disabled ;DEFAULT_EMAIL_NOTIFICATIONS = enabled -;; Disabled features for users, could be "deletion","manage_gpg_keys" more features can be disabled in future +;; Send an email to all admins when a new user signs up to inform the admins about this act. Options: true, false ;SEND_NOTIFICATION_EMAIL_ON_NEW_USER = false -;; Disabled features for users, could be "deletion", more features can be disabled in future +;; Disabled features for users, could be "deletion", "manage_ssh_keys","manage_gpg_keys" more features can be disabled in future ;; - deletion: a user cannot delete their own account +;; - manage_ssh_keys: a user cannot configure ssh keys ;; - manage_gpg_keys: a user cannot configure gpg keys ;USER_DISABLED_FEATURES = @@ -2622,7 +2623,7 @@ LEVEL = Info ;ENDLESS_TASK_TIMEOUT = 3h ;; Timeout to cancel the jobs which have waiting status, but haven't been picked by a runner for a long time ;ABANDONED_JOB_TIMEOUT = 24h -;; Strings committers can place inside a commit message to skip executing the corresponding actions workflow +;; Strings committers can place inside a commit message or PR title to skip executing the corresponding actions workflow ;SKIP_WORKFLOW_STRINGS = [skip ci],[ci skip],[no ci],[skip actions],[actions skip] ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; diff --git a/docs/content/administration/config-cheat-sheet.en-us.md b/docs/content/administration/config-cheat-sheet.en-us.md index ea6e1eb1a4..8ca1dd3b2b 100644 --- a/docs/content/administration/config-cheat-sheet.en-us.md +++ b/docs/content/administration/config-cheat-sheet.en-us.md @@ -518,9 +518,10 @@ And the following unique queues: - `DEFAULT_EMAIL_NOTIFICATIONS`: **enabled**: Default configuration for email notifications for users (user configurable). Options: enabled, onmention, disabled - `DISABLE_REGULAR_ORG_CREATION`: **false**: Disallow regular (non-admin) users from creating organizations. -- `USER_DISABLED_FEATURES`: **_empty_** Disabled features for users, could be `deletion`, `manage_gpg_keys` and more features can be added in future. +- `USER_DISABLED_FEATURES`: **_empty_** Disabled features for users, could be `deletion`, `manage_ssh_keys`, `manage_gpg_keys` and more features can be added in future. - `deletion`: User cannot delete their own account. - - `manage_gpg_keys`: User cannot configure gpg keys + - `manage_ssh_keys`: User cannot configure ssh keys. + - `manage_gpg_keys`: User cannot configure gpg keys. ## Security (`security`) @@ -831,7 +832,7 @@ Default templates for project boards: ## Issue and pull request attachments (`attachment`) - `ENABLED`: **true**: Whether issue and pull request attachments are enabled. -- `ALLOWED_TYPES`: **.csv,.docx,.fodg,.fodp,.fods,.fodt,.gif,.gz,.jpeg,.jpg,.log,.md,.mov,.mp4,.odf,.odg,.odp,.ods,.odt,.patch,.pdf,.png,.pptx,.svg,.tgz,.txt,.webm,.xls,.xlsx,.zip**: Comma-separated list of allowed file extensions (`.zip`), mime types (`text/plain`) or wildcard type (`image/*`, `audio/*`, `video/*`). Empty value or `*/*` allows all types. +- `ALLOWED_TYPES`: **.cpuprofile,.csv,.dmp,.docx,.fodg,.fodp,.fods,.fodt,.gif,.gz,.jpeg,.jpg,.json,.jsonc,.log,.md,.mov,.mp4,.odf,.odg,.odp,.ods,.odt,.patch,.pdf,.png,.pptx,.svg,.tgz,.txt,.webm,.xls,.xlsx,.zip**: Comma-separated list of allowed file extensions (`.zip`), mime types (`text/plain`) or wildcard type (`image/*`, `audio/*`, `video/*`). Empty value or `*/*` allows all types. - `MAX_SIZE`: **2048**: Maximum size (MB). - `MAX_FILES`: **5**: Maximum number of attachments that can be uploaded at once. - `STORAGE_TYPE`: **local**: Storage type for attachments, `local` for local disk or `minio` for s3 compatible object storage service, default is `local` or other name defined with `[storage.xxx]` @@ -841,6 +842,10 @@ Default templates for project boards: - `MINIO_ACCESS_KEY_ID`: Minio accessKeyID to connect only available when STORAGE_TYPE is `minio` - `MINIO_SECRET_ACCESS_KEY`: Minio secretAccessKey to connect only available when STORAGE_TYPE is `minio` - `MINIO_BUCKET`: **gitea**: Minio bucket to store the attachments only available when STORAGE_TYPE is `minio` +- `MINIO_BUCKET_LOOKUP`: **auto**: Minio bucket lookup type only available when `STORAGE_TYPE` is `minio` + - `auto` Auto detect + - `dns` Virtual Host Style bucket lookup + - `path` Path style bucket lookup - `MINIO_LOCATION`: **us-east-1**: Minio location to create bucket only available when STORAGE_TYPE is `minio` - `MINIO_BASE_PATH`: **attachments/**: Minio base path on the bucket only available when STORAGE_TYPE is `minio` - `MINIO_USE_SSL`: **false**: Minio enabled ssl only available when STORAGE_TYPE is `minio` @@ -1271,6 +1276,10 @@ is `data/lfs` and the default of `MINIO_BASE_PATH` is `lfs/`. - `MINIO_ACCESS_KEY_ID`: Minio accessKeyID to connect only available when `STORAGE_TYPE` is `minio` - `MINIO_SECRET_ACCESS_KEY`: Minio secretAccessKey to connect only available when `STORAGE_TYPE is` `minio` - `MINIO_BUCKET`: **gitea**: Minio bucket to store the lfs only available when `STORAGE_TYPE` is `minio` +- `MINIO_BUCKET_LOOKUP`: **auto**: Minio bucket lookup type only available when `STORAGE_TYPE` is `minio` + - `auto` Auto detect + - `dns` Virtual Host Style bucket lookup + - `path` Path style bucket lookup - `MINIO_LOCATION`: **us-east-1**: Minio location to create bucket only available when `STORAGE_TYPE` is `minio` - `MINIO_BASE_PATH`: **lfs/**: Minio base path on the bucket only available when `STORAGE_TYPE` is `minio` - `MINIO_USE_SSL`: **false**: Minio enabled ssl only available when `STORAGE_TYPE` is `minio` @@ -1286,6 +1295,10 @@ Default storage configuration for attachments, lfs, avatars, repo-avatars, repo- - `MINIO_ACCESS_KEY_ID`: Minio accessKeyID to connect only available when `STORAGE_TYPE` is `minio` - `MINIO_SECRET_ACCESS_KEY`: Minio secretAccessKey to connect only available when `STORAGE_TYPE is` `minio` - `MINIO_BUCKET`: **gitea**: Minio bucket to store the data only available when `STORAGE_TYPE` is `minio` +- `MINIO_BUCKET_LOOKUP`: **auto**: Minio bucket lookup type only available when `STORAGE_TYPE` is `minio` + - `auto` Auto detect + - `dns` Virtual Host Style bucket lookup + - `path` Path style bucket lookup - `MINIO_LOCATION`: **us-east-1**: Minio location to create bucket only available when `STORAGE_TYPE` is `minio` - `MINIO_USE_SSL`: **false**: Minio enabled ssl only available when `STORAGE_TYPE` is `minio` - `MINIO_INSECURE_SKIP_VERIFY`: **false**: Minio skip SSL verification available when STORAGE_TYPE is `minio` @@ -1371,6 +1384,10 @@ is `data/repo-archive` and the default of `MINIO_BASE_PATH` is `repo-archive/`. - `MINIO_ACCESS_KEY_ID`: Minio accessKeyID to connect only available when `STORAGE_TYPE` is `minio` - `MINIO_SECRET_ACCESS_KEY`: Minio secretAccessKey to connect only available when `STORAGE_TYPE is` `minio` - `MINIO_BUCKET`: **gitea**: Minio bucket to store the lfs only available when `STORAGE_TYPE` is `minio` +- `MINIO_BUCKET_LOOKUP`: **auto**: Minio bucket lookup type only available when `STORAGE_TYPE` is `minio` + - `auto` Auto detect + - `dns` Virtual Host Style bucket lookup + - `path` Path style bucket lookup - `MINIO_LOCATION`: **us-east-1**: Minio location to create bucket only available when `STORAGE_TYPE` is `minio` - `MINIO_BASE_PATH`: **repo-archive/**: Minio base path on the bucket only available when `STORAGE_TYPE` is `minio` - `MINIO_USE_SSL`: **false**: Minio enabled ssl only available when `STORAGE_TYPE` is `minio` @@ -1405,7 +1422,7 @@ PROXY_HOSTS = *.github.com - `ZOMBIE_TASK_TIMEOUT`: **10m**: Timeout to stop the task which have running status, but haven't been updated for a long time - `ENDLESS_TASK_TIMEOUT`: **3h**: Timeout to stop the tasks which have running status and continuous updates, but don't end for a long time - `ABANDONED_JOB_TIMEOUT`: **24h**: Timeout to cancel the jobs which have waiting status, but haven't been picked by a runner for a long time -- `SKIP_WORKFLOW_STRINGS`: **[skip ci],[ci skip],[no ci],[skip actions],[actions skip]**: Strings committers can place inside a commit message to skip executing the corresponding actions workflow +- `SKIP_WORKFLOW_STRINGS`: **[skip ci],[ci skip],[no ci],[skip actions],[actions skip]**: Strings committers can place inside a commit message or PR title to skip executing the corresponding actions workflow `DEFAULT_ACTIONS_URL` indicates where the Gitea Actions runners should find the actions with relative path. For example, `uses: actions/checkout@v4` means `https://github.com/actions/checkout@v4` since the value of `DEFAULT_ACTIONS_URL` is `github`. diff --git a/docs/content/administration/config-cheat-sheet.zh-cn.md b/docs/content/administration/config-cheat-sheet.zh-cn.md index 5cc5734359..f636927da6 100644 --- a/docs/content/administration/config-cheat-sheet.zh-cn.md +++ b/docs/content/administration/config-cheat-sheet.zh-cn.md @@ -497,9 +497,10 @@ Gitea 创建以下非唯一队列: - `DEFAULT_EMAIL_NOTIFICATIONS`: **enabled**:用户电子邮件通知的默认配置(用户可配置)。选项:enabled、onmention、disabled - `DISABLE_REGULAR_ORG_CREATION`: **false**:禁止普通(非管理员)用户创建组织。 -- `USER_DISABLED_FEATURES`:**_empty_** 禁用的用户特性,当前允许为空或者 `deletion`,`manage_gpg_keys` 未来可以增加更多设置。 +- `USER_DISABLED_FEATURES`:**_empty_** 禁用的用户特性,当前允许为空或者 `deletion`,`manage_ssh_keys`, `manage_gpg_keys` 未来可以增加更多设置。 - `deletion`: 用户不能通过界面或者API删除他自己。 - - `manage_gpg_keys`: 用户不能配置 GPG 密钥 + - `manage_ssh_keys`: 用户不能通过界面或者API配置SSH Keys。 + - `manage_gpg_keys`: 用户不能配置 GPG 密钥。 ## 安全性 (`security`) @@ -781,7 +782,7 @@ Gitea 创建以下非唯一队列: ## 工单和合并请求的附件 (`attachment`) - `ENABLED`: **true**: 是否允许用户上传附件。 -- `ALLOWED_TYPES`: **.csv,.docx,.fodg,.fodp,.fods,.fodt,.gif,.gz,.jpeg,.jpg,.log,.md,.mov,.mp4,.odf,.odg,.odp,.ods,.odt,.patch,.pdf,.png,.pptx,.svg,.tgz,.txt,.webm,.xls,.xlsx,.zip**: 允许的文件扩展名(`.zip`)、mime 类型(`text/plain`)或通配符类型(`image/*`、`audio/*`、`video/*`)的逗号分隔列表。空值或 `*/*` 允许所有类型。 +- `ALLOWED_TYPES`: **.cpuprofile,.csv,.dmp,.docx,.fodg,.fodp,.fods,.fodt,.gif,.gz,.jpeg,.jpg,.json,.jsonc,.log,.md,.mov,.mp4,.odf,.odg,.odp,.ods,.odt,.patch,.pdf,.png,.pptx,.svg,.tgz,.txt,.webm,.xls,.xlsx,.zip**: 允许的文件扩展名(`.zip`)、mime 类型(`text/plain`)或通配符类型(`image/*`、`audio/*`、`video/*`)的逗号分隔列表。空值或 `*/*` 允许所有类型。 - `MAX_SIZE`: **2048**: 附件的最大限制(MB)。 - `MAX_FILES`: **5**: 一次最多上传的附件数量。 - `STORAGE_TYPE`: **local**: 附件的存储类型,`local` 表示本地磁盘,`minio` 表示兼容 S3 的对象存储服务,如果未设置将使用默认值 `local` 或其他在 `[storage.xxx]` 中定义的名称。 @@ -791,6 +792,10 @@ Gitea 创建以下非唯一队列: - `MINIO_ACCESS_KEY_ID`: Minio accessKeyID 以连接,仅当 STORAGE_TYPE 为 `minio` 时可用。 - `MINIO_SECRET_ACCESS_KEY`: Minio secretAccessKey 以连接,仅当 STORAGE_TYPE 为 `minio` 时可用。 - `MINIO_BUCKET`: **gitea**: Minio 存储附件的存储桶,仅当 STORAGE_TYPE 为 `minio` 时可用。 +- `MINIO_BUCKET_LOOKUP`: **auto**: Minio 存储桶寻址方式, 仅当 `STORAGE_TYPE` 为 `minio` 时可用。 + - `auto` 自动检测 + - `dns` 子域名寻址 + - `path` 路径寻址 - `MINIO_LOCATION`: **us-east-1**: Minio 存储桶的位置以创建,仅当 STORAGE_TYPE 为 `minio` 时可用。 - `MINIO_BASE_PATH`: **attachments/**: Minio 存储桶上的基本路径,仅当 STORAGE_TYPE 为 `minio` 时可用。 - `MINIO_USE_SSL`: **false**: Minio 启用 SSL,仅当 STORAGE_TYPE 为 `minio` 时可用。 @@ -1206,6 +1211,10 @@ ALLOW_DATA_URI_IMAGES = true - `MINIO_ACCESS_KEY_ID`:Minio 的 accessKeyID,仅在 `STORAGE_TYPE` 为 `minio` 时可用。 - `MINIO_SECRET_ACCESS_KEY`:Minio 的 secretAccessKey,仅在 `STORAGE_TYPE` 为 `minio` 时可用。 - `MINIO_BUCKET`:**gitea**:用于存储 lfs 的 Minio 桶,仅在 `STORAGE_TYPE` 为 `minio` 时可用。 +- `MINIO_BUCKET_LOOKUP`: **auto**: Minio 存储桶寻址方式,可选值为 `auto`, `dns`, `path` 仅当 `STORAGE_TYPE` 为 `minio` 时可用。 + - `auto` 自动检测 + - `dns` 子域名寻址 + - `path` 路径寻址 - `MINIO_LOCATION`:**us-east-1**:创建桶的 Minio 位置,仅在 `STORAGE_TYPE` 为 `minio` 时可用。 - `MINIO_BASE_PATH`:**lfs/**:桶上的 Minio 基本路径,仅在 `STORAGE_TYPE` 为 `minio` 时可用。 - `MINIO_USE_SSL`:**false**:Minio 启用 ssl,仅在 `STORAGE_TYPE` 为 `minio` 时可用。 @@ -1221,6 +1230,10 @@ ALLOW_DATA_URI_IMAGES = true - `MINIO_ACCESS_KEY_ID`:Minio 的 accessKeyID,仅在 `STORAGE_TYPE` 为 `minio` 时可用。 - `MINIO_SECRET_ACCESS_KEY`:Minio 的 secretAccessKey,仅在 `STORAGE_TYPE` 为 `minio` 时可用。 - `MINIO_BUCKET`:**gitea**:用于存储数据的 Minio 桶,仅在 `STORAGE_TYPE` 为 `minio` 时可用。 +- `MINIO_BUCKET_LOOKUP`: **auto**: Minio 存储桶寻址方式,可选值为 `auto`, `dns`, `path` 仅当 `STORAGE_TYPE` 为 `minio` 时可用。 + - `auto` 自动检测 + - `dns` 子域名寻址 + - `path` 路径寻址 - `MINIO_LOCATION`:**us-east-1**:创建桶的 Minio 位置,仅在 `STORAGE_TYPE` 为 `minio` 时可用。 - `MINIO_USE_SSL`:**false**:Minio 启用 ssl,仅在 `STORAGE_TYPE` 为 `minio` 时可用。 - `MINIO_INSECURE_SKIP_VERIFY`:**false**:Minio 跳过 SSL 验证,仅在 `STORAGE_TYPE` 为 `minio` 时可用。 @@ -1304,6 +1317,10 @@ MINIO_INSECURE_SKIP_VERIFY = false - `MINIO_ACCESS_KEY_ID`: Minio的accessKeyID,仅在`STORAGE_TYPE`为`minio`时可用。 - `MINIO_SECRET_ACCESS_KEY`: Minio的secretAccessKey,仅在`STORAGE_TYPE`为`minio`时可用。 - `MINIO_BUCKET`: **gitea**:用于存储归档的Minio存储桶,仅在`STORAGE_TYPE`为`minio`时可用。 +- `MINIO_BUCKET_LOOKUP`: **auto**: Minio 存储桶寻址方式,可选值为 `auto`, `dns`, `path` 仅当 `STORAGE_TYPE` 为 `minio` 时可用。 + - `auto` 自动检测 + - `dns` 子域名寻址 + - `path` 路径寻址 - `MINIO_LOCATION`: **us-east-1**:用于创建存储桶的Minio位置,仅在`STORAGE_TYPE`为`minio`时可用。 - `MINIO_BASE_PATH`: **repo-archive/**:存储桶上的Minio基本路径,仅在`STORAGE_TYPE`为`minio`时可用。 - `MINIO_USE_SSL`: **false**:启用Minio的SSL,仅在`STORAGE_TYPE`为`minio`时可用。 diff --git a/docs/content/administration/mail-templates.en-us.md b/docs/content/administration/mail-templates.en-us.md index 0154fe55d0..8e4e416e8d 100644 --- a/docs/content/administration/mail-templates.en-us.md +++ b/docs/content/administration/mail-templates.en-us.md @@ -163,7 +163,7 @@ clients don't even support HTML, so they show the text version included in the g If the template fails to render, it will be noticed only at the moment the mail is sent. A default subject is used if the subject template fails, and whatever was rendered successfully -from the the _mail body_ is used, disregarding the rest. +from the _mail body_ is used, disregarding the rest. Please check [Gitea's logs](administration/logging-config.md) for error messages in case of trouble. @@ -224,7 +224,7 @@ Please check [Gitea's logs](administration/logging-config.md) for error messages {{if not (eq .Body "")}}
"); err != nil { - return err - } - if _, err := tmpBlock.WriteString(html.EscapeString(string(rawBytes))); err != nil { - return err - } - _, err = tmpBlock.WriteString("") + if int64(len(rawBytes)) <= maxSize { + return r.tableRender(ctx, bytes.NewReader(rawBytes), tmpBlock) + } + return r.fallbackRender(io.MultiReader(bytes.NewReader(rawBytes), input), tmpBlock) +} + +func (Renderer) fallbackRender(input io.Reader, tmpBlock *bufio.Writer) error { + _, err := tmpBlock.WriteString("
") + if err != nil { return err } - rd, err := csv.CreateReaderAndDetermineDelimiter(ctx, bytes.NewReader(rawBytes)) + scan := bufio.NewScanner(input) + scan.Split(bufio.ScanRunes) + for scan.Scan() { + switch scan.Text() { + case `&`: + _, err = tmpBlock.WriteString("&") + case `'`: + _, err = tmpBlock.WriteString("'") // "'" is shorter than "'" and apos was not in HTML until HTML5. + case `<`: + _, err = tmpBlock.WriteString("<") + case `>`: + _, err = tmpBlock.WriteString(">") + case `"`: + _, err = tmpBlock.WriteString(""") // """ is shorter than """. + default: + _, err = tmpBlock.Write(scan.Bytes()) + } + if err != nil { + return err + } + } + + _, err = tmpBlock.WriteString("") + if err != nil { + return err + } + return tmpBlock.Flush() +} + +func (Renderer) tableRender(ctx *markup.RenderContext, input io.Reader, tmpBlock *bufio.Writer) error { + rd, err := csv.CreateReaderAndDetermineDelimiter(ctx, input) if err != nil { return err } diff --git a/modules/markup/csv/csv_test.go b/modules/markup/csv/csv_test.go index 8c07184b21..3d12be477c 100644 --- a/modules/markup/csv/csv_test.go +++ b/modules/markup/csv/csv_test.go @@ -4,6 +4,8 @@ package markup import ( + "bufio" + "bytes" "strings" "testing" @@ -29,4 +31,12 @@ func TestRenderCSV(t *testing.T) { assert.NoError(t, err) assert.EqualValues(t, v, buf.String()) } + + t.Run("fallbackRender", func(t *testing.T) { + var buf bytes.Buffer + err := render.fallbackRender(strings.NewReader("1,\n2,"), bufio.NewWriter(&buf)) + assert.NoError(t, err) + want := "
1,<a>\n2,<b>" + assert.Equal(t, want, buf.String()) + }) } diff --git a/modules/markup/html.go b/modules/markup/html.go index b7291823b5..0cfd8be590 100644 --- a/modules/markup/html.go +++ b/modules/markup/html.go @@ -609,7 +609,7 @@ func mentionProcessor(ctx *RenderContext, node *html.Node) { if ok && strings.Contains(mention, "/") { mentionOrgAndTeam := strings.Split(mention, "/") if mentionOrgAndTeam[0][1:] == ctx.Metas["org"] && strings.Contains(teams, ","+strings.ToLower(mentionOrgAndTeam[1])+",") { - replaceContent(node, loc.Start, loc.End, createLink(util.URLJoin(setting.AppURL, "org", ctx.Metas["org"], "teams", mentionOrgAndTeam[1]), mention, "mention")) + replaceContent(node, loc.Start, loc.End, createLink(util.URLJoin(ctx.Links.Prefix(), "org", ctx.Metas["org"], "teams", mentionOrgAndTeam[1]), mention, "mention")) node = node.NextSibling.NextSibling start = 0 continue @@ -620,7 +620,7 @@ func mentionProcessor(ctx *RenderContext, node *html.Node) { mentionedUsername := mention[1:] if DefaultProcessorHelper.IsUsernameMentionable != nil && DefaultProcessorHelper.IsUsernameMentionable(ctx.Ctx, mentionedUsername) { - replaceContent(node, loc.Start, loc.End, createLink(util.URLJoin(setting.AppURL, mentionedUsername), mention, "mention")) + replaceContent(node, loc.Start, loc.End, createLink(util.URLJoin(ctx.Links.Prefix(), mentionedUsername), mention, "mention")) node = node.NextSibling.NextSibling } else { node = node.NextSibling @@ -898,9 +898,9 @@ func issueIndexPatternProcessor(ctx *RenderContext, node *html.Node) { path = "pulls" } if ref.Owner == "" { - link = createLink(util.URLJoin(setting.AppURL, ctx.Metas["user"], ctx.Metas["repo"], path, ref.Issue), reftext, "ref-issue") + link = createLink(util.URLJoin(ctx.Links.Prefix(), ctx.Metas["user"], ctx.Metas["repo"], path, ref.Issue), reftext, "ref-issue") } else { - link = createLink(util.URLJoin(setting.AppURL, ref.Owner, ref.Name, path, ref.Issue), reftext, "ref-issue") + link = createLink(util.URLJoin(ctx.Links.Prefix(), ref.Owner, ref.Name, path, ref.Issue), reftext, "ref-issue") } } @@ -939,7 +939,7 @@ func commitCrossReferencePatternProcessor(ctx *RenderContext, node *html.Node) { } reftext := ref.Owner + "/" + ref.Name + "@" + base.ShortSha(ref.CommitSha) - link := createLink(util.URLJoin(setting.AppSubURL, ref.Owner, ref.Name, "commit", ref.CommitSha), reftext, "commit") + link := createLink(util.URLJoin(ctx.Links.Prefix(), ref.Owner, ref.Name, "commit", ref.CommitSha), reftext, "commit") replaceContent(node, ref.RefLocation.Start, ref.RefLocation.End, link) node = node.NextSibling.NextSibling @@ -1166,7 +1166,7 @@ func hashCurrentPatternProcessor(ctx *RenderContext, node *html.Node) { continue } - link := util.URLJoin(setting.AppURL, ctx.Metas["user"], ctx.Metas["repo"], "commit", hash) + link := util.URLJoin(ctx.Links.Prefix(), ctx.Metas["user"], ctx.Metas["repo"], "commit", hash) replaceContent(node, m[2], m[3], createCodeLink(link, base.ShortSha(hash), "commit")) start = 0 node = node.NextSibling.NextSibling diff --git a/modules/markup/html_internal_test.go b/modules/markup/html_internal_test.go index 93ba9d7667..e313be7040 100644 --- a/modules/markup/html_internal_test.go +++ b/modules/markup/html_internal_test.go @@ -287,6 +287,7 @@ func TestRender_IssueIndexPattern_Document(t *testing.T) { } func testRenderIssueIndexPattern(t *testing.T, input, expected string, ctx *RenderContext) { + ctx.Links.AbsolutePrefix = true if ctx.Links.Base == "" { ctx.Links.Base = TestRepoURL } diff --git a/modules/markup/html_test.go b/modules/markup/html_test.go index 132955c019..1db6952bed 100644 --- a/modules/markup/html_test.go +++ b/modules/markup/html_test.go @@ -43,7 +43,8 @@ func TestRender_Commits(t *testing.T) { Ctx: git.DefaultContext, RelativePath: ".md", Links: markup.Links{ - Base: markup.TestRepoURL, + AbsolutePrefix: true, + Base: markup.TestRepoURL, }, Metas: localMetas, }, input) @@ -96,7 +97,8 @@ func TestRender_CrossReferences(t *testing.T) { Ctx: git.DefaultContext, RelativePath: "a.md", Links: markup.Links{ - Base: setting.AppSubURL, + AbsolutePrefix: true, + Base: setting.AppSubURL, }, Metas: localMetas, }, input) @@ -579,7 +581,8 @@ func TestPostProcess_RenderDocument(t *testing.T) { err := markup.PostProcess(&markup.RenderContext{ Ctx: git.DefaultContext, Links: markup.Links{ - Base: "https://example.com", + AbsolutePrefix: true, + Base: "https://example.com", }, Metas: localMetas, }, strings.NewReader(input), &res) diff --git a/modules/markup/markdown/ast.go b/modules/markup/markdown/ast.go index 72d32600f5..7f0ac6a92c 100644 --- a/modules/markup/markdown/ast.go +++ b/modules/markup/markdown/ast.go @@ -174,10 +174,3 @@ func NewColorPreview(color []byte) *ColorPreview { Color: color, } } - -// IsColorPreview returns true if the given node implements the ColorPreview interface, -// otherwise false. -func IsColorPreview(node ast.Node) bool { - _, ok := node.(*ColorPreview) - return ok -} diff --git a/modules/markup/markdown/callout/github.go b/modules/markup/markdown/callout/github.go index 58f1fc960f..78f1db7e96 100644 --- a/modules/markup/markdown/callout/github.go +++ b/modules/markup/markdown/callout/github.go @@ -71,6 +71,7 @@ func (g *GitHubCalloutTransformer) Transform(node *ast.Document, reader text.Rea v.SetAttributeString("class", []byte("gt-py-3 attention attention-"+attentionType)) // create an emphasis to make it bold + attentionParagraph := ast.NewParagraph() emphasis := ast.NewEmphasis(2) emphasis.SetAttributeString("class", []byte("attention-"+attentionType)) firstParagraph.InsertBefore(firstParagraph, firstTextNode, emphasis) @@ -78,14 +79,11 @@ func (g *GitHubCalloutTransformer) Transform(node *ast.Document, reader text.Rea // capitalize first letter attentionText := ast.NewString([]byte(strings.ToUpper(string(attentionType[0])) + attentionType[1:])) - // replace the ![TYPE] with icon+Type + // replace the ![TYPE] with a dedicated paragraph of icon+Type emphasis.AppendChild(emphasis, attentionText) - for i := 0; i < 2; i++ { - lineBreak := ast.NewText() - lineBreak.SetSoftLineBreak(true) - firstParagraph.InsertAfter(firstParagraph, emphasis, lineBreak) - } - firstParagraph.InsertBefore(firstParagraph, emphasis, NewAttention(attentionType)) + attentionParagraph.AppendChild(attentionParagraph, NewAttention(attentionType)) + attentionParagraph.AppendChild(attentionParagraph, emphasis) + firstParagraph.Parent().InsertBefore(firstParagraph.Parent(), firstParagraph, attentionParagraph) firstParagraph.RemoveChild(firstParagraph, firstTextNode) firstParagraph.RemoveChild(firstParagraph, secondTextNode) firstParagraph.RemoveChild(firstParagraph, thirdTextNode) diff --git a/modules/markup/markdown/markdown.go b/modules/markup/markdown/markdown.go index 7750279ef2..77c876dfff 100644 --- a/modules/markup/markdown/markdown.go +++ b/modules/markup/markdown/markdown.go @@ -105,7 +105,8 @@ func SpecializedMarkdown() goldmark.Markdown { } // include language-x class as part of commonmark spec - _, err = w.WriteString(`
`)
+ // the "display" class is used by "js/markup/math.js" to render the code element as a block
+ _, err = w.WriteString(``)
if err != nil {
return
}
diff --git a/modules/markup/markdown/markdown_test.go b/modules/markup/markdown/markdown_test.go
index e7c496a913..ddb6814cd9 100644
--- a/modules/markup/markdown/markdown_test.go
+++ b/modules/markup/markdown/markdown_test.go
@@ -23,12 +23,11 @@ import (
)
const (
- AppURL = "http://localhost:3000/"
- Repo = "gogits/gogs"
- AppSubURL = AppURL + Repo + "/"
+ AppURL = "http://localhost:3000/"
+ FullURL = AppURL + "gogits/gogs/"
)
-// these values should match the Repo const above
+// these values should match the const above
var localMetas = map[string]string{
"user": "gogits",
"repo": "gogs",
@@ -50,13 +49,12 @@ func TestMain(m *testing.M) {
func TestRender_StandardLinks(t *testing.T) {
setting.AppURL = AppURL
- setting.AppSubURL = AppSubURL
test := func(input, expected, expectedWiki string) {
buffer, err := markdown.RenderString(&markup.RenderContext{
Ctx: git.DefaultContext,
Links: markup.Links{
- Base: setting.AppSubURL,
+ Base: FullURL,
},
}, input)
assert.NoError(t, err)
@@ -65,7 +63,7 @@ func TestRender_StandardLinks(t *testing.T) {
buffer, err = markdown.RenderString(&markup.RenderContext{
Ctx: git.DefaultContext,
Links: markup.Links{
- Base: setting.AppSubURL,
+ Base: FullURL,
},
IsWiki: true,
}, input)
@@ -76,8 +74,8 @@ func TestRender_StandardLinks(t *testing.T) {
googleRendered := ``
test(" ", googleRendered, googleRendered)
- lnk := util.URLJoin(AppSubURL, "WikiPage")
- lnkWiki := util.URLJoin(AppSubURL, "wiki", "WikiPage")
+ lnk := util.URLJoin(FullURL, "WikiPage")
+ lnkWiki := util.URLJoin(FullURL, "wiki", "WikiPage")
test("[WikiPage](WikiPage)",
``,
``)
@@ -85,13 +83,12 @@ func TestRender_StandardLinks(t *testing.T) {
func TestRender_Images(t *testing.T) {
setting.AppURL = AppURL
- setting.AppSubURL = AppSubURL
test := func(input, expected string) {
buffer, err := markdown.RenderString(&markup.RenderContext{
Ctx: git.DefaultContext,
Links: markup.Links{
- Base: setting.AppSubURL,
+ Base: FullURL,
},
}, input)
assert.NoError(t, err)
@@ -101,7 +98,7 @@ func TestRender_Images(t *testing.T) {
url := "../../.images/src/02/train.jpg"
title := "Train"
href := "https://gitea.io"
- result := util.URLJoin(AppSubURL, url)
+ result := util.URLJoin(FullURL, url)
// hint: With Markdown v2.5.2, there is a new syntax: [link](URL){:target="_blank"} , but we do not support it now
test(
@@ -134,11 +131,11 @@ func testAnswers(baseURLContent, baseURLImages string) []string {
Links, Language bindings, Engine bindings
Tips
-See commit 65f1bf27bc
+See commit 65f1bf27bc
Ideas and codes
-- Bezier widget (by @r-lyeh) ocornut/imgui#786
-- Bezier widget (by @r-lyeh) #786
+- Bezier widget (by @r-lyeh) ocornut/imgui#786
+- Bezier widget (by @r-lyeh) #786
- Node graph editors https://github.com/ocornut/imgui/issues/306
- Memory Editor
- Plot var helper
@@ -291,15 +288,14 @@ This PR has been generated by [Renovate Bot](https://github.com/renovatebot/reno
func TestTotal_RenderWiki(t *testing.T) {
setting.AppURL = AppURL
- setting.AppSubURL = AppSubURL
- answers := testAnswers(util.URLJoin(AppSubURL, "wiki"), util.URLJoin(AppSubURL, "wiki", "raw"))
+ answers := testAnswers(util.URLJoin(FullURL, "wiki"), util.URLJoin(FullURL, "wiki", "raw"))
for i := 0; i < len(sameCases); i++ {
line, err := markdown.RenderString(&markup.RenderContext{
Ctx: git.DefaultContext,
Links: markup.Links{
- Base: setting.AppSubURL,
+ Base: FullURL,
},
Metas: localMetas,
IsWiki: true,
@@ -312,12 +308,12 @@ func TestTotal_RenderWiki(t *testing.T) {
// Guard wiki sidebar: special syntax
`[[Guardfile-DSL / Configuring-Guard|Guardfile-DSL---Configuring-Guard]]`,
// rendered
- `Guardfile-DSL / Configuring-Guard
+ `Guardfile-DSL / Configuring-Guard
`,
// special syntax
`[[Name|Link]]`,
// rendered
- `
+ `
`,
}
@@ -325,7 +321,7 @@ func TestTotal_RenderWiki(t *testing.T) {
line, err := markdown.RenderString(&markup.RenderContext{
Ctx: git.DefaultContext,
Links: markup.Links{
- Base: setting.AppSubURL,
+ Base: FullURL,
},
IsWiki: true,
}, testCases[i])
@@ -336,15 +332,14 @@ func TestTotal_RenderWiki(t *testing.T) {
func TestTotal_RenderString(t *testing.T) {
setting.AppURL = AppURL
- setting.AppSubURL = AppSubURL
- answers := testAnswers(util.URLJoin(AppSubURL, "src", "master"), util.URLJoin(AppSubURL, "media", "master"))
+ answers := testAnswers(util.URLJoin(FullURL, "src", "master"), util.URLJoin(FullURL, "media", "master"))
for i := 0; i < len(sameCases); i++ {
line, err := markdown.RenderString(&markup.RenderContext{
Ctx: git.DefaultContext,
Links: markup.Links{
- Base: AppSubURL,
+ Base: FullURL,
BranchPath: "master",
},
Metas: localMetas,
@@ -359,7 +354,7 @@ func TestTotal_RenderString(t *testing.T) {
line, err := markdown.RenderString(&markup.RenderContext{
Ctx: git.DefaultContext,
Links: markup.Links{
- Base: AppSubURL,
+ Base: FullURL,
},
}, testCases[i])
assert.NoError(t, err)
@@ -1176,15 +1171,13 @@ space
func TestCustomMarkdownURL(t *testing.T) {
defer test.MockVariableValue(&setting.Markdown.CustomURLSchemes, []string{"abp"})()
-
setting.AppURL = AppURL
- setting.AppSubURL = AppSubURL
test := func(input, expected string) {
buffer, err := markdown.RenderString(&markup.RenderContext{
Ctx: git.DefaultContext,
Links: markup.Links{
- Base: setting.AppSubURL,
+ Base: FullURL,
BranchPath: "branch/main",
},
}, input)
diff --git a/modules/markup/renderer.go b/modules/markup/renderer.go
index 5a7adcc553..0f0bf55740 100644
--- a/modules/markup/renderer.go
+++ b/modules/markup/renderer.go
@@ -82,9 +82,17 @@ type RenderContext struct {
}
type Links struct {
- Base string
- BranchPath string
- TreePath string
+ AbsolutePrefix bool
+ Base string
+ BranchPath string
+ TreePath string
+}
+
+func (l *Links) Prefix() string {
+ if l.AbsolutePrefix {
+ return setting.AppURL
+ }
+ return setting.AppSubURL
}
func (l *Links) HasBranchInfo() bool {
diff --git a/modules/markup/sanitizer.go b/modules/markup/sanitizer.go
index ffc33c3b8e..b942406901 100644
--- a/modules/markup/sanitizer.go
+++ b/modules/markup/sanitizer.go
@@ -105,18 +105,12 @@ func createDefaultPolicy() *bluemonday.Policy {
// Allow icons
policy.AllowAttrs("class").Matching(regexp.MustCompile(`^icon(\s+[\p{L}\p{N}_-]+)+$`)).OnElements("i")
- // Allow unlabelled labels
- policy.AllowNoAttrs().OnElements("label")
-
// Allow classes for emojis
policy.AllowAttrs("class").Matching(regexp.MustCompile(`emoji`)).OnElements("img")
// Allow icons, emojis, chroma syntax and keyword markup on span
policy.AllowAttrs("class").Matching(regexp.MustCompile(`^((icon(\s+[\p{L}\p{N}_-]+)+)|(emoji)|(language-math display)|(language-math inline))$|^([a-z][a-z0-9]{0,2})$|^` + keywordClass + `$`)).OnElements("span")
- // Allow 'style' attribute on text elements.
- policy.AllowAttrs("style").OnElements("span", "p")
-
// Allow 'color' and 'background-color' properties for the style attribute on text elements.
policy.AllowStyles("color", "background-color").OnElements("span", "p")
@@ -144,7 +138,7 @@ func createDefaultPolicy() *bluemonday.Policy {
generalSafeElements := []string{
"h1", "h2", "h3", "h4", "h5", "h6", "h7", "h8", "br", "b", "i", "strong", "em", "a", "pre", "code", "img", "tt",
- "div", "ins", "del", "sup", "sub", "p", "ol", "ul", "table", "thead", "tbody", "tfoot", "blockquote",
+ "div", "ins", "del", "sup", "sub", "p", "ol", "ul", "table", "thead", "tbody", "tfoot", "blockquote", "label",
"dl", "dt", "dd", "kbd", "q", "samp", "var", "hr", "ruby", "rt", "rp", "li", "tr", "td", "th", "s", "strike", "summary",
"details", "caption", "figure", "figcaption",
"abbr", "bdo", "cite", "dfn", "mark", "small", "span", "time", "video", "wbr",
diff --git a/modules/queue/workergroup.go b/modules/queue/workergroup.go
index e3801ef2b2..8c9dd274f0 100644
--- a/modules/queue/workergroup.go
+++ b/modules/queue/workergroup.go
@@ -146,8 +146,6 @@ func (q *WorkerPoolQueue[T]) doStartNewWorker(wp *workerGroup[T]) {
log.Debug("Queue %q starts new worker", q.GetName())
defer log.Debug("Queue %q stops idle worker", q.GetName())
- atomic.AddInt32(&q.workerStartedCounter, 1) // Only increase counter, used for debugging
-
t := time.NewTicker(workerIdleDuration)
defer t.Stop()
diff --git a/modules/queue/workerqueue.go b/modules/queue/workerqueue.go
index 4160622d81..b28fd88027 100644
--- a/modules/queue/workerqueue.go
+++ b/modules/queue/workerqueue.go
@@ -40,8 +40,6 @@ type WorkerPoolQueue[T any] struct {
workerMaxNum int
workerActiveNum int
workerNumMu sync.Mutex
-
- workerStartedCounter int32
}
type flushType chan struct{}
diff --git a/modules/queue/workerqueue_test.go b/modules/queue/workerqueue_test.go
index e09669c542..9898ceb873 100644
--- a/modules/queue/workerqueue_test.go
+++ b/modules/queue/workerqueue_test.go
@@ -4,7 +4,9 @@
package queue
import (
+ "bytes"
"context"
+ "runtime"
"strconv"
"sync"
"testing"
@@ -14,6 +16,7 @@ import (
"code.gitea.io/gitea/modules/test"
"github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
)
func runWorkerPoolQueue[T any](q *WorkerPoolQueue[T]) func() {
@@ -249,23 +252,40 @@ func TestWorkerPoolQueueShutdown(t *testing.T) {
}
func TestWorkerPoolQueueWorkerIdleReset(t *testing.T) {
- defer test.MockVariableValue(&workerIdleDuration, 10*time.Millisecond)()
+ defer test.MockVariableValue(&workerIdleDuration, 1*time.Millisecond)()
+ chGoroutineIDs := make(chan string)
handler := func(items ...int) (unhandled []int) {
- time.Sleep(50 * time.Millisecond)
+ time.Sleep(10 * workerIdleDuration)
+ chGoroutineIDs <- goroutineID() // hacky way to identify a worker
return nil
}
q, _ := newWorkerPoolQueueForTest("test-workpoolqueue", setting.QueueSettings{Type: "channel", BatchLength: 1, MaxWorkers: 2, Length: 100}, handler, false)
stop := runWorkerPoolQueue(q)
- for i := 0; i < 20; i++ {
+
+ const workloadSize = 12
+ for i := 0; i < workloadSize; i++ {
assert.NoError(t, q.Push(i))
}
- time.Sleep(500 * time.Millisecond)
- assert.EqualValues(t, 2, q.GetWorkerNumber())
- assert.EqualValues(t, 2, q.GetWorkerActiveNumber())
- // when the queue never becomes empty, the existing workers should keep working
- assert.EqualValues(t, 2, q.workerStartedCounter)
+ workerIDs := make(map[string]struct{})
+ for i := 0; i < workloadSize; i++ {
+ c := <-chGoroutineIDs
+ workerIDs[c] = struct{}{}
+ t.Logf("%d workers: overall=%d current=%d", i, len(workerIDs), q.GetWorkerNumber())
+
+ // ensure that no more than qs.MaxWorkers workers are created over the whole lifetime of the queue
+ // (otherwise it would mean that some workers got shut down while the queue was full)
+ require.LessOrEqual(t, len(workerIDs), q.GetWorkerMaxNumber())
+ }
+ close(chGoroutineIDs)
+
stop()
}
+
+func goroutineID() string {
+ var buffer [31]byte
+ _ = runtime.Stack(buffer[:], false)
+ return string(bytes.Fields(buffer[10:])[0])
+}
diff --git a/modules/setting/admin.go b/modules/setting/admin.go
index c292db9c8f..35ffa9efbf 100644
--- a/modules/setting/admin.go
+++ b/modules/setting/admin.go
@@ -22,5 +22,6 @@ func loadAdminFrom(rootCfg ConfigProvider) {
const (
UserFeatureDeletion = "deletion"
+ UserFeatureManageSSHKeys = "manage_ssh_keys"
UserFeatureManageGPGKeys = "manage_gpg_keys"
)
diff --git a/modules/setting/attachment.go b/modules/setting/attachment.go
index 934d4d7f46..0fdabb5032 100644
--- a/modules/setting/attachment.go
+++ b/modules/setting/attachment.go
@@ -12,7 +12,7 @@ var Attachment = struct {
Enabled bool
}{
Storage: &Storage{},
- AllowedTypes: ".csv,.docx,.fodg,.fodp,.fods,.fodt,.gif,.gz,.jpeg,.jpg,.log,.md,.mov,.mp4,.odf,.odg,.odp,.ods,.odt,.patch,.pdf,.png,.pptx,.svg,.tgz,.txt,.webm,.xls,.xlsx,.zip",
+ AllowedTypes: ".cpuprofile,.csv,.dmp,.docx,.fodg,.fodp,.fods,.fodt,.gif,.gz,.jpeg,.jpg,.json,.jsonc,.log,.md,.mov,.mp4,.odf,.odg,.odp,.ods,.odt,.patch,.pdf,.png,.pptx,.svg,.tgz,.txt,.webm,.xls,.xlsx,.zip",
MaxSize: 2048,
MaxFiles: 5,
Enabled: true,
@@ -25,7 +25,7 @@ func loadAttachmentFrom(rootCfg ConfigProvider) (err error) {
return err
}
- Attachment.AllowedTypes = sec.Key("ALLOWED_TYPES").MustString(".csv,.docx,.fodg,.fodp,.fods,.fodt,.gif,.gz,.jpeg,.jpg,.log,.md,.mov,.mp4,.odf,.odg,.odp,.ods,.odt,.patch,.pdf,.png,.pptx,.svg,.tgz,.txt,.webm,.xls,.xlsx,.zip")
+ Attachment.AllowedTypes = sec.Key("ALLOWED_TYPES").MustString(".cpuprofile,.csv,.dmp,.docx,.fodg,.fodp,.fods,.fodt,.gif,.gz,.jpeg,.jpg,.json,.jsonc,.log,.md,.mov,.mp4,.odf,.odg,.odp,.ods,.odt,.patch,.pdf,.png,.pptx,.svg,.tgz,.txt,.webm,.xls,.xlsx,.zip")
Attachment.MaxSize = sec.Key("MAX_SIZE").MustInt64(2048)
Attachment.MaxFiles = sec.Key("MAX_FILES").MustInt(5)
Attachment.Enabled = sec.Key("ENABLED").MustBool(true)
diff --git a/modules/setting/config.go b/modules/setting/config.go
index db189f44ac..03558574c2 100644
--- a/modules/setting/config.go
+++ b/modules/setting/config.go
@@ -15,8 +15,45 @@ type PictureStruct struct {
EnableFederatedAvatar *config.Value[bool]
}
+type OpenWithEditorApp struct {
+ DisplayName string
+ OpenURL string
+}
+
+type OpenWithEditorAppsType []OpenWithEditorApp
+
+func (t OpenWithEditorAppsType) ToTextareaString() string {
+ ret := ""
+ for _, app := range t {
+ ret += app.DisplayName + " = " + app.OpenURL + "\n"
+ }
+ return ret
+}
+
+func DefaultOpenWithEditorApps() OpenWithEditorAppsType {
+ return OpenWithEditorAppsType{
+ {
+ DisplayName: "VS Code",
+ OpenURL: "vscode://vscode.git/clone?url={url}",
+ },
+ {
+ DisplayName: "VSCodium",
+ OpenURL: "vscodium://vscode.git/clone?url={url}",
+ },
+ {
+ DisplayName: "Intellij IDEA",
+ OpenURL: "jetbrains://idea/checkout/git?idea.required.plugins.id=Git4Idea&checkout.repo={url}",
+ },
+ }
+}
+
+type RepositoryStruct struct {
+ OpenWithEditorApps *config.Value[OpenWithEditorAppsType]
+}
+
type ConfigStruct struct {
- Picture *PictureStruct
+ Picture *PictureStruct
+ Repository *RepositoryStruct
}
var (
@@ -28,8 +65,11 @@ func initDefaultConfig() {
config.SetCfgSecKeyGetter(&cfgSecKeyGetter{})
defaultConfig = &ConfigStruct{
Picture: &PictureStruct{
- DisableGravatar: config.Bool(false, config.CfgSecKey{Sec: "picture", Key: "DISABLE_GRAVATAR"}, "picture.disable_gravatar"),
- EnableFederatedAvatar: config.Bool(false, config.CfgSecKey{Sec: "picture", Key: "ENABLE_FEDERATED_AVATAR"}, "picture.enable_federated_avatar"),
+ DisableGravatar: config.ValueJSON[bool]("picture.disable_gravatar").WithFileConfig(config.CfgSecKey{Sec: "picture", Key: "DISABLE_GRAVATAR"}),
+ EnableFederatedAvatar: config.ValueJSON[bool]("picture.enable_federated_avatar").WithFileConfig(config.CfgSecKey{Sec: "picture", Key: "ENABLE_FEDERATED_AVATAR"}),
+ },
+ Repository: &RepositoryStruct{
+ OpenWithEditorApps: config.ValueJSON[OpenWithEditorAppsType]("repository.open-with.editor-apps"),
},
}
}
@@ -42,6 +82,9 @@ func Config() *ConfigStruct {
type cfgSecKeyGetter struct{}
func (c cfgSecKeyGetter) GetValue(sec, key string) (v string, has bool) {
+ if key == "" {
+ return "", false
+ }
cfgSec, err := CfgProvider.GetSection(sec)
if err != nil {
log.Error("Unable to get config section: %q", sec)
diff --git a/modules/setting/config/value.go b/modules/setting/config/value.go
index 817fcdb786..f0ec120544 100644
--- a/modules/setting/config/value.go
+++ b/modules/setting/config/value.go
@@ -5,8 +5,11 @@ package config
import (
"context"
- "strconv"
"sync"
+
+ "code.gitea.io/gitea/modules/json"
+ "code.gitea.io/gitea/modules/log"
+ "code.gitea.io/gitea/modules/util"
)
type CfgSecKey struct {
@@ -23,14 +26,14 @@ type Value[T any] struct {
revision int
}
-func (value *Value[T]) parse(s string) (v T) {
- switch any(v).(type) {
- case bool:
- b, _ := strconv.ParseBool(s)
- return any(b).(T)
- default:
- panic("unsupported config type, please complete the code")
+func (value *Value[T]) parse(key, valStr string) (v T) {
+ v = value.def
+ if valStr != "" {
+ if err := json.Unmarshal(util.UnsafeStringToBytes(valStr), &v); err != nil {
+ log.Error("Unable to unmarshal json config for key %q, err: %v", key, err)
+ }
}
+ return v
}
func (value *Value[T]) Value(ctx context.Context) (v T) {
@@ -62,7 +65,7 @@ func (value *Value[T]) Value(ctx context.Context) (v T) {
if valStr == nil {
v = value.def
} else {
- v = value.parse(*valStr)
+ v = value.parse(value.dynKey, *valStr)
}
value.mu.Lock()
@@ -76,6 +79,16 @@ func (value *Value[T]) DynKey() string {
return value.dynKey
}
-func Bool(def bool, cfgSecKey CfgSecKey, dynKey string) *Value[bool] {
- return &Value[bool]{def: def, cfgSecKey: cfgSecKey, dynKey: dynKey}
+func (value *Value[T]) WithDefault(def T) *Value[T] {
+ value.def = def
+ return value
+}
+
+func (value *Value[T]) WithFileConfig(cfgSecKey CfgSecKey) *Value[T] {
+ value.cfgSecKey = cfgSecKey
+ return value
+}
+
+func ValueJSON[T any](dynKey string) *Value[T] {
+ return &Value[T]{dynKey: dynKey}
}
diff --git a/modules/setting/i18n.go b/modules/setting/i18n.go
index c3076c0ab7..1639f3ae5b 100644
--- a/modules/setting/i18n.go
+++ b/modules/setting/i18n.go
@@ -20,11 +20,14 @@ var defaultI18nLangNames = []string{
"pt-BR", "Português do Brasil",
"pt-PT", "Português de Portugal",
"pl-PL", "Polski",
- "bg-BG", "Български",
+ "bg", "Български",
"it-IT", "Italiano",
"fi-FI", "Suomi",
+ "fil", "Filipino",
+ "eo", "Esperanto",
"tr-TR", "Türkçe",
"cs-CZ", "Čeština",
+ "sl", "Slovenščina",
"sv-SE", "Svenska",
"ko-KR", "한국어",
"el-GR", "Ελληνικά",
diff --git a/modules/setting/repository.go b/modules/setting/repository.go
index 7a07fec85c..50f0fd704c 100644
--- a/modules/setting/repository.go
+++ b/modules/setting/repository.go
@@ -7,7 +7,6 @@ import (
"os/exec"
"path"
"path/filepath"
- "slices"
"strings"
"code.gitea.io/gitea/modules/log"
@@ -20,10 +19,12 @@ const (
RepoCreatingPublic = "public"
)
-var RecognisedRepositoryDownloadOrCloneMethods = []string{"download-zip", "download-targz", "download-bundle", "vscode-clone", "vscodium-clone", "cite"}
+// MaxUserCardsPerPage sets maximum amount of watchers and stargazers shown per page
+// those pages use 2 or 3 column layout, so the value should be divisible by 2 and 3
+var MaxUserCardsPerPage = 36
-// ItemsPerPage maximum items per page in forks, watchers and stars of a repo
-const ItemsPerPage = 40
+// MaxForksPerPage sets maximum amount of forks shown per page
+var MaxForksPerPage = 40
// Repository settings
var (
@@ -46,7 +47,6 @@ var (
DisabledRepoUnits []string
DefaultRepoUnits []string
DefaultForkRepoUnits []string
- DownloadOrCloneMethods []string
PrefixArchiveFiles bool
DisableMigrations bool
DisableStars bool
@@ -169,7 +169,6 @@ var (
DisabledRepoUnits: []string{},
DefaultRepoUnits: []string{},
DefaultForkRepoUnits: []string{},
- DownloadOrCloneMethods: []string{"download-zip", "download-targz", "download-bundle", "vscode-clone"},
PrefixArchiveFiles: true,
DisableMigrations: false,
DisableStars: false,
@@ -373,12 +372,5 @@ func loadRepositoryFrom(rootCfg ConfigProvider) {
if err := loadRepoArchiveFrom(rootCfg); err != nil {
log.Fatal("loadRepoArchiveFrom: %v", err)
}
-
- for _, method := range Repository.DownloadOrCloneMethods {
- if !slices.Contains(RecognisedRepositoryDownloadOrCloneMethods, method) {
- log.Error("Unrecognised repository download or clone method: %s", method)
- }
- }
-
Repository.EnableFlags = sec.Key("ENABLE_FLAGS").MustBool()
}
diff --git a/modules/setting/setting.go b/modules/setting/setting.go
index 87e7b08c6e..781e794d5d 100644
--- a/modules/setting/setting.go
+++ b/modules/setting/setting.go
@@ -13,6 +13,7 @@ import (
"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/user"
+ "code.gitea.io/gitea/modules/util"
)
var ForgejoVersion = "1.0.0"
@@ -161,9 +162,11 @@ func loadCommonSettingsFrom(cfg ConfigProvider) error {
func loadRunModeFrom(rootCfg ConfigProvider) {
rootSec := rootCfg.Section("")
RunUser = rootSec.Key("RUN_USER").MustString(user.CurrentUsername())
+
// The following is a purposefully undocumented option. Please do not run Gitea as root. It will only cause future headaches.
// Please don't use root as a bandaid to "fix" something that is broken, instead the broken thing should instead be fixed properly.
unsafeAllowRunAsRoot := ConfigSectionKeyBool(rootSec, "I_AM_BEING_UNSAFE_RUNNING_AS_ROOT")
+ unsafeAllowRunAsRoot = unsafeAllowRunAsRoot || util.OptionalBoolParse(os.Getenv("GITEA_I_AM_BEING_UNSAFE_RUNNING_AS_ROOT")).Value()
RunMode = os.Getenv("GITEA_RUN_MODE")
if RunMode == "" {
RunMode = rootSec.Key("RUN_MODE").MustString("prod")
diff --git a/modules/setting/storage.go b/modules/setting/storage.go
index f937c7cff3..1e2d28a88b 100644
--- a/modules/setting/storage.go
+++ b/modules/setting/storage.go
@@ -41,6 +41,7 @@ type MinioStorageConfig struct {
AccessKeyID string `ini:"MINIO_ACCESS_KEY_ID" json:",omitempty"`
SecretAccessKey string `ini:"MINIO_SECRET_ACCESS_KEY" json:",omitempty"`
Bucket string `ini:"MINIO_BUCKET" json:",omitempty"`
+ BucketLookup string `ini:"MINIO_BUCKET_LOOKUP" json:",omitempty"`
Location string `ini:"MINIO_LOCATION" json:",omitempty"`
BasePath string `ini:"MINIO_BASE_PATH" json:",omitempty"`
UseSSL bool `ini:"MINIO_USE_SSL"`
@@ -78,6 +79,7 @@ func getDefaultStorageSection(rootCfg ConfigProvider) ConfigSection {
storageSec.Key("MINIO_ACCESS_KEY_ID").MustString("")
storageSec.Key("MINIO_SECRET_ACCESS_KEY").MustString("")
storageSec.Key("MINIO_BUCKET").MustString("gitea")
+ storageSec.Key("MINIO_BUCKET_LOOKUP").MustString("auto")
storageSec.Key("MINIO_LOCATION").MustString("us-east-1")
storageSec.Key("MINIO_USE_SSL").MustBool(false)
storageSec.Key("MINIO_INSECURE_SKIP_VERIFY").MustBool(false)
diff --git a/modules/storage/minio.go b/modules/storage/minio.go
index b58ab67dc7..0b65577cb5 100644
--- a/modules/storage/minio.go
+++ b/modules/storage/minio.go
@@ -82,14 +82,26 @@ func NewMinioStorage(ctx context.Context, cfg *setting.Storage) (ObjectStorage,
if config.ChecksumAlgorithm != "" && config.ChecksumAlgorithm != "default" && config.ChecksumAlgorithm != "md5" {
return nil, fmt.Errorf("invalid minio checksum algorithm: %s", config.ChecksumAlgorithm)
}
+ var lookup minio.BucketLookupType
+ switch config.BucketLookup {
+ case "auto", "":
+ lookup = minio.BucketLookupAuto
+ case "dns":
+ lookup = minio.BucketLookupDNS
+ case "path":
+ lookup = minio.BucketLookupPath
+ default:
+ return nil, fmt.Errorf("invalid minio bucket lookup type %s", config.BucketLookup)
+ }
log.Info("Creating Minio storage at %s:%s with base path %s", config.Endpoint, config.Bucket, config.BasePath)
minioClient, err := minio.New(config.Endpoint, &minio.Options{
- Creds: credentials.NewStaticV4(config.AccessKeyID, config.SecretAccessKey, ""),
- Secure: config.UseSSL,
- Transport: &http.Transport{TLSClientConfig: &tls.Config{InsecureSkipVerify: config.InsecureSkipVerify}},
- Region: config.Location,
+ Creds: credentials.NewStaticV4(config.AccessKeyID, config.SecretAccessKey, ""),
+ Secure: config.UseSSL,
+ Transport: &http.Transport{TLSClientConfig: &tls.Config{InsecureSkipVerify: config.InsecureSkipVerify}},
+ Region: config.Location,
+ BucketLookup: lookup,
})
if err != nil {
return nil, convertMinioErr(err)
diff --git a/modules/storage/minio_test.go b/modules/storage/minio_test.go
index 2364ced0ef..2e1a3028c7 100644
--- a/modules/storage/minio_test.go
+++ b/modules/storage/minio_test.go
@@ -31,6 +31,23 @@ func TestMinioStorageIterator(t *testing.T) {
})
}
+func TestVirtualHostMinioStorage(t *testing.T) {
+ if os.Getenv("CI") == "" {
+ t.Skip("minioStorage not present outside of CI")
+ return
+ }
+ testStorageIterator(t, setting.MinioStorageType, &setting.Storage{
+ MinioConfig: setting.MinioStorageConfig{
+ Endpoint: "minio:9000",
+ AccessKeyID: "123456",
+ SecretAccessKey: "12345678",
+ Bucket: "gitea",
+ Location: "us-east-1",
+ BucketLookup: "dns",
+ },
+ })
+}
+
func TestMinioStoragePath(t *testing.T) {
m := &MinioStorage{basePath: ""}
assert.Equal(t, "", m.buildMinioPath("/"))
diff --git a/modules/templates/helper.go b/modules/templates/helper.go
index 9afcb96fc9..18a2993fb8 100644
--- a/modules/templates/helper.go
+++ b/modules/templates/helper.go
@@ -38,7 +38,7 @@ func NewFuncMap() template.FuncMap {
"SafeHTML": SafeHTML,
"HTMLFormat": HTMLFormat,
"HTMLEscape": HTMLEscape,
- "QueryEscape": url.QueryEscape,
+ "QueryEscape": QueryEscape,
"JSEscape": JSEscapeSafe,
"SanitizeHTML": SanitizeHTML,
"URLJoin": util.URLJoin,
@@ -211,14 +211,8 @@ func SafeHTML(s any) template.HTML {
}
// SanitizeHTML sanitizes the input by pre-defined markdown rules
-func SanitizeHTML(s any) template.HTML {
- switch v := s.(type) {
- case string:
- return template.HTML(markup.Sanitize(v))
- case template.HTML:
- return template.HTML(markup.Sanitize(string(v)))
- }
- panic(fmt.Sprintf("unexpected type %T", s))
+func SanitizeHTML(s string) template.HTML {
+ return template.HTML(markup.Sanitize(s))
}
func HTMLEscape(s any) template.HTML {
@@ -235,6 +229,10 @@ func JSEscapeSafe(s string) template.HTML {
return template.HTML(template.JSEscapeString(s))
}
+func QueryEscape(s string) template.URL {
+ return template.URL(url.QueryEscape(s))
+}
+
// DotEscape wraps a dots in names with ZWJ [U+200D] in order to prevent autolinkers from detecting these as urls
func DotEscape(raw string) string {
return strings.ReplaceAll(raw, ".", "\u200d.\u200d")
diff --git a/modules/templates/helper_test.go b/modules/templates/helper_test.go
index 3365278ac2..64f29d033e 100644
--- a/modules/templates/helper_test.go
+++ b/modules/templates/helper_test.go
@@ -64,5 +64,4 @@ func TestHTMLFormat(t *testing.T) {
func TestSanitizeHTML(t *testing.T) {
assert.Equal(t, template.HTML(`link xss inline`), SanitizeHTML(`link xss inline`))
- assert.Equal(t, template.HTML(`link xss inline`), SanitizeHTML(template.HTML(`link xss inline`)))
}
diff --git a/modules/templates/util_render_test.go b/modules/templates/util_render_test.go
index 465640e08d..5fea4d9a16 100644
--- a/modules/templates/util_render_test.go
+++ b/modules/templates/util_render_test.go
@@ -61,7 +61,7 @@ func TestMain(m *testing.M) {
func TestApostrophesInMentions(t *testing.T) {
rendered := RenderMarkdownToHtml(context.Background(), "@mention-user's comment")
- assert.EqualValues(t, "@mention-user's comment
\n", rendered)
+ assert.EqualValues(t, template.HTML("@mention-user's comment
\n"), rendered)
}
func TestRenderCommitBody(t *testing.T) {
@@ -122,21 +122,21 @@ com 88fc37a3c0a4dda553bdcfc80c178a58247f42fb...12fc37a3c0a4dda553bdcfc80c178a582
com 88fc37a3c0a4dda553bdcfc80c178a58247f42fb mit
👍
mail@domain.com
-@mention-user test
-#123
+@mention-user test
+#123
space`
assert.EqualValues(t, expected, RenderCommitBody(context.Background(), testInput, testMetas))
}
func TestRenderCommitMessage(t *testing.T) {
- expected := `space @mention-user `
+ expected := `space @mention-user `
assert.EqualValues(t, expected, RenderCommitMessage(context.Background(), testInput, testMetas))
}
func TestRenderCommitMessageLinkSubject(t *testing.T) {
- expected := `space @mention-user`
+ expected := `space @mention-user`
assert.EqualValues(t, expected, RenderCommitMessageLinkSubject(context.Background(), testInput, "https://example.com/link", testMetas))
}
@@ -160,14 +160,14 @@ com 88fc37a3c0a4dda553bdcfc80c178a58247f42fb mit
👍
mail@domain.com
@mention-user test
-#123
+#123
space
`
assert.EqualValues(t, expected, RenderIssueTitle(context.Background(), testInput, testMetas))
}
func TestRenderMarkdownToHtml(t *testing.T) {
- expected := `space @mention-user
+ expected := `
space @mention-user
/just/a/path.bin
https://example.com/file.bin
local link
@@ -184,7 +184,7 @@ com 88fc37a3c0a4dda553bdcfc80c178a58247f42fb...12fc37a3c0a4dda553bdcfc80c178a582
com 88fc37a3c0a4dda553bdcfc80c178a58247f42fb mit
👍
mail@domain.com
-@mention-user test
+@mention-user test
#123
space
`
diff --git a/modules/timeutil/datetime.go b/modules/timeutil/datetime.go
index 62b94f7cf4..c089173560 100644
--- a/modules/timeutil/datetime.go
+++ b/modules/timeutil/datetime.go
@@ -13,6 +13,8 @@ import (
// DateTime renders an absolute time HTML element by datetime.
func DateTime(format string, datetime any, extraAttrs ...string) template.HTML {
+ // TODO: remove the extraAttrs argument, it's not used in any call to DateTime
+
if p, ok := datetime.(*time.Time); ok {
datetime = *p
}
@@ -51,18 +53,16 @@ func DateTime(format string, datetime any, extraAttrs ...string) template.HTML {
attrs := make([]string, 0, 10+len(extraAttrs))
attrs = append(attrs, extraAttrs...)
- attrs = append(attrs, `data-tooltip-content`, `data-tooltip-interactive="true"`)
- attrs = append(attrs, `format="datetime"`, `weekday=""`, `year="numeric"`)
+ attrs = append(attrs, `weekday=""`, `year="numeric"`)
switch format {
- case "short":
- attrs = append(attrs, `month="short"`, `day="numeric"`)
- case "long":
- attrs = append(attrs, `month="long"`, `day="numeric"`)
- case "full":
- attrs = append(attrs, `month="short"`, `day="numeric"`, `hour="numeric"`, `minute="numeric"`, `second="numeric"`)
+ case "short", "long": // date only
+ attrs = append(attrs, `month="`+format+`"`, `day="numeric"`)
+ return template.HTML(fmt.Sprintf(`%s `, strings.Join(attrs, " "), datetimeEscaped, textEscaped))
+ case "full": // full date including time
+ attrs = append(attrs, `format="datetime"`, `month="short"`, `day="numeric"`, `hour="numeric"`, `minute="numeric"`, `second="numeric"`, `data-tooltip-content`, `data-tooltip-interactive="true"`)
+ return template.HTML(fmt.Sprintf(`%s `, strings.Join(attrs, " "), datetimeEscaped, textEscaped))
default:
panic(fmt.Sprintf("Unsupported format %s", format))
}
- return template.HTML(fmt.Sprintf(`%s `, strings.Join(attrs, " "), datetimeEscaped, textEscaped))
}
diff --git a/modules/timeutil/datetime_test.go b/modules/timeutil/datetime_test.go
index 26494b8475..ac2ce35ba2 100644
--- a/modules/timeutil/datetime_test.go
+++ b/modules/timeutil/datetime_test.go
@@ -18,6 +18,7 @@ func TestDateTime(t *testing.T) {
defer test.MockVariableValue(&setting.DefaultUILocation, testTz)()
refTimeStr := "2018-01-01T00:00:00Z"
+ refDateStr := "2018-01-01"
refTime, _ := time.Parse(time.RFC3339, refTimeStr)
refTimeStamp := TimeStamp(refTime.Unix())
@@ -27,17 +28,20 @@ func TestDateTime(t *testing.T) {
assert.EqualValues(t, "-", DateTime("short", TimeStamp(0)))
actual := DateTime("short", "invalid")
- assert.EqualValues(t, `invalid `, actual)
+ assert.EqualValues(t, `invalid `, actual)
actual = DateTime("short", refTimeStr)
- assert.EqualValues(t, `2018-01-01T00:00:00Z `, actual)
+ assert.EqualValues(t, `2018-01-01T00:00:00Z `, actual)
actual = DateTime("short", refTime)
- assert.EqualValues(t, `2018-01-01 `, actual)
+ assert.EqualValues(t, `2018-01-01 `, actual)
+
+ actual = DateTime("short", refDateStr)
+ assert.EqualValues(t, `2018-01-01 `, actual)
actual = DateTime("short", refTimeStamp)
- assert.EqualValues(t, `2017-12-31 `, actual)
+ assert.EqualValues(t, `2017-12-31 `, actual)
actual = DateTime("full", refTimeStamp)
- assert.EqualValues(t, `2017-12-31 19:00:00 -05:00 `, actual)
+ assert.EqualValues(t, `2017-12-31 19:00:00 -05:00 `, actual)
}
diff --git a/modules/timeutil/since.go b/modules/timeutil/since.go
index dfaa0e3e3a..dba42c793a 100644
--- a/modules/timeutil/since.go
+++ b/modules/timeutil/since.go
@@ -126,7 +126,7 @@ func timeSinceUnix(then, now time.Time, _ translation.Locale) template.HTML {
}
// declare data-tooltip-content attribute to switch from "title" tooltip to "tippy" tooltip
- htm := fmt.Sprintf(`%s `,
+ htm := fmt.Sprintf(`%s `,
attrs, then.Format(time.RFC3339), friendlyText)
return template.HTML(htm)
}
@@ -134,7 +134,7 @@ func timeSinceUnix(then, now time.Time, _ translation.Locale) template.HTML {
// TimeSince renders relative time HTML given a time.Time
func TimeSince(then time.Time, lang translation.Locale) template.HTML {
if setting.UI.PreferredTimestampTense == "absolute" {
- return DateTime("full", then, `class="time-since"`)
+ return DateTime("full", then)
}
return timeSinceUnix(then, time.Now(), lang)
}
diff --git a/modules/util/slice.go b/modules/util/slice.go
index a7073fedee..f00e84bf06 100644
--- a/modules/util/slice.go
+++ b/modules/util/slice.go
@@ -53,3 +53,12 @@ func Sorted[S ~[]E, E cmp.Ordered](values S) S {
slices.Sort(values)
return values
}
+
+// TODO: Replace with "maps.Values" once available
+func ValuesOfMap[K comparable, V any](m map[K]V) []V {
+ values := make([]V, 0, len(m))
+ for _, v := range m {
+ values = append(values, v)
+ }
+ return values
+}
diff --git a/modules/web/middleware/data.go b/modules/web/middleware/data.go
index c1d1af8528..08d83f94be 100644
--- a/modules/web/middleware/data.go
+++ b/modules/web/middleware/data.go
@@ -53,7 +53,6 @@ func CommonTemplateContextData() ContextData {
"ShowMilestonesDashboardPage": setting.Service.ShowMilestonesDashboardPage,
"ShowFooterVersion": setting.Other.ShowFooterVersion,
"DisableDownloadSourceArchives": setting.Repository.DisableDownloadSourceArchives,
- "DownloadOrCloneMethods": setting.Repository.DownloadOrCloneMethods,
"EnableSwagger": setting.API.EnableSwagger,
"EnableOpenIDSignIn": setting.Service.EnableOpenIDSignIn,
diff --git a/options/locale/locale_ar.ini b/options/locale/locale_ar.ini
index c60ed5c42c..0e27147e10 100644
--- a/options/locale/locale_ar.ini
+++ b/options/locale/locale_ar.ini
@@ -1448,7 +1448,7 @@ oauth_signin_tab = أربط بحساب موجود
invalid_password = كلمة المرور الخاصة بك لا تطابق كلمة المرور التي استخدمت لتسجيل الحساب.
oauth_signin_title = سجّل الدخول لتأذن للحساب المربوط
reset_password_helper = إعادة الحساب
-login_openid = تسجيل دخول بـOpenID
+tab_openid = تسجيل دخول بـOpenID
openid_connect_submit = اتصل
oauth_signup_tab = سجل حساب جديد
oauth.signin.error.temporarily_unavailable = فشل طلب الإذن لأن خادم التوثيق غير متاح مؤقتا. حاول مرة أخرى لاحقاً.
@@ -1535,7 +1535,7 @@ filter.container.tagged = موسوم
[heatmap]
less = أقل
number_of_contributions_in_the_last_12_months = %s مساهم في آخر 12 شهر
-no_contributions = بلا مساهمات
+contributions_zero = بلا مساهمات
more = أكثر
[admin]
diff --git a/options/locale/locale_bg.ini b/options/locale/locale_bg.ini
index 3eca60f551..b6ad948b46 100644
--- a/options/locale/locale_bg.ini
+++ b/options/locale/locale_bg.ini
@@ -1270,7 +1270,7 @@ approve_pull_request = `одобри %[3]s#%[2]s`
reject_pull_request = `предложи промени за %[3]s#%[2]s`
[auth]
-login_openid = OpenID
+tab_openid = OpenID
openid_connect_submit = Свързване
sign_up_successful = Акаунтът е създаден успешно. Добре дошли!
login_userpass = Влизане
@@ -1357,7 +1357,7 @@ runners.description = Описание
[heatmap]
less = По-малко
number_of_contributions_in_the_last_12_months = %s приноса през последните 12 месеца
-no_contributions = Няма приноси
+contributions_zero = Няма приноси
more = Повече
[git.filemode]
@@ -1382,4 +1382,4 @@ recent_commits.what = скорошни подавания
component_loading = Зареждане на %s...
[projects]
-type-1.display_name = Индивидуален проект
\ No newline at end of file
+type-1.display_name = Индивидуален проект
diff --git a/options/locale/locale_cs-CZ.ini b/options/locale/locale_cs-CZ.ini
index 409b014fab..cb984aad07 100644
--- a/options/locale/locale_cs-CZ.ini
+++ b/options/locale/locale_cs-CZ.ini
@@ -57,7 +57,7 @@ mirror=Zrcadlo
new_repo=Nový repozitář
new_migrate=Nová migrace
new_mirror=Nové zrcadlo
-new_fork=Nové rozštěpení repozitáře
+new_fork=Nový fork repozitáře
new_org=Nová organizace
new_project=Nový projekt
new_project_column=Nový sloupec
@@ -76,7 +76,7 @@ collaborative=Spolupráce
forks=Rozštěpení
activities=Aktivity
-pull_requests=Požadavky na natažení
+pull_requests=Požadavky na sloučení
issues=Úkoly
milestones=Milníky
@@ -145,6 +145,18 @@ value=Hodnota
sign_in_with_provider = Přihlásit se přes %s
confirm_delete_artifact = Opravdu chcete odstranit artefakt „%s“?
toggle_menu = Přepnout nabídku
+filter = Filtr
+filter.is_fork = Forknuto
+filter.not_fork = Není forkuto
+filter.is_mirror = Zrcadleno
+filter.is_template = Šablona
+filter.not_template = Není šablona
+filter.public = Veřejné
+filter.private = Soukromé
+filter.is_archived = Archivováno
+filter.not_mirror = Není zrcadleno
+filter.not_archived = Není archivováno
+filter.clear = Vymazat filtr
[aria]
navbar=Navigační lišta
@@ -154,9 +166,12 @@ footer.links=Odkazy
[heatmap]
number_of_contributions_in_the_last_12_months=%s příspěvků za posledních 12 měsíců
-no_contributions=Žádné příspěvky
+contributions_zero=Žádné příspěvky
less=Méně
more=Více
+contributions_format = {contributions} dne {day}. {month} {year}
+contributions_one = příspěvek
+contributions_few = příspěvků
[editor]
buttons.heading.tooltip=Přidat nadpis
@@ -200,7 +215,7 @@ license_desc=Vše je na dokumentaci, než budete měnit jakákoliv nastavení.
require_db_desc=Forgejo requires MySQL, PostgreSQL, MSSQL, SQLite3 or TiDB (MySQL protocol).
db_title=Nastavení databáze
@@ -228,7 +243,7 @@ err_admin_name_pattern_not_allowed=Uživatelské jméno administrátora je nepla
err_admin_name_is_invalid=Uživatelské jméno administrátora není platné
general_title=Obecná nastavení
-app_name=Název stránky
+app_name=Název instance
app_name_helper=Zde můžete zadat název vaší společnosti.
repo_path=Kořenový adresář repozitářů
repo_path_helper=Všechny vzdálené repozitáře Gitu budou uloženy do tohoto adresáře.
@@ -239,47 +254,47 @@ run_user_helper=Zadejte uživatelské jméno, pod kterým Gitea běží v opera
domain=Doména serveru
domain_helper=Adresa domény, nebo hostitele serveru.
ssh_port=Port SSH serveru
-ssh_port_helper=Číslo portu, na kterém SSH server naslouchá. Když ponecháte prázdné, SSH server zakážete.
-http_port=Port, na kterém Forgejo naslouchá HTTP protokolu
-http_port_helper=Číslo portu, na kterém bude naslouchat webový server Forgejo.
-app_url=Základní URL Forgejo
+ssh_port_helper=Číslo portu, který bude použit pro SSH server. Nechte prázdné pro zakázání SSH serveru.
+http_port=Port pro naslouchání HTTP
+http_port_helper=Číslo portu, který bude použit webovým serverem Forgejo.
+app_url=Základní URL
app_url_helper=Základní adresa pro HTTP(S) URL adresy pro klonování a e-mailová oznámení.
-log_root_path=Adresář logů
+log_root_path=Adresář protokolů
log_root_path_helper=Soubory protokolu budou zapsány do tohoto adresáře.
-optional_title=Dodatečná nastavení
+optional_title=Volitelná nastavení
email_title=Nastavení e-mailu
-smtp_addr=Server SMTP
+smtp_addr=Hostitel SMTP
smtp_port=Port SMTP
smtp_from=Odeslat e-mail jako
smtp_from_helper=E-mailová adresa, kterou bude Forgejo používat. Zadejte běžnou e-mailovou adresu, nebo použijte formát "Jméno".
mailer_user=Uživatelské jméno SMTP
-mailer_password=Heslo pro SMTP
+mailer_password=Heslo SMTP
register_confirm=Pro registraci vyžadovat potvrzení e-mailu
mail_notify=Povolit e-mailová oznámení
-server_service_title=Nastavení serveru a dalších služeb
+server_service_title=Nastavení serveru a služeb třetích stran
offline_mode=Povolit místní režim
offline_mode_popup=Zakázat sítě pro doručování obsahu a poskytovat veškerý obsah lokálně.
disable_gravatar=Zakázat Gravatar
disable_gravatar_popup=Zakážete Gravatar a jiné cizí zdroje avatarů. Pokud uživatel nenahraje avatar, bude použit výchozí.
-federated_avatar_lookup=Povolit avatary z veřejných zdrojů
+federated_avatar_lookup=Povolit federované avatary
federated_avatar_lookup_popup=Povolte vyhledání avatarů z veřejných zdrojů pro využití služeb založených na libravatar.
-disable_registration=Vypnout možnost uživatelské registrace
+disable_registration=Zakázat uživatelské registrace
disable_registration_popup=Vypnout možnost registrace. Pouze správci budou moci vytvářet účty.
allow_only_external_registration_popup=Povolit registraci pouze prostřednictvím externích služeb
openid_signin=Povolit přihlášení pomocí OpenID
openid_signin_popup=Umožňuje uživateli přihlásit se pomocí OpenID.
-openid_signup=Povolit automatickou registraci pomocí OpenID
+openid_signup=Povolit uživatelskou registraci pomocí OpenID
openid_signup_popup=Umožňuje uživateli automaticky se registrovat pomocí OpenID.
enable_captcha=Povolit CAPTCHA při registraci
enable_captcha_popup=Vyžadovat správně zadaný text CAPTCHA při registraci.
-require_sign_in_view=Vyžadovat přihlášení k zobrazení stránek
+require_sign_in_view=Vyžadovat přihlášení pro zobrazení obsahu instance
require_sign_in_view_popup=Povolí přístup ke stránkám jen přihlášeným uživatelům. Návštěvníci uvidí jen přihlašovací a registrační stránky.
admin_setting_desc=Vytvoření účtu správce je nepovinné. První registrovaný uživatel se automaticky stane správcem.
admin_title=Nastavení účtu správce
admin_name=Uživatelské jméno správce
admin_password=Heslo
-confirm_password=Potvrdit heslo
+confirm_password=Potvrzení hesla
admin_email=E-mailová adresa
install_btn_confirm=Nainstalovat Forgejo
test_git_failed=Chyba při testu příkazu „git“: %v
@@ -288,30 +303,31 @@ invalid_db_setting=Nastavení databáze je neplatné: %v
invalid_db_table=Databázová tabulka „%s“ je neplatná: %v
invalid_repo_path=Kořenový adresář repozitářů není správný: %v
invalid_app_data_path=Cesta k datům aplikace je neplatná: %v
-run_user_not_match=Uživatelské jméno v poli „Spustit jako“ není aktuální uživatelské jméno: %s -> %s
+run_user_not_match=Uživatelské jméno v poli „spustit jako uživatel“ není aktuální uživatelské jméno: %s -> %s
internal_token_failed=Nepodařilo se vytvořit interní token: %v
secret_key_failed=Nepodařilo se vytvořit tajný klíč: %v
save_config_failed=Uložení konfigurace se nezdařilo: %v
invalid_admin_setting=Nastavení účtu správce není správné: %v
invalid_log_root_path=Kořenový adresář logů není správný: %v
-default_keep_email_private=Jako počáteční nastavení skrýt e-mailové adresy
+default_keep_email_private=Ve výchozím nastavení skrýt e-mailové adresy
default_keep_email_private_popup=Nastaví e-mailové adresy novým uživatelským účtům jako skryté.
-default_allow_create_organization=Dovolí novým uživatelům zakládat organizace
+default_allow_create_organization=Povolit novým uživatelům zakládat organizace
default_allow_create_organization_popup=Povolit novým uživatelským účtům vytvářet organizace.
-default_enable_timetracking=Povolit sledování času ve výchozím nastavení
+default_enable_timetracking=Povolit ve výchozím nastavení sledování času
default_enable_timetracking_popup=Povolí sledování času pro nové repozitáře.
no_reply_address=Skrytá e-mailová doména
no_reply_address_helper=Název domény pro uživatele se skrytou e-mailovou adresou. Příklad: pokud je název skryté e-mailové domény nastaven na „noreply.example.org“, uživatelské jméno „joe“ bude zaznamenáno v Gitu jako „joe@noreply.example.org“.
-password_algorithm=Hash algoritmus hesla
+password_algorithm=Hashovací algoritmus hesla
invalid_password_algorithm=Neplatný algoritmus hash hesla
password_algorithm_helper=Nastavte algoritmus hashování hesla. Algoritmy mají odlišné požadavky a sílu. Algoritmus argon2 je poměrně bezpečný, ale používá spoustu paměti a může být nevhodný pro malé systémy.
enable_update_checker=Povolit kontrolu aktualizací
enable_update_checker_helper=Kontroluje vydání nových verzí pravidelně připojením ke gitea.io.
env_config_keys=Konfigurace prostředí
env_config_keys_prompt=Následující proměnné prostředí budou také použity pro váš konfigurační soubor:
-enable_update_checker_helper_forgejo = Pravidelně kontroluje nové verze Forgejo kontrolou DNS TXT záznamu na adrese release.forgejo.org.
+enable_update_checker_helper_forgejo = Bude pravidelně kontrolovat nové verze Forgejo kontrolou TXT DNS záznamu na adrese release.forgejo.org.
allow_dots_in_usernames = Povolit uživatelům používat tečky ve svých uživatelských jménech. Neovlivní stávající účty.
smtp_from_invalid = Adresa v poli „Poslat e-mail jako“ je neplatná
+config_location_hint = Tyto možnosti konfigurace budou uloženy do:
[home]
uname_holder=Uživatelské jméno nebo e-mailová adresa
@@ -320,7 +336,7 @@ switch_dashboard_context=Přepnout kontext přehledu
my_repos=Repozitáře
show_more_repos=Zobrazit více repozitářů…
collaborative_repos=Společné repozitáře
-my_orgs=Mé organizace
+my_orgs=Organizace
my_mirrors=Má zrcadla
view_home=Zobrazit %s
search_repos=Nalézt repozitář…
@@ -361,6 +377,10 @@ code_search_results=Výsledky hledání pro „%s“
code_last_indexed_at=Naposledy indexováno %s
relevant_repositories_tooltip=Repozitáře, které jsou rozštěpení nebo nemají žádné téma, ikonu a žádný popis jsou skryty.
relevant_repositories=Zobrazují se pouze relevantní repositáře, zobrazit nefiltrované výsledky.
+forks_one = %d fork
+forks_few = %d forků
+stars_one = %d hvězda
+stars_few = %d hvězd
[auth]
create_new_account=Registrovat účet
@@ -381,7 +401,7 @@ allow_password_change=Vyžádat od uživatele změnu hesla (doporučeno)
reset_password_mail_sent_prompt=Na adresu %s byl zaslán potvrzovací e-mail. Zkontrolujte prosím vaši doručenou poštu během následujících %s, abyste dokončili proces obnovení účtu.
active_your_account=Aktivujte si váš účet
account_activated=Účet byl aktivován
-prohibit_login=Přihlášení zakázáno
+prohibit_login=Přihlašování je zakázáno
prohibit_login_desc=Vašemu účtu je zakázáno se přihlásit, kontaktujte prosím správce webu.
resent_limit_prompt=Omlouváme se, ale před chvílí jste požádal o zaslání aktivačního e-mailu. Počkejte prosím 3 minuty a pak to zkuste znovu.
has_unconfirmed_mail=Zdravím, %s, máte nepotvrzenou e-mailovou adresu (%s). Pokud jste nedostali e-mail pro potvrzení nebo potřebujete zaslat nový, klikněte prosím na tlačítku níže.
@@ -403,7 +423,7 @@ twofa_scratch_used=Použili jste váš pomocný kód. Byli jste přesměrování
twofa_passcode_incorrect=Vaše heslo je neplatné. Pokud jste ztratili vaše zařízení, použijte pomocný kód k přihlášení.
twofa_scratch_token_incorrect=Váš pomocný kód není správný.
login_userpass=Přihlásit se
-login_openid=OpenID
+tab_openid=OpenID
oauth_signup_tab=Zaregistrovat nový účet
oauth_signup_title=Dokončit nový účet
oauth_signup_submit=Dokončit účet
@@ -436,6 +456,8 @@ change_unconfirmed_email = Pokud jste při registraci zadali nesprávnou e-mailo
change_unconfirmed_email_error = Nepodařilo se změnit e-mailovou adresu: %v
change_unconfirmed_email_summary = Změna e-mailové adresy, na kterou bude odeslán aktivační e-mail.
last_admin=Nelze odstranit posledního správce. Musí existovat alespoň jeden správce.
+tab_signup = Registrace
+tab_signin = Přihlášení
[mail]
view_it_on=Zobrazit na %s
@@ -490,13 +512,13 @@ release.downloads=Soubory ke stažení:
release.download.zip=Zdrojový kód (ZIP)
release.download.targz=Zdrojový kód (TAR.GZ)
-repo.transfer.subject_to=%s by chtěl převést „%s“ pro %s
-repo.transfer.subject_to_you=%s by Vám chtěl převést „%s“
+repo.transfer.subject_to=%s chce převést repozitář „%s“ k uživateli %s
+repo.transfer.subject_to_you=%s by k vám chce převést repozitář „%s“
repo.transfer.to_you=vám
repo.transfer.body=Chcete-li ji přijmout nebo odmítnout, navštivte %s nebo ji prostě ignorujte.
-repo.collaborator.added.subject=%s vás přidal do %s
-repo.collaborator.added.text=Byl jste přidán jako spolupracovník repozitáře:
+repo.collaborator.added.subject=%s vás přidal do %s jako spolupracovníka
+repo.collaborator.added.text=Byli jste přidáni jako spolupracovník repozitáře:
team_invite.subject=%[1]s vás pozval/a, abyste se připojili k organizaci %[2]s
team_invite.text_1=%[1]s vás pozval/a do týmu %[2]s v organizaci %[3]s.
@@ -518,7 +540,7 @@ UserName=Uživatelské jméno
RepoName=Název repozitáře
Email=E-mailová adresa
Password=Heslo
-Retype=Potvrdit heslo
+Retype=Potvrzení hesla
SSHTitle=Název klíče SSH
HttpsUrl=HTTPS URL
PayloadUrl=URL nákladu
@@ -607,6 +629,8 @@ admin_cannot_delete_self = Nemůžete odstranit sami sebe, když jste administr
username_error_no_dots = ` může obsahovat pouze alfanumerické znaky („0-9“, „a-z“, „A-Z“), pomlčky („-“) a podtržítka („_“). Nemůže začínat nebo končit nealfanumerickými znaky. Jsou také zakázány po sobě jdoucí nealfanumerické znaky.`
admin_cannot_delete_self=Nemůžete se smazat, dokud jste správce. Nejdříve prosím odeberte svá administrátorská oprávnění.
+unset_password = Tento uživatel nemá nastavené heslo.
+unsupported_login_type = U tohoto typu účtu není funkce odstranění účtu podporována.
[user]
change_avatar=Změnit váš avatar…
@@ -648,17 +672,17 @@ appearance=Vzhled
password=Heslo
security=Zabezpečení
avatar=Avatar
-ssh_gpg_keys=SSH / GPG klíče
+ssh_gpg_keys=Klíče SSH / GPG
social=Účty sociálních sítí
applications=Aplikace
orgs=Spravovat organizace
repos=Repozitáře
delete=Smazat účet
-twofa=Dvoufaktorové ověřování
+twofa=Dvoufaktorové ověřování (TOTP)
account_link=Propojené účty
organization=Organizace
uid=UID
-webauthn=Bezpečnostní klíče
+webauthn=Dvoufaktorové ověřování (bezpečnostní klíče)
public_profile=Veřejný profil
biography_placeholder=Řekněte nám něco o sobě! (Můžete použít Markdown)
@@ -668,9 +692,9 @@ password_username_disabled=Externí uživatelé nemohou měnit svoje uživatelsk
full_name=Celé jméno
website=Web
location=Místo
-update_theme=Aktualizovat motiv vzhledu
-update_profile=Aktualizovat profil
-update_language=Aktualizovat jazyk
+update_theme=Změnit motiv
+update_profile=Upravit profil
+update_language=Změnit jazyk
update_language_not_found=Jazyk „%s“ není k dispozici.
update_language_success=Jazyk byl aktualizován.
update_profile_success=Váš profil byl aktualizován.
@@ -702,20 +726,20 @@ comment_type_group_issue_ref=Referenční číslo úkolu
saved_successfully=Vaše nastavení bylo úspěšně uloženo.
privacy=Soukromí
keep_activity_private=Skrýt aktivitu z profilové stránky
-keep_activity_private_popup=Učinit aktivitu viditelnou pouze pro vás a administrátory
+keep_activity_private_popup=Vaše aktivita bude viditelná pouze pro vás a správce instance
lookup_avatar_by_mail=Vyhledat avatar pomocí e-mailové adresy
-federated_avatar_lookup=Vyhledání avatarů ve veřejných zdrojích
+federated_avatar_lookup=Federované vyhledávání avatarů
enable_custom_avatar=Použít vlastní avatar
choose_new_avatar=Vybrat nový avatar
-update_avatar=Aktualizovat avatar
-delete_current_avatar=Smazat aktuální avatar
+update_avatar=Upravit avatar
+delete_current_avatar=Odstranit aktuální avatar
uploaded_avatar_not_a_image=Nahraný soubor není obrázek.
uploaded_avatar_is_too_big=Nahraný soubor (%d KiB) přesahuje maximální velikost (%d KiB).
update_avatar_success=Vaše avatar byl aktualizován.
update_user_avatar_success=Uživatelův avatar byl aktualizován.
-update_password=Aktualizovat heslo
+update_password=Upravit heslo
old_password=Stávající heslo
new_password=Nové heslo
retype_new_password=Potvrzení nového hesla
@@ -723,10 +747,10 @@ password_incorrect=Zadané heslo není správné.
change_password_success=Vaše heslo bylo aktualizováno. Od teď se přihlašujte novým heslem.
password_change_disabled=Externě ověřovaní uživatelé nemohou aktualizovat své heslo prostřednictvím webového rozhraní Forgejo.
-emails=E-mailová adresa
+emails=E-mailové adresy
manage_emails=Správa e-mailových adres
manage_themes=Vyberte výchozí motiv vzhledu
-manage_openid=Správa OpenID adres
+manage_openid=Správa adres OpenID
email_desc=Vaše hlavní e-mailová adresa bude použita pro oznámení, obnovení hesla, a pokud není skrytá, pro operace Gitu.
theme_desc=Toto bude váš výchozí motiv vzhledu napříč stránkou.
primary=Hlavní
@@ -767,7 +791,7 @@ gpg_desc=Tyto veřejné klíče GPG jsou propojeny s vaším účtem a používa
ssh_helper=Potřebujete pomoct? Podívejte se do příručky GitHubu na to vytvoření vlastních klíčů SSH nebo vyřešte běžné problémy, se kterými se můžete potkat při použití SSH.
gpg_helper=Potřebujete pomoct? Podívejte se do příručky GitHubu o GPG.
add_new_key=Přidat klíč SSH
-add_new_gpg_key=Přidat GPG klíč
+add_new_gpg_key=Přidat klíč GPG
key_content_ssh_placeholder=Začíná s „ssh-ed25519“, „ssh-rsa“, „ecdsa-sha2-nistp256“, „ecdsa-sha2-nistp384“, „ecdsa-sha2-nistp521“, „sk-ecdsa-sha2-nistp256@openssh.com“ nebo „sk-ssh-ed25519@openssh.com“
key_content_gpg_placeholder=Začíná s „-----BEGIN PGP PUBLIC KEY BLOCK-----“
add_new_principal=Přidat SSH Principal certifikát
@@ -808,8 +832,8 @@ add_key_success=SSH klíč „%s“ byl přidán.
add_gpg_key_success=GPG klíč „%s“ byl přidán.
add_principal_success=Byl přidán SSH Principal certifikát „%s“.
delete_key=Odstranit
-ssh_key_deletion=Odstraňte SSH klíč
-gpg_key_deletion=Odstraňte GPG klíč
+ssh_key_deletion=Odebrat klíč SSH
+gpg_key_deletion=Odebrat klíč GPG
ssh_principal_deletion=Odstranit SSH Principal certifikát
ssh_key_deletion_desc=Odstranění SSH klíče zruší jeho přístup k vašemu účtu. Pokračovat?
gpg_key_deletion_desc=Odstranění GPG klíče zneplatníte ověření commitů, které jsou jím podepsány. Pokračovat?
@@ -871,7 +895,7 @@ create_oauth2_application_button=Vytvořit aplikaci
create_oauth2_application_success=Úspěšně jste vytvořili novou OAuth2 aplikaci.
update_oauth2_application_success=Úspěšně jste aktualizovali OAuth2 aplikaci.
oauth2_application_name=Název aplikace
-oauth2_confidential_client=Důvěrný klient. Vyberte aplikace, které zachovávají důvěrnosti v utajení, jako jsou webové aplikace. Nevybírejte pro nativní aplikace včetně stolních a mobilních aplikací.
+oauth2_confidential_client=Důvěrný klient. Zvolte jej pro aplikace, které ukládají soubor secret, například webové aplikace. Nevybírejte jej pro nativní aplikace včetně aplikací pro počítače a mobilní zařízení.
oauth2_redirect_uris=Přesměrování URI. Použijte nový řádek pro každou URI.
save_application=Uložit
oauth2_client_id=ID klienta
@@ -896,7 +920,7 @@ twofa_recovery_tip=Pokud ztratíte své zařízení, budete moci použít jednor
twofa_is_enrolled=Váš účet aktuálně používá dvoufaktorové ověřování.
twofa_not_enrolled=Váš účet aktuálně nepoužívá dvoufaktorové ověřování.
twofa_disable=Zakázat dvoufaktorové ověřování
-twofa_scratch_token_regenerate=Obnovit pomocný token
+twofa_scratch_token_regenerate=Znovu vygenerovat jednorázový klíč pro obnovení
twofa_scratch_token_regenerated=Váš jednorázový obnovovací klíč je nyní %s. Uložte jej na bezpečném místě, protože se znovu nezobrazí.
twofa_enroll=Povolit dvoufaktorové ověřování
twofa_disable_note=Dvoufaktorové ověřování můžete zakázat, když bude potřeba.
@@ -913,7 +937,7 @@ twofa_failed_get_secret=Nepodařilo se získat tajemství.
webauthn_desc=Bezpečnostní klíče jsou hardwarová zařízení obsahující kryptografické klíče. Mohou být použity pro dvoufaktorové ověřování. Bezpečnostní klíče musí podporovat WebAuthn Authenticator standard.
webauthn_register_key=Přidat bezpečnostní klíč
webauthn_nickname=Přezdívka
-webauthn_delete_key=Odstranit bezpečnostní klíč
+webauthn_delete_key=Odebrat bezpečnostní klíč
webauthn_delete_key_desc=Pokud odstraníte bezpečnostní klíč, již se s ním nebudete moci přihlásit. Pokračovat?
webauthn_key_loss_warning=Pokud ztratíte své bezpečnostní klíče, ztratíte přístup k vašemu účtu.
webauthn_alternative_tip=Možná budete chtít nakonfigurovat další metodu ověřování.
@@ -931,18 +955,18 @@ hooks.desc=Přidat webhooky, které budou spouštěny pro všechny repoz
orgs_none=Nejste členem žádné organizace.
repos_none=Nevlastníte žádné repozitáře.
-delete_account=Smazat váš účet
+delete_account=Odstranit svůj účet
delete_prompt=Tato operace natrvalo odstraní váš uživatelský účet. NELZE ji vrátit zpět.
delete_with_all_comments=Váš účet je mladší než %s. Aby se zabránilo fantomovým komentářům, všechny komentáře k úkolům/požadavkům na natažení budou smazány.
-confirm_delete_account=Potvrdit smazání
-delete_account_title=Smazat uživatelský účet
+confirm_delete_account=Potvrdit odstranění
+delete_account_title=Odstranit uživatelský účet
delete_account_desc=Jste si jisti, že chcete trvale smazat tento účet?
email_notifications.enable=Povolit e-mailová oznámení
email_notifications.onmention=E-mail pouze při zmínce
email_notifications.disable=Zakázat e-mailová oznámení
email_notifications.submit=Nastavit předvolby e-mailu
-email_notifications.andyourown=A Vaše vlastní upozornění
+email_notifications.andyourown=A vaše vlastní upozornění
visibility=Viditelnost uživatele
visibility.public=Veřejný
@@ -974,10 +998,10 @@ visibility=Viditelnost
visibility_description=Pouze majitelé nebo členové organizace to budou moci vidět, pokud mají práva.
visibility_helper=Nastavit repozitář jako soukromý
visibility_helper_forced=Váš administrátor vynutil, že nové repozitáře budou soukromé.
-visibility_fork_helper=(Změna tohoto ovlivní všechny rozštěpení repozitáře.)
+visibility_fork_helper=(Změna této možnosti ovlivní viditelnost všech forků repozitáře.)
clone_helper=Potřebujete pomoci s klonováním? Navštivte nápovědu.
-fork_repo=Rozštěpení repozitáře
-fork_from=Rozštěpit z
+fork_repo=Fork repozitáře
+fork_from=Fork z
already_forked=Již jsi rozštěpil %s
fork_to_different_account=Rozštěpit na jiný účet
fork_visibility_helper=Viditelnost rozštěpeného repozitáře nemůže být změněna.
@@ -996,7 +1020,7 @@ repo_desc_helper=Zadejte krátký popis (volitelné)
repo_lang=Jazyk
repo_gitignore_helper=Vyberte šablony .gitignore.
repo_gitignore_helper_desc=Vyberte soubory, které nechcete sledovat ze seznamu šablon pro běžné jazyky. Typické artefakty generované nástroji pro sestavení každého jazyka jsou ve výchozím stavu součástí .gitignore.
-issue_labels=Štítky úkolů
+issue_labels=Štítky problémů
issue_labels_helper=Vyberte sadu štítků úkolů.
license=Licence
license_helper=Vyberte licenční soubor.
@@ -1006,7 +1030,7 @@ object_format_helper=Objektový formát repozitáře. Nelze později změnit. SH
readme=README
readme_helper=Vyberte šablonu souboru README.
readme_helper_desc=Toto je místo, kde můžete napsat úplný popis vašeho projektu.
-auto_init=Inicializovat repozitář (Přidá .gitignore, License a README)
+auto_init=Inicializovat repozitář (přidá soubory .gitignore, License a README)
trust_model_helper=Vyberte model důvěry pro ověření podpisu. Možnosti jsou:
trust_model_helper_collaborator=Spolupracovník: Důvěřovat podpisům spolupracovníků
trust_model_helper_committer=Přispěvatel: Důvěřovat podpisům, které se shodují s přispěvateli
@@ -1018,7 +1042,7 @@ default_branch_label=výchozí
default_branch_helper=Výchozí větev je základní větev pro požadavky na natažení a commity kódu.
mirror_prune=Vyčistit
mirror_prune_desc=Odstranit zastaralé reference na vzdálené sledování
-mirror_interval=Interval zrcadlení (platné časové jednotky jsou „h“, „m“ a „s“). 0 zakáže periodickou synchronizaci. (Minimální interval: %s)
+mirror_interval=Interval zrcadlení (platné časové jednotky jsou „h“, „m“ a „s“). Nastavením na 0 zakážete periodickou synchronizaci. (Minimální interval: %s)
mirror_interval_invalid=Interval zrcadlení není platný.
mirror_sync_on_commit=Synchronizovat při nahrávání revizí
mirror_address=Klonovat z URL
@@ -1027,7 +1051,7 @@ mirror_address_url_invalid=Poskytnutá URL je neplatná. Všechny části musít
mirror_address_protocol_invalid=Zadaná URL je neplatná. Mohou být zrcadleny pouze umístění http(s):// nebo git://.
mirror_lfs=Úložiště velkých souborů (LFS)
mirror_lfs_desc=Aktivovat zrcadlení dat LFS.
-mirror_lfs_endpoint=Koncový bod LFS
+mirror_lfs_endpoint=Endpoint LFS
mirror_lfs_endpoint_desc=Synchronizace se pokusí použít URL pro klonování k určení LFS serveru. Můžete také zadat vlastní koncový bod, pokud jsou data LFS repozitáře uložena někde jinde.
mirror_last_synced=Poslední synchronizace
mirror_password_placeholder=(Nezměněno)
@@ -1057,9 +1081,9 @@ tree_path_not_found_commit=Cesta %[1]s v commitu %[2]s neexistuje
tree_path_not_found_branch=Cesta %[1]s ve větvi %[2]s neexistuje
tree_path_not_found_tag=Cesta %[1]s ve značce %[2]s neexistuje
-transfer.accept=Přijmout převod
+transfer.accept=Přijmout přesun
transfer.accept_desc=Převést do „%s“
-transfer.reject=Odmítnout převod
+transfer.reject=Odmítnout přesun
transfer.reject_desc=Zrušit převod do „%s“
transfer.no_permission_to_accept=Nemáte oprávnění k přijetí tohoto převodu.
transfer.no_permission_to_reject=Nemáte oprávnění k odmítnutí tohoto převodu.
@@ -1072,13 +1096,13 @@ desc.archived=Archivováno
desc.sha256=SHA256
template.items=Položky šablony
-template.git_content=Obsah gitu (výchozí větev)
-template.git_hooks=Háčky Gitu
-template.git_hooks_tooltip=Momentálně nemůžete po přidání upravovat nebo odebrat háčky gitu. Vyberte pouze v případě, že důvěřujete šabloně repozitáře.
+template.git_content=Obsah Gitu (výchozí větev)
+template.git_hooks=Git hooks
+template.git_hooks_tooltip=Momentálně nemůžete po přidání upravovat nebo odebírat Git hooky. Vyberte pouze v případě, že důvěřujete šabloně repozitáře.
template.webhooks=Webové háčky
template.topics=Témata
template.avatar=Avatar
-template.issue_labels=Štítky úkolů
+template.issue_labels=Štítky problémů
template.one_item=Musíte vybrat alespoň jednu položku šablony
template.invalid=Musíte vybrat repositář šablony
@@ -1097,7 +1121,7 @@ migrate_options=Možnosti migrace
migrate_service=Migrační služba
migrate_options_mirror_helper=Tento repozitář bude zrcadlem
migrate_options_lfs=Migrovat LFS soubory
-migrate_options_lfs_endpoint.label=Koncový bod LFS
+migrate_options_lfs_endpoint.label=Endpoint LFS
migrate_options_lfs_endpoint.description=Migrace se pokusí použít váš vzdálený Git pro určení LFS serveru. Můžete také zadat vlastní koncový bod, pokud jsou data LFS repozitáře uložena někde jinde.
migrate_options_lfs_endpoint.description.local=Podporována je také cesta k lokálnímu serveru.
migrate_options_lfs_endpoint.placeholder=Ponecháte-li prázdné, koncový bod bude odvozen z adresy URL klonu
@@ -1106,8 +1130,8 @@ migrate_items_wiki=Wiki
migrate_items_milestones=Milníky
migrate_items_labels=Štítky
migrate_items_issues=Úkoly
-migrate_items_pullrequests=Požadavky na natažení
-migrate_items_merge_requests=Sloučit požadavky
+migrate_items_pullrequests=Žádosti o sloučení
+migrate_items_merge_requests=Sloučit žádosti
migrate_items_releases=Vydání
migrate_repo=Migrovat repozitář
migrate.clone_address=Migrovat / klonovat z URL
@@ -1127,7 +1151,7 @@ migrate.migrating=Probíhá migrace z %s ...
migrate.migrating_failed=Migrace z %s se nezdařila.
migrate.migrating_failed.error=Nepodařilo se migrovat: %s
migrate.migrating_failed_no_addr=Migrace se nezdařila.
-migrate.github.description=Migrovat data z github.com nebo jiných GitHub instancí.
+migrate.github.description=Migrovat data z github.com nebo serveru GitHub Enterprise.
migrate.git.description=Migrovat pouze repozitář z libovolné služby Git.
migrate.gitlab.description=Migrovat data z gitlab.com nebo jiných GitLab instancí.
migrate.gitea.description=Migrovat data z gitea.com nebo jiných Gitea/Forgejo instancí.
@@ -1135,13 +1159,13 @@ migrate.gogs.description=Migrovat data z notabug.com nebo jiných Gogs instancí
migrate.onedev.description=Migrovat data z code.onedev.io nebo jiných OneDev instancí.
migrate.codebase.description=Migrovat data z codebasehq.com.
migrate.gitbucket.description=Migrovat data z GitBucket instancí.
-migrate.migrating_git=Migrování data gitu
-migrate.migrating_topics=Migrování témat
-migrate.migrating_milestones=Migrování milnků
-migrate.migrating_labels=Migrování štítků
-migrate.migrating_releases=Migrování vydání
-migrate.migrating_issues=Migrování úkolů
-migrate.migrating_pulls=Migrování požadavků na natažení
+migrate.migrating_git=Migrace dat z Gitu
+migrate.migrating_topics=Migrace témat
+migrate.migrating_milestones=Migrace milníků
+migrate.migrating_labels=Migrace štítků
+migrate.migrating_releases=Migrace vydání
+migrate.migrating_issues=Migrace problémů
+migrate.migrating_pulls=Migrace žádostí o sloučení
migrate.cancel_migrating_title=Zrušit migraci
migrate.cancel_migrating_confirm=Chcete zrušit tuto migraci?
@@ -1179,7 +1203,7 @@ find_tag=Najít značku
branches=Větve
tags=Značky
issues=Úkoly
-pulls=Požadavky na natažení
+pulls=Žádosti o sloučení
project_board=Projekty
packages=Balíčky
actions=Akce
@@ -1214,7 +1238,7 @@ ambiguous_character=`%[1]c [U+%04[1]X] je zaměnitelný s %[2]c [U+%04[2]X]`
escape_control_characters=Escape sekvence
unescape_control_characters=Bez escape sekvencí
file_copy_permalink=Kopírovat trvalý odkaz
-view_git_blame=Zobrazit Git Blame
+view_git_blame=Zobrazit git blame
video_not_supported_in_browser=Váš prohlížeč nepodporuje značku HTML5 „video“.
audio_not_supported_in_browser=Váš prohlížeč nepodporuje značku HTML5 „audio“.
stored_lfs=Uloženo pomocí Git LFS
@@ -1224,7 +1248,7 @@ vendored=Vendorováno
generated=Generováno
commit_graph=Graf commitů
commit_graph.select=Vybrat větve
-commit_graph.hide_pr_refs=Skrýt požadavky na natažení
+commit_graph.hide_pr_refs=Skrýt žádosti o sloučení
commit_graph.monochrome=Černobílé
commit_graph.color=Barva
commit.contained_in=Tento commit je obsažen v:
@@ -1248,7 +1272,7 @@ editor.edit_this_file=Upravit soubor
editor.this_file_locked=Soubor je uzamčen
editor.must_be_on_a_branch=Musíte mít zvolenu větev pro úpravu či návrh změn tohoto souboru.
editor.fork_before_edit=Musíte rozštěpit tento repozitář pro vytvoření nebo navržení změny tohoto souboru.
-editor.delete_this_file=Smazat soubor
+editor.delete_this_file=Odstranit soubor
editor.must_have_write_access=Musíte mít přístup pro zápis pro dělání či navrhování změn tohoto souboru.
editor.file_delete_success=Soubor „%s“ byl odstraněn.
editor.name_your_file=Pojmenujte váš soubor…
@@ -1290,8 +1314,8 @@ editor.commit_empty_file_text=Soubor, který se chystáte odevzdat, je prázdný
editor.no_changes_to_show=Žádné změny k zobrazení.
editor.fail_to_update_file=Nepodařilo se aktualizovat/vytvořit soubor „%s“.
editor.fail_to_update_file_summary=Chybové hlášení:
-editor.push_rejected_no_message=Změna byla serverem zamítnuta bez zprávy. Prosím, zkontrolujte háčky Gitu.
-editor.push_rejected=Změna byla serverem zamítnuta. Prosím, zkontrolujte háčky Gitu.
+editor.push_rejected_no_message=Změna byla serverem zamítnuta bez zprávy. Zkontrolujte prosím Git hooks.
+editor.push_rejected=Změna byla serverem zamítnuta. Zkontrolujte prosím Git hooks.
editor.push_rejected_summary=Úplná zpráva o odmítnutí:
editor.add_subdir=Přidat adresář…
editor.unable_to_upload_files=Nepodařilo se nahrát soubory do „%s“. Chyba: %v
@@ -1320,7 +1344,7 @@ commits.newer=Novější
commits.signed_by=Podepsáno
commits.signed_by_untrusted_user=Podepsáno nedůvěryhodným uživatelem
commits.signed_by_untrusted_user_unmatched=Podepsáno nedůvěryhodným uživatelem, který nesouhlasí s přispěvatelem
-commits.gpg_key_id=ID GPG klíče
+commits.gpg_key_id=ID klíče GPG
commits.ssh_key_fingerprint=Otisk klíče SSH
commits.view_path=Zobrazit v tomto bodě v historii
@@ -1337,7 +1361,7 @@ commitstatus.failure=Chyba
commitstatus.pending=Čekající
commitstatus.success=Úspěch
-ext_issues=Přístup k externím úkolům
+ext_issues=Přístup k externím problémům
ext_issues.desc=Odkaz na externí systém úkolů.
projects=Projekty
@@ -1352,9 +1376,9 @@ projects.create_success=Projekt „%s“ byl vytvořen.
projects.deletion=Odstranit projekt
projects.deletion_desc=Odstranění projektu jej odstraní ze všech souvisejících úkolů. Pokračovat?
projects.deletion_success=Projekt byl odstraněn.
-projects.edit=Upravit projekty
+projects.edit=Upravit projekt
projects.edit_subheader=Projekty organizují úkoly a sledují pokrok.
-projects.modify=Aktualizovat projekt
+projects.modify=Upravit projekt
projects.edit_success=Projekt „%s“ byl aktualizován.
projects.type.none=Žádný
projects.type.basic_kanban=Základní Kanban
@@ -1387,7 +1411,7 @@ issues.filter_milestones=Filtrovat milník
issues.filter_projects=Filtrovat projekt
issues.filter_labels=Filtrovat štítky
issues.filter_reviewers=Filtrovat posuzovatele
-issues.new=Nový úkol
+issues.new=Nový problém
issues.new.title_empty=Název nesmí být prázdný
issues.new.labels=Štítky
issues.new.no_label=Bez štítku
@@ -1395,17 +1419,17 @@ issues.new.clear_labels=Zrušit štítky
issues.new.projects=Projekty
issues.new.clear_projects=Vymazat projekty
issues.new.no_projects=Žádný projekt
-issues.new.open_projects=Otevřít projekty
+issues.new.open_projects=Otevřené projekty
issues.new.closed_projects=Uzavřené projekty
issues.new.no_items=Žádné položky
issues.new.milestone=Milník
-issues.new.no_milestone=Bez milníku
+issues.new.no_milestone=Žádný milník
issues.new.clear_milestone=Smazat milník
-issues.new.open_milestone=Otevřít milník
+issues.new.open_milestone=Otevřené milníky
issues.new.closed_milestone=Zavřené milníky
issues.new.assignees=Zpracovatelé
issues.new.clear_assignees=Smazat zpracovatele
-issues.new.no_assignees=Bez zpracovatelů
+issues.new.no_assignees=Žádní přiřazení uživatelé
issues.new.no_reviewers=Žádní posuzovatelé
issues.choose.get_started=Začínáme
issues.choose.open_external_link=Otevřít
@@ -1415,15 +1439,15 @@ issues.choose.ignore_invalid_templates=Neplatné šablony byly ignorovány
issues.choose.invalid_templates=%v nalezených neplatných šablon
issues.choose.invalid_config=Nastavení problému obsahuje chyby:
issues.no_ref=Není určena žádná větev/značka
-issues.create=Vytvořit úkol
+issues.create=Vytvořit problém
issues.new_label=Nový štítek
issues.new_label_placeholder=Název štítku
issues.new_label_desc_placeholder=Popis
issues.create_label=Vytvořit štítek
-issues.label_templates.title=Nahrát předdefinovanou sadu značek
-issues.label_templates.info=Zatím nebyly vytvořeny žádné štítky. Vytvořte štítek kliknutím na „Nový štítek“ nebo použijte přednastavenou sadu štítků:
-issues.label_templates.helper=Vyberte sadu značek
-issues.label_templates.use=Použít sadu štítků
+issues.label_templates.title=Nahrát přednastavené štítky
+issues.label_templates.info=Zatím nebyly vytvořeny žádné štítky. Vytvořte štítek kliknutím na „Nový štítek“ nebo použijte přednastavené štítky:
+issues.label_templates.helper=Vyberte přednastavené značky
+issues.label_templates.use=Použít přednastavené štítky
issues.label_templates.fail_to_load_file=Nepodařilo se načíst soubor šablony popisku „%s“: %v
issues.add_label=přidal/a %s štítek %s
issues.add_labels=přidal/a %s štítky %s
@@ -1511,7 +1535,7 @@ issues.commented_at=`okomentoval %s`
issues.delete_comment_confirm=Jste si jist, že chcete smazat tento komentář?
issues.context.copy_link=Kopírovat odkaz
issues.context.quote_reply=Citovat odpověď
-issues.context.reference_issue=Odkázat v novém úkolu
+issues.context.reference_issue=Odkázat v novém problému
issues.context.edit=Upravit
issues.context.delete=Smazat
issues.no_content=K dispozici není žádný popis.
@@ -1520,7 +1544,7 @@ issues.comment_pull_merged_at=sloučený commit %[1]s do %[2]s %[3]s
issues.comment_manually_pull_merged_at=ručně sloučený commit %[1]s do %[2]s %[3]s
issues.close_comment_issue=Okomentovat a zavřít
issues.reopen_issue=Znovuotevřít
-issues.reopen_comment_issue=Okomentovat a znovuotevřít
+issues.reopen_comment_issue=Okomentovat a znovu otevřít
issues.create_comment=Okomentovat
issues.closed_at=`uzavřel/a tento úkol %[2]s`
issues.reopened_at=`znovuotevřel/a tento úkol %[2]s`
@@ -1567,7 +1591,7 @@ issues.label_open_issues=%d otevřených úkolů
issues.label_edit=Upravit
issues.label_delete=Smazat
issues.label_modify=Upravit štítek
-issues.label_deletion=Smazat štítek
+issues.label_deletion=Odstranit štítek
issues.label_deletion_desc=Odstranění štítku jej smaže ze všech úkolů. Pokračovat?
issues.label_deletion_success=Štítek byl odstraněn.
issues.label.filter_sort.alphabetically=Od začátku abecedy
@@ -1669,7 +1693,7 @@ issues.dependency.blocked_by_short=Závisí na
issues.dependency.remove_header=Odstranit závislost
issues.dependency.issue_remove_text=Tímto krokem odeberete závislost z úkolu. Pokračovat?
issues.dependency.pr_remove_text=Tímto krokem odeberete závislost z požadavku na natažení. Pokračovat?
-issues.dependency.setting=Povolit závislosti pro úkoly a požadavky na natažení
+issues.dependency.setting=Povolit závislosti pro problémy a žádosti o sloučení
issues.dependency.add_error_same_issue=Úkol nemůže záviset sám na sobě.
issues.dependency.add_error_dep_issue_not_exist=Související úkol neexistuje.
issues.dependency.add_error_dep_not_exist=Závislost neexistuje.
@@ -1718,9 +1742,9 @@ compare.compare_base=základní
compare.compare_head=porovnat
pulls.desc=Povolit požadavky na natažení a posuzování kódu.
-pulls.new=Nový požadavek na natažení
-pulls.view=Zobrazit požadavek na natažení
-pulls.compare_changes=Nový požadavek na natažení
+pulls.new=Nová žádost o sloučení
+pulls.view=Zobrazit žádost o sloučení
+pulls.compare_changes=Nová žádost o sloučení
pulls.allow_edits_from_maintainers=Povolit úpravy od správců
pulls.allow_edits_from_maintainers_desc=Uživatelé s přístupem k zápisu do základní větve mohou také nahrávat do této větve
pulls.allow_edits_from_maintainers_err=Aktualizace se nezdařila
@@ -1747,9 +1771,9 @@ pulls.nothing_to_compare=Tyto větve jsou stejné. Není potřeba vytvářet po
pulls.nothing_to_compare_have_tag=Vybraná větev/značka je stejná.
pulls.nothing_to_compare_and_allow_empty_pr=Tyto větve jsou stejné. Tento požadavek na natažení bude prázdný.
pulls.has_pull_request=`Požadavek na natažení mezi těmito větvemi již existuje: %[2]s#%[3]d`
-pulls.create=Vytvořit požadavek na natažení
-pulls.title_desc=chce sloučit %[1]d commity z větve %[2]s
do %[3]s
-pulls.merged_title_desc=sloučil %[1]d commity z větve %[2]s
do větve %[3]s
před %[4]s
+pulls.create=Vytvořit žádost o sloučení
+pulls.title_desc_few=chce sloučit %[1]d commity z větve %[2]s
do %[3]s
+pulls.merged_title_desc_few=sloučil %[1]d commity z větve %[2]s
do větve %[3]s
před %[4]s
pulls.change_target_branch_at=`změnil/a cílovou větev z %s na %s %s`
pulls.tab_conversation=Konverzace
pulls.tab_commits=Commity
@@ -1816,9 +1840,9 @@ pulls.unrelated_histories=Sloučení selhalo: Hlavní a základní revize nesdí
pulls.merge_out_of_date=Sloučení selhalo: Základ byl aktualizován při generování sloučení. Tip: Zkuste to znovu.
pulls.head_out_of_date=Sloučení selhalo: Hlavní revize byla aktualizován při generování sloučení. Tip: Zkuste to znovu.
pulls.has_merged=Chyba: Požadavek na natažení byl sloučen, nelze znovu sloučit nebo změnit cílovou větev.
-pulls.push_rejected=Sloučení selhalo: Nahrání bylo zamítnuto. Zkontrolujte háčky Gitu pro tento repozitář.
+pulls.push_rejected=Push selhal: nahrání bylo zamítnuto. Zkontrolujte Git hooky pro tento repozitář.
pulls.push_rejected_summary=Úplná zpráva o odmítnutí
-pulls.push_rejected_no_message=Sloučení se nezdařilo: Nahrání bylo odmítnuto, ale nebyla nalezena žádná vzdálená zpráva.
Zkontrolujte háčky gitu pro tento repozitář
+pulls.push_rejected_no_message=Push selhal: nahrání bylo odmítnuto, ale nebyla nalezena žádná vzdálená zpráva. Zkontrolujte Git hooky pro tento repozitář
pulls.open_unmerged_pull_exists=`Nemůžete provést operaci znovuotevření protože je tu čekající požadavek na natažení (#%d) s identickými vlastnostmi.`
pulls.status_checking=Některé kontroly jsou nedořešeny
pulls.status_checks_success=Všechny kontroly byly úspěšné
@@ -1834,7 +1858,7 @@ pulls.update_branch_rebase=Aktualizovat větev pomocí rebase
pulls.update_branch_success=Aktualizace větve byla úspěšná
pulls.update_not_allowed=Nemáte oprávnění aktualizovat větev
pulls.outdated_with_base_branch=Tato větev je zastaralá oproti základní větvi
-pulls.close=Zavřít požadavek na natažení
+pulls.close=Zavřít žádost o sloučení
pulls.closed_at=`uzavřel/a tento požadavek na natažení %[2]s`
pulls.reopened_at=`znovuotevřel/a tento požadavek na natažení %[2]s`
pulls.cmd_instruction_hint=`Zobrazit instrukce příkazové řádky.`
@@ -1879,13 +1903,13 @@ milestones.create_success=Milník „%s“ byl vytvořen.
milestones.edit=Upravit milník
milestones.edit_subheader=Milník organizuje úkoly a sledují pokrok.
milestones.cancel=Zrušit
-milestones.modify=Aktualizovat milník
+milestones.modify=Upravit milník
milestones.edit_success=Milník „%s“ byl aktualizován.
-milestones.deletion=Smazat milník
+milestones.deletion=Odstranit milník
milestones.deletion_desc=Odstranění milníku jej smaže ze všech souvisejících úkolů. Pokračovat?
milestones.deletion_success=Milník byl odstraněn.
-milestones.filter_sort.earliest_due_data=Nejstarší datum dokončení
-milestones.filter_sort.latest_due_date=Nejnovější datum dokončení
+milestones.filter_sort.earliest_due_data=Nejbližší termín dokončení
+milestones.filter_sort.latest_due_date=Nejzazší termín dokončení
milestones.filter_sort.least_complete=Nejméně dokončené
milestones.filter_sort.most_complete=Nejvíce dokončené
milestones.filter_sort.most_issues=Nejvíce úkolů
@@ -1945,38 +1969,38 @@ activity.period.quarterly=3 měsíce
activity.period.semiyearly=6 měsíců
activity.period.yearly=1 rok
activity.overview=Přehled
-activity.active_prs_count_1=%d aktivní požadavek na natažení
-activity.active_prs_count_n=%d aktivní požadavky na natažení
-activity.merged_prs_count_1=Sloučený požadavek na natažení
-activity.merged_prs_count_n=Sloučené požadavky na natažení
-activity.opened_prs_count_1=Navrhovaný požadavek na natažení
-activity.opened_prs_count_n=Navrhované požadavky na natažení
+activity.active_prs_count_1=%d aktivní žádost o sloučení
+activity.active_prs_count_n=%d aktivních žádostí o sloučení
+activity.merged_prs_count_1=Sloučená žádost
+activity.merged_prs_count_n=Sloučené žádosti
+activity.opened_prs_count_1=Navrhovaná žádost o sloučení
+activity.opened_prs_count_n=Navrhované žádosti o sloučení
activity.title.user_1=%d uživatel
activity.title.user_n=%d uživatelů
-activity.title.prs_1=%d Požadavek na natažení
-activity.title.prs_n=%d Požadavků na natažení
+activity.title.prs_1=%d žádost o sloučení
+activity.title.prs_n=%d žádostí o sloučení
activity.title.prs_merged_by=%s sloučil %s
activity.title.prs_opened_by=%s navrhl %s
activity.merged_prs_label=Sloučený
activity.opened_prs_label=Navrhovaný
-activity.active_issues_count_1=%d aktivní úkol
-activity.active_issues_count_n=%d aktivní úkoly
-activity.closed_issues_count_1=Uzavřený úkol
-activity.closed_issues_count_n=Uzavřené úkoly
-activity.title.issues_1=%d úkol
-activity.title.issues_n=%d úkolů
+activity.active_issues_count_1=%d aktivní problém
+activity.active_issues_count_n=%d aktivních problémů
+activity.closed_issues_count_1=Uzavřený problém
+activity.closed_issues_count_n=Uzavřené problémy
+activity.title.issues_1=%d problémy
+activity.title.issues_n=%d problémů
activity.title.issues_closed_from=%s uzavřel z %s
activity.title.issues_created_by=%s vytvořil %s
activity.closed_issue_label=Uzavřený
-activity.new_issues_count_1=Nový úkol
-activity.new_issues_count_n=Nové úkoly
+activity.new_issues_count_1=Nový problém
+activity.new_issues_count_n=Nové problémy
activity.new_issue_label=Otevřený
activity.title.unresolved_conv_1=%d nevyřešená konverzace
activity.title.unresolved_conv_n=%d nevyřešených konverzací
activity.unresolved_conv_desc=Tyto nedávno změněné úkolu a požadavky na natažení ještě nebyly vyřešeny.
activity.unresolved_conv_label=Otevřít
-activity.title.releases_1=%d Vydání
-activity.title.releases_n=%d Vydání
+activity.title.releases_1=%d vydání
+activity.title.releases_n=%d vydání
activity.title.releases_published_by=%s publikoval %s
activity.published_release_label=Publikováno
activity.no_git_activity=V tomto období nebyla žádná aktivita při odevzdání.
@@ -2025,7 +2049,7 @@ settings.collaboration.read=Čtení
settings.collaboration.owner=Vlastník
settings.collaboration.undefined=Neurčeno
settings.hooks=Webové háčky
-settings.githooks=Háčky Gitu
+settings.githooks=Git hooky
settings.basic_settings=Základní nastavení
settings.mirror_settings=Nastavení zrcadla
settings.mirror_settings.docs=Nastavte repozitář pro automatickou synchronizaci commitů, značek a větví s jiným repozitářem.
@@ -2042,7 +2066,7 @@ settings.mirror_settings.direction.pull=Natáhnout
settings.mirror_settings.direction.push=Nahrát
settings.mirror_settings.last_update=Poslední aktualizace
settings.mirror_settings.push_mirror.none=Nenastavena žádná zrcadla pro nahrání
-settings.mirror_settings.push_mirror.remote_url=URL vzdáleného Git repozitáře
+settings.mirror_settings.push_mirror.remote_url=Adresa URL vzdáleného Git repozitáře
settings.mirror_settings.push_mirror.add=Přidat zrcadlo pro nahrání
settings.mirror_settings.push_mirror.edit_sync_time=Upravit interval synchronizace zrcadla
@@ -2054,21 +2078,21 @@ settings.branches.switch_default_branch=Přepnout výchozí větev
settings.branches.update_default_branch=Aktualizovat výchozí větev
settings.branches.add_new_rule=Přidat nové pravidlo
settings.advanced_settings=Pokročilá nastavení
-settings.wiki_desc=Povolit Wiki repozitáře
-settings.use_internal_wiki=Používat vestavěnou Wiki
-settings.use_external_wiki=Používat externí Wiki
-settings.external_wiki_url=URL externí Wiki
+settings.wiki_desc=Povolit wiki repozitáře
+settings.use_internal_wiki=Používat vestavěnou wiki
+settings.use_external_wiki=Použít externí wiki
+settings.external_wiki_url=Adresa URL externí wiki
settings.external_wiki_url_error=URL externí wiki platné URL.
settings.external_wiki_url_desc=Když návštěvníci kliknou na záložku Wiki, jsou přesměrování na URL externí Wiki.
-settings.issues_desc=Povolit systém úkolů repozitáře
-settings.use_internal_issue_tracker=Použít vestavěný systém úkolů
-settings.use_external_issue_tracker=Použít externí systém úkolů
-settings.external_tracker_url=URL externího systému úkolů
+settings.issues_desc=Povolit systém problémů repozitáře
+settings.use_internal_issue_tracker=Použít vestavěný systém problémů
+settings.use_external_issue_tracker=Použít externí systém problémů
+settings.external_tracker_url=Adresa URL externího systému problémů
settings.external_tracker_url_error=URL externího systému úkolu není platné URL.
settings.external_tracker_url_desc=Když návštěvníci kliknou na záložku úkolů, jsou přesměrování na externí systém úkolů.
-settings.tracker_url_format=Formát URL externího systému úkolů
+settings.tracker_url_format=Formát adresy URL externího systému problémů
settings.tracker_url_format_error=Formát URL externího systému úkolu není platné URL.
-settings.tracker_issue_style=Formát čísel externího systému úkolů
+settings.tracker_issue_style=Formát čísel externího systému problémů
settings.tracker_issue_style.numeric=Číselný
settings.tracker_issue_style.alphanumeric=Alfanumerický
settings.tracker_issue_style.regexp=Regulární výraz
@@ -2077,7 +2101,7 @@ settings.tracker_issue_style.regexp_pattern_desc=První zachycená skupina bude
settings.tracker_url_format_desc=Použijte zástupné symboly {user}
, {repo}
a {index}
pro uživatelské jméno, jméno repozitáře a číslo úkolu.
settings.enable_timetracker=Povolit sledování času
settings.allow_only_contributors_to_track_time=Povolit sledování času pouze přispěvatelům
-settings.pulls_desc=Povolit požadavky na natažení
+settings.pulls_desc=Povolit žádosti o sloučení
settings.pulls.ignore_whitespace=Ignorovat bílé znaky při konfliktech
settings.pulls.enable_autodetect_manual_merge=Povolit autodetekci ručních sloučení (Poznámka: V některých zvláštních případech může dojít k nesprávnému rozhodnutí)
settings.pulls.allow_rebase_update=Povolit aktualizaci větve požadavku na natažení pomocí rebase
@@ -2087,7 +2111,7 @@ settings.releases_desc=Povolit vydání v repozitáři
settings.packages_desc=Povolit registr balíčků repozitáře
settings.projects_desc=Povolit projekty v repozitáři
settings.actions_desc=Povolit akce repozitáře
-settings.admin_settings=Nastavení správce
+settings.admin_settings=Administrátorská nastavení
settings.admin_enable_health_check=Povolit kontrolu stavu repozitáře (git fsck)
settings.admin_code_indexer=Indexování kódu
settings.admin_stats_indexer=Index statistiky kódu
@@ -2121,7 +2145,7 @@ settings.transfer_notices_1=- Ztratíte přístup k repozitáři, pokud jej pře
settings.transfer_notices_2=- Zůstane vám přístup k repozitáři, pokud jej převedete na organizaci kterou (spolu)vlastníte.
settings.transfer_notices_3=- Pokud je repozitář soukromý a je předán jednotlivému uživateli, tato akce se ujistí, že uživatel má alespoň oprávnění ke čtení (a v případě potřeby změní oprávnění).
settings.transfer_owner=Nový vlastník
-settings.transfer_perform=Provést převod
+settings.transfer_perform=Provést přesun
settings.transfer_started=Tento repozitář byl označen pro převod a čeká na potvrzení od „%s“
settings.transfer_succeed=Repozitář byl předán.
settings.signing_settings=Nastavení ověřování podpisu
@@ -2137,12 +2161,12 @@ settings.trust_model.committer.desc=Platné podpisy budou označeny pouze jako
settings.trust_model.collaboratorcommitter=Spolupracovník+Přispěvatel
settings.trust_model.collaboratorcommitter.long=Spolupracovník+Přispěvatel: Důvěřovat podpisům od spolupracovníků, které odpovídají tvůrci revize
settings.trust_model.collaboratorcommitter.desc=Platné podpisy spolupracovníků tohoto repozitáře budou označeny jako „důvěryhodné“, pokud se shodují s přispěvatelem. V opačném případě budou platné podpisy označeny jako "nedůvěryhodné", pokud se podpis shoduje s přispěvatelem a „neodpovídajícím“ v opačném případě. To přinutí Giteu, aby byla označena jako přispěvatel podepsaných commitů se skutečným přispěvatelem označeným jako Co-Authored-By: a Co-Committed-By: na konci commitu. Výchozí klíč Forgejo musí odpovídat uživateli v databázi.
-settings.wiki_delete=Odstranit data Wiki
+settings.wiki_delete=Odstranit data wiki
settings.wiki_delete_desc=Smazání Wiki dat repozitáře je trvalé a nemůže být vráceno zpět.
settings.wiki_delete_notices_1=- Natrvalo odstraní a zakáže wiki repozitáře pro %s.
-settings.confirm_wiki_delete=Odstranit data Wiki
+settings.confirm_wiki_delete=Odstranit data wiki
settings.wiki_deletion_success=Wiki data repozitáře byla odstraněna.
-settings.delete=Smazat tento repozitář
+settings.delete=Odstranit tento repozitář
settings.delete_desc=Smazání repozitáře je trvalé a nemůže být vráceno zpět.
settings.delete_notices_1=- Tuto operaci nelze zvrátit.
settings.delete_notices_2=- Tato operace trvale smaže repozitář %s včetně kódu, úkolů, komentářů, Wiki dat a nastavení spolupracovníků.
@@ -2150,7 +2174,7 @@ settings.delete_notices_fork_1=- Rozštěpení repozitáře bude nezávislé po
settings.deletion_success=Repozitář byl odstraněn.
settings.update_settings_success=Nastavení repozitáře bylo aktualizováno.
settings.update_settings_no_unit=Repozitář by měl povolit alespoň určitý druh interakce.
-settings.confirm_delete=Smazat repozitář
+settings.confirm_delete=Odstranit repozitář
settings.add_collaborator=Přidat spolupracovníka
settings.add_collaborator_success=Spolupracovník byl přidán.
settings.add_collaborator_inactive_user=Nelze přidat neaktivního uživatele jako spolupracovníka.
@@ -2172,10 +2196,10 @@ settings.search_team=Vyhledat tým…
settings.change_team_permission_tip=Oprávnění týmu je nastaveno na stránce nastavení týmu a nelze je změnit pro každý repozitář
settings.delete_team_tip=Tento tým má přístup ke všem repositářům a nemůže být odstraněn
settings.remove_team_success=Přístup týmu k repozitáři byl odstraněn.
-settings.add_webhook=Přidat webový háček
+settings.add_webhook=Přidat webhook
settings.add_webhook.invalid_channel_name=Kanál webového háčku nemůže být prázdný a nemůže obsahovat pouze znak #.
settings.hooks_desc=Webové háčky automaticky vytvářejí dotazy HTTP POST na server, když nastane určitá událost v Forgejo. Čtěte více v příručce webových háčků.
-settings.webhook_deletion=Odstranit webový háček
+settings.webhook_deletion=Odstranit webhook
settings.webhook_deletion_desc=Odstranění webového háčku smaže jeho nastavení a historii doručení. Pokračovat?
settings.webhook_deletion_success=Webový háček byl smazán.
settings.webhook.test_delivery=Test doručitelnosti
@@ -2189,23 +2213,23 @@ settings.webhook.body=Tělo zprávy
settings.webhook.replay.description=Zopakovat tento webový háček.
settings.webhook.replay.description_disabled=Chcete-li znovu spustit tento webový háček, aktivujte jej.
settings.webhook.delivery.success=Událost byla přidána do fronty doručení. Může to trvat několik sekund, než se zobrazí v historii doručení.
-settings.githooks_desc=Jelikož Git háčky jsou spravovány Gitem samotným, můžete upravit soubory háčků níže, k provádění libovolných operací.
+settings.githooks_desc=Git hooks jsou spravovány samotným Gitem. Níže můžete upravit soubory hooků pro nastavení vlastních operací.
settings.githook_edit_desc=Je-li háček neaktivní, bude zobrazen vzorový obsah. Nebude-li zadán žádný obsah, háček bude vypnut.
-settings.githook_name=Název háčku
-settings.githook_content=Obsah háčku
-settings.update_githook=Aktualizovat háček
-settings.add_webhook_desc=Forgejo odešle dotaz POST
s nastaveným Content Type na cílovou URL. Čtěte více v průvodci webovými háčky.
+settings.githook_name=Název hooku
+settings.githook_content=Obsah hooku
+settings.update_githook=Upravit hook
+settings.add_webhook_desc=Forgejo odešle na cílovou adresu URL dotaz POST
s nastaveným Content-Type. Více informací v průvodci webhooky.
settings.payload_url=Cílové URL
settings.http_method=HTTP metoda
-settings.content_type=POST Content Type
+settings.content_type=Typ obsahu POST
settings.secret=Tajný klíč
settings.slack_username=Uživatelské jméno
settings.slack_icon_url=URL ikony uživatele
settings.slack_color=Barva
settings.discord_username=Uživatelské jméno
settings.discord_icon_url=URL ikony
-settings.event_desc=Spuštěno na:
-settings.event_push_only=Události nahrání
+settings.event_desc=Spustit při:
+settings.event_push_only=Události nahrání (push)
settings.event_send_everything=Všechny události
settings.event_choose=Vlastní události…
settings.event_header_repository=Události repozitáře
@@ -2223,33 +2247,33 @@ settings.event_push=Nahrát
settings.event_push_desc=Nahrání pomocí Gitu do repozitáře.
settings.event_repository=Repozitář
settings.event_repository_desc=Repozitář vytvořen nebo smazán.
-settings.event_header_issue=Události úkolů
+settings.event_header_issue=Události problémů
settings.event_issues=Úkoly
settings.event_issues_desc=Úkol otevřen, uzavřen, znovu otevřen nebo upraven.
-settings.event_issue_assign=Úkol přiřazen
+settings.event_issue_assign=Problém přiřazen
settings.event_issue_assign_desc=Úkol přiřazen nebo nepřiřazen.
-settings.event_issue_label=Úkol oštítkován
+settings.event_issue_label=Problém označen
settings.event_issue_label_desc=Štítky úkolu aktualizovány nebo vymazány.
-settings.event_issue_milestone=Úkolu přidán milník
+settings.event_issue_milestone=K problému přidán milník
settings.event_issue_milestone_desc=Úkolu přidán nebo odebrán milník.
-settings.event_issue_comment=Komentář k úkolu
+settings.event_issue_comment=Komentář k problému
settings.event_issue_comment_desc=Komentář úkolu přidán, upraven nebo smazán.
-settings.event_header_pull_request=Události požadavku na natažení
-settings.event_pull_request=Požadavek na stažení
+settings.event_header_pull_request=Události žádosti o sloučení
+settings.event_pull_request=Žádost o sloučení
settings.event_pull_request_desc=Požadavek na natažení otevřen, uzavřen, znovu otevřen nebo upraven.
-settings.event_pull_request_assign=Požadavek na natažení přiřazen
+settings.event_pull_request_assign=Žádost o sloučení přiřazena
settings.event_pull_request_assign_desc=Požadavek na natažení přiřazen nebo nepřiřazen.
-settings.event_pull_request_label=Požadavek na natažení oštítkován
+settings.event_pull_request_label=Žádost o sloučení označena
settings.event_pull_request_label_desc=Štítky požadavku na natažení aktualizovány nebo vymazány.
-settings.event_pull_request_milestone=Požadavku na natažení přidán milník
+settings.event_pull_request_milestone=K žádosti o sloučení přidán milník
settings.event_pull_request_milestone_desc=Požadavku na natažení přidán nebo odebrán milník.
-settings.event_pull_request_comment=Požadavek na natažení okomentován
+settings.event_pull_request_comment=Žádost o sloučení okomentována
settings.event_pull_request_comment_desc=Komentář požadavku na natažení vytvořen, upraven nebo odstraněn.
-settings.event_pull_request_review=Požadavek na natažení přezkoumán
+settings.event_pull_request_review=Žádost o sloučení zkontrolována
settings.event_pull_request_review_desc=Požadavek na natažení schválen, odmítnut nebo zkontrolován.
-settings.event_pull_request_sync=Požadavek na natažení synchronizován
+settings.event_pull_request_sync=Žádost o sloučení synchronizována
settings.event_pull_request_sync_desc=Požadavek na natažení synchronizován.
-settings.event_pull_request_review_request=Vyžádán požadavek na natažení
+settings.event_pull_request_review_request=Vyžádána kontrola žádosti o sloučení
settings.event_package=Balíček
settings.event_package_desc=Balíček vytvořen nebo odstraněn v repozitáři.
settings.branch_filter=Filtr větví
@@ -2259,11 +2283,11 @@ settings.authorization_header_desc=Pokud vyplněno, bude připojeno k požadavk
settings.active=Aktivní
settings.active_helper=Informace o spuštěných událostech budou odeslány na URL webového háčku.
settings.add_hook_success=Webový háček byl přidán.
-settings.update_webhook=Aktualizovat webový háček
+settings.update_webhook=Upravit webhook
settings.update_hook_success=Webový háček byl aktualizován.
-settings.delete_webhook=Odstranit webový háček
-settings.recent_deliveries=Nedávné dodávky
-settings.hook_type=Typ háčku
+settings.delete_webhook=Odstranit webhook
+settings.recent_deliveries=Nedávná doručení
+settings.hook_type=Typ hooku
settings.slack_token=Token
settings.slack_domain=Doména
settings.slack_channel=Kanál
@@ -2300,28 +2324,28 @@ settings.deploy_key_deletion=Odstranit klíč pro nasazení
settings.deploy_key_deletion_desc=Odstranění klíče pro nasazení zruší jeho přístup k repozitáři. Pokračovat?
settings.deploy_key_deletion_success=Klíč pro nasazení byl odstraněn.
settings.branches=Větve
-settings.protected_branch=Ochrana větví
+settings.protected_branch=Ochrana větve
settings.protected_branch.save_rule=Uložit pravidlo
settings.protected_branch.delete_rule=Odstranit pravidlo
settings.protected_branch_can_push=Povolit nahrání?
settings.protected_branch_can_push_yes=Můžete nahrávat
settings.protected_branch_can_push_no=Nemůžete nahrávat
-settings.branch_protection=Pravidla ochrany větví pro větev „%s“
-settings.protect_this_branch=Povolit ochranu větví
+settings.branch_protection=Pravidla ochrany větve pro větev „%s“
+settings.protect_this_branch=Povolit ochranu větve
settings.protect_this_branch_desc=Zabraňuje smazání a omezuje gitu nahrávání a slučování do větve.
settings.protect_disable_push=Zakázat nahrávání
settings.protect_disable_push_desc=Žádné nahrávání do této větve nebude povoleno.
settings.protect_enable_push=Povolit nahrávání
settings.protect_enable_push_desc=Každý, kdo má přístup k zápisu, bude moci nahrávat do této větve (ale ne vynucená nahrávání).
settings.protect_enable_merge=Povolit sloučení
-settings.protect_whitelist_committers=Povolit nahrání jen vyjmenovaným
+settings.protect_whitelist_committers=Povolit omezené nahrání
settings.protect_whitelist_committers_desc=Pouze povolení uživatelé budou moci nahrávat do této větve (ale ne vynucení nahrávání).
settings.protect_whitelist_deploy_keys=Povolit nahrání klíčům pro nasazení s přístupem pro zápis.
settings.protect_whitelist_users=Povolení uživatelé pro nahrávání:
settings.protect_whitelist_search_users=Hledat uživatele…
settings.protect_whitelist_teams=Povolené týmy pro nahrávání:
settings.protect_whitelist_search_teams=Vyhledat týmy…
-settings.protect_merge_whitelist_committers=Povolit vyjmenovaným slučování
+settings.protect_merge_whitelist_committers=Povolit whitelist pro slučování
settings.protect_merge_whitelist_committers_desc=Povolit pouze vyjmenovaným uživatelům nebo týmům slučovat požadavky na natažení do této větve.
settings.protect_merge_whitelist_users=Povolení uživatelé pro slučování:
settings.protect_merge_whitelist_teams=Povolené týmy pro slučování:
@@ -2340,9 +2364,9 @@ settings.protect_approvals_whitelist_users=Povolení posuzovatelé:
settings.protect_approvals_whitelist_teams=Povolené týmy pro posuzování:
settings.dismiss_stale_approvals=Odmítnout nekvalitní schválení
settings.dismiss_stale_approvals_desc=Pokud budou do větve nahrány nové revize, které mění obsah tohoto požadavku na natažení, všechna stará schválení budou zamítnuta.
-settings.require_signed_commits=Vyžadovat podepsané revize
+settings.require_signed_commits=Vyžadovat podepsané commity
settings.require_signed_commits_desc=Odmítnout nahrání do této větve pokud nejsou podepsaná nebo jsou neověřitelná.
-settings.protect_branch_name_pattern=Vzor jména chráněných větví
+settings.protect_branch_name_pattern=Vzor jména chráněné větve
settings.protect_branch_name_pattern_desc=Vzory názvů chráněných větví. Pro vzorovou syntaxi viz dokumentace. Příklady: main, release/**
settings.protect_patterns=Vzory
settings.protect_protected_file_patterns=Vzory chráněných souborů (oddělené středníkem „;“):
@@ -2354,7 +2378,7 @@ settings.delete_protected_branch=Vypnout ochranu
settings.update_protect_branch_success=Ochrana větví pro větev „%s“ byla aktualizována.
settings.remove_protected_branch_success=Ochrana větví pro větev „%s“ byla zakázána.
settings.remove_protected_branch_failed=Odstranění ochranného pravidla větve „%s“ se nezdařilo.
-settings.protected_branch_deletion=Zakázat ochranu větví
+settings.protected_branch_deletion=Zakázat ochranu větve
settings.protected_branch_deletion_desc=Zakázání ochrany větví umožní uživatelům s právem zápisu nahrávat do této větve. Pokračovat?
settings.block_rejected_reviews=Blokovat sloučení při zamítavých posouzeních
settings.block_rejected_reviews_desc=Slučování nebude možné, pokud o změny požádají oficiální posuzovatelé, i když je k dispozici dostatek schválení.
@@ -2364,7 +2388,7 @@ settings.block_outdated_branch=Blokovat sloučení, pokud je požadavek na nata
settings.block_outdated_branch_desc=Slučování nebude možné, pokud je hlavní větev za základní větví.
settings.default_branch_desc=Vybrat výchozí větev repozitáře pro požadavky na natažení a revize kódu:
settings.merge_style_desc=Sloučit styly
-settings.default_merge_style_desc=Výchozí styl sloučení pro požadavky na natažení:
+settings.default_merge_style_desc=Výchozí styl sloučení
settings.choose_branch=Vyberte větev…
settings.no_protected_branch=Nejsou tu žádné chráněné větve.
settings.edit_protected_branch=Upravit
@@ -2378,10 +2402,10 @@ settings.tags.protection.allowed=Povoleno
settings.tags.protection.allowed.users=Povolení uživatelé
settings.tags.protection.allowed.teams=Povolené týmy
settings.tags.protection.allowed.noone=Nikdo
-settings.tags.protection.create=Chránit značku
+settings.tags.protection.create=Přidat pravidlo
settings.tags.protection.none=Neexistují žádné chráněné značky.
settings.tags.protection.pattern.description=Můžete použít jediné jméno nebo vzor glob nebo regulární výraz, který bude odpovídat více značek. Přečtěte si více v průvodci chráněnými značkami.
-settings.bot_token=Token pro robota
+settings.bot_token=Token bota
settings.chat_id=ID chatu
settings.thread_id=ID vlákna
settings.matrix.homeserver_url=URL adresa Homeserveru
@@ -2395,7 +2419,7 @@ settings.archive.error=Nastala chyba při archivování repozitáře. Prohlédn
settings.archive.error_ismirror=Nemůžete archivovat zrcadlený repozitář.
settings.archive.branchsettings_unavailable=Nastavení větví není dostupné, pokud je repozitář archivovaný.
settings.archive.tagsettings_unavailable=Nastavení značek není k dispozici, pokud je repozitář archivován.
-settings.unarchive.button=Obnovit repozitář
+settings.unarchive.button=Zrušit archivaci repozitáře
settings.unarchive.header=Obnovit tento repozitář
settings.unarchive.text=Obnovení repozitáře vrátí možnost přijímání commitů a nahrávání. Stejně tak se obnoví i možnost zadávání nových úkolů a požadavků na natažení.
settings.unarchive.success=Repozitář byl úspěšně obnoven.
@@ -2433,15 +2457,15 @@ settings.rename_branch_from=starý název větve
settings.rename_branch_to=nový název větve
settings.rename_branch=Přejmenovat větev
-diff.browse_source=Procházet zdrojové kódy
+diff.browse_source=Procházet zdroj
diff.parent=rodič
diff.commit=revize
diff.git-notes=Poznámky
diff.data_not_available=Rozdílový obsah není dostupný
-diff.options_button=Možnosti rozdílového porovnání
+diff.options_button=Možnosti porovnání
diff.show_diff_stats=Zobrazit statistiky
-diff.download_patch=Stáhněte soubor záplaty
-diff.download_diff=Stáhněte rozdílový soubor
+diff.download_patch=Stáhnout soubor patche
+diff.download_diff=Stáhnout rozdílový soubor
diff.show_split_view=Rozdělené zobrazení
diff.show_unified_view=Jednotný pohled
diff.whitespace_button=Bílý znak
@@ -2463,7 +2487,7 @@ diff.file_suppressed=Rozdílový obsah nebyl zobrazen, protože je příliš vel
diff.file_suppressed_line_too_long=Rozdílový obsah nebyl zobrazen, protože některé řádky jsou příliš dlouhá
diff.too_many_files=Některé soubory nejsou zobrazny, neboť je v této revizi změněno mnoho souborů
diff.show_more=Zobrazit více
-diff.load=Načíst rozdílové porovnání
+diff.load=Načíst porovnání
diff.generated=vygenerováno
diff.vendored=vendorováno
diff.comment.add_line_comment=Přidat jednořádkový komentář
@@ -2538,11 +2562,11 @@ release.add_tag=Vytvořit pouze značku
release.releases_for=Vydání pro %s
release.tags_for=Značky pro %s
-branch.name=Jméno větve
+branch.name=Název větve
branch.already_exists=Větev pojmenovaná „%s“ již existuje.
branch.delete_head=Smazat
-branch.delete=Smazat větev „%s“
-branch.delete_html=Smazat větev
+branch.delete=Odstranit větev „%s“
+branch.delete_html=Odstranit větev
branch.delete_desc=Smazání větve je trvalé. Přestože zrušená větev může existovat i po krátkou dobu, než bude skutečně odstraněna, NELZE ji většinou vrátit. Pokračovat?
branch.deletion_success=Větev „%s“ byla smazána.
branch.deletion_failed=Nepodařilo se odstranit větev „%s“.
@@ -2656,9 +2680,9 @@ settings.mirror_settings.docs.doc_link_pull_section = sekci „Pulling from a re
settings.units.overview = Přehled
settings.units.add_more = Přidat další...
settings.push_mirror_sync_in_progress = Probíhá odesílání změn na vzdálený %s.
-settings.wiki_globally_editable = Umožnit komukoli editovat Wiki
+settings.wiki_globally_editable = Umožnit komukoli editovat wiki
settings.confirmation_string = Potvrzovací řetězec
-settings.wiki_rename_branch_main_notices_2 = Touto akcí trvale přejmenujete interní větev Wiki repozitáře %s. Existující kontroly budou muset být aktualizovány.
+settings.wiki_rename_branch_main_notices_2 = Touto akcí trvale přejmenujete interní větev wiki repozitáře %s. Existující kontroly budou muset být aktualizovány.
settings.wiki_branch_rename_failure = Nepodařilo se normalizovat název větve Wiki repozitáře.
settings.add_collaborator_blocked_them = Nepodařilo se přidat spolupracovníka, jelikož má zablokovaného majitele repozitáře.
settings.ignore_stale_approvals = Ignorovat zastaralá schválení
@@ -2671,6 +2695,7 @@ settings.archive.mirrors_unavailable = Zrcadla nejsou dostupná, když je repozi
settings.protect_enable_merge_desc = Kdokoli s přístupem k zápisu bude moci slučovat žádosti o sloučení do této větve.
settings.archive.text = Archivováním repozitáře jej celý převedete do stavu pouze pro čtení. Bude skryt z nástěnky. Nikdo (ani vy!) nebude moci vytvářet nové commity ani otevírat problémy a žádosti o sloučení.
settings.event_pull_request_review_request_desc = Bylo požádáno o posouzení žádosti o sloučení nebo bylo toto požádání odstraněno.
+error.broken_git_hook = Zdá se, že u tohoto repozitáře jsou rozbité Git hooks. Pro jejich opravení se prosím řiďte pokyny v dokumentaci a poté odešlete několik commitů pro obnovení stavu.
[graphs]
component_loading_info = Tohle může chvíli trvat…
@@ -2718,7 +2743,7 @@ settings.permission=Oprávnění
settings.repoadminchangeteam=Správce úložišť může týmům přidávat a odebírat přístup
settings.visibility=Viditelnost
settings.visibility.public=Veřejná
-settings.visibility.limited=Omezeno (Viditelné pouze pro ověřené uživatele)
+settings.visibility.limited=Omezená (viditelné pouze pro ověřené uživatele)
settings.visibility.limited_shortname=Omezený
settings.visibility.private=Soukromá (viditelné jen členům organizace)
settings.visibility.private_shortname=Soukromý
@@ -2728,11 +2753,11 @@ settings.update_setting_success=Nastavení organizace bylo upraveno.
settings.change_orgname_prompt=Poznámka: Změna názvu organizace také změní adresu URL vaší organizace a uvolní staré jméno této organizace.
settings.change_orgname_redirect_prompt=Staré jméno bude přesměrovávat, dokud nebude znovu obsazeno.
settings.update_avatar_success=Avatar organizace byl aktualizován.
-settings.delete=Smazat organizaci
-settings.delete_account=Smazat tuto organizaci
+settings.delete=Odstranit organizaci
+settings.delete_account=Odstranit tuto organizaci
settings.delete_prompt=Organizace bude trvale odstraněna. Tato změna NEMŮŽE být vrácena!
-settings.confirm_delete_account=Potvrdit smazání
-settings.delete_org_title=Smazat organizaci
+settings.confirm_delete_account=Potvrdit odstranění
+settings.delete_org_title=Odstranit organizaci
settings.delete_org_desc=Tato organizace bude trvale smazána. Pokračovat?
settings.hooks_desc=Přidat webové háčky, které budou spouštěny pro všechny repozitáře v této organizaci.
@@ -2773,11 +2798,11 @@ teams.settings=Nastavení
teams.owners_permission_desc=Vlastníci mají plný přístup do všech repozitářů a mají správcovský přístup do této organizace.
teams.members=Členové týmu
teams.update_settings=Upravit nastavení
-teams.delete_team=Smazat tým
+teams.delete_team=Odstranit tým
teams.add_team_member=Přidat člena týmu
teams.invite_team_member=Pozvat do %s
teams.invite_team_member.list=Čekající pozvánky
-teams.delete_team_title=Smazat tým
+teams.delete_team_title=Odstranit tým
teams.delete_team_desc=Smazání týmu zruší přístup jeho členům. Pokračovat?
teams.delete_team_success=Tým byl odstraněn.
teams.read_permission_desc=Členství v tom týmu poskytuje právo čtení: členové mohou číst z a vytvářet klony repozitářů týmu.
@@ -2827,7 +2852,7 @@ settings=Nastavení správce
dashboard.new_version_hint=Gitea %s je nyní k dispozici, právě u vás běži %s. Podívej se na blogu pro více informací.
dashboard.statistic=Souhrn
dashboard.operations=Operace údržby
-dashboard.system_status=Status systému
+dashboard.system_status=Stav systému
dashboard.operation_name=Název operace
dashboard.operation_switch=Přepnout
dashboard.operation_run=Spustit
@@ -2852,7 +2877,7 @@ dashboard.delete_missing_repos=Smazat všechny repozitáře, které nemají Git
dashboard.delete_missing_repos.started=Spuštěna úloha mazání všech repozitářů, které nemají Git soubory.
dashboard.delete_generated_repository_avatars=Odstranit vygenerované avatary repozitářů
dashboard.sync_repo_tags=Synchronizovat značky z git dat do databáze
-dashboard.update_mirrors=Aktualizovat zrcadla
+dashboard.update_mirrors=Upravit zrcadla
dashboard.repo_health_check=Kontrola stavu všech repozitářů
dashboard.check_repo_stats=Zkontrolovat všechny statistiky repositáře
dashboard.archive_cleanup=Smazat staré archivy repozitářů
@@ -2867,30 +2892,30 @@ dashboard.sync_external_users=Synchronizovat externí uživatelská data
dashboard.cleanup_hook_task_table=Vyčistit tabulku hook_task
dashboard.cleanup_packages=Vyčistit prošlé balíčky
dashboard.server_uptime=Doba provozu serveru
-dashboard.current_goroutine=Aktuální Goroutines
+dashboard.current_goroutine=Aktuální goroutines
dashboard.current_memory_usage=Aktuální využití paměti
-dashboard.total_memory_allocated=Přidělené paměti celkem
-dashboard.memory_obtained=Celkem získané paměti
+dashboard.total_memory_allocated=Celková přidělená paměť
+dashboard.memory_obtained=Získaná paměť
dashboard.pointer_lookup_times=Časy vyhledávání ukazatelů
dashboard.memory_allocate_times=Alokace paměti
dashboard.memory_free_times=Uvolnění paměti
dashboard.current_heap_usage=Aktuální využití paměti zásobníku
dashboard.heap_memory_obtained=Získaná paměť zásobníku
dashboard.heap_memory_idle=Nečinná paměť zásobníku
-dashboard.heap_memory_in_use=Používána paměť zásobníku
+dashboard.heap_memory_in_use=Používaná paměť zásobníku
dashboard.heap_memory_released=Uvolněná paměť zásobníku
dashboard.heap_objects=Objekty zásobníku
dashboard.bootstrap_stack_usage=Využití zásobníku prvotního zavedení
-dashboard.stack_memory_obtained=Celkem získané paměti zásobníku
+dashboard.stack_memory_obtained=Celková získaná pamět zásobníku
dashboard.mspan_structures_usage=Užití struktur MSpan
dashboard.mspan_structures_obtained=Získané struktury MSpan
-dashboard.mcache_structures_usage=Užití struktur MCache
+dashboard.mcache_structures_usage=Využití struktur MCache
dashboard.mcache_structures_obtained=Získané struktury MCache
-dashboard.profiling_bucket_hash_table_obtained=Získaná analytická tabulka
-dashboard.gc_metadata_obtained=Získané metadata GC
+dashboard.profiling_bucket_hash_table_obtained=Získaná profilovací bucket hash tabulka
+dashboard.gc_metadata_obtained=Získaná metadata GC
dashboard.other_system_allocation_obtained=Získaná alokace ostatních systémových prostředků
dashboard.next_gc_recycle=Příští recyklace GC
-dashboard.last_gc_time=Doba od poslední recyklace GC
+dashboard.last_gc_time=Doba od posledního GC
dashboard.total_gc_time=Celková pauza GC
dashboard.total_gc_pause=Celková pauza GC
dashboard.last_gc_pause=Poslední pauza GC
@@ -2928,7 +2953,7 @@ users.new_success=Uživatelský účet „%s“ byl vytvořen.
users.edit=Upravit
users.auth_source=Zdroj ověřování
users.local=Místní
-users.auth_login_name=Přihlašovací jméno způsobu ověřování
+users.auth_login_name=Název ověření přihlášení
users.password_helper=Ponechte heslo prázdné, aby se nezměnilo.
users.update_profile_success=Uživatelský účet byl aktualizován.
users.edit_account=Upravit uživatelský účet
@@ -2938,12 +2963,12 @@ users.is_activated=Uživatelský účet je aktivován
users.prohibit_login=Zakázat přihlášení
users.is_admin=Je správce
users.is_restricted=Je omezený
-users.allow_git_hook=Může vytvářet háčky Gitu
-users.allow_git_hook_tooltip=Háčky Gitu se spustí pod uživatelem operačního systému, jako běží Forgejo a budou mít stejnou úroveň přístupu k hostiteli. Díky tomu mohou uživatelé s tímto zvláštním oprávněním k háčkům Gitu přistupovat a upravovat všechny Forgejo repozitáře a také databázi používanou Giteou. V důsledku toho mohou také získat oprávnění administrátora Gitey.
+users.allow_git_hook=Může vytvářet Git hooks
+users.allow_git_hook_tooltip=Git hooks jsou spouštěny jako uživatel operačního systému, pod kterým je spuštěno Forgejo, a mají stejnou úroveň přístupu k hostiteli. Výsledkem je, že uživatelé s tímto speciálním oprávněním Git hooks mohou přistupovat ke všem repozitářům Forgejo a upravovat je, stejně jako databázi používanou systémem Forgejo. V důsledku toho mohou také získat oprávnění správce systému Forgejo.
users.allow_import_local=Může importovat lokální repozitáře
users.allow_create_organization=Může vytvářet organizace
-users.update_profile=Aktualizovat uživatelský účet
-users.delete_account=Smazat uživatelský účet
+users.update_profile=Upravit uživatelský účet
+users.delete_account=Odstranit uživatelský účet
users.cannot_delete_self=Nemůžete odstranit sami sebe
users.still_own_repo=Tento uživatel stále vlastní jeden nebo více repozitářů. Tyto repozitáře nejprve smažte nebo je převeďte.
users.still_has_org=Uživatel je člen organizace. Nejprve odstraňte uživatele ze všech organizací.
@@ -2966,7 +2991,7 @@ users.list_status_filter.is_2fa_enabled=2FA povoleno
users.list_status_filter.not_2fa_enabled=2FA zakázáno
users.details=Detaily uživatele
-emails.email_manage_panel=Správa e-mailů uživatele
+emails.email_manage_panel=Správa uživatelských e-mailů
emails.primary=Hlavní
emails.activated=Aktivován
emails.filter_sort.email=E-mail
@@ -2985,7 +3010,7 @@ orgs.teams=Týmy
orgs.members=Členové
orgs.new_orga=Nová organizace
-repos.repo_manage_panel=Správa repozitáře
+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.owner=Vlastník
@@ -3011,15 +3036,15 @@ packages.repository=Repozitář
packages.size=Velikost
packages.published=Publikováno
-defaulthooks=Výchozí webové háčky
+defaulthooks=Výchozí webhooky
defaulthooks.add_webhook=Přidat výchozí webový háček
defaulthooks.update_webhook=Aktualizovat výchozí webový háček
-systemhooks=Systémové webové háčky
+systemhooks=Systémové webhooky
systemhooks.add_webhook=Přidat systémový webový háček
systemhooks.update_webhook=Aktualizovat systémový webový háček
-auths.auth_manage_panel=Správa zdroje ověřování
+auths.auth_manage_panel=Správa zdrojů ověřování
auths.new=Přidat zdroj ověřování
auths.name=Název
auths.type=Typ
@@ -3041,11 +3066,11 @@ auths.attribute_username_placeholder=Nechte prázdně a použije se uživatelsk
auths.attribute_name=Atribut křestního jména
auths.attribute_surname=Atribut příjmení
auths.attribute_mail=Atribut e-mailové adresy
-auths.attribute_ssh_public_key=Atribut veřejného SSH klíče
-auths.attribute_avatar=Atributy avataru
-auths.attributes_in_bind=Získat atributy v kontextu Bind DN
+auths.attribute_ssh_public_key=Atribut veřejného klíče SSH
+auths.attribute_avatar=Atribut avataru
+auths.attributes_in_bind=Načíst atributy v kontextu bind DN
auths.allow_deactivate_all=Povolit prázdný výsledek hledání pro deaktivaci všech uživatelů
-auths.use_paged_search=Použijte vyhledávání ve stránce
+auths.use_paged_search=Použít stránkované vyhledávání
auths.search_page_size=Velikost stránky
auths.filter=Uživatelský filtr
auths.admin_filter=Správcovský filtr
@@ -3060,18 +3085,18 @@ auths.map_group_to_team_removal=Odebrat uživatele z synchronizovaných týmů,
auths.enable_ldap_groups=Povolit LDAP skupiny
auths.ms_ad_sa=Atributy vyhledávání MS AD
auths.smtp_auth=Typ ověření SMTP
-auths.smtphost=Server SMTP
+auths.smtphost=Hostitel SMTP
auths.smtpport=Port SMTP
auths.allowed_domains=Povolené domény
auths.allowed_domains_helper=Nechte prázdné k povolení všech domén. Více domén oddělte čárkou („,“).
auths.skip_tls_verify=Přeskočit ověření TLS
auths.force_smtps=Vynutit SMTPS
auths.force_smtps_helper=SMTPS se vždy používá na portu 465. Nastavením této hodnoty vynutíte použití SMTPS na jiných portech. (V opačném případě se na ostatních portech použije STARTTLS, pokud je podporován hostiteslkým serverem.)
-auths.helo_hostname=HELO Hostname
+auths.helo_hostname=Hostname HELO
auths.helo_hostname_helper=Název hostitele odeslaný s HELO. Chcete-li odeslat aktuální název hostitele, ponechte prázdné.
auths.disable_helo=Zakázat HELO
auths.pam_service_name=Název služby PAM
-auths.pam_email_domain=PAM e-mailová doména (volitelné)
+auths.pam_email_domain=E-mailová doména PAM (volitelné)
auths.oauth2_provider=Poskytovatel OAuth2
auths.oauth2_icon_url=URL ikony
auths.oauth2_clientID=Klientské ID (klíč)
@@ -3086,15 +3111,15 @@ auths.skip_local_two_fa=Přeskočit lokální 2FA
auths.skip_local_two_fa_helper=Ponechání nenastavené hodnoty znamená, že místní uživatelé s nastavenou funkcí 2FA budou muset při přihlašování stále projít funkcí 2FA
auths.oauth2_tenant=Nájemník
auths.oauth2_scopes=Další rozsahy
-auths.oauth2_required_claim_name=Požadovaný název tvrzení
+auths.oauth2_required_claim_name=Požadovaný název claimu
auths.oauth2_required_claim_name_helper=Nastavte toto jméno pro omezení přihlášení z tohoto zdroje pro uživatele s tvrzením s tímto jménem
-auths.oauth2_required_claim_value=Požadovaná hodnota tvrzení
+auths.oauth2_required_claim_value=Požadovaná hodnota claimu
auths.oauth2_required_claim_value_helper=Nastavte tuto hodnotu pro omezení přihlášení z tohoto zdroje pro uživatele s tvrzením s tímto jménem a hodnotou
auths.oauth2_group_claim_name=Název tvrzení poskytující názvy skupin pro tento zdroj. (nepovinné)
-auths.oauth2_admin_group=Hodnota tvrzení pro skupinu uživatelů administrátorů. (Volitelné - vyžaduje název tvrzení výše)
-auths.oauth2_restricted_group=Hodnota tvrzení pro skupinu omezených uživatelů. (Volitelné - vyžaduje název tvrzení výše)
+auths.oauth2_admin_group=Hodnota claimu pro skupinu uživatelů administrátorů. (Volitelné - vyžaduje název claimu výše)
+auths.oauth2_restricted_group=Hodnota claimu pro skupinu omezených uživatelů. (Volitelné - vyžaduje název claimu výše)
auths.oauth2_map_group_to_team_removal=Odebrat uživatele z synchronizovaných týmů, pokud uživatel nepatří do odpovídající skupiny.
-auths.enable_auto_register=Povolit zaregistrování se
+auths.enable_auto_register=Povolit automatické registrace
auths.sspi_auto_create_users=Automaticky vytvářet uživatele
auths.sspi_auto_create_users_helper=Povolit SSPI autentizační metodě automaticky vytvářet nové účty pro uživatele, kteří se poprvé přihlásili
auths.sspi_auto_activate_users=Automaticky aktivovat uživatele
@@ -3126,9 +3151,9 @@ auths.edit=Upravit zdroj ověřování
auths.activated=Tento zdroj ověřování je aktivován
auths.new_success=Zdroj ověřování „%s“ byl přidán.
auths.update_success=Zdroj ověřování byl aktualizován.
-auths.update=Aktualizovat zdroj ověřování
-auths.delete=Smazat zdroj ověřování
-auths.delete_auth_title=Smazat zdroj ověřování
+auths.update=Upravit zdroj ověřování
+auths.delete=Odstranit zdroj ověřování
+auths.delete_auth_title=Odstranit zdroj ověřování
auths.delete_auth_desc=Zamezíte přihlášení uživatelům pomocí tohoto zdroje ověřování, pokud ho smažete. Pokračovat?
auths.still_in_used=Zdroj ověřování je stále používán. Nejprve převeďte nebo smažte všechny uživatele, kteří používají tento způsob ověřování.
auths.deletion_success=Zdroj ověřování byl smazán.
@@ -3138,23 +3163,23 @@ auths.unable_to_initialize_openid=Nelze inicializovat poskytovatele OpenID Conne
auths.invalid_openIdConnectAutoDiscoveryURL=Neplatná URL adresa pro automatické vyhledání (musí být platná adresa URL začínající http:// nebo https://)
config.server_config=Nastavení serveru
-config.app_name=Název stránky
+config.app_name=Název instance
config.app_ver=Verze Forgejo
-config.app_url=Základní URL Forgejo
+config.app_url=Základní URL
config.custom_conf=Cesta ke konfiguračnímu souboru
config.custom_file_root_path=Vlastní kořenový adresář souborů
config.domain=Doména serveru
config.offline_mode=Lokální režim
-config.disable_router_log=Vypnout log směrovače
+config.disable_router_log=Vypnout protokol směrovače
config.run_user=Spustit jako uživatel
config.run_mode=Režim spouštění
config.git_version=Verze Gitu
config.app_data_path=Cesta k datům aplikace
config.repo_root_path=Kořenový adresář repozitářů
config.lfs_root_path=Kořenový adresář LFS
-config.log_file_root_path=Adresář logů
+config.log_file_root_path=Adresář protokolů
config.script_type=Typ skriptu
-config.reverse_auth_user=Uživatel obráceného ověření
+config.reverse_auth_user=Obrátit uživatele ověření
config.ssh_config=Nastavení SSH
config.ssh_enabled=Zapnutý
@@ -3171,7 +3196,7 @@ config.ssh_minimum_key_sizes=Minimální velikost klíčů
config.lfs_config=Nastavení LFS
config.lfs_enabled=Povoleno
config.lfs_content_path=Cesta k obsahu LFS
-config.lfs_http_auth_expiry=Vypršení autorizace LFS HTTPS
+config.lfs_http_auth_expiry=Čas vypršení autorizace LFS HTTP
config.db_config=Nastavení databáze
config.db_type=Typ
@@ -3187,55 +3212,55 @@ config.register_email_confirm=Pro registraci vyžadovat potvrzení e-mailu
config.disable_register=Vypnout možnost uživatelské registrace
config.allow_only_internal_registration=Povolit registraci pouze prostřednictvím Forgejo
config.allow_only_external_registration=Povolit registraci pouze prostřednictvím externích služeb
-config.enable_openid_signup=Povolit automatickou registraci pomocí OpenID
+config.enable_openid_signup=Povolit uživatelskou registraci pomocí OpenID
config.enable_openid_signin=Povolit přihlášení pomocí OpenID
-config.show_registration_button=Ukázat tlačítko registrace
-config.require_sign_in_view=Vyžadovat přihlášení k zobrazení stránek
+config.show_registration_button=Zobrazit tlačítko registrace
+config.require_sign_in_view=Vyžadovat přihlášení pro zobrazení obsahu
config.mail_notify=Povolit e-mailová oznámení
config.enable_captcha=Povolit CAPTCHA
-config.active_code_lives=Doba života aktivního kódu
-config.reset_password_code_lives=Čas vypršení platnosti kódu pro obnovení účtu
-config.default_keep_email_private=Jako počáteční nastavení skrýt e-mailové adresy
-config.default_allow_create_organization=Dovolí novým uživatelům zakládat organizace
+config.active_code_lives=Doba expirace aktivačního kódu
+config.reset_password_code_lives=Čas vypršení platnosti obnovovacího kódu
+config.default_keep_email_private=Ve výchozím nastavení skrýt e-mailové adresy
+config.default_allow_create_organization=Povolit ve výchozím nastavení vytvářet organizace
config.enable_timetracking=Povolit sledování času
-config.default_enable_timetracking=Povolit sledování času ve výchozím nastavení
+config.default_enable_timetracking=Povolit ve výchozím nastavení sledování času
config.default_allow_only_contributors_to_track_time=Povolit sledování času pouze přispěvatelům
config.no_reply_address=Skrytá e-mailová doména
-config.default_visibility_organization=Výchozí viditelnost pro nové organizace
-config.default_enable_dependencies=Povolit závislosti úkolů ve výchozím stavu
+config.default_visibility_organization=Výchozí viditelnost nových organizací
+config.default_enable_dependencies=Povolit ve výchozím nastavení závislosti úkolů
-config.webhook_config=Nastavení webových háčků
+config.webhook_config=Nastavení webhooků
config.queue_length=Délka fronty
config.deliver_timeout=Časový limit doručení
-config.skip_tls_verify=Přeskočit verifikaci TLS
+config.skip_tls_verify=Přeskočit ověření TLS
config.mailer_config=Nastavení odesílání e-mailů
config.mailer_enabled=Zapnutý
config.mailer_enable_helo=Povolit HELO
config.mailer_name=Název
config.mailer_protocol=Protokol
-config.mailer_smtp_addr=Adresa SMTP
+config.mailer_smtp_addr=Hostitel SMTP
config.mailer_smtp_port=Port SMTP
config.mailer_user=Uživatel
config.mailer_use_sendmail=Použít Sendmail
config.mailer_sendmail_path=Cesta k Sendmail
config.mailer_sendmail_args=Dodatečné argumenty pro Sendmail
-config.mailer_sendmail_timeout=Časový limit Sandmail
+config.mailer_sendmail_timeout=Časový limit Sendmail
config.mailer_use_dummy=Fiktivní
config.test_email_placeholder=E-mail (např.: test@example.com)
config.send_test_mail=Odeslat zkušební e-mail
config.send_test_mail_submit=Odeslat
-config.test_mail_failed=Odeslání testovacího e-mailu na „%s“ selhalo: %v
-config.test_mail_sent=Zkušební e-mail byl odeslán na „%s“.
+config.test_mail_failed=Nepodařilo se odeslat zkušební e-mail na adresu „%s“: %v
+config.test_mail_sent=Zkušební e-mail byl odeslán na adresu „%s“.
-config.oauth_config=Nastavení ověření OAuth
+config.oauth_config=Nastavení OAuth
config.oauth_enabled=Zapnutý
config.cache_config=Nastavení mezipaměti
config.cache_adapter=Adaptér mezipaměti
config.cache_interval=Interval mezipaměti
config.cache_conn=Připojení mezipaměti
-config.cache_item_ttl=Čas vypršení položky v mezipaměti
+config.cache_item_ttl=TTL položky v mezipaměti
config.session_config=Nastavení relace
config.session_provider=Poskytovatel relace
@@ -3243,37 +3268,37 @@ config.provider_config=Nastavení poskytovatele
config.cookie_name=Název souboru cookie
config.gc_interval_time=Čas intervalu GC
config.session_life_time=Doba trvání relace
-config.https_only=Pouze protokol HTTPS
+config.https_only=Pouze HTTPS
config.cookie_life_time=Doba života souboru cookie
-config.picture_config=Nastavení obrázku a avataru
-config.picture_service=Služba ikon uživatelů
+config.picture_config=Nastavení obrázků a avatarů
+config.picture_service=Služba obrázků
config.disable_gravatar=Zakázat službu Gravatar
-config.enable_federated_avatar=Povolit avatary z veřejných zdrojů
+config.enable_federated_avatar=Povolit federované avatary
config.git_config=Konfigurace Gitu
-config.git_disable_diff_highlight=Zakázat zvýraznění syntaxe v rozdílovém zobrazení
-config.git_max_diff_lines=Maximální počet rozdílových řádků jednoho souboru
-config.git_max_diff_line_characters=Maximální počet zobrazených rozdílových znaků
-config.git_max_diff_files=Maximální počet zobrazených rozdílových souborů
-config.git_gc_args=Parametry GC
+config.git_disable_diff_highlight=Zakázat zvýraznění syntaxe v zobrazení rozdílů
+config.git_max_diff_lines=Maximální počet rozdílových řádků na soubor
+config.git_max_diff_line_characters=Maximální počet zobrazených rozdílných znaků
+config.git_max_diff_files=Maximální počet zobrazených rozdílných souborů
+config.git_gc_args=Argumenty GC
config.git_migrate_timeout=Časový limit migrace
config.git_mirror_timeout=Časový limit aktualizace zrcadla
-config.git_clone_timeout=Časový limit operace naklonování
-config.git_pull_timeout=Časový limit operace stažení
+config.git_clone_timeout=Časový limit operace klonování
+config.git_pull_timeout=Časový limit operace Pull
config.git_gc_timeout=Časový limit operace GC
-config.log_config=Nastavení logů
+config.log_config=Nastavení protokolů
config.disabled_logger=Zakázané
-config.access_log_mode=Režim logování přístupu
-config.access_log_template=Šablona záznamu přístupu
+config.access_log_mode=Režim protokolování přístupu
+config.access_log_template=Šablona protokolu přístupu
config.xorm_log_sql=Logovat SQL
config.set_setting_failed=Nastavení %s se nezdařilo
monitor.stats=Statistiky
-monitor.cron=Naplánované úlohy
+monitor.cron=Úlohy Cron
monitor.name=Název
monitor.schedule=Rozvrh
monitor.next=Příští čas spuštění
@@ -3300,31 +3325,31 @@ monitor.queue.numberworkers=Počet workerů
monitor.queue.maxnumberworkers=Maximální počet workerů
monitor.queue.numberinqueue=Číslo ve frontě
monitor.queue.review_add=Posoudit / přidat workery
-monitor.queue.settings.title=Nastavení fondu
+monitor.queue.settings.title=Nastavení poolu
monitor.queue.settings.maxnumberworkers=Maximální počet workerů
monitor.queue.settings.maxnumberworkers.placeholder=V současné době %[1]d
monitor.queue.settings.maxnumberworkers.error=Maximální počet workerů musí být číslo
-monitor.queue.settings.submit=Aktualizovat nastavení
-monitor.queue.settings.changed=Nastavení aktualizováno
+monitor.queue.settings.submit=Upravit nastavení
+monitor.queue.settings.changed=Nastavení upravena
monitor.queue.settings.remove_all_items=Odstranit vše
monitor.queue.settings.remove_all_items_done=Všechny položky ve frontě byly odstraněny.
notices.system_notice_list=Systémová oznámení
-notices.view_detail_header=Zobrazit detaily oznámení
+notices.view_detail_header=Podrobnosti oznámení
notices.operations=Operace
notices.select_all=Vybrat vše
notices.deselect_all=Zrušit výběr všech
-notices.inverse_selection=Inverzní výběr
-notices.delete_selected=Smazat vybrané
-notices.delete_all=Smazat všechna oznámení
+notices.inverse_selection=Invertovat výběr
+notices.delete_selected=Odstranit vybrané
+notices.delete_all=Odstranit všechna oznámení
notices.type=Typ
notices.type_1=Repozitář
notices.type_2=Úloha
notices.desc=Popis
notices.op=Akce
notices.delete_success=Systémové upozornění bylo smazáno.
-dashboard.sync_repo_branches = Synchronizovat zmeškané větve z dat gitu do databáze
-dashboard.sync_repo_tags = Synchronizovat značky z dat gitu do databáze
+dashboard.sync_repo_branches = Synchronizovat vynechané větve z dat Gitu do databáze
+dashboard.sync_repo_tags = Synchronizovat značky z dat Gitu do databáze
dashboard.gc_lfs = Sbírat garbage z LFS meta objektů
monitor.queue.activeworkers = Aktivní workery
defaulthooks.desc = Webhooky automaticky vytvářejí žádosti HTTP POST na server, kde se spustí určité události Forgejo. Webhooky zde definované jsou výchozí a budou zkopírovány do všech nových repozitářů. Více informací zjistíte v návodu webhooků.
@@ -3343,7 +3368,7 @@ dashboard.sync_tag.started = Synchronizace značek spuštěna
dashboard.rebuild_issue_indexer = Přestavit indexer vydání
self_check.database_collation_case_insensitive = Databáze používá collation %s. Jedná se o intenzivní collation. Ačkoli s ní Forgejo nejspíše bude pracovat, mohou nastat určité vzácné případy, kdy nebude pracovat tak, jak má.
self_check.database_fix_mssql = Uživatelé MSSQL mohou tento problém vyřešit pouze ručními SQL příkazy „ALTER ... COLLATE ...“.
-auths.oauth2_map_group_to_team = Zmapovat zabrané skupiny u týmů organizací (volitelné - vyžaduje název zabrání výše)
+auths.oauth2_map_group_to_team = Zmapovat zabrané skupiny u týmů organizací (volitelné - vyžaduje název claimu výše)
monitor.queue.settings.desc = Pooly dynamicky rostou podle blokování fronty jejich workerů.
self_check.no_problem_found=Zatím nebyl nalezen žádný problém.
@@ -3352,6 +3377,7 @@ self_check.database_collation_case_insensitive=Databáze používá collation %s
self_check.database_inconsistent_collation_columns=Databáze používá collation %s, ale tyto sloupce používají chybné collation. To může způsobit neočekávané problémy.
self_check.database_fix_mysql=Pro uživatele MySQL/MariaDB můžete použít příkaz "gitea doctor convert", který opraví problémy s collation, nebo můžete také problém vyřešit příkazem "ALTER ... COLLATE ..." SQL ručně.
self_check.database_fix_mssql=Uživatelé MSSQL mohou problém vyřešit pouze pomocí příkazu "ALTER ... COLLATE ..." SQL ručně.
+auths.tips.gmail_settings = Nastavení služby Gmail:
[action]
create_repo=vytvořil/a repozitář %s
@@ -3463,9 +3489,9 @@ dependencies=Závislosti
keywords=Klíčová slova
details=Podrobnosti
details.author=Autor
-details.project_site=Stránka projektu
-details.repository_site=Stránka repositáře
-details.documentation_site=Stránka dokumentace
+details.project_site=Web projektu
+details.repository_site=Web repositáře
+details.documentation_site=Web dokumentace
details.license=Licence
assets=Prostředky
versions=Verze
@@ -3566,7 +3592,7 @@ owner.settings.cargo.initialize=Inicializovat index
owner.settings.cargo.initialize.description=Pro použití Cargo registru je zapotřebí speciální index Git. Použití této možnosti (znovu)vytvoří repozitář a automaticky jej nastaví.
owner.settings.cargo.initialize.error=Nepodařilo se inicializovat Cargo index: %v
owner.settings.cargo.initialize.success=Index Cargo byl úspěšně vytvořen.
-owner.settings.cargo.rebuild=Znovu vytvořit Index
+owner.settings.cargo.rebuild=Znovu vytvořit index
owner.settings.cargo.rebuild.error=Obnovení Cargo indexu se nezdařilo: %v
owner.settings.cargo.rebuild.success=Cargo Index byl úspěšně obnoven.
owner.settings.cleanuprules.title=Správa pravidel čištění
@@ -3594,6 +3620,7 @@ owner.settings.chef.keypair=Generovat pár klíčů
owner.settings.chef.keypair.description=Pro autentizaci do registru Chef je zapotřebí pár klíčů. Pokud jste předtím vytvořili pár klíčů, nově vygenerovaný pár klíčů vyřadí starý pár klíčů.
rpm.repository.multiple_groups = Tento balíček je dostupný v několika skupinách.
owner.settings.cargo.rebuild.description = Opětovné sestavení může být užitečné, pokud není index synchronizován s uloženými balíčky Cargo.
+owner.settings.cargo.rebuild.no_index = Opětovné vytvoření selhalo, nebyl inicializován žádný index.
[secrets]
secrets=Tajné klíče
@@ -3632,7 +3659,7 @@ runners.name=Název
runners.owner_type=Typ
runners.description=Popis
runners.labels=Štítky
-runners.last_online=Poslední čas online
+runners.last_online=Naposledy online
runners.runner_title=Runner
runners.task_list=Nedávné úlohy na tomto runneru
runners.task_list.no_tasks=Zatím zde nejsou žádné úlohy.
@@ -3658,7 +3685,7 @@ runners.version=Verze
runners.reset_registration_token=Resetovat registrační token
runners.reset_registration_token_success=Registrační token runneru byl úspěšně obnoven
-runs.all_workflows=Všechny pracovní postupy
+runs.all_workflows=Všechny workflowy
runs.commit=Commit
runs.scheduled=Naplánováno
runs.invalid_workflow_helper=Konfigurační soubor pracovního postupu je neplatný. Zkontrolujte prosím konfigurační soubor: %s
@@ -3674,9 +3701,9 @@ runs.no_workflows.documentation=Další informace o Gitea Actions naleznete v Codeberg nach Issues oder erstelle gegebenenfalls ein neues Issue.
-missing_csrf=Fehlerhafte Anfrage: Kein CSRF Token verfügbar
-invalid_csrf=Fehlerhafte Anfrage: Ungültiger CSRF Token
+missing_csrf=Fehlerhafte Anfrage: Kein CSRF-Token verfügbar
+invalid_csrf=Fehlerhafte Anfrage: Ungültiger CSRF-Token
not_found=Das Ziel konnte nicht gefunden werden.
network_error=Netzwerkfehler
server_internal = Interner Serverfehler
@@ -226,7 +241,7 @@ err_admin_name_pattern_not_allowed=Administrator-Benutzername ist ungültig, der
err_admin_name_is_invalid=Administratornutzername ist ungültig
general_title=Allgemeine Einstellungen
-app_name=Seitentitel
+app_name=Instanztitel
app_name_helper=Du kannst hier den Namen deines Unternehmens eingeben.
repo_path=Repository-Verzeichnis
repo_path_helper=Remote-Git-Repositorys werden in diesem Verzeichnis gespeichert.
@@ -238,9 +253,9 @@ domain=Server-Domain
domain_helper=Domain oder Host-Adresse für den Server.
ssh_port=SSH-Server-Port
ssh_port_helper=Der Port deines SSH-Servers. Leer lassen, um SSH zu deaktivieren.
-http_port=Forgejo-HTTP-Listen-Port
+http_port=HTTP-Listen-Port
http_port_helper=Port, unter dem der Forgejo-Webserver laufen soll.
-app_url=Forgejo-Basis-URL
+app_url=Basis-URL
app_url_helper=Adresse für HTTP(S)-Klon-URLs und E-Mail-Benachrichtigungen.
log_root_path=Logdateipfad
log_root_path_helper=Log-Dateien werden in diesem Verzeichnis gespeichert.
@@ -257,7 +272,7 @@ register_confirm=E-Mail-Bestätigung benötigt zum Registrieren
mail_notify=E-Mail-Benachrichtigungen aktivieren
server_service_title=Sonstige Server- und Drittserviceeinstellungen
offline_mode=Offline-Modus aktivieren
-offline_mode_popup=Drittanbieter-CDNs deaktivieren und alle Ressourcen lokal zur Verfügung stellen.
+offline_mode_popup=Drittanbieter-CDNs deaktivieren und alle Ressourcen lokal zustellen.
disable_gravatar=Gravatar deaktivieren
disable_gravatar_popup=Gravatar und Drittanbieter-Avatar-Quellen deaktivieren. Ein Standardavatar wird verwendet, bis der Nutzer einen eigenen Avatar hochlädt.
federated_avatar_lookup=Föderierte Profilbilder einschalten
@@ -310,6 +325,7 @@ env_config_keys_prompt=Die folgenden Umgebungsvariablen werden auch auf Ihre Kon
allow_dots_in_usernames = Erlaubt Benutzern die Verwendung von Punkten in ihren Benutzernamen. Hat keine Auswirkungen auf bestehende Konten.
enable_update_checker_helper_forgejo = Prüft regelmäßig auf neue Forgejo-Versionen, indem ein DNS-TXT-Eintrag unter release.forgejo.org überprüft wird.
smtp_from_invalid = Die „Sende E-Mail Als“-Adresse ist ungültig
+config_location_hint = Diese Konfigurationsoptionen werden gespeichert in:
[home]
uname_holder=E-Mail-Adresse oder Benutzername
@@ -318,7 +334,7 @@ switch_dashboard_context=Kontext der Übersichtsseite wechseln
my_repos=Repositorys
show_more_repos=Zeige mehr Repositorys …
collaborative_repos=Gemeinschaftliche Repositorys
-my_orgs=Meine Organisationen
+my_orgs=Organisationen
my_mirrors=Meine Spiegel
view_home=%s ansehen
search_repos=Finde ein Repository …
@@ -356,9 +372,13 @@ user_no_results=Keine passenden Benutzer gefunden.
org_no_results=Keine passenden Organisationen gefunden.
code_no_results=Es konnte kein passender Code für deinen Suchbegriff gefunden werden.
code_search_results=Suchergebnisse für „%s“
-code_last_indexed_at=Zuletzt indexiert %s
+code_last_indexed_at=Zuletzt indiziert %s
relevant_repositories_tooltip=Repositorys, die Forks sind oder die kein Thema, kein Symbol und keine Beschreibung haben, werden ausgeblendet.
relevant_repositories=Es werden nur relevante Repositorys angezeigt, ungefilterte Ergebnisse anzeigen.
+stars_one = %d Favorisierung
+stars_few = %d Favorisierungen
+forks_one = %d Fork
+forks_few = %d Forks
[auth]
create_new_account=Konto anlegen
@@ -400,7 +420,7 @@ twofa_scratch_used=Du hast dein Einmalpasswort verwendet. Du wurdest zu den Eins
twofa_passcode_incorrect=Ungültige PIN. Wenn du dein Gerät verloren hast, verwende dein Einmalpasswort.
twofa_scratch_token_incorrect=Das Einmalpasswort ist falsch.
login_userpass=Anmelden
-login_openid=OpenID
+tab_openid=OpenID
oauth_signup_tab=Neues Konto registrieren
oauth_signup_title=Neuen Account fertigstellen
oauth_signup_submit=Konto vervollständigen
@@ -434,6 +454,8 @@ change_unconfirmed_email_error = Ändern der E-Mail-Adresse fehlgeschlagen: %v
last_admin = Du kannst den letzten Administrator nicht entfernen. Es muss mindestens einen Administrator geben.
change_unconfirmed_email = Wenn Sie bei der Registrierung eine falsche E-Mail-Adresse angegeben haben, können Sie diese unten ändern, woraufhin eine Bestätigung an die neue Adresse geschickt wird.
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
[mail]
view_it_on=Auf %s ansehen
@@ -603,6 +625,8 @@ org_still_own_packages=Diese Organisation besitzt noch ein oder mehrere Pakete,
target_branch_not_exist=Der Ziel-Branch existiert nicht.
username_error_no_dots = ` darf nur alphanumerische Zeichen („0-9“, „a-z“, „A-Z“), Bindestriche („-“), Unterstriche („_“) enthalten. Es kann nicht mit nicht-alphanumerischen Zeichen beginnen oder enden und aufeinanderfolgende nicht-alphanumerische Zeichen sind ebenfalls verboten.`
admin_cannot_delete_self = Du kannst dich nicht selbst löschen, wenn du ein Admin bist. Bitte entferne zuerst deine Adminrechte.
+unset_password = Der Anmeldebenutzer hat das Passwort nicht gesetzt.
+unsupported_login_type = Dieser Login-Typ unterstützt keine Accountlöschung.
[user]
@@ -651,7 +675,7 @@ applications=Anwendungen
orgs=Organisationen verwalten
repos=Repositorys
delete=Konto löschen
-twofa=Zwei-Faktor-Authentifizierung
+twofa=Zwei-Faktor-Authentifizierung (TOTP)
account_link=Verknüpfte Benutzerkonten
organization=Organisationen
uid=UID
@@ -667,7 +691,7 @@ website=Webseite
location=Standort
update_theme=Theme ändern
update_profile=Profil aktualisieren
-update_language=Sprache aktualisieren
+update_language=Sprache ändern
update_language_not_found=Sprache „%s“ ist nicht verfügbar.
update_language_success=Sprache wurde aktualisiert.
update_profile_success=Dein Profil wurde aktualisiert.
@@ -699,7 +723,7 @@ comment_type_group_issue_ref=Issue-Referenz
saved_successfully=Die Einstellungen wurden erfolgreich gespeichert.
privacy=Datenschutz
keep_activity_private=Aktivität auf der Profilseite ausblenden
-keep_activity_private_popup=Macht die Aktivität nur für dich und die Administratoren sichtbar
+keep_activity_private_popup=Deine Aktivität wird nur für dich und die Instanzadministratoren sichtbar sein
lookup_avatar_by_mail=Profilbild anhand der E-Mail-Addresse suchen
federated_avatar_lookup=Suche nach föderierten Profilbildern
@@ -778,12 +802,12 @@ gpg_key_matched_identities_long=Die eingebetteten Identitäten in diesem Schlüs
gpg_key_verified=Verifizierter Schlüssel
gpg_key_verified_long=Der Schlüssel wurde mit einem Token verifiziert. Er kann verwendet werden, um Commits zu verifizieren, die mit irgendeiner für diesen Nutzer aktivierten E-Mail-Adresse und irgendeiner Identität dieses Schlüssels übereinstimmen.
gpg_key_verify=Verifizieren
-gpg_invalid_token_signature=Der GPG Key, die Signatur, und das Token stimmen nicht überein, oder das Token ist veraltet.
+gpg_invalid_token_signature=Der GPG-Key, die Signatur, und das Token stimmen nicht überein, oder das Token ist veraltet.
gpg_token_required=Du musst eine Signatur für das folgende Token angeben
gpg_token=Token
gpg_token_help=Du kannst eine Signatur wie folgt generieren:
gpg_token_code=echo "%s" | gpg -a --default-key %s --detach-sig
-gpg_token_signature=GPG Textsignatur (armored signature)
+gpg_token_signature=GPG-Textsignatur (armored signature)
key_signature_gpg_placeholder=Beginnt mit „-----BEGIN PGP SIGNATURE-----“
verify_gpg_key_success=GPG-Schlüssel „%s“ wurde verifiziert.
ssh_key_verified=Verifizierter Schlüssel
@@ -793,7 +817,7 @@ ssh_invalid_token_signature=Der gegebene SSH-Schlüssel, Signatur oder Token sti
ssh_token_required=Du musst eine Signatur für den Token unten angeben
ssh_token=Token
ssh_token_help=Du kannst eine Signatur wie folgt generieren:
-ssh_token_signature=SSH Textsignatur (armored signature)
+ssh_token_signature=SSH-Textsignatur (armored signature)
key_signature_ssh_placeholder=Beginnt mit „-----BEGIN SSH SIGNATURE-----“
verify_ssh_key_success=SSH-Key „%s“ wurde verifiziert.
subkeys=Unterschlüssel
@@ -839,7 +863,7 @@ generate_new_token=Neuen Token erzeugen
tokens_desc=Diese Tokens gewähren vollen Zugriff auf dein Konto via die Forgejo-API.
token_name=Token-Name
generate_token=Token generieren
-generate_token_success=Ein neuer Token wurde generiert. Kopiere diesen, da er nicht erneut angezeigt wird.
+generate_token_success=Ein neuer Token wurde generiert. Kopiere diesen jetzt, da er nicht erneut angezeigt wird.
generate_token_name_duplicate=%s wurde bereits als Anwendungsname verwendet. Bitte wähle einen neuen Namen.
delete_token=Löschen
access_token_deletion=Zugriffstoken löschen
@@ -894,17 +918,17 @@ twofa_is_enrolled=Für dein Konto ist die Zwei-Faktor-Authentifizierung
twofa_not_enrolled=Für dein Konto ist die Zwei-Faktor-Authentifizierung momentan nicht eingeschaltet.
twofa_disable=Zwei-Faktor-Authentifizierung deaktivieren
twofa_scratch_token_regenerate=Neues Einmalpasswort erstellen
-twofa_scratch_token_regenerated=Dein temporärer Token ist jetzt %s. Speichere ihn an einem sicheren Ort, er wird nie wieder angezeigt.
+twofa_scratch_token_regenerated=Dein einmalig verwendbarer Wiederherstellungsschlüssel ist jetzt %s. Speichere ihn an einem sicheren Ort, denn er wird nie wieder angezeigt.
twofa_enroll=Zwei-Faktor-Authentifizierung aktivieren
twofa_disable_note=Du kannst die Zwei-Faktor-Authentifizierung auch wieder deaktivieren.
twofa_disable_desc=Wenn du die Zwei-Faktor-Authentifizierung deaktivierst, wird die Sicherheit deines Kontos verringert. Fortfahren?
-regenerate_scratch_token_desc=Wenn du dein Einmalpasswort verlegt oder es bereits benutzt hast, kannst du es hier zurücksetzen.
+regenerate_scratch_token_desc=Wenn du deinen Wiederherstellungsschlüssel verlegst oder es bereits benutzt hast, kannst du es hier zurücksetzen.
twofa_disabled=Zwei-Faktor-Authentifizierung wurde deaktiviert.
scan_this_image=Scanne diese Grafik mit deiner Authentifizierungs-App:
or_enter_secret=Oder gib das Secret ein: %s
then_enter_passcode=Und gib dann die angezeigte PIN der Anwendung ein:
passcode_invalid=Die PIN ist falsch. Probiere es erneut.
-twofa_enrolled=Die Zwei-Faktor-Authentifizierung wurde für dein Konto aktiviert. Bewahre dein Einmalpasswort (%s) an einem sicheren Ort auf, da es nicht wieder angezeigt werden wird.
+twofa_enrolled=Die Zwei-Faktor-Authentifizierung wurde für dein Konto aktiviert. Bewahre deinen einmalig verwendbaren Wiederherstellungsschlüssel (%s) an einem sicheren Ort auf, da er nicht wieder angezeigt werden wird.
twofa_failed_get_secret=Fehler beim Abrufen des Secrets.
webauthn_desc=Sicherheitsschlüssel sind Geräte, die kryptografische Schlüssel beeinhalten. Diese können für die Zwei-Faktor-Authentifizierung verwendet werden. Der Sicherheitsschlüssel muss den Standard „WebAuthn“ unterstützen.
@@ -947,7 +971,7 @@ visibility.limited_tooltip=Nur für authentifizierte Benutzer sichtbar
visibility.private=Privat
visibility.private_tooltip=Sichtbar nur für Mitglieder von Organisationen, denen du beigetreten bist
user_block_success = Dieser Benutzer wurde erfolgreich blockiert.
-twofa_recovery_tip = Falls du dein Gerät verlierst, wirst du in der Lage sein, einen einmalig verwendbaren Key zu benutzen, um den auf dein Konto wiederherzustellen.
+twofa_recovery_tip = Falls du dein Gerät verlierst, wirst du in der Lage sein, einen einmalig verwendbaren Wiederherstellungsschlüssel zu benutzen, um den auf dein Konto wiederherzustellen.
webauthn_alternative_tip = Du möchtest vielleicht eine zusätzliche Authentifizierungsmethode einrichten.
blocked_users_none = Keine Benutzer blockiert.
webauthn_key_loss_warning = Falls du deine Security-Keys verlierst, wirst du Zugang zu deinem Konto verlieren.
@@ -970,7 +994,7 @@ visibility=Sichtbarkeit
visibility_description=Nur der Besitzer oder Organisationsmitglieder mit entsprechender Berechtigung werden in der Lage sein, es zu sehen.
visibility_helper=In privates Repository umwandeln
visibility_helper_forced=Auf dieser Forgejo-Instanz können nur private Repositorys angelegt werden.
-visibility_fork_helper=(Eine Änderung dieses Wertes wirkt sich auf alle Forks aus)
+visibility_fork_helper=(Eine Änderung dieses Wertes wirkt sich auf die Sichtbarkeit aller Forks aus)
clone_helper=Benötigst du Hilfe beim Klonen? Öffne die Hilfe.
fork_repo=Repository forken
fork_from=Fork von
@@ -1121,7 +1145,7 @@ migrate.migrating=Migriere von %s ...
migrate.migrating_failed=Migrieren von %s fehlgeschlagen.
migrate.migrating_failed.error=Migration fehlgeschlagen: %s
migrate.migrating_failed_no_addr=Migration fehlgeschlagen.
-migrate.github.description=Daten von github.com oder anderen GitHub-Instanzen migrieren.
+migrate.github.description=Daten von github.com oder GitHub Enterprise Server migrieren.
migrate.git.description=Ein Repository von einem beliebigen Git Service klonen.
migrate.gitlab.description=Daten von gitlab.com oder anderen GitLab-Instanzen migrieren.
migrate.gitea.description=Daten von gitea.com oder anderen Gitea-/Forgejo-Instanzen migrieren.
@@ -1395,7 +1419,7 @@ issues.new.no_milestone=Kein Meilenstein
issues.new.clear_milestone=Meilenstein entfernen
issues.new.open_milestone=Offene Meilensteine
issues.new.closed_milestone=Geschlossene Meilensteine
-issues.new.assignees=Zuständig
+issues.new.assignees=Zuständige
issues.new.clear_assignees=Zuständige entfernen
issues.new.no_assignees=Niemand zuständig
issues.new.no_reviewers=Keine Reviewer
@@ -1412,7 +1436,7 @@ issues.new_label=Neues Label
issues.new_label_placeholder=Labelname
issues.new_label_desc_placeholder=Beschreibung
issues.create_label=Label erstellen
-issues.label_templates.title=Eine vordefinierte Label-Sammung laden
+issues.label_templates.title=Eine Label-Sammlung laden
issues.label_templates.info=Es existieren noch keine Labels. Erstelle ein neues Label („Neues Label“) oder verwende die Standard-Label-Sammlung:
issues.label_templates.helper=Wähle eine Label-Sammlung
issues.label_templates.use=Label-Sammlung verwenden
@@ -1422,18 +1446,18 @@ issues.add_labels=hat die Labels %s %s hinzugefügt
issues.remove_label=hat das Label %s %s entfernt
issues.remove_labels=hat die Labels %s %s entfernt
issues.add_remove_labels=hat %s hinzugefügt, und %s %s entfernt
-issues.add_milestone_at=`hat diesen Issue %[2]s zum %[1]s Meilenstein hinzugefügt`
-issues.add_project_at=`hat dieses zum %s projekt %s hinzugefügt`
+issues.add_milestone_at=`hat dieses Issue %[2]s zum Meilenstein %[1]s hinzugefügt`
+issues.add_project_at=`hat dies zum Projekt %s %s hinzugefügt`
issues.change_milestone_at=`hat den Meilenstein %[3]s von %[1]s zu %[2]s geändert`
issues.change_project_at=`hat das Projekt %[3]s von %[1]s zu %[2]s geändert`
issues.remove_milestone_at=`hat dieses Issue %[2]s vom %[1]s Meilenstein entfernt`
-issues.remove_project_at=`hat dieses vom %s Projekt %s entfernt`
+issues.remove_project_at=`hat dies vom Projekt %s %s entfernt`
issues.deleted_milestone=`(gelöscht)`
issues.deleted_project=`(gelöscht)`
issues.self_assign_at=`hat sich das Issue %s selbst zugewiesen`
issues.add_assignee_at=`wurde von %s %s zugewiesen`
-issues.remove_assignee_at=`wurde von %s %s nicht zugewiesen`
-issues.remove_self_assignment=`hat seine Zuweisung %s entfernt`
+issues.remove_assignee_at=`wurde von %s von der Zuweisung %s befreit`
+issues.remove_self_assignment=`hat die Selbstzuweisung %s entfernt`
issues.change_title_at=`hat den Titel von %s zu %s %s geändert`
issues.change_ref_at=`hat die Referenz von %s zu %s %s geändert`
issues.remove_ref_at=`hat die Referenz %s entfernt %s`
@@ -1462,7 +1486,7 @@ issues.filter_type.assigned_to_you=Dir zugewiesen
issues.filter_type.created_by_you=Von dir erstellt
issues.filter_type.mentioning_you=Hat dich erwähnt
issues.filter_type.review_requested=Review angefordert
-issues.filter_type.reviewed_by_you=Bewertet von dir
+issues.filter_type.reviewed_by_you=Von dir gereviewt
issues.filter_sort=Sortieren
issues.filter_sort.latest=Neueste
issues.filter_sort.oldest=Älteste
@@ -1508,14 +1532,14 @@ issues.context.edit=Bearbeiten
issues.context.delete=Löschen
issues.no_content=Keine Beschreibung angegeben.
issues.close=Issue schließen
-issues.comment_pull_merged_at=hat Commit %[1]s in %[2]s %[3]s gemerged
+issues.comment_pull_merged_at=hat Commit %[1]s in %[2]s %[3]s gemergt
issues.comment_manually_pull_merged_at=hat Commit %[1]s in %[2]s %[3]s manuell gemergt
issues.close_comment_issue=Kommentieren und schließen
issues.reopen_issue=Wieder öffnen
issues.reopen_comment_issue=Kommentieren und wieder öffnen
issues.create_comment=Kommentieren
issues.closed_at=`hat diesen Issue %[2]s geschlossen`
-issues.reopened_at=`hat diesen Issue %[2]s wieder geöffnet`
+issues.reopened_at=`hat dieses Issue %[2]s wieder geöffnet`
issues.commit_ref_at=`hat dieses Issue %[2]s aus einem Commit referenziert`
issues.ref_issue_from=`hat %[2]s auf dieses Issue verwiesen %[4]s`
issues.ref_pull_from=`hat %[2]s auf diesen Pull-Request verwiesen %[4]s`
@@ -1574,15 +1598,15 @@ issues.subscribe=Abonnieren
issues.unsubscribe=Abbestellen
issues.unpin_issue=Issue abheften
issues.max_pinned=Du kannst keine weiteren Issues anheften
-issues.pin_comment=hat das %s angeheftet
+issues.pin_comment=hat dies %s angeheftet
issues.unpin_comment=hat das %s abgeheftet
issues.lock=Diskussion sperren
issues.unlock=Diskussion entsperren
issues.lock.unknown_reason=Es ist nicht möglich, einen Issue mit unbekanntem Grund zu sperren.
issues.lock_duplicate=Eine Diskussion kann nicht mehrfach gesperrt werden.
issues.unlock_error=Es ist nicht möglich, einen nicht gesperrten Issue zu entsperren.
-issues.lock_with_reason=gesperrt als %s und Diskussion auf Mitarbeiter beschränkt %s
-issues.lock_no_reason=gesperrt und Diskussion auf Mitarbeiter beschränkt %s
+issues.lock_with_reason=sperrte dies %s mit der Begründung „%s“ und schränkte die Diskussion auf Mitarbeiter ein
+issues.lock_no_reason=sperrte dies %s und schränkte die Diskussion auf Mitarbeiter ein
issues.unlock_comment=hat diese Diskussion %s entsperrt
issues.lock_confirm=Sperren
issues.unlock_confirm=Entsperren
@@ -1612,13 +1636,13 @@ issues.add_time=Zeit manuell hinzufügen
issues.del_time=Diese Zeiterfassung löschen
issues.add_time_short=Zeit hinzufügen
issues.add_time_cancel=Abbrechen
-issues.add_time_history=`hat %s gearbeitete Zeit hinzugefügt`
-issues.del_time_history=`hat %s gearbeitete Zeit gelöscht`
+issues.add_time_history=`hat %s den Zeitaufwand hinzugefügt`
+issues.del_time_history=`hat %s den Zeitaufwand gelöscht`
issues.add_time_hours=Stunden
issues.add_time_minutes=Minuten
issues.add_time_sum_to_small=Es wurde keine Zeit eingegeben.
issues.time_spent_total=Zeitaufwand insgesamt
-issues.time_spent_from_all_authors=`Aufgewendete Zeit: %s`
+issues.time_spent_from_all_authors=`Gesamtzeitaufwand: %s`
issues.due_date=Fällig am
issues.invalid_due_date_format=Das Fälligkeitsdatum muss das Format „JJJJ-MM-TT“ haben.
issues.error_modifying_due_date=Fehler beim Ändern des Fälligkeitsdatums.
@@ -1634,20 +1658,20 @@ issues.due_date_form_remove=Entfernen
issues.due_date_not_writer=Du musst Schreibrechte für dieses Repository haben, um das Fälligkeitsdatum zu ändern.
issues.due_date_not_set=Kein Fälligkeitsdatum gesetzt.
issues.due_date_added=hat %[2]s das Fälligkeitsdatum %[1]s hinzugefügt
-issues.due_date_modified=ändert das Abgabedatum von %[2]s auf %[1]s %[3]s s
+issues.due_date_modified=hat das Fälligkeitsdatum von %[2]s auf %[1]s %[3]s geändert
issues.due_date_remove=hat %[2]s das Fälligkeitsdatum %[1]s entfernt
issues.due_date_overdue=Überfällig
issues.due_date_invalid=Das Fälligkeitsdatum ist ungültig oder außerhalb des zulässigen Bereichs. Bitte verwende das Format „jjjj-mm-tt“.
issues.dependency.title=Abhängigkeiten
issues.dependency.issue_no_dependencies=Keine Abhängigkeiten gesetzt.
issues.dependency.pr_no_dependencies=Keine Abhängigkeiten gesetzt.
-issues.dependency.no_permission_1=Du bist nicht berechtigt %d Abhängigkeit zu lesen
-issues.dependency.no_permission_n=Du bist nicht berechtigt %d Abhängigkeiten zu lesen
-issues.dependency.no_permission.can_remove=Du hast keine Berechtigung diese Abhängigkeit zu lesen, kannst diese Abhängigkeit aber entfernen
+issues.dependency.no_permission_1=Du bist nicht berechtigt, %d Abhängigkeit zu lesen
+issues.dependency.no_permission_n=Du bist nicht berechtigt, %d Abhängigkeiten zu lesen
+issues.dependency.no_permission.can_remove=Du hast keine Berechtigung, diese Abhängigkeit zu lesen, kannst diese Abhängigkeit aber entfernen
issues.dependency.add=Abhängigkeit hinzufügen …
issues.dependency.cancel=Abbrechen
issues.dependency.remove=Entfernen
-issues.dependency.remove_info=Abhängigkeit löschen
+issues.dependency.remove_info=Diese Abhängigkeit löschen
issues.dependency.added_dependency=`hat eine neue Abhängigkeit %s hinzugefügt`
issues.dependency.removed_dependency=`hat eine Abhängigkeit %s entfernt`
issues.dependency.pr_closing_blockedby=Das Schließen dieses Pull-Requests wird von den folgenden Issues blockiert
@@ -1672,7 +1696,7 @@ issues.dependency.add_error_dep_not_same_repo=Beide Issues müssen sich im selbe
issues.review.self.approval=Du kannst nicht dein eigenen Pull-Request genehmigen.
issues.review.self.rejection=Du kannst keine Änderungen an deinem eigenen Pull-Request anfragen.
issues.review.approve=hat die Änderungen %s genehmigt
-issues.review.comment=hat %s überprüft
+issues.review.comment=hat %s gereviewt
issues.review.dismissed=verwarf %ss Review %s
issues.review.dismissed_label=Verworfen
issues.review.left_comment=hat einen Kommentar hinterlassen
@@ -1692,12 +1716,12 @@ issues.review.option.show_outdated_comments=Veraltete Kommentare anzeigen
issues.review.option.hide_outdated_comments=Veraltete Kommentare ausblenden
issues.review.show_outdated=Veraltete anzeigen
issues.review.hide_outdated=Veraltete ausblenden
-issues.review.show_resolved=Gelöste anzeigen
-issues.review.hide_resolved=Gelöste ausblenden
+issues.review.show_resolved=Erledigte anzeigen
+issues.review.hide_resolved=Erledigte ausblenden
issues.review.resolve_conversation=Diskussion als „erledigt“ markieren
issues.review.un_resolve_conversation=Diskussion als „nicht erledigt“ markieren
issues.review.resolved_by=markierte diese Unterhaltung als gelöst
-issues.assignee.error=Aufgrund eines unerwarteten Fehlers konnten nicht alle Beauftragten hinzugefügt werden.
+issues.assignee.error=Aufgrund eines unerwarteten Fehlers konnten nicht alle Zuständigen hinzugefügt werden.
issues.reference_issue.body=Beschreibung
issues.content_history.deleted=gelöscht
issues.content_history.edited=bearbeitet
@@ -1740,8 +1764,8 @@ pulls.nothing_to_compare=Diese Branches sind identisch. Es muss kein Pull-Reques
pulls.nothing_to_compare_and_allow_empty_pr=Diese Branches sind gleich. Der Pull-Request wird leer sein.
pulls.has_pull_request=`Es existiert bereits ein Pull-Request zwischen diesen beiden Branches: %[2]s#%[3]d`
pulls.create=Pull-Request erstellen
-pulls.title_desc=möchte %[1]d Commits von %[2]s
nach %[3]s
mergen
-pulls.merged_title_desc=hat %[1]d Commits von %[2]s
nach %[3]s
%[4]s zusammengeführt
+pulls.title_desc_few=möchte %[1]d Commits von %[2]s
nach %[3]s
mergen
+pulls.merged_title_desc_few=hat %[1]d Commits von %[2]s
nach %[3]s
%[4]s zusammengeführt
pulls.change_target_branch_at=`hat den Zielbranch von %s nach %s %s geändert`
pulls.tab_conversation=Diskussion
pulls.tab_commits=Commits
@@ -1778,8 +1802,8 @@ pulls.cannot_auto_merge_desc=Dieser Pull-Request kann nicht automatisch gemergt
pulls.cannot_auto_merge_helper=Bitte manuell mergen, um die Konflikte zu beheben.
pulls.num_conflicting_files_1=%d Datei mit Konflikten
pulls.num_conflicting_files_n=%d Dateien mit Konflikten
-pulls.approve_count_1=%d Zustimmung
-pulls.approve_count_n=%d Zustimmungen
+pulls.approve_count_1=%d Genehmigung
+pulls.approve_count_n=%d Genehmigungen
pulls.reject_count_1=%d Änderungsanfrage
pulls.reject_count_n=%d Änderungsanfragen
pulls.waiting_count_1=%d wartendes Review
@@ -1808,9 +1832,9 @@ pulls.unrelated_histories=Merge fehlgeschlagen: Der Head des Merges und die Basi
pulls.merge_out_of_date=Merge fehlgeschlagen: Während des Mergens wurde die Basis aktualisiert. Hinweis: Versuche es erneut.
pulls.head_out_of_date=Mergen fehlgeschlagen: Der Head wurde aktualisiert während der Merge erstellt wurde. Tipp: Versuche es erneut.
pulls.has_merged=Fehler: Der Pull-Request wurde gemergt, du kannst den Zielbranch nicht wieder mergen oder ändern.
-pulls.push_rejected=Mergen fehlgeschlagen: Der Push wurde abgelehnt. Überprüfe die Git Hooks für dieses Repository.
+pulls.push_rejected=Pushen fehlgeschlagen: Der Push wurde abgelehnt. Überprüfe die Git-Hooks für dieses Repository.
pulls.push_rejected_summary=Vollständige Ablehnungsmeldung
-pulls.push_rejected_no_message=Mergen fehlgeschlagen: Der Push wurde abgelehnt, aber es gab keine Fehlermeldung.
Überprüfe die Git Hooks für dieses Repository
+pulls.push_rejected_no_message=Pushen fehlgeschlagen: Der Push wurde abgelehnt, aber es gab keine Fehlermeldung. Überprüfe die Git-Hooks für dieses Repository
pulls.open_unmerged_pull_exists=`Du kannst diesen Pull-Request nicht erneut öffnen, da noch ein anderer (#%d) mit identischen Eigenschaften offen ist.`
pulls.status_checking=Einige Prüfungen sind noch ausstehend
pulls.status_checks_success=Alle Prüfungen waren erfolgreich
@@ -2084,10 +2108,10 @@ settings.admin_settings=Administratoreinstellungen
settings.admin_enable_health_check=Repository-Health-Checks aktivieren (git fsck)
settings.admin_code_indexer=Code-Indexer
settings.admin_stats_indexer=Code-Statistik-Indexer
-settings.admin_indexer_commit_sha=Zuletzt indexierter SHA
+settings.admin_indexer_commit_sha=Zuletzt indizierter SHA
settings.admin_indexer_unindexed=Unindiziert
-settings.reindex_button=Zur Warteschlange für erneutes Indexieren hinzufügen
-settings.reindex_requested=Erneutes Indexieren angefordert
+settings.reindex_button=Zur Warteschlange für erneutes Indizieren hinzufügen
+settings.reindex_requested=Erneutes Indizieren angefordert
settings.admin_enable_close_issues_via_commit_in_any_branch=Einen Issue mit einem Commit auf einem Nicht-Standard-Branch schließen
settings.danger_zone=Gefahrenzone
settings.new_owner_has_same_repo=Der neue Besitzer hat bereits ein Repository mit dem gleichen Namen. Bitte wähle einen anderen Namen.
@@ -2171,7 +2195,7 @@ settings.hooks_desc=Webhooks senden bei bestimmten Forgejo-Events automatisch
settings.webhook_deletion=Webhook löschen
settings.webhook_deletion_desc=Das Entfernen eines Webhooks löscht seine Einstellungen und Zustellungsverlauf. Fortfahren?
settings.webhook_deletion_success=Webhook wurde entfernt.
-settings.webhook.test_delivery=Senden testen
+settings.webhook.test_delivery=Zustellung testen
settings.webhook.test_delivery_desc=Teste diesen Webhook mit einem Fake-Event.
settings.webhook.test_delivery_desc_disabled=Um diesen Webhook mit einem Fake-Event zu testen, aktiviere ihn.
settings.webhook.request=Anfrage
@@ -2181,7 +2205,7 @@ settings.webhook.payload=Inhalt
settings.webhook.body=Inhalt
settings.webhook.replay.description=Diesen Webhook wiederholen.
settings.webhook.replay.description_disabled=Um diesen Webhook wiederzugeben, aktiviere ihn.
-settings.webhook.delivery.success=Ein Event wurde zur Sendungs-Warteschlange hinzugefügt. Es kann ein paar Sekunden dauern, bevor es im Verlauf erscheint.
+settings.webhook.delivery.success=Ein Event wurde zur Zustellungswarteschlange hinzugefügt. Es kann ein paar Sekunden dauern, bevor es im Zustellungsverlauf erscheint.
settings.githooks_desc=Git-Hooks werden von Git selbst bereitgestellt. Du kannst die Dateien der unterstützten Hooks in der Liste unten bearbeiten, um eigene Operationen einzubinden.
settings.githook_edit_desc=Wenn ein Hook nicht aktiv ist, wird der Standardinhalt benutzt. Lasse den Inhalt leer, um den Hook zu deaktivieren.
settings.githook_name=Hook-Name
@@ -2234,8 +2258,8 @@ settings.event_pull_request_assign=Pull-Request zugewiesen
settings.event_pull_request_assign_desc=Pull-Request zugewiesen oder Zuweisung entfernt.
settings.event_pull_request_label=Pull-Request mit Label versehen
settings.event_pull_request_label_desc=Pull-Request-Labels aktualisiert oder geleert.
-settings.event_pull_request_milestone=Pull-Request zu Milestone hinzugefügt
-settings.event_pull_request_milestone_desc=Pull-Request zu Milestone hinzugefügt oder entfernt.
+settings.event_pull_request_milestone=Pull-Request zum Meilenstein hinzugefügt
+settings.event_pull_request_milestone_desc=Pull-Request zum Meilenstein hinzugefügt oder entfernt.
settings.event_pull_request_comment=Pull-Request-Kommentar
settings.event_pull_request_comment_desc=Pull-Request-Kommentar angelegt, geändert oder gelöscht.
settings.event_pull_request_review=Pull-Request überprüft
@@ -2244,7 +2268,7 @@ settings.event_pull_request_sync=Pull-Request synchronisiert
settings.event_pull_request_sync_desc=Pull-Request synchronisiert.
settings.event_pull_request_review_request=Überprüfung des Pull-Requests angefragt
settings.event_pull_request_review_request_desc=Überprüfung des Pull-Requests angefragt oder die Anfrage entfernt.
-settings.event_pull_request_approvals=Zustimmungen zum Pull-Request
+settings.event_pull_request_approvals=Genehmigungen zum Pull-Request
settings.event_pull_request_merge=Pull-Request-Merge
settings.event_package=Paket
settings.event_package_desc=Paket wurde in einem Repository erstellt oder gelöscht.
@@ -2282,7 +2306,7 @@ settings.packagist_username=Benutzername für Packagist
settings.packagist_api_token=API-Token
settings.packagist_package_url=Paket-URL
settings.deploy_keys=Deploy-Keys
-settings.add_deploy_key=Deploy-Schlüssel hinzufügen
+settings.add_deploy_key=Deploy-Key hinzufügen
settings.deploy_key_desc=Deploy-Keys haben nur Lesezugriff auf das Repository.
settings.is_writable=Erlaube Schreibzugriff
settings.is_writable_info=Erlaube diesem Deploy-Key auf das Repository zu pushen.
@@ -2311,9 +2335,9 @@ settings.protect_enable_push=Push aktivieren
settings.protect_enable_push_desc=Jeder, der Schreibzugriff hat, darf in diesen Branch pushen (aber kein Force-Push).
settings.protect_enable_merge=Merge aktivieren
settings.protect_enable_merge_desc=Jeder mit Schreibzugriff darf die Pull-Requests in diesen Branch mergen.
-settings.protect_whitelist_committers=Schütze gewhitelistete Commiter
+settings.protect_whitelist_committers=Whitelist-eingeschränkter Push
settings.protect_whitelist_committers_desc=Jeder, der auf der Whitelist steht, darf in diesen Branch pushen (aber kein Force-Push).
-settings.protect_whitelist_deploy_keys=Deploy-Schlüssel mit Schreibzugriff zum Pushen whitelisten.
+settings.protect_whitelist_deploy_keys=Deploy-Key mit Schreibzugriff zum Pushen whitelisten.
settings.protect_whitelist_users=Nutzer, die pushen dürfen:
settings.protect_whitelist_search_users=Benutzer suchen …
settings.protect_whitelist_teams=Teams, die pushen dürfen:
@@ -2322,7 +2346,7 @@ settings.protect_merge_whitelist_committers=Merge-Whitelist aktivieren
settings.protect_merge_whitelist_committers_desc=Erlaube Nutzern oder Teams auf der Whitelist, Pull-Requests in diesen Branch zu mergen.
settings.protect_merge_whitelist_users=Nutzer, die mergen dürfen:
settings.protect_merge_whitelist_teams=Teams, die mergen dürfen:
-settings.protect_check_status_contexts=Statusprüfungen aktivieren
+settings.protect_check_status_contexts=Statusprüfung aktivieren
settings.protect_status_check_patterns=Statuscheck-Muster:
settings.protect_status_check_patterns_desc=Gib Muster ein, um festzulegen, welche Statusüberprüfungen durchgeführt werden müssen, bevor Branches in einen Branch, der dieser Regel entspricht, gemergt werden können. Jede Zeile gibt ein Muster an. Muster dürfen nicht leer sein.
settings.protect_check_status_contexts_desc=Vor dem Mergen müssen Statusprüfungen bestanden werden. Wähle aus, welche Statusprüfungen erfolgreich durchgeführt werden müssen, bevor Branches in einen anderen gemergt werden können, der dieser Regel entspricht. Wenn aktiviert, müssen Commits zuerst auf einen anderen Branch gepusht werden, dann nach bestandener Statusprüfung gemergt oder direkt auf einen Branch gepusht werden, der dieser Regel entspricht. Wenn kein Kontext ausgewählt ist, muss der letzte Commit unabhängig vom Kontext erfolgreich sein.
@@ -2330,12 +2354,12 @@ settings.protect_check_status_contexts_list=Statusprüfungen, die in der letzten
settings.protect_status_check_matched=Übereinstimmung
settings.protect_invalid_status_check_pattern=Ungültiges Statusprüfungspattern: „%s“.
settings.protect_no_valid_status_check_patterns=Keine gültigen Statuscheck-Muster.
-settings.protect_required_approvals=Erforderliche Zustimmungen:
+settings.protect_required_approvals=Erforderliche Genehmigungen:
settings.protect_required_approvals_desc=Erlaube das Mergen des Pull-Requests nur mit genügend positiven Reviews.
-settings.protect_approvals_whitelist_enabled=Freigaben auf Benutzer oder Teams auf der Whitelist beschränken
-settings.protect_approvals_whitelist_enabled_desc=Nur Bewertungen von Benutzern auf der Whitelist oder Teams zählen zu den erforderlichen Genehmigungen. Gibt es keine Whitelist, so zählen Reviews von jedem mit Schreibzugriff zu den erforderlichen Genehmigungen.
-settings.protect_approvals_whitelist_users=Freigeschaltete Reviewer:
-settings.protect_approvals_whitelist_teams=Freigeschaltete Teams:
+settings.protect_approvals_whitelist_enabled=Genehmigungen auf Benutzer oder Teams auf der Whitelist beschränken
+settings.protect_approvals_whitelist_enabled_desc=Nur Reviews von Benutzern auf der Whitelist oder Teams zählen zu den erforderlichen Genehmigungen. Gibt es keine Whitelist, so zählen Reviews von jedem mit Schreibzugriff zu den erforderlichen Genehmigungen.
+settings.protect_approvals_whitelist_users=Reviewer auf der Whitelist:
+settings.protect_approvals_whitelist_teams=Für Reviews gewhitelistete Teams:
settings.dismiss_stale_approvals=Entferne alte Genehmigungen
settings.dismiss_stale_approvals_desc=Wenn neue Commits gepusht werden, die den Inhalt des Pull-Requests ändern, werden alte Genehmigungen entfernt.
settings.require_signed_commits=Signierte Commits erforderlich
@@ -2351,12 +2375,12 @@ settings.delete_protected_branch=Schutz deaktivieren
settings.update_protect_branch_success=Branchschutzregel „%s“ wurde aktualisiert.
settings.remove_protected_branch_success=Branchschutzregel „%s“ wurde entfernt.
settings.remove_protected_branch_failed=Entfernen der Branchschutzregel „%s“ fehlgeschlagen.
-settings.protected_branch_deletion=Branch-Schutz deaktivieren
+settings.protected_branch_deletion=Branch-Schutz löschen
settings.protected_branch_deletion_desc=Wenn du den Branch-Schutz deaktivierst, können alle Nutzer mit Schreibrechten auf den Branch pushen. Fortfahren?
settings.block_rejected_reviews=Merge bei abgelehnten Reviews blockieren
-settings.block_rejected_reviews_desc=Mergen ist nicht möglich, wenn Änderungen durch offizielle Reviewer angefragt werden, auch wenn es genügend Zustimmungen gibt.
+settings.block_rejected_reviews_desc=Mergen ist nicht möglich, wenn Änderungen durch offizielle Reviewer angefragt werden, auch wenn es genügend Genehmigungen gibt.
settings.block_on_official_review_requests=Mergen bei offiziellen Review-Anfragen blockieren
-settings.block_on_official_review_requests_desc=Mergen ist nicht möglich wenn offizielle Review-Anfrangen vorliegen, selbst wenn es genügend Zustimmungen gibt.
+settings.block_on_official_review_requests_desc=Mergen ist nicht möglich, wenn offizielle Review-Anfrangen vorliegen, selbst wenn es genügend Genehmigungen gibt.
settings.block_outdated_branch=Merge blockieren, wenn der Pull-Request veraltet ist
settings.block_outdated_branch_desc=Mergen ist nicht möglich, wenn der Head-Branch hinter dem Basis-Branch ist.
settings.default_branch_desc=Wähle einen Standardbranch für Pull-Requests und Code-Commits:
@@ -2367,7 +2391,7 @@ settings.no_protected_branch=Es gibt keine geschützten Branches.
settings.edit_protected_branch=Bearbeiten
settings.protected_branch_required_rule_name=Regelname erforderlich
settings.protected_branch_duplicate_rule_name=Es existiert bereits eine Regel für dieses Branch-Set
-settings.protected_branch_required_approvals_min=Die Anzahl der erforderlichen Zustimmungen darf nicht negativ sein.
+settings.protected_branch_required_approvals_min=Die Anzahl der erforderlichen Genehmigungen darf nicht negativ sein.
settings.tags=Tags
settings.tags.protection=Tag-Schutz
settings.tags.protection.pattern=Tag-Muster
@@ -2375,7 +2399,7 @@ settings.tags.protection.allowed=Erlaubt
settings.tags.protection.allowed.users=Erlaubte Benutzer
settings.tags.protection.allowed.teams=Erlaubte Teams
settings.tags.protection.allowed.noone=Niemand
-settings.tags.protection.create=Tag schützen
+settings.tags.protection.create=Regel hinzufügen
settings.tags.protection.none=Es gibt keine geschützten Tags.
settings.tags.protection.pattern.description=Du kannst einen einzigen Namen oder ein globales Schema oder einen regulären Ausdruck verwenden, um mehrere Tags zu schützen. Mehr dazu im Guide für geschützte Tags (Englisch).
settings.bot_token=Bot-Token
@@ -2386,7 +2410,7 @@ settings.matrix.room_id=Raum-ID
settings.matrix.message_type=Nachrichtentyp
settings.archive.button=Repo archivieren
settings.archive.header=Dieses Repo archivieren
-settings.archive.text=Durch das Archivieren wird ein Repo vollständig schreibgeschützt. Es wird vom Dashboard versteckt. Niemand (nicht einmal du!) wird in der Lage sein, neue Commits zu erstellen oder Issues oder Pull-Requests zu öffnen.
+settings.archive.text=Durch das Archivieren wird ein Repo vollständig schreibgeschützt. Es wird von der Übersichtsseite versteckt. Niemand (nicht einmal du!) wird in der Lage sein, neue Commits zu erstellen oder Issues oder Pull-Requests zu öffnen.
settings.archive.success=Das Repo wurde erfolgreich archiviert.
settings.archive.error=Beim Versuch, das Repository zu archivieren, ist ein Fehler aufgetreten. Weitere Details finden sich im Log.
settings.archive.error_ismirror=Du kannst kein gespiegeltes Repo archivieren.
@@ -2434,11 +2458,11 @@ diff.browse_source=Quellcode durchsuchen
diff.parent=Ursprung
diff.commit=Commit
diff.git-notes=Hinweise
-diff.data_not_available=Keine Diff-Daten verfügbar
+diff.data_not_available=Kein Diff-Inhalt verfügbar
diff.options_button=Diff-Optionen
diff.show_diff_stats=Statistiken anzeigen
diff.download_patch=Patch-Datei herunterladen
-diff.download_diff=Vergleichs-Datei herunterladen
+diff.download_diff=Diff-Datei herunterladen
diff.show_split_view=Geteilte Ansicht
diff.show_unified_view=Gesamtansicht
diff.whitespace_button=Leerzeichen
@@ -2462,7 +2486,7 @@ diff.too_many_files=Einige Dateien werden nicht angezeigt, da zu viele Dateien i
diff.show_more=Mehr anzeigen
diff.load=Diff laden
diff.generated=generiert
-diff.vendored=vendored
+diff.vendored=gevendort
diff.comment.add_line_comment=Einzelnen Kommentar hinzufügen
diff.comment.placeholder=Kommentieren
diff.comment.markdown_info=Styling mit Markdown wird unterstützt.
@@ -2470,13 +2494,13 @@ diff.comment.add_single_comment=Einzelnen Kommentar hinzufügen
diff.comment.add_review_comment=Kommentar hinzufügen
diff.comment.start_review=Review starten
diff.comment.reply=Antworten
-diff.review=Überprüfen
+diff.review=Reviewen
diff.review.header=Review einreichen
diff.review.placeholder=Kommentar zum Review
diff.review.comment=Kommentieren
diff.review.approve=Genehmigen
diff.review.self_reject=Pull-Request-Autoren können keine Änderungen an ihren eigenen Pull-Request anfordern
-diff.review.reject=Änderung anfragen
+diff.review.reject=Änderungen anfragen
diff.review.self_approve=Pull-Request-Autoren können ihren eigenen Pull-Request nicht genehmigen
diff.committed_by=committet von
diff.protected=Geschützt
@@ -2655,6 +2679,7 @@ pulls.agit_explanation = Mittels AGit-Workflow erstellt. AGit erlaubt Mitwirkend
activity.navbar.recent_commits = Neueste Commits
activity.navbar.code_frequency = Code-Frequenz
file_follow = Symlink folgen
+error.broken_git_hook = Die Git-Hooks des Repositorys scheinen kaputt zu sein. Bitte folge der Dokumentation um sie zu reparieren, dann pushe einige Commits um den Status zu aktualisieren.
[graphs]
@@ -2700,7 +2725,7 @@ settings.visibility.limited_shortname=Begrenzt
settings.visibility.private=Privat (nur für Organisationsmitglieder sichtbar)
settings.visibility.private_shortname=Privat
-settings.update_settings=Einstellungen speichern
+settings.update_settings=Einstellungen aktualisieren
settings.update_setting_success=Organisationseinstellungen wurden aktualisiert.
settings.change_orgname_prompt=Hinweis: Das Ändern des Organisationsnamens wird auch die URL deiner Organisation ändern und den alten Namen freigeben.
settings.change_orgname_redirect_prompt=Der alte Name wird weiterleiten, bis er wieder beansprucht wird.
@@ -2784,8 +2809,8 @@ teams.invite.description=Bitte klicke auf die folgende Schaltfläche, um dem Tea
follow_blocked_user = Du kannst dieser Organisation nicht folgen, weil diese Organisation dich blockiert hat.
[admin]
-dashboard=Dashboard
-identity_access=Identität & Zugriff
+dashboard=Übersicht
+identity_access=Identität u. Zugriff
users=Benutzerkonten
organizations=Organisationen
assets=Code-Assets
@@ -2873,7 +2898,7 @@ dashboard.last_gc_time=Seit letztem GC-Zyklus
dashboard.total_gc_time=Gesamte GC-Pause
dashboard.total_gc_pause=Gesamte GC-Pause
dashboard.last_gc_pause=Letzte GC-Pause
-dashboard.gc_times=Anzahl GC
+dashboard.gc_times=GC-Zeiten
dashboard.delete_old_actions=Alle alten Aktionen aus der Datenbank löschen
dashboard.delete_old_actions.started=Löschen aller alten Aktionen in der Datenbank gestartet.
dashboard.update_checker=Update-Checker
@@ -2886,7 +2911,7 @@ dashboard.start_schedule_tasks=Terminierte Aufgaben starten
dashboard.sync_branch.started=Synchronisierung der Branches gestartet
dashboard.rebuild_issue_indexer=Issue-Indexer neu bauen
-users.user_manage_panel=Benutzerkontenverwaltung
+users.user_manage_panel=Benutzerkonten verwalten
users.new_account=Benutzerkonto erstellen
users.name=Benutzername
users.full_name=Vollständiger Name
@@ -2916,10 +2941,10 @@ users.is_activated=Account ist aktiviert
users.prohibit_login=Anmelden deaktivieren
users.is_admin=Ist Administrator
users.is_restricted=Ist eingeschränkt
-users.allow_git_hook=Darf „Git Hooks“ erstellen
+users.allow_git_hook=Kann Git-Hooks erstellen
users.allow_git_hook_tooltip=Git-Hooks werden mit denselben Benutzer-Rechten ausgeführt, mit denen Forgejo läuft, und haben die gleiche Ebene von Host-Zugriff. Dadurch können Benutzer mit diesen speziellen Git-Hook-Rechten auf alle Forgejo-Repositorys sowie auf die von Forgejo verwendete Datenbank zugreifen und diese ändern. Auch das Erhalten von Administratorrechten für Forgejo ist möglich.
-users.allow_import_local=Darf lokale Repositorys importieren
-users.allow_create_organization=Darf Organisationen erstellen
+users.allow_import_local=Kann lokale Repositorys importieren
+users.allow_create_organization=Kann Organisationen erstellen
users.update_profile=Benutzerkonto aktualisieren
users.delete_account=Benutzerkonto löschen
users.cannot_delete_self=Du kannst dich nicht selbst löschen
@@ -2944,7 +2969,7 @@ users.list_status_filter.is_2fa_enabled=2FA aktiviert
users.list_status_filter.not_2fa_enabled=2FA deaktiviert
users.details=Benutzerdetails
-emails.email_manage_panel=Benutzer-E-Mail-Verwaltung
+emails.email_manage_panel=Benutzer-E-Mails verwalten
emails.primary=Primär
emails.activated=Aktiviert
emails.filter_sort.email=E-Mail
@@ -2956,13 +2981,13 @@ emails.not_updated=Fehler beim Aktualisieren der angeforderten E-Mail-Adresse: %
emails.duplicate_active=Diese E-Mail-Adresse wird bereits von einem Nutzer verwendet.
emails.change_email_header=E-Mail-Eigenschaften aktualisieren
-orgs.org_manage_panel=Organisationsverwaltung
+orgs.org_manage_panel=Organisationen verwalten
orgs.name=Name
orgs.teams=Teams
orgs.members=Mitglieder
orgs.new_orga=Neue Organisation
-repos.repo_manage_panel=Repositoryverwaltung
+repos.repo_manage_panel=Repositorys verwalten
repos.unadopted=Nicht übernommene Repositorys
repos.unadopted.no_more=Keine weiteren nicht übernommenen Repositorys gefunden
repos.owner=Besitzer
@@ -2975,7 +3000,7 @@ repos.issues=Issues
repos.size=Größe
repos.lfs_size=LFS-Größe
-packages.package_manage_panel=Paketverwaltung
+packages.package_manage_panel=Pakete verwalten
packages.total_size=Gesamtgröße: %s
packages.unreferenced_size=Nicht referenzierte Größe: %s
packages.cleanup=Veraltete Daten löschen
@@ -3022,7 +3047,7 @@ auths.attribute_surname=Nachnamensattribut
auths.attribute_mail=E-Mail-Attribut
auths.attribute_ssh_public_key=Öffentlicher-SSH-Schlüssel-Attribut
auths.attribute_avatar=Avatar-Attribut
-auths.attributes_in_bind=Hole Attribute im Bind-Kontext
+auths.attributes_in_bind=Hole Attribute im Nind-DN-Kontext
auths.allow_deactivate_all=Erlaube ein leeres Suchergebnis, um alle Benutzer zu deaktivieren
auths.use_paged_search=Seitensuche verwenden
auths.search_page_size=Seitengröße
@@ -3032,7 +3057,7 @@ auths.restricted_filter=Eingeschränkte Filter
auths.restricted_filter_helper=Leer lassen, um keine Benutzer als eingeschränkt festzulegen. Verwende einen Asterisk („*“), um alle Benutzer, die nicht dem Admin-Filter entsprechen, als eingeschränkt zu setzen.
auths.verify_group_membership=Gruppenmitgliedschaft in LDAP verifizieren (zum Überspringen leer lassen)
auths.group_search_base=Gruppensuche Basisdomainname
-auths.group_attribute_list_users=Gruppenattribut, welches die Benutzerliste enthält
+auths.group_attribute_list_users=Gruppenattribut, welches Benutzerliste enthält
auths.user_attribute_in_group=Benutzerattribut in der Gruppenliste
auths.map_group_to_team=Ordne LDAP-Gruppen Organisationsteams zu (zum Überspringen leer lassen)
auths.map_group_to_team_removal=Benutzer aus synchronisierten Teams entfernen, wenn der Benutzer nicht zur entsprechenden LDAP-Gruppe gehört
@@ -3050,7 +3075,7 @@ auths.helo_hostname=HELO-Hostname
auths.helo_hostname_helper=Mit HELO gesendeter Hostname. Leer lassen, um den aktuellen Hostnamen zu senden.
auths.disable_helo=HELO deaktivieren
auths.pam_service_name=PAM-Dienstname
-auths.pam_email_domain=PAM E-Mail-Domain (optional)
+auths.pam_email_domain=PAM-E-Mail-Domain (optional)
auths.oauth2_provider=OAuth2-Anbieter
auths.oauth2_icon_url=Symbol-URL
auths.oauth2_clientID=Client-ID (Schlüssel)
@@ -3118,10 +3143,10 @@ auths.unable_to_initialize_openid=OpenID Connect Provider konnte nicht initialis
auths.invalid_openIdConnectAutoDiscoveryURL=Ungültige Auto-Discovery-URL (dies muss eine gültige URL sein, die mit http:// oder https:// beginnt)
config.server_config=Serverkonfiguration
-config.app_name=Seitentitel
+config.app_name=Instanztitel
config.app_ver=Forgejo-Version
-config.app_url=Forgejo-Basis-URL
-config.custom_conf=Konfigurations-Datei-Pfad
+config.app_url=Basis-URL
+config.custom_conf=Konfigurationsdatei-Pfad
config.custom_file_root_path=Benutzerdefinierter Root-Pfad
config.domain=Server-Domain
config.offline_mode=Lokaler Modus
@@ -3150,8 +3175,8 @@ config.ssh_minimum_key_sizes=Mindestschlüssellängen
config.lfs_config=LFS-Konfiguration
config.lfs_enabled=Aktiviert
-config.lfs_content_path=LFS Content-Pfad
-config.lfs_http_auth_expiry=Ablauf der LFS HTTP Authentifizierung
+config.lfs_content_path=LFS-Content-Pfad
+config.lfs_http_auth_expiry=Ablauf der LFS-HTTP-Authentifizierung
config.db_config=Datenbankkonfiguration
config.db_type=Typ
@@ -3174,7 +3199,7 @@ config.require_sign_in_view=Seiten nur für angemeldete Benutzer zugänglich
config.mail_notify=E-Mail-Benachrichtigungen aktivieren
config.enable_captcha=CAPTCHA aktivieren
config.active_code_lives=Aktivierungscode-Lebensdauer
-config.reset_password_code_lives=Kontowiederherstellungs-Code Ablaufzeit
+config.reset_password_code_lives=Kontowiederherstellungscode-Ablaufzeit
config.default_keep_email_private=E-Mail-Adressen standardmäßig verbergen
config.default_allow_create_organization=Erstellen von Organisationen standardmäßig erlauben
config.enable_timetracking=Zeiterfassung aktivieren
@@ -3194,7 +3219,7 @@ config.mailer_enabled=Aktiviert
config.mailer_enable_helo=HELO aktivieren
config.mailer_name=Name
config.mailer_protocol=Protokoll
-config.mailer_smtp_addr=SMTP-Adresse
+config.mailer_smtp_addr=SMTP-Host
config.mailer_smtp_port=SMTP-Port
config.mailer_user=Benutzer
config.mailer_use_sendmail=Sendmail benutzen
@@ -3215,7 +3240,7 @@ config.cache_config=Cache-Konfiguration
config.cache_adapter=Cache-Adapter
config.cache_interval=Cache-Intervall
config.cache_conn=Cache-Anbindung
-config.cache_item_ttl=Cache Item-TTL
+config.cache_item_ttl=Cache-Item-TTL
config.session_config=Session-Konfiguration
config.session_provider=Session-Provider
@@ -3239,14 +3264,14 @@ config.git_max_diff_files=Max. Diff-Dateien (Angezeigte)
config.git_gc_args=GC-Argumente
config.git_migrate_timeout=Zeitlimit für Migration
config.git_mirror_timeout=Zeitlimit für Spiegel-Aktualisierung
-config.git_clone_timeout=Zeitlimit für Clone
+config.git_clone_timeout=Zeitlimit für Klon
config.git_pull_timeout=Zeitlimit für Pull
config.git_gc_timeout=Zeitlimit für GC
config.log_config=Konfiguration des Loggings
config.logger_name_fmt=Logger: %s
config.disabled_logger=Deaktiviert
-config.access_log_mode=Access-Log-Modus
+config.access_log_mode=Zugriffslog-Modus
config.access_log_template=Zugriffslog-Vorlage
config.xorm_log_sql=SQL protokollieren
@@ -3318,6 +3343,7 @@ self_check.database_fix_mssql = Für MSSQL-Benutzer: Du kannst das Problem im Mo
self_check.no_problem_found = Noch kein Problem gefunden.
self_check.database_inconsistent_collation_columns = Datenbank benutzt Collation %s, aber diese Spalten benutzen Collations, die nicht zusammenpassen. Das könnte ein paar unerwartete Probleme verursachen.
self_check.database_collation_mismatch = Erwarte von Datenbank, folgende Collation zu verwenden: %s
+auths.tips.gmail_settings = Gmail-Einstellungen:
[action]
@@ -3430,9 +3456,9 @@ dependencies=Abhängigkeiten
keywords=Schlüsselwörter
details=Details
details.author=Autor
-details.project_site=Projektseite
-details.repository_site=Repository-Seite
-details.documentation_site=Dokumentationsseite
+details.project_site=Projektwebseite
+details.repository_site=Repository-Webseite
+details.documentation_site=Dokumentationswebseite
details.license=Lizenz
assets=Dateien
versions=Versionen
@@ -3483,9 +3509,9 @@ go.install=Installiere das Paket über die Kommandozeile:
helm.registry=Diese Paketverwaltung über die Kommandozeile einrichten:
helm.install=Nutze folgenden Befehl, um das Paket zu installieren:
maven.registry=Setze diese Paketverwaltung in der pom.xml
deines Projektes auf:
-maven.install=Nimm Folgendes in den dependencies
deiner pom.xml
auf, um das Paket zu installieren:
+maven.install=Um das Paket zu verwenden, nimm folgendes in den dependencies
-Block in der pom.xml
-Datei auf:
maven.install2=Über die Kommandozeile ausführen:
-maven.download=Nutze folgendes Kommando, um die Dependency herunterzuladen:
+maven.download=Nutze folgendes Kommando, um die Abhängigkeit herunterzuladen:
nuget.registry=Diese Registry über die Kommandozeile einrichten:
nuget.install=Um das Paket mit NuGet zu installieren, führe den folgenden Befehl aus:
nuget.dependency.framework=Zielframework
@@ -3494,7 +3520,7 @@ npm.install=Um das Paket mit npm zu installieren, führe den folgenden Befehl au
npm.install2=oder füge es zur package.json-Datei hinzu:
npm.dependencies=Abhängigkeiten
npm.dependencies.development=Entwicklungsabhängigkeiten
-npm.dependencies.peer=Peer Abhängigkeiten
+npm.dependencies.peer=Peer-Abhängigkeiten
npm.dependencies.optional=Optionale Abhängigkeiten
npm.details.tag=Tag
pub.install=Um das Paket mit Dart zu installieren, führe den folgenden Befehl aus:
@@ -3562,6 +3588,7 @@ owner.settings.chef.keypair.description=Ein Schlüsselpaar ist notwendig, um mit
rpm.repository = Repository-Info
rpm.repository.multiple_groups = Dieses Paket ist in mehreren Gruppen verfügbar.
rpm.repository.architectures = Architekturen
+owner.settings.cargo.rebuild.no_index = Kann nicht erneut erzeugen, es wurde kein Index initialisiert.
[secrets]
secrets=Secrets
@@ -3576,7 +3603,7 @@ deletion=Secret entfernen
deletion.description=Das Entfernen eines Secrets kann nicht rückgängig gemacht werden. Fortfahren?
deletion.success=Das Secret wurde entfernt.
deletion.failed=Secret konnte nicht entfernt werden.
-management=Secret-Verwaltung
+management=Secrets verwalten
[actions]
actions=Actions
@@ -3593,7 +3620,7 @@ status.skipped=Übersprungen
status.blocked=Blockiert
runners=Runner
-runners.runner_manage_panel=Runner-Verwaltung
+runners.runner_manage_panel=Runner verwalten
runners.new=Neuen Runner erstellen
runners.new_notice=Wie man einen Runner startet
runners.status=Status
@@ -3650,7 +3677,7 @@ workflow.disabled=Workflow ist deaktiviert.
need_approval_desc=Um Workflows für den Pull-Request eines Forks auszuführen, ist eine Genehmigung erforderlich.
variables=Variablen
-variables.management=Variablenverwaltung
+variables.management=Variablen verwalten
variables.creation=Variable hinzufügen
variables.none=Es gibt noch keine Variablen.
variables.deletion=Variable entfernen
diff --git a/options/locale/locale_el-GR.ini b/options/locale/locale_el-GR.ini
index 129ade8946..7d43c83cc3 100644
--- a/options/locale/locale_el-GR.ini
+++ b/options/locale/locale_el-GR.ini
@@ -17,34 +17,34 @@ page=Σελίδα
template=Πρότυπο
language=Γλώσσα
notifications=Ειδοποιήσεις
-active_stopwatch=Ενεργή Καταγραφή Χρόνου
-tracked_time_summary=Περίληψη του χρόνου παρακολούθησης με βάση τα φίλτρα της λίστας ζητημάτων
+active_stopwatch=Ενεργή καταγραφή χρόνου
+tracked_time_summary=Περίληψη του χρόνου παρακολούθησης βάσει των φίλτρων της λίστας ζητημάτων
create_new=Δημιουργία…
user_profile_and_more=Προφίλ και ρυθμίσεις…
signed_in_as=Συνδεδεμένος ως
enable_javascript=Απαιτείται JavaScript για να εμφανιστεί αυτή η ιστοσελίδα.
toc=Πίνακας Περιεχομένων
-licenses=Άδειες
+licenses=Άδειες Χρήσης
return_to_gitea=Επιστροφή στο Forgejo
-username=Όνομα Χρήστη
-email=Διεύθυνση ηλεκτρονικού ταχυδρομείου (email)
+username=Όνομα χρήστη
+email=Διεύθυνση email
password=Κωδικός πρόσβασης
-access_token=Διακριτικό Πρόσβασης
-re_type=Επιβεβαίωση Κωδικού Πρόσβασης
+access_token=Διακριτικό πρόσβασης
+re_type=Επιβεβαίωση κωδικού
captcha=CAPTCHA
-twofa=Έλεγχος Ταυτότητας Δύο Παραγόντων
-twofa_scratch=Κωδικός Μίας Χρήσης Δύο Παραγόντων
+twofa=Πιστοποίηση Δύο Παραγόντων
+twofa_scratch=Κωδικός μίας χρήσης (για πιστοποίηση δύο παραγόντων / 2FA)
passcode=Κωδικός
webauthn_insert_key=Εισάγετε το κλειδί ασφαλείας σας
-webauthn_sign_in=Πατήστε το κουμπί πάνω στο κλειδί ασφαλείας. Αν το κλειδί ασφαλείας σας δεν έχει κουμπί, αποσυνδέστε το και συνδέστε το ξανά.
+webauthn_sign_in=Πατήστε το κουμπί στο κλειδί ασφαλείας σας. Αν το κλειδί ασφαλείας σας δεν έχει κουμπί, αποσυνδέστε το και συνδέστε το ξανά.
webauthn_press_button=Παρακαλώ πατήστε το κουμπί στο κλειδί ασφαλείας…
webauthn_use_twofa=Χρησιμοποιήστε έναν κωδικό δύο παραγόντων από το τηλέφωνό σας
-webauthn_error=Αδύνατη η ανάγνωση του κλειδιού ασφαλείας.
+webauthn_error=Δεν ήταν δυνατή η επικοινωνία με το κλειδί ασφαλείας σας.
webauthn_unsupported_browser=Το πρόγραμμα περιήγησής σας δεν υποστηρίζει επί του παρόντος WebAuthn.
webauthn_error_unknown=Παρουσιάστηκε ένα άγνωστο σφάλμα. Παρακαλώ προσπαθήστε ξανά.
-webauthn_error_insecure=`Το WebAuthn υποστηρίζει μόνο ασφαλείς συνδέσεις. Για δοκιμές πάνω από HTTP, μπορείτε να χρησιμοποιήσετε την προέλευση "localhost" ή "127.0.0.1"`
+webauthn_error_insecure=Το WebAuthn υποστηρίζει μόνο ασφαλές συνδέσεις. Για την διεξαγωγή δοκιμών μέσω HTTP, μπορείτε να χρησιμοποιήσετε την προέλευση «localhost» ή «127.0.0.1»
webauthn_error_unable_to_process=Ο διακομιστής δεν μπόρεσε να επεξεργαστεί το αίτημά σας.
webauthn_error_duplicated=Το κλειδί ασφαλείας δεν επιτρέπεται για αυτό το αίτημα. Βεβαιωθείτε ότι το κλειδί δεν έχει ήδη καταχωρηθεί.
webauthn_error_empty=Πρέπει να ορίσετε ένα όνομα για αυτό το κλειδί.
@@ -66,7 +66,7 @@ admin_panel=Διαχείριση
account_settings=Ρυθμίσεις Λογαριασμού
settings=Ρυθμίσεις
your_profile=Προφίλ
-your_starred=Με αστέρι
+your_starred=Αγαπημένα
your_settings=Ρυθμίσεις
all=Όλα
@@ -80,17 +80,17 @@ pull_requests=Pull Requests
issues=Ζητήματα
milestones=Ορόσημα
-ok=OK
+ok=Εντάξει
cancel=Ακύρωση
-retry=Επανάληψη
+retry=Επαναπροσπάθεια
rerun=Επανεκτέλεση
rerun_all=Επανεκτέλεση όλων
save=Αποθήκευση
add=Προσθήκη
add_all=Προσθήκη Όλων
remove=Αφαίρεση
-remove_all=Αφαίρεση Όλων
-remove_label_str=`Αφαίρεση του αντικειμένου "%s"`
+remove_all=Αφαίρεση όλων
+remove_label_str=Αφαίρεση αντικειμένου «%s»
edit=Επεξεργασία
view=Προβολή
@@ -135,12 +135,25 @@ concept_user_organization=Οργανισμός
show_timestamps=Εμφάνιση χρονοσημάνσεων
show_log_seconds=Εμφάνιση δευτερολέπτων
show_full_screen=Εμφάνιση πλήρους οθόνης
-download_logs=Λήψη καταγραφών
+download_logs=Λήψη αρχείων καταγραφής
-confirm_delete_selected=Επιβεβαιώνετε τη διαγραφή όλων των επιλεγμένων στοιχείων;
+confirm_delete_selected=Είστε βέβαιοι πως θέλετε να διαγράψετε όλα τα επιλεγμένα στοιχεία;
name=Όνομα
value=Τιμή
+toggle_menu = Μενού
+confirm_delete_artifact = Είστε βέβαιοι πως θέλετε να διαγράψετε το προϊόν «%s»;
+filter = Φίλτρο
+filter.is_archived = Αρχειοθετημένο
+filter.clear = Απενεργοποίηση φίλτρου
+filter.not_archived = Μη αρχειοθετημένο
+filter.is_template = Πρότυπο
+filter.public = Δημόσιο
+filter.private = Ιδιωτικό
+filter.not_fork = Εξαίρεση Fork
+filter.is_mirror = Είδωλα
+filter.not_mirror = Εξαίρεση Ειδώλων
+filter.not_template = Εξαίρεση Προτύπων
[aria]
navbar=Γραμμή Πλοήγησης
@@ -150,7 +163,7 @@ footer.links=Συνδέσεις
[heatmap]
number_of_contributions_in_the_last_12_months=%s συνεισφορές τους τελευταίους 12 μήνες
-no_contributions=Χωρίς συνεισφορές
+contributions_zero=Χωρίς συνεισφορές
less=Λιγότερα
more=Περισσότερα
@@ -176,34 +189,35 @@ string.desc=Z - A
[error]
occurred=Παρουσιάστηκε ένα σφάλμα
-report_message=Αν πιστεύετε ότι αυτό είναι ένα πρόβλημα στο Gitea, παρακαλούμε αναζητήστε ζητήματα στο GitHub ή ανοίξτε ένα νέο ζήτημα εάν είναι απαραίτητο.
+report_message=Αν πιστεύετε ότι αυτό προέκυψε λόγω κάποιου σφάλματος στο Forgejo, σας παρακαλούμε να αναζητήσετε τα ζητήματα στο Codeberg ή να ανοίξετε ένα νέο ζήτημα εάν είναι απαραίτητο.
missing_csrf=Bad Request: δεν υπάρχει διακριτικό CSRF
invalid_csrf=Λάθος Αίτημα: μη έγκυρο διακριτικό CSRF
not_found=Ο προορισμός δεν βρέθηκε.
network_error=Σφάλμα δικτύου
+server_internal = Σφάλμα Διακομιστή
[startpage]
app_desc=Μια ανώδυνη, αυτο-φιλοξενούμενη υπηρεσία Git
-install=Εύκολο στην εγκατάσταση
-install_desc=Απλά εκτελέστε το αρχείο προγράμματος για την πλατφόρμα σας, χρήσιμοποιήστε το με το Docker, ή εγκαταστήστε το πακέτο.
-platform=Πολυπλατφορμικό
+install=Εύκολη εγκατάσταση
+install_desc=Απλά τρέξε το αρχείο που αντιστοιχεί στην πλατφόρμα σου, εγκατέστησε το με το Docker ή χρησιμοποίησε ένα πακέτο λογισμικού.
+platform=Τρέχει παντού
platform_desc=Το Forgejo τρέχει σε όλα τα συστήματα που υποστηρίζει η γλώσσα Go, όπως: Windows, macOS, Linux, ARM, κλπ. Διάλεξε αυτό που αγαπάς!
lightweight=Ελαφρύ
-lightweight_desc=Forgejo έχει χαμηλές ελάχιστες απαιτήσεις και μπορεί να τρέξει σε ένα οικονομικό Raspberry Pi. Εξοικονομήστε ενέργεια!
+lightweight_desc=Το Forgejo έχει ελάχιστες απαιτήσεις, μπορείς και να το τρέξεις σε ένα φτηνό Raspberry Pi. Εξοικονόμησε ενέργεια!
license=Ανοικτού κώδικα
-license_desc=Κατεβάστε το Forgejo! Ελάτε μαζί μας και συνεισφέρετε για να κάνετε αυτό το έργο ακόμα καλύτερο. Δεν είναι ντροπή να συνεισφέρετε!
+license_desc=Κατέβασε το Forgejo! Επίσης, μπορείς να μας βοηθήσεις να το βελτιώσουμε με τις συνεισφορές σου. Χωρίς ντροπή!
[install]
install=Εγκατάσταση
-title=Αρχικές Ρυθμίσεις
-docker_helper=Αν εκτελέσετε το Forgejo μέσα στο Docker, παρακαλώ διαβάστε την τεκμηρίωση πριν αλλάξετε τις ρυθμίσεις.
+title=Αρχικές ρυθμίσεις
+docker_helper=Αν εκτελέσετε το Forgejo μέσα στο Docker, παρακαλώ διαβάστε το εγχειρίδιο πριν αλλάξετε τις ρυθμίσεις.
require_db_desc=Το Forgejo απαιτεί MySQL, PostgreSQL, MSSQL, SQLite3 ή TiDB (με πρωτόκολλο MySQL).
-db_title=Ρυθμίσεις Βάσης Δεδομένων
-db_type=Τύπος της Βάσης Δεδομένων
+db_title=Ρυθμίσεις βάσης δεδομένων
+db_type=Είδος βάσης δεδομένων
host=Διακομιστής
user=Όνομα Χρήστη
password=Συνθηματικό
-db_name=Όνομα Βάσης Δεδομένων
+db_name=Όνομα βάσης Δδδομένων
db_schema=Σχήμα
db_schema_helper=Αφήστε κενό για την προεπιλογή της βάσης δεδομένων ("public").
ssl_mode=SSL
@@ -222,91 +236,95 @@ err_admin_name_is_reserved=Το Όνομα χρήστη του Διαχειρι
err_admin_name_pattern_not_allowed=Το Όνομα χρήστη του Διαχειριστή δεν είναι έγκυρο, ταιριάζει σε μια δεσμευμένη μορφή
err_admin_name_is_invalid=Το Όνομα Χρήστη του Διαχειριστή δεν είναι έγκυρο
-general_title=Γενικές Ρυθμίσεις
-app_name=Τίτλος Ιστοτόπου
+general_title=Γενικές ρυθμίσεις
+app_name=Όνομα διακομιστή
app_name_helper=Μπορείτε να εισάγετε το όνομα της εταιρείας σας εδώ.
-repo_path=Ριζική Διαδρομή Αποθετηρίου
+repo_path=Τοποθεσία αρχείων αποθετηρίων
repo_path_helper=Τα απομακρυσμένα αποθετήρια Git θα αποθηκεύονται σε αυτόν τον κατάλογο.
-lfs_path=Ριζική Διαδρομή Git LFS
+lfs_path=Τοποθεσία αρχείων Git LFS
lfs_path_helper=Τα αρχεία που παρακολουθούνται από το Git LFS θα αποθηκεύονται σε αυτόν τον φάκελο. Αφήστε κενό για να το απενεργοποιήσετε.
-run_user=Εκτέλεση Σαν Χρήστη
-run_user_helper=Το όνομα του χρήστη του λειτουργικού συστήματος ο οποίος εκτελεί το Gitea. Επισημαίνεται ότι αυτός ο χρήστης πρέπει να έχει πρόσβαση στο ριζικό φάκελο του αποθετηρίου.
-domain=Domain Διακομιστή
+run_user=Εκτέλεση ως
+run_user_helper=Το όνομα του χρήστη στο λειτουργικό σας σύστημα που εκτελεί το Forgejo. Επισημαίνεται ότι αυτός ο χρήστης πρέπει να έχει πρόσβαση στον φάκελο που περιέχει όλα τα αποθετηρία.
+domain=Domain διακομιστή
domain_helper=Όνομα domain διακομιστή ή η διεύθυνση του.
-ssh_port=Θύρα της υπηρεσίας SSH
-ssh_port_helper=Αριθμός θύρας που ακούει η υπηρεσία SSH. Αφήστε κενό για να το απενεργοποιήσετε.
-http_port=Η HTTP θύρα που ακούει το Forgejo
-http_port_helper=Αριθμός θύρας που θα ακούει η υπηρεσία web του Forgejo.
-app_url=Βασικό URL του Forgejo
+ssh_port=Θύρα υπηρεσίας SSH
+ssh_port_helper=Αριθμός θύρας στην οποία θα «ακούει» η υπηρεσία SSH. Αφήστε το πεδίο κενό για να την απενεργοποιήσετε.
+http_port=Θύρα υπηρεσίας HTTP
+http_port_helper=Αριθμός θύρας στην οποία θα «ακούει» η web υπηρεσία του Forgejo. Αφήστε το πεδίο κενό για να την απενεργοποιήσετε.
+app_url=Βασικό URL
app_url_helper=Βασική Διεύθυνση για τα URL κλωνοποίησης μέσω HTTP(S) και για τις ειδοποιήσεις μέσω email.
-log_root_path=Διαδρομή Αρχείων Καταγραφής
+log_root_path=Τοποθεσία αρχείων καταγραφής
log_root_path_helper=Τα αρχεία καταγραφής θα γράφονται σε αυτόν τον κατάλογο.
-optional_title=Προαιρετικές Ρυθμίσεις
-email_title=Ρυθμίσεις Email
+optional_title=Προαιρετικές ρυθμίσεις
+email_title=Ρυθμίσεις email
smtp_addr=Διακομιστής SMTP
smtp_port=Θύρα SMTP
-smtp_from=Αποστολή Email Ως
+smtp_from=Αποστολή email ως
smtp_from_helper=Η διεύθυνση email που θα χρησιμοποιεί το Forgejo. Εισάγετε μια απλή διεύθυνση ηλεκτρονικού ταχυδρομείου ή χρησιμοποιήστε τη μορφή "Όνομα" .
-mailer_user=Όνομα Χρήστη SMTP
+mailer_user=Όνομα χρήστη SMTP
mailer_password=Κωδικός SMTP
-register_confirm=Απαιτείται Επιβεβαίωση της Διεύθυνσης Εmail για Εγγραφή
-mail_notify=Ενεργοποίηση Ειδοποιήσεων με Email
-server_service_title=Ρυθμίσεις Διακομιστή και Υπηρεσιών Τρίτων
-offline_mode=Ενεργοποίηση Τοπικής Λειτουργίας
+register_confirm=Να απαιτείται η επιβεβαίωση της διεύθυνσης email για την δημιουργία λογαριασμού
+mail_notify=Ενεργοποίηση ειδοποιήσεων email
+server_service_title=Ρυθμίσεις διακομιστή και υπηρεσιών τρίτων
+offline_mode=Ενεργοποίηση τοπικής λειτουργίας
offline_mode_popup=Απενεργοποιήση των δικτύων διανομής περιεχομένου τρίτων και σερβίρετε όλων των πόρων τοπικά.
disable_gravatar=Απενεργοποίηση Gravatar
disable_gravatar_popup=Απενεργοποιήση του Gravatar και των εξωτερικών πηγών avatar. Θα χρησιμοποιηθεί ένα προεπιλεγμένο avatar εκτός αν ένας χρήστης ανεβάσει τοπικά ένα avatar.
-federated_avatar_lookup=Ενεργοποίηση Ομόσπονδων Avatars
+federated_avatar_lookup=Ενεργοποίηση αποκεντρωμένων avatars
federated_avatar_lookup_popup=Ενεργοποίηση ομόσπονδης αναζήτησης avatar χρησιμοποιώντας το Libravatar.
-disable_registration=Απενεργοποίηση Αυτοεγγραφής
+disable_registration=Απενεργοποίηση αυτοεγγραφής
disable_registration_popup=Απενεργοποίηση αυτοεγγραφής χρήστη. Μόνο οι διαχειριστές θα μπορούν να δημιουργήσουν νέους λογαριασμούς χρηστών.
-allow_only_external_registration_popup=Να Επιτρέπεται Η Εγγραφή Μόνο Μέσω Εξωτερικών Υπηρεσιών
-openid_signin=Ενεργοποίηση Σύνδεσης μέσω OpenID
+allow_only_external_registration_popup=Να επιτρέπεται η εγγραφή μόνο μέσω εξωτερικών υπηρεσιών
+openid_signin=Ενεργοποίηση σύνδεσης μέσω OpenID
openid_signin_popup=Ενεργοποίηση σύνδεσης χρήστη μέσω OpenID.
-openid_signup=Ενεργοποίηση Ιδιοεγγραφής μέσω OpenID
+openid_signup=Ενεργοποίηση εγγραφών μέσω OpenID
openid_signup_popup=Ενεργοποίηση ιδιοεγγραφής χρηστών με βάση το OpenID.
enable_captcha=Ενεργοποίηση CAPTCHA στην εγγραφή
-enable_captcha_popup=Απαιτείται ένα CAPTCHA για τη ιδιοεγγραφή του χρήστη.
-require_sign_in_view=Απαιτείται Είσοδος για τη Προβολή Σελίδων
+enable_captcha_popup=Να απαιτείται CAPTCHA για την δημιουργία λογαριασμού.
+require_sign_in_view=Να απαιτείται είσοδος για την προβολή περιεχομένων
require_sign_in_view_popup=Περιορισμός της πρόσβασης σε συνδεδεμένους χρήστες. Οι επισκέπτες θα μπορούν μόνο να δουν τις σελίδες εισόδου και εγγραφής.
admin_setting_desc=Η δημιουργία ενός λογαριασμού διαχειριστή είναι προαιρετική. Ο πρώτος εγγεγραμμένος χρήστης θα γίνει αυτόματα διαχειριστής.
-admin_title=Ρυθμίσεις Λογαριασμού Διαχειριστή
-admin_name=Όνομα Χρήστη Διαχειριστή
+admin_title=Ρυθμίσεις λογαριασμού διαχειριστή
+admin_name=Όνομα χρήστη διαχειριστή
admin_password=Κωδικός Πρόσβασης
-confirm_password=Επιβεβαίωση Κωδικού Πρόσβασης
-admin_email=Διεύθυνση Email
+confirm_password=Επιβεβαίωση κωδικού
+admin_email=Διεύθυνση email
install_btn_confirm=Εγκατάσταση Forgejo
-test_git_failed=Αδυναμία δοκιμής της εντολής 'git': %v
-sqlite3_not_available=Αυτή η έκδοση Forgejo δεν υποστηρίζει την SQLite3. Παρακαλώ κατεβάστε την επίσημη δυαδική έκδοση από το %s (όχι την έκδοση 'gobuild').
+test_git_failed=Αδυναμία δοκιμής της εντολής «git»: %v
+sqlite3_not_available=Αυτή η έκδοση του Forgejo δεν υποστηρίζει την SQLite3. Παρακαλώ κατεβάστε την επίσημη έκδοση από το %s (όχι την έκδοση «gobuild»).
invalid_db_setting=Οι ρυθμίσεις της βάσης δεδομένων δεν είναι έγκυρες: %v
-invalid_db_table=Ο πίνακας βάσης δεδομένων "%s" δεν είναι έγκυρος: %v
+invalid_db_table=Ο πίνακας βάσης δεδομένων «%s» δεν είναι έγκυρος: %v
invalid_repo_path=Η αρχική διαδρομή των αποθετηρίων δεν είναι έγκυρη: %v
invalid_app_data_path=Η διαδρομή δεδομένων εφαρμογής (app data) δεν είναι έγκυρη: %v
-run_user_not_match=Το όνομα χρήστη 'εκτέλεση ως' δεν είναι το τρέχον όνομα χρήστη: %s -> %s
+run_user_not_match=Το όνομα χρήστη «Εκτέλεση ως» δεν είναι το τρέχον όνομα χρήστη: %s -> %s
internal_token_failed=Αποτυχία δημιουργίας εσωτερικού διακριτικού: %v
secret_key_failed=Αποτυχία δημιουργίας μυστικού κλειδιού: %v
save_config_failed=Αποτυχία αποθήκευσης ρυθμίσεων: %v
invalid_admin_setting=Η ρύθμιση λογαριασμού διαχειριστή δεν είναι έγκυρη: %v
-invalid_log_root_path=Η διαδρομή της καταγραφής δεν είναι έγκυρη: %v
+invalid_log_root_path=Η τοποθεσία αρχείων καταγραφής δεν είναι έγκυρη: %v
default_keep_email_private=Απόκρυψη διευθύνσεων email από προεπιλογή
default_keep_email_private_popup=Απόκρυψη διευθύνσεων email των νέων λογαριασμών χρήστη σαν προεπιλογή.
-default_allow_create_organization=Να επιτρέπεται η δημιουργία οργανισμών σαν προεπιλογή
+default_allow_create_organization=Να επιτρέπεται η δημιουργία οργανισμών από προεπιλογή
default_allow_create_organization_popup=Επιτρέψτε σε νέους λογαριασμούς χρηστών να δημιουργούν οργανισμούς σαν προεπιλογή.
-default_enable_timetracking=Ενεργοποίηση Καταγραφής Χρόνου σαν Προεπιλογή
+default_enable_timetracking=Ενεργοποίηση καταγραφής χρόνου από προεπιλογή
default_enable_timetracking_popup=Ενεργοποίηση καταγραφής χρόνου για νέα αποθετήρια σαν προεπιλογή.
-no_reply_address=Κρυφό Όνομα Τομέα Email
-no_reply_address_helper=Όνομα τομέα για χρήστες με μια κρυφή διεύθυνση email. Για παράδειγμα, το όνομα χρήστη 'nikos' θα συνδεθεί στο Git ως 'nikos@noreply.example.org' αν ο κρυφός τομέας email έχει οριστεί ως 'noreply.example.org'.
-password_algorithm=Αλγόριθμος Hash Κωδικού Πρόσβασης
+no_reply_address=Domain κρυφών email
+no_reply_address_helper=Όνομα τομέα (domain) για χρήστες με μια κρυφή διεύθυνση email. Για παράδειγμα, το όνομα χρήστη 'nikos' θα συνδεθεί στο Git ως 'nikos@noreply.example.org' αν ο κρυφός τομέας email έχει οριστεί ως 'noreply.example.org'.
+password_algorithm=Αλγόριθμος hash για κωδικούς
invalid_password_algorithm=Μη έγκυρος αλγόριθμος κωδικού πρόσβασης
password_algorithm_helper=Ορίστε τον αλγόριθμο κατακερματισμού για το κωδικό πρόσβασης. Οι αλγόριθμοι διαφέρουν σε απαιτήσεις και αντοχή. Ο αλγόριθμος argon2 είναι αρκετά ασφαλής, αλλά χρησιμοποιεί πολλή μνήμη και μπορεί να είναι ακατάλληλος για μικρά συστήματα.
-enable_update_checker=Ενεργοποίηση Ελεγκτή Ενημερώσεων
+enable_update_checker=Ενεργοποίηση ελέγχου ενημερώσεων
enable_update_checker_helper=Ελέγχει περιοδικά για νέες εκδόσεις κάνοντας σύνδεση στο gitea.io.
env_config_keys=Ρυθμίσεις Περιβάλλοντος
env_config_keys_prompt=Οι ακόλουθες μεταβλητές περιβάλλοντος θα εφαρμοστούν επίσης στο αρχείο ρυθμίσεων σας:
+allow_dots_in_usernames = Επιτρέπει την χρήση τελείων σε ονόματα χρηστών. Δεν θα επηρεαστούν λογαριασμοί που ήδη υπάρχουν.
+enable_update_checker_helper_forgejo = Θα γίνεται τακτικά έλεγχος για νέες εκδόσεις του Forgejo ελέγχοντας μία εγγραφή DNS TXT στο release.forgejo.org.
+smtp_from_invalid = Η διεύθυνση του πεδίου «Αποστολή email ως» δεν είναι έγκυρη
+config_location_hint = Αυτές οι ρυθμίσεις θα αποθηκευτούν στην ακόλουθη τοποθεσία:
[home]
-uname_holder=Όνομα Χρήστη ή Διεύθυνση Email
+uname_holder=Όνομα χρήστη ή διεύθυνση email
password_holder=Κωδικός Πρόσβασης
switch_dashboard_context=Εναλλαγή Περιεχομένων Αρχικού Πίνακα
my_repos=Αποθετήρια
@@ -318,7 +336,7 @@ view_home=Προβολή %s
search_repos=Βρείτε ένα αποθετήριο…
filter=Άλλα Φίλτρα
filter_by_team_repositories=Φιλτράρισμα ανά αποθετήρια ομάδας
-feed_of=`Τροφοδοσία του "%s"`
+feed_of=Ροή (feed) του «%s»
show_archived=Αρχειοθετήθηκε
show_both_archived_unarchived=Εμφάνιση και αρχειοθετημένων και μη αρχειοθετημένων
@@ -340,63 +358,63 @@ search=Αναζήτηση
go_to=Μετάβαση σε
code=Κώδικας
search.type.tooltip=Τύπος αναζήτησης
-search.fuzzy=Fuzzy
+search.fuzzy=Όμοιο
search.fuzzy.tooltip=Συμπερίληψη και των αποτελεσμάτων που είναι πλησιέστερα με τον όρο αναζήτησης
search.match=Ταίριασμα
search.match.tooltip=Συμπερίληψη μόνο των αποτελεσμάτων που ταιριάζουν ακριβώς με τον όρο αναζήτησης
code_search_unavailable=Η αναζήτηση κώδικα δεν είναι διαθέσιμη αυτή τη στιγμή. Παρακαλώ επικοινωνήστε με το διαχειριστή.
-repo_no_results=Δεν βρέθηκαν αποθετήρια που να ταιρίαζουν με τα κριτήρια.
+repo_no_results=Δεν βρέθηκαν σχετικά αποθετήρια.
user_no_results=Δεν βρέθηκαν χρήστες που να ταιριάζουν με τα κριτήρια.
org_no_results=Δεν βρέθηκαν οργανισμοί που να ταιριάζουν με τα κριτήρια.
code_no_results=Δεν βρέθηκε πηγαίος κώδικας που να ταιριάζει με τον όρο αναζήτησης.
-code_search_results=`Αποτελέσματα αναζήτησης για "%s"`
-code_last_indexed_at=Τελευταίο δημιουργία ευρετηρίου στις %s
+code_search_results=`Αποτελέσματα για «%s»`
+code_last_indexed_at=Τελευταία δημιουργία ευρετηρίου: %s
relevant_repositories_tooltip=Τα αποθετήρια που είναι forks ή που δεν έχουν θέμα, εικονίδιο και περιγραφή είναι κρυμμένα.
-relevant_repositories=Εμφανίζονται μόνο τα σχετικά αποθετήρια, εμφάνιση χωρίς φίλτρο.
+relevant_repositories=Εμφανίζονται μόνο αποθετήρια που θεωρούμε «σχετικά» για εσάς. Εμφάνιση αποτελεσμάτων χωρίς φίλτρο.
[auth]
-create_new_account=Εγγραφή Λογαριασμού
+create_new_account=Δημιουργία Λογαριασμού
register_helper_msg=Έχετε ήδη λογαριασμό; Συνδεθείτε τώρα!
social_register_helper_msg=Έχετε ήδη λογαριασμό; Συνδέστε το τώρα!
-disable_register_prompt=Η εγγραφή είναι απενεργοποιημένη. Παρακαλούμε επικοινωνήστε με το διαχειριστή του ιστοτόπου.
-disable_register_mail=Η Επιβεβαίωση email για την εγγραφή είναι απενεργοποιημένη.
+disable_register_prompt=Οι εγγραφές είναι απενεργοποιημένες. Παρακαλούμε να επικοινωνήσετε με το διαχειριστή του ιστοτόπου.
+disable_register_mail=Η επιβεβαίωση email κατά την εγγραφή είναι απενεργοποιημένη.
manual_activation_only=Επικοινωνήστε με το διαχειριστή της υπηρεσίας για να ολοκληρώσετε την ενεργοποίηση.
-remember_me=Απομνημόνευση αυτής της συσκευής
-remember_me.compromised=Το διακριτικό σύνδεσης δεν είναι πλέον έγκυρο, αυτό ίσως υποδεικνύει έναν κλεμμένο λογαριασμό. Παρακαλώ ελέγξτε το λογαριασμό σας για ασυνήθιστες δραστηριότητες.
-forgot_password_title=Ξέχασα Τον Κωδικό Πρόσβασης
-forgot_password=Ξεχάσατε τον κωδικό πρόσβασης;
+remember_me=Θέλω να παραμείνω συνδεδεμένος
+remember_me.compromised=Το διακριτικό σύνδεσης δεν είναι πλέον έγκυρο, αυτό ίσως υποδεικνύει έναν κλεμμένο λογαριασμό. Παρακαλώ ελέγξτε τον λογαριασμό σας για ασυνήθιστες δραστηριότητες.
+forgot_password_title=Ξέχασα τον κωδικό μου
+forgot_password=Ξεχάσατε τον κωδικό σας;
sign_up_now=Χρειάζεστε λογαριασμό; Εγγραφείτε τώρα.
sign_up_successful=Ο λογαριασμός δημιουργήθηκε επιτυχώς. Καλώς ορίσατε!
-confirmation_mail_sent_prompt=Ένα νέο email επιβεβαίωσης έχει σταλεί στο %s. Παρακαλώ ελέγξτε τα εισερχόμενα σας μέσα στις επόμενες %s για να ολοκληρώσετε τη διαδικασία εγγραφής.
+confirmation_mail_sent_prompt=Ένα νέο email επιβεβαίωσης έχει σταλεί στην διεύθυνση %s. Για την ολοκλήρωση της εγγραφής σας, παρακαλώ ελέγξτε τα εισερχόμενα σας μέσα στις επόμενες %s.
must_change_password=Ενημερώστε τον κωδικό πρόσβασης σας
allow_password_change=Απαιτείται από το χρήστη να αλλάξει τον κωδικό πρόσβασης (συνιστόμενο)
-reset_password_mail_sent_prompt=Ένα email επιβεβαίωσης έχει σταλεί στο %s. Παρακαλώ ελέγξτε τα εισερχόμενα σας στις επόμενες %s για να ολοκληρώσετε τη διαδικασία ανάκτησης λογαριασμού.
+reset_password_mail_sent_prompt=Ένα email επιβεβαίωσης έχει σταλεί στο %s. Για την ολοκλήρωση της διαδικασίας ανάκτησης του λογαριασμού σας, παρακαλώ ελέγξτε τα εισερχόμενα σας στις επόμενες %s.
active_your_account=Ενεργοποιήστε Το Λογαριασμό Σας
account_activated=Ο λογαριασμός έχει ενεργοποιηθεί
prohibit_login=Απαγορεύεται η Σύνδεση
-prohibit_login_desc=Ο λογαριασμός σας δεν επιτρέπεται να συνδεθεί, παρακαλούμε επικοινωνήστε με το διαχειριστή σας.
+prohibit_login_desc=Δεν επιτρέπεται η σύνδεση στον λογαριασμό σας, παρακαλούμε επικοινωνήστε με το διαχειριστή σας.
resent_limit_prompt=Έχετε ήδη ζητήσει ένα email ενεργοποίησης πρόσφατα. Παρακαλώ περιμένετε 3 λεπτά και προσπαθήστε ξανά.
-has_unconfirmed_mail=Γεια σας %s, έχετε μια ανεπιβεβαίωτη διεύθυνση ηλεκτρονικού ταχυδρομείου (%s). Εάν δεν έχετε λάβει email επιβεβαίωσης ή χρειάζεται να αποστείλετε εκ νέου ένα νέο, παρακαλώ κάντε κλικ στο παρακάτω κουμπί.
+has_unconfirmed_mail=Γειά %s, η διεύθυνση ηλεκτρονικού ταχυδρομείου σας (%s) δεν έχει επιβεβαιωθεί ακόμα. Εάν δεν έχετε λάβει κάποιο email επιβεβαίωσης ή αν χρειάζεστε ένα νέο email επιβεβαίωσης, παρακαλώ πατήστε το παρακάτω κουμπί.
resend_mail=Κάντε κλικ εδώ για να στείλετε ξανά το email ενεργοποίησης
email_not_associate=Η διεύθυνση ηλεκτρονικού ταχυδρομείου δεν είναι συσχετισμένη με κάποιο λογαριασμό.
send_reset_mail=Αποστολή Email Ανάκτησης Λογαριασμού
reset_password=Ανάκτηση Λογαριασμού
invalid_code=Ο κωδικός επιβεβαίωσης δεν είναι έγκυρος ή έχει λήξει.
-invalid_code_forgot_password=Ο κωδικός επιβεβαίωσης δεν είναι έγκυρος ή έληξε. Πατήστε εδώ για να ξεκινήσετε νέα συνεδρία.
+invalid_code_forgot_password=Ο κωδικός επιβεβαίωσης έχει λήξει ή δεν είναι έγκυρος. Πατήστε εδώ για να ξαναξεκινήσετε την διαδικασία.
invalid_password=Ο κωδικός πρόσβασης σας δεν ταιριάζει με τον κωδικό που χρησιμοποιήθηκε για τη δημιουργία του λογαριασμού.
reset_password_helper=Ανάκτηση Λογαριασμού
-reset_password_wrong_user=Έχετε συνδεθεί ως %s, αλλά ο σύνδεσμος ανάκτησης λογαριασμού προορίζεται για το %s
+reset_password_wrong_user=Έχετε συνδεθεί με τον λογαριασμό %s, αλλά ο σύνδεσμος ανάκτησης λογαριασμού προορίζεται για τον λογαριασμό %s
password_too_short=Το μήκος του κωδικού πρόσβασης δεν μπορεί να είναι μικρότερο από %d χαρακτήρες.
non_local_account=Οι μη τοπικοί χρήστες δεν μπορούν να ενημερώσουν τον κωδικό πρόσβασής τους μέσω του διεπαφής web του Forgejo.
verify=Επαλήθευση
scratch_code=Κωδικός μιας χρήσης
use_scratch_code=Χρήση κωδικού μιας χρήσης
-twofa_scratch_used=Έχετε χρησιμοποιήσει τον κωδικό μιας χρήσης. Έχετε ανακατευθυνθεί στη σελίδα ρυθμίσεων δύο παραγόντων ώστε να μπορείτε να αφαιρέσετε την εγγραφή της συσκευής σας ή να δημιουργήσετε ένα νέο κωδικό μιας χρήσης.
+twofa_scratch_used=Χρησιμοποιήσατε τον κωδικό μιας χρήσης σας. Ανακατευθυνθήκατε στις ρυθμίσεις δύο παραγόντων για να αφαιρέσετε την συσκευή με την οποία ταυτοποιήστε κανονικά ή για να δημιουργήσετε έναν νέο κωδικό μιας χρήσης.
twofa_passcode_incorrect=Ο κωδικός σας είναι εσφαλμένος. Αν χάσατε τη συσκευή σας, χρησιμοποιήστε τον κωδικό μιας χρήσης για να συνδεθείτε.
twofa_scratch_token_incorrect=Ο κωδικός μιας χρήσης είναι εσφαλμένος.
login_userpass=Είσοδος
-login_openid=OpenID
-oauth_signup_tab=Εγγραφή Νέου Λογαριασμού
+tab_openid=OpenID
+oauth_signup_tab=Δημιουργία νέου λογαριασμού
oauth_signup_title=Ολοκλήρωση Νέου Λογαριασμού
oauth_signup_submit=Ολοκληρωμένος Λογαριασμός
oauth_signin_tab=Σύνδεση με υπάρχων λογαριασμό
@@ -410,86 +428,93 @@ openid_connect_title=Σύνδεση σε υπάρχων λογαριασμό
openid_connect_desc=Το επιλεγμένο OpenID URI είναι άγνωστο. Συνδέστε το με ένα νέο λογαριασμό εδώ.
openid_register_title=Δημιουργία νέου λογαριασμού
openid_register_desc=Το επιλεγμένο OpenID URI είναι άγνωστο. Συνδέστε το με ένα νέο λογαριασμό εδώ.
-openid_signin_desc=Εισάγετε το OpenID URI σας. Για παράδειγμα: alice.openid.example.org ή https://openid.example.org/alice.
-disable_forgot_password_mail=Η ανάκτηση λογαριασμού είναι απενεργοποιημένη επειδή δεν έχει οριστεί email. Παρακαλούμε επικοινωνήστε με το διαχειριστή.
-disable_forgot_password_mail_admin=Η ανάκτηση λογαριασμού είναι διαθέσιμη μόνο όταν έχει οριστεί το email. Παρακαλούμε ορίστει το email σας για να ενεργοποιήσετε την ανάκτηση λογαριασμού.
+openid_signin_desc=Εισάγετε το OpenID URI σας. Για παράδειγμα: ioanna.openid.example.org ή https://openid.example.org/grigoris.
+disable_forgot_password_mail=Ο λογαριασμός δεν μπορεί να ανακτηθεί επειδή δεν αντιστοιχείται κάποιο email με αυτόν τον λογαριασμό. Παρακαλούμε επικοινωνήστε με τον διαχειριστή σας.
+disable_forgot_password_mail_admin=Η ανάκτηση λογαριασμού είναι διαθέσιμη μόνο όταν έχει οριστεί το email. Παρακαλούμε ορίστε το email σας για να ενεργοποιήσετε την ανάκτηση λογαριασμού.
email_domain_blacklisted=Δεν μπορείτε να εγγραφείτε με τη διεύθυνση email σας.
authorize_application=Εξουσιοδότηση Εφαρμογής
authorize_redirect_notice=Θα μεταφερθείτε στο %s εάν εξουσιοδοτήσετε αυτήν την εφαρμογή.
authorize_application_created_by=Αυτή η εφαρμογή δημιουργήθηκε από %s.
authorize_application_description=Εάν παραχωρήσετε την πρόσβαση, θα μπορεί να έχει πρόσβαση και να γράφει σε όλες τις πληροφορίες του λογαριασμού σας, συμπεριλαμβανομένων των ιδιωτικών αποθετηρίων και οργανισμών.
-authorize_title=Εξουσιοδότηση του "%s" για έχει πρόσβαση στο λογαριασμό σας;
+authorize_title=Είστε βέβαιοι πως θέλετε να δώσετε πρόσβαση στον λογαριασμό σας στην εφαρμογή «%s»;
authorization_failed=Αποτυχία εξουσιοδότησης
authorization_failed_desc=Η εξουσιοδότηση απέτυχε επειδή εντοπίστηκε μια μη έγκυρη αίτηση. Παρακαλούμε επικοινωνήστε με το συντηρητή της εφαρμογής που προσπαθήσατε να εξουσιοδοτήσετε.
sspi_auth_failed=Αποτυχία ταυτοποίησης SSPI
-password_pwned=Ο κωδικός πρόσβασης που επιλέξατε είναι σε μια λίστα κλεμμένων κωδικών πρόσβασης που προηγουμένως εκτέθηκαν σε παραβίαση δημόσιων δεδομένων. Παρακαλώ δοκιμάστε ξανά με διαφορετικό κωδικό πρόσβασης και σκεφτείτε να αλλάξετε αυτόν τον κωδικό πρόσβασης όπου αλλού χρησιμοποιείται.
+password_pwned=Ο κωδικός πρόσβασης που επιλέξατε βρίσκεται σε μια λίστα κλεμμένων κωδικών πρόσβασης που προηγουμένως εκτέθηκαν σε παραβίαση δημόσιων δεδομένων. Παρακαλώ δοκιμάστε ξανά με διαφορετικό κωδικό πρόσβασης και σκεφτείτε να αλλάξετε αυτόν τον κωδικό πρόσβασης όπου αλλού χρησιμοποιείται.
password_pwned_err=Δεν ήταν δυνατή η ολοκλήρωση του αιτήματος προς το HaveIBeenPwned
+change_unconfirmed_email_error = Δεν ήταν δυνατή η αλλαγή της διεύθυνσης email: %v
+last_admin = Δεν μπορείτε να αφαιρέσετε τον μοναδικό διαχειριστή. Πρέπει να υπάρχει τουλάχιστον ένας διαχειριστής.
+change_unconfirmed_email = Αν έχετε εισάγει μία λανθασμένη διεύθυνση email κατά την εγγραφή σας, μπορείτε να την αλλάξετε παρακάτω, έτσι ώστε να σας σταλεί εκ νέου ένα νέο email επιβεβαίωσης στην νέα σας διεύθυνση.
+change_unconfirmed_email_summary = Αλλαγή της διεύθυνσης email στην οποία θα σταλεί το email επιβεβαίωσης.
[mail]
view_it_on=Δείτε το στο %s
reply=ή απαντήστε απευθείας σε αυτό το email
-link_not_working_do_paste=Δε λειτουργεί; Δοκιμάστε να το αντιγράψετε στο browser σας.
-hi_user_x=Γειά σου %s,
+link_not_working_do_paste=Δεν δουλεύει το link; Δοκιμάστε να το αντιγράψετε στην μπάρα διεύθυνσης (URL bar) του browser σας.
+hi_user_x=Γειά %s,
activate_account=Παρακαλώ ενεργοποιήστε το λογαριασμό σας
-activate_account.title=%s, παρακαλώ ενεργοποιήστε το λογαριασμό σας
+activate_account.title=%s, παρακαλώ ενεργοποιήστε τον λογαριασμό σας
activate_account.text_1=Γεια σας %[1]s, ευχαριστούμε για την εγγραφή στο %[2]s!
-activate_account.text_2=Παρακαλούμε κάντε κλικ στον παρακάτω σύνδεσμο για να ενεργοποιήσετε το λογαριασμό σας μέσα σε %s:
+activate_account.text_2=Για να ενεργοποιήσετε τον λογαριασμό σας, παρακαλώ πατήστε τον σύνδεσμο που ακολουθεί μέσα σε %s:
activate_email=Επιβεβαιώστε τη διεύθυνση email σας
-activate_email.title=%s, παρακαλώ επαληθεύστε τη διεύθυνση email σας
-activate_email.text=Παρακαλώ κάντε κλικ στον παρακάτω σύνδεσμο για να επαληθεύσετε τη διεύθυνση email σας στο %s:
+activate_email.title=%s, επαληθεύστε τη διεύθυνση email σας
+activate_email.text=Για να επαληθεύσετε τη διεύθυνση email σας, παρακαλώ πατήστε τον ακόλουθο σύνδεσμο μέσα σε %s:
register_notify=Καλώς ήλθατε στο Forgejo
-register_notify.title=%[1]s, καλώς ήρθατε στο %[2]s
-register_notify.text_1=αυτό είναι το email επιβεβαίωσης εγγραφής για το %s!
-register_notify.text_2=Τώρα μπορείτε να συνδεθείτε μέσω του ονόματος χρήστη: %s.
-register_notify.text_3=Εάν αυτός ο λογαριασμός έχει δημιουργηθεί για εσάς, παρακαλώ ορίστε πρώτα τον κωδικό πρόσβασής σας.
+register_notify.title=%[1]s, καλώς ήλθατε στο %[2]s
+register_notify.text_1=αυτό είναι το email επιβεβαίωσης εγγραφής σας για το %s!
+register_notify.text_2=Μπορείτε να συνδεθείτε χρησιμοποιώντας το όνομα χρήστη σας: %s
+register_notify.text_3=Εάν κάποιος άλλος δημιούργησε τον λογαριασμό για εσάς, παρακαλώ ορίστε πρώτα τον κωδικό πρόσβασής σας.
reset_password=Ανάκτηση του λογαριασμού σας
-reset_password.title=%s, ζητήσατε να ανακτήσετε το λογαριασμό σας
-reset_password.text=Κάντε κλικ στον παρακάτω σύνδεσμο για να ανακτήσετε το λογαριασμό σας εντός %s:
+reset_password.title=%s, λάβαμε ένα αίτημα ανάκτησης για τον λογαριασμό σας
+reset_password.text=Εφόσον το αίτημα δημιουργήθηκε από εσάς, πατήστε τον ακόλουθο σύνδεσμο για να ανακτήσετε το λογαριασμό σας μέσα σε %s:
-register_success=Επιτυχής εγγραφή
+register_success=Η εγγραφή ολοκληρώθηκε επιτυχώς
-issue_assigned.pull=@%[1]s σας έχει αναθέσει στο pull request %[2]s στο αποθετήριο %[3]s.
-issue_assigned.issue=@%[1]s σας ανέθεσε το ζήτημα %[2]s στο αποθετήριο %[3]s.
+issue_assigned.pull=Ο/Η @%[1]s σας έχει αναθέσει στο pull request %[2]s στο αποθετήριο %[3]s.
+issue_assigned.issue=Ο/Η @%[1]s σας ανέθεσε το ζήτημα %[2]s στο αποθετήριο %[3]s.
-issue.x_mentioned_you=@%s σας ανέφερε:
-issue.action.force_push=%[1]s έκανε force-push το %[2]s από %[3]s σε %[4]s.
-issue.action.push_1=@%[1]s έκανε push την υποβολή %[3]d στο %[2]s
-issue.action.push_n=@%[1]s έκανε push τις υποβολές %[3]d στο %[2]s
-issue.action.close=@%[1]s έκλεισε το #%[2]d.
-issue.action.reopen=@%[1]s άνοιξε ξανά το #%[2]d.
-issue.action.merge=@%[1]s συγχώνευσε το #%[2]d στο %[3]s.
+issue.x_mentioned_you=Ο/Η @%s σας ανέφερε:
+issue.action.force_push=Ο/Η %[1]s έκανε force-push το %[2]s από %[3]s σε %[4]s.
+issue.action.push_1=Ο/Η @%[1]s έκανε push την υποβολή %[3]d στο %[2]s
+issue.action.push_n=Ο/Η @%[1]s έκανε push τις υποβολές %[3]d στο %[2]s
+issue.action.close=Ο/Η @%[1]s έκλεισε το #%[2]d.
+issue.action.reopen=Ο/Η @%[1]s άνοιξε ξανά το #%[2]d.
+issue.action.merge=Ο/Η @%[1]s συγχώνευσε το #%[2]d στο %[3]s.
issue.action.approve=@%[1]s ενέκρινε αυτό το pull request.
issue.action.reject=@%[1]s ζήτησε αλλαγές σε αυτό το pull request.
issue.action.review=@%[1]s σχολίασε αυτό το pull request.
issue.action.review_dismissed=@%[1]s απέρριψε την τελευταία αναθεώρηση από %[2]s για αυτό το pull request.
-issue.action.ready_for_review=@%[1]s σημείωσε αυτό το pull request σαν έτοιμο για αναθεώρηση.
-issue.action.new=@%[1]s δημιούργησε το #%[2]d.
+issue.action.ready_for_review=Ο/Η @%[1]s επισήμανε πως αυτό το pull request είναι έτοιμο για αξιολόγηση.
+issue.action.new=Ο/Η @%[1]s δημιούργησε το #%[2]d.
issue.in_tree_path=Σε %s:
-release.new.subject=%s σε %s κυκλοφόρησε
-release.new.text=@%[1]s κυκλοφόρησε το %[2]s στο %[3]s
+release.new.subject=Κυκλοφόρησε νέα έκδοση %s του %s
+release.new.text=Ο/Η @%[1]s κυκλοφόρησε την έκδοση %[2]s στο %[3]s
release.title=Τίτλος: %s
release.note=Σημείωση:
release.downloads=Λήψεις:
-release.download.zip=Πηγαίος Κώδικας (Zip)
+release.download.zip=Πηγαίος Κώδικας (ZIP)
release.download.targz=Πηγαίος Κώδικας (TAR.GZ)
-repo.transfer.subject_to=%s θα ήθελε να μεταφέρει το "%s" σε %s
-repo.transfer.subject_to_you=`%s θα ήθελε να σας μεταφέρει το "%s"`
+repo.transfer.subject_to=Ο/Η %s θα ήθελε να μεταφέρει το αποθετήριο «%s» σε %s
+repo.transfer.subject_to_you=Ο/Η %s θα ήθελε να σας μεταφέρει το αποθετήριο «%s»
repo.transfer.to_you=εσάς
-repo.transfer.body=Για να το αποδεχτείτε ή να το απορρίψετε, επισκεφθείτε το %s ή απλά αγνοήστε το.
+repo.transfer.body=Για να αποδεχτείτε ή να απορρίψετε το αίτημα αυτό, επισκεφθείτε το %s ή απλά αγνοήστε το.
-repo.collaborator.added.subject=%s σας πρόσθεσε στο %s
-repo.collaborator.added.text=Έχετε προστεθεί ως συνεργάτης του αποθετηρίου:
+repo.collaborator.added.subject=Ο/Η %s σας πρόσθεσε στο %s ως συνεργάτη
+repo.collaborator.added.text=Είστε πλέον συνεργάτης στο αποθετήριο:
-team_invite.subject=%[1]s σας προσκάλεσε να συμμετέχετε στον οργανισμό %[2]s
-team_invite.text_1=%[1]s σας προσκάλεσε να συμμετέχετε στην ομάδα %[2]s στον οργανισμός %[3]s.
+team_invite.subject=Ο/Η %[1]s σας προσκάλεσε να συμμετέχετε στον οργανισμό %[2]s
+team_invite.text_1=Ο/Η %[1]s σας προσκάλεσε να συμμετέχετε στην ομάδα %[2]s του οργανισμού %[3]s.
team_invite.text_2=Παρακαλώ κάντε κλικ στον παρακάτω σύνδεσμο για να συμμετάσχετε στην ομάδα:
team_invite.text_3=Σημείωση: Αυτή η πρόσκληση προοριζόταν για %[1]s. Αν δεν περιμένατε αυτή την πρόσκληση, μπορείτε να αγνοήσετε αυτό το email.
+admin.new_user.text = Παρακαλώ πατήστε εδώ για να διαχειριστείτε τον χρήστη μέσω του πίνακα διαχειριστών.
+admin.new_user.subject = Εγγραφή νέου χρήστη %s
+admin.new_user.user_info = Πληροφορίες Χρήστη
[modal]
yes=Ναι
@@ -503,7 +528,7 @@ UserName=Όνομα Χρήστη
RepoName=Όνομα αποθετηρίου
Email=Διεύθυνση email
Password=Κωδικός πρόσβασης
-Retype=Επιβεβαίωση Κωδικού Πρόσβασης
+Retype=Επιβεβαίωση κωδικού
SSHTitle=Όνομα κλειδιού SSH
HttpsUrl=HTTPS URL
PayloadUrl=Payload URL
@@ -522,18 +547,18 @@ SSPISeparatorReplacement=Διαχωριστικό
SSPIDefaultLanguage=Προεπιλεγμένη Γλώσσα
require_error=` δεν μπορεί να είναι κενό.`
-alpha_dash_error=` πρέπει να περιέχει μόνο αλφαριθμητικά, παύλες ('-') και κάτω παύλες ('_').`
-alpha_dash_dot_error=` πρέπει να περιέχει μόνο αλφαριθμητικά, παύλα ('-'), κάτω παύλα ('_') και τελείες ('.').`
+alpha_dash_error=`: Πρέπει να περιέχει μόνο αλφαριθμητικά, παύλες ('-') και κάτω παύλες ('_').`
+alpha_dash_dot_error=`: Πρέπει να περιέχει μόνο αλφαριθμητικά, παύλα ('-'), κάτω παύλα ('_') και τελείες ('.').`
git_ref_name_error=` πρέπει να είναι ένα καλά διαμορφωμένο όνομα αναφοράς Git.`
size_error=`πρέπει να έχει μέγεθος %s.`
min_size_error=` πρέπει να περιέχει τουλάχιστον %s χαρακτήρες.`
max_size_error=` πρέπει να περιέχει το πολύ %s χαρακτήρες.`
email_error=` δεν είναι έγκυρη διεύθυνση email.`
-url_error=`Το "%s" δεν είναι ένα έγκυρο URL.`
-include_error=` πρέπει να περιέχει το μέρος "%s".`
+url_error=`Το «%s» δεν είναι ένα έγκυρο URL.`
+include_error=` πρέπει να περιέχει το μέρος «%s».`
glob_pattern_error=` το μοτίβο ταιριάσματος (glob) δεν είναι έγκυρο: %s.`
regex_pattern_error=` το μοτίβο regex δεν είναι έγκυρο: %s.`
-username_error=` μπορεί να περιέχει μόνο αλφαριθμητικούς χαρακτήρες ('0-9','a-z','A-Z'), παύλα ('-'), κάτω παύλα ('_') και τελεία ('.'). Δεν μπορεί να ξεκινά ή να τελειώνει με μη αλφαριθμητικούς χαρακτήρες, επίσης απαγορεύονται οι διαδοχικοί μη αλφαριθμητικοί χαρακτήρες.`
+username_error=`: Μπορεί να περιέχει μόνο αλφαριθμητικούς χαρακτήρες ('0-9','a-z','A-Z'), παύλα ('-'), κάτω παύλα ('_') και τελεία ('.'). Δεν μπορεί να αρχίζει ή να τελειώνει με μη αλφαριθμητικούς χαρακτήρες. Επίσης δεν επιτρέπεται η χρήση διαδοχικών μη αλφαριθμητικών χαρακτήρων.`
invalid_group_team_map_error=` η αντιστοίχιση δεν είναι έγκυρη: %s`
unknown_error=Άγνωστο σφάλμα:
captcha_incorrect=Ο κωδικός CAPTCHA είναι λάθος.
@@ -556,7 +581,7 @@ team_name_been_taken=Το όνομα της ομάδας χρησιμοποιε
team_no_units_error=Να επιτρέπεται η πρόσβαση σε τουλάχιστον μία ενότητα αποθετηρίου.
email_been_used=Η διεύθυνση email χρησιμοποιείται ήδη.
email_invalid=Η διεύθυνση email δεν είναι έγκυρη.
-openid_been_used=Η διεύθυνση OpenID "%s" χρησιμοποιείται ήδη.
+openid_been_used=Η διεύθυνση OpenID «%s» χρησιμοποιείται ήδη.
username_password_incorrect=Το όνομα χρήστη ή ο κωδικός πρόσβασης δεν είναι σωστά.
password_complexity=Ο κωδικός πρόσβασης δεν περνά τις απαιτήσεις πολυπλοκότητας:
password_lowercase_one=Τουλάχιστον ένα πεζό γράμμα
@@ -569,51 +594,61 @@ enterred_invalid_owner_name=Το όνομα νέου ιδιοκτήτη δεν
enterred_invalid_password=Ο κωδικός πρόσβασης που εισάγατε είναι λάθος.
user_not_exist=Δεν υπάρχει ο χρήστης.
team_not_exist=Δεν υπάρχει η ομάδα.
-last_org_owner=Δεν μπορείτε να καταργήσετε τον τελευταίο χρήστη από την ομάδα 'ιδιοκτήτών'. Πρέπει να υπάρχει τουλάχιστον ένας ιδιοκτήτης για έναν οργανισμό.
+last_org_owner=Δεν μπορείτε να καταργήσετε τον τελευταίο χρήστη από την ομάδα ιδιοκτητών. Πρέπει να υπάρχει τουλάχιστον ένας ιδιοκτήτης στον οργανισμό.
cannot_add_org_to_team=Ένας οργανισμός δεν μπορεί να προστεθεί ως μέλος ομάδας.
duplicate_invite_to_team=Ο χρήστης είχε ήδη προσκληθεί ως μέλος της ομάδας.
-organization_leave_success=Έχετε εγκαταλείψει με επιτυχία τον οργανισμό %s.
+organization_leave_success=Η αποχώρησή σας από τον οργανισμό %s ήταν επιτυχής.
-invalid_ssh_key=Δεν είναι δυνατή η επαλήθευση του SSH κλειδιού σας: %s
-invalid_gpg_key=Δεν είναι δυνατή η επαλήθευση του GPG κλειδιού σας: %s
+invalid_ssh_key=Δεν είναι δυνατή η επαλήθευση του κλειδιού SSH σας: %s
+invalid_gpg_key=Δεν είναι δυνατή η επαλήθευση του κλειδιού GPG σας: %s
invalid_ssh_principal=Μη έγκυρη αρχή: %s
must_use_public_key=Το κλειδί που δώσατε είναι ένα ιδιωτικό κλειδί. Παρακαλώ μην ανεβάζετε το ιδιωτικό σας κλειδί οπουδήποτε. Χρησιμοποιήστε το δημόσιο κλειδί αντί αυτού.
-unable_verify_ssh_key=Αδυναμία επαλήθευσης του κλειδιού SSH, ελέγξτε το ξανά για λάθη.
+unable_verify_ssh_key=Δεν είναι δυνατή η επαλήθευση του κλειδιού SSH, ελέγξτε το ξανά για λάθη.
auth_failed=Αποτυχία ταυτοποίησης: %v
-still_own_repo=Ο λογαριασμός σας κατέχει ένα ή περισσότερα αποθετήρια, διαγράψτε ή μεταφέρετε τα πρώτα.
-still_has_org=Ο λογαριασμός σας είναι μέλος σε ένα ή περισσότερους οργανισμούς, φύγετε από αυτούς πρώτα.
-still_own_packages=Ο λογαριασμός σας κατέχει ένα ή περισσότερα πακέτα, διαγράψτε τα πρώτα.
-org_still_own_repo=Αυτός ο οργανισμός κατέχει ακόμα ένα ή περισσότερα αποθετήρια, διαγράψτε τα ή μεταφέρετε τα πρώτα.
-org_still_own_packages=Αυτός ο οργανισμός κατέχει ακόμα ένα ή περισσότερα πακέτα, διαγράψτε τα πρώτα.
+still_own_repo=Ο λογαριασμός σας κατέχει ένα ή περισσότερα αποθετήρια, πρέπει πρώτα να τα διαγράψετε ή να τα μεταφέρετε.
+still_has_org=Ο λογαριασμός σας είναι μέλος σε έναν ή και περισσότερους οργανισμούς, πρέπει πρώτα να αποχωρήσετε από αυτούς.
+still_own_packages=Ο λογαριασμός σας κατέχει ένα ή περισσότερα πακέτα, πρέπει πρώτα να τα διαγράψετε.
+org_still_own_repo=Αυτός ο οργανισμός κατέχει ακόμα ένα ή περισσότερα αποθετήρια, πρέπει πρώτα να τα διαγράψετε ή να τα μεταφέρετε.
+org_still_own_packages=Αυτός ο οργανισμός κατέχει ακόμα ένα ή περισσότερα πακέτα, πρέπει πρώτα να τα διαγράψετε.
target_branch_not_exist=Ο κλάδος προορισμού δεν υπάρχει.
+username_error_no_dots = `: Μπορεί να περιέχει μόνο αλφαριθμητικούς χαρακτήρες ('0-9','a-z','A-Z'), παύλα ('-') και κάτω παύλα ('_'). Δεν μπορεί να αρχίζει ή να τελειώνει με μη αλφαριθμητικούς χαρακτήρες. Επίσης δεν επιτρέπεται η χρήση διαδοχικών μη αλφαριθμητικών χαρακτήρων.`
+admin_cannot_delete_self = Δεν μπορείτε να διαγράψετε τον εαυτό σας όσο είστε διαχειριστής. Πρέπει πρώτα να αφαιρέσετε τα δικαιώματα διαχειριστή σας.
[user]
change_avatar=Αλλαγή του avatar σας…
-joined_on=Εγγράφηκε την %s
+joined_on=Εγγράφηκε στις %s
repositories=Αποθετήρια
activity=Δημόσια Δραστηριότητα
-followers=Ακόλουθοι
+followers=ακόλουθοι
starred=Αγαπημένα Αποθετήρια
watched=Ακολουθούμενα Αποθετήρια
code=Κώδικας
projects=Έργα
overview=Επισκόπηση
-following=Ακολουθεί
-follow=Ακολουθήστε
+following=ακολουθεί
+follow=Ακολούθηση
unfollow=Να μην ακολουθώ
user_bio=Βιογραφικό
-disabled_public_activity=Αυτός ο χρήστης έχει απενεργοποιήσει τη δημόσια προβολή της δραστηριότητας.
+disabled_public_activity=Αυτός ο χρήστης έχει απενεργοποιήσει τη δημόσια προβολή της δραστηριότητας του.
email_visibility.limited=Η διεύθυνση email σας είναι ορατή σε όλους τους ταυτοποιημένους χρήστες
email_visibility.private=Η διεύθυνση email σας είναι ορατή μόνο σε εσάς και στους διαχειριστές
-show_on_map=Εμφάνιση της τοποθεσίας στο χάρτη
-settings=Ρυθμίσεις Χρήστη
+show_on_map=Δείτε το μέρος αυτό σε έναν χάρτη
+settings=Ρυθμίσεις χρήστη
-form.name_reserved=Το όνομα χρήστη "%s" είναι δεσμευμένο.
-form.name_pattern_not_allowed=Το μοτίβο "%s" δεν επιτρέπεται μέσα σε ένα όνομα χρήστη.
-form.name_chars_not_allowed=Το όνομα χρήστη "%s" περιέχει μη έγκυρους χαρακτήρες.
+form.name_reserved=Το όνομα χρήστη «%s» είναι δεσμευμένο.
+form.name_pattern_not_allowed=Το μοτίβο «%s» δεν επιτρέπεται μέσα σε ένα όνομα χρήστη.
+form.name_chars_not_allowed=Το όνομα χρήστη «%s» περιέχει μη έγκυρους χαρακτήρες.
+follow_blocked_user = Δεν μπορείτε να ακολουθήσετε τον χρήστη, επειδή τον έχετε αποκλείσει ή επειδή ο χρήστης σας έχει αποκλείσει.
+unblock = Άρση αποκλεισμού
+block = Αποκλεισμός
+block_user = Αποκλεισμός χρήστη
+block_user.detail_1 = Ο χρήστης δεν θα ακολουθεί πια τον λογαριασμό σας.
+block_user.detail_2 = Ο χρήστης δεν θα μπορεί να αλληλεπιδράσει με τα αποθετήριά σας, να δημιουργήσει ζητήματα ή να αφήσει σχόλια.
+block_user.detail_3 = Ο χρήστης δεν θα μπορέσει να σας προσθέσει στα αποθετήριά του ως συνεργάτη και αντίστοιχα δεν θα μπορείτε να τον προσθέσετε στα δικά σας αποθετήρια.
+block_user.detail = Επισημαίνεται πως αν αποκλείσετε αυτόν τον χρήστη, θα προκύψουν ταυτόχρονα και άλλες ενέργειες. Μερικές από αυτές:
[settings]
profile=Προφίλ
@@ -623,18 +658,18 @@ password=Κωδικός πρόσβασης
security=Ασφάλεια
avatar=Εικόνα
ssh_gpg_keys=Κλειδιά SSH / GPG
-social=Λογαριασμοί Κοινωνικών Δικτύων
+social=Λογαριασμοί κοινωνικών δικτύων
applications=Εφαρμογές
-orgs=Διαχείριση Οργανισμών
+orgs=Διαχείριση οργανισμών
repos=Αποθετήρια
-delete=Διαγραφή Λογαριασμού
-twofa=Έλεγχος Ταυτότητας Δύο Παραγόντων
+delete=Διαγραφή λογαριασμού
+twofa=Πιστοποίηση Δύο Παραγόντων (TOTP)
account_link=Συνδεδεμένοι Λογαριασμοί
organization=Οργανισμοί
uid=UID
-webauthn=Κλειδιά Ασφαλείας
+webauthn=Πιστοποίηση Δύο Παραγόντων (Κλειδιά Ασφαλείας)
-public_profile=Δημόσιο Προφίλ
+public_profile=Δημόσιο προφίλ
biography_placeholder=Πείτε μας λίγο για τον εαυτό σας! (Μπορείτε να γράψετε με Markdown)
location_placeholder=Μοιραστείτε την κατά προσέγγιση τοποθεσία σας με άλλους
profile_desc=Ελέγξτε πώς εμφανίζεται το προφίλ σας σε άλλους χρήστες. Η κύρια διεύθυνση email σας θα χρησιμοποιηθεί για ειδοποιήσεις, ανάκτηση κωδικού πρόσβασης και λειτουργίες Git που βασίζονται στο web.
@@ -645,12 +680,12 @@ location=Τοποθεσία
update_theme=Ενημέρωση Θέματος Διεπαφής
update_profile=Ενημέρωση Προφίλ
update_language=Ενημέρωση Γλώσσας
-update_language_not_found=Η γλώσσα "%s" δεν είναι διαθέσιμη.
-update_language_success=Η γλώσσα ενημερώθηκε.
+update_language_not_found=Η γλώσσα «%s» δεν είναι διαθέσιμη.
+update_language_success=Η γλώσσα έχει ενημερωθεί.
update_profile_success=Το προφίλ σας έχει ενημερωθεί.
change_username=Το όνομα χρήστη σας έχει αλλάξει.
-change_username_prompt=Σημείωση: Αλλάζοντας το όνομα χρήστη σας αλλάζει επίσης το URL του λογαριασμού σας.
-change_username_redirect_prompt=Το παλιό όνομα χρήστη θα ανακατευθύνει μέχρι να ζητηθεί ξανά.
+change_username_prompt=Επισήμανση: Η αλλαγή του ονόματος χρήστη σας θα αλλάξει και το URL του λογαριασμού σας.
+change_username_redirect_prompt=Το παλιό όνομα χρήστη θα ανακατευθύνει έως ότου χρησιμοποιηθεί ξανά.
continue=Συνέχεια
cancel=Ακύρωση
language=Γλώσσα
@@ -662,7 +697,7 @@ hidden_comment_types.issue_ref_tooltip=Σχόλια όπου ο χρήστης
comment_type_group_reference=Αναφορά
comment_type_group_label=Σήμα
comment_type_group_milestone=Ορόσημο
-comment_type_group_assignee=Αποδέκτης
+comment_type_group_assignee=Υπεύθυνος
comment_type_group_title=Τίτλος
comment_type_group_branch=Κλάδος
comment_type_group_time_tracking=Καταγραφή Χρόνου
@@ -675,30 +710,30 @@ comment_type_group_project=Έργο
comment_type_group_issue_ref=Αναφορά ζητήματος
saved_successfully=Οι ρυθμίσεις σας αποθηκεύτηκαν επιτυχώς.
privacy=Απόρρητο
-keep_activity_private=Απόκρυψη Δραστηριότητας από τη σελίδα προφίλ
+keep_activity_private=Απόκρυψη δραστηριότητας από τη σελίδα προφίλ
keep_activity_private_popup=Με αυτή την επιλογή η δραστηριότητα σας είναι ορατή μόνο σε εσάς και τους διαχειριστές
lookup_avatar_by_mail=Αναζήτηση ενός Avatar με διεύθυνση email
federated_avatar_lookup=Συνενωμένη Αναζήτηση Avatar
-enable_custom_avatar=Χρήση Προσαρμοσμένης Εικόνας
+enable_custom_avatar=Χρήση προσαρμοσμένης εικόνας προφίλ
choose_new_avatar=Επιλέξτε νέα εικόνα
update_avatar=Ενημέρωση Εικόνας
delete_current_avatar=Διαγραφή Τρέχουσας Εικόνας
uploaded_avatar_not_a_image=Το αρχείο που ανεβάσατε δεν είναι εικόνα.
-uploaded_avatar_is_too_big=Το μέγεθος αρχείου που ανέβηκε (%d KiB) υπερβαίνει το μέγιστο μέγεθος (%d KiB).
-update_avatar_success=Η εικόνα σας έχει ενημερωθεί.
+uploaded_avatar_is_too_big=Το μέγεθος του ανεβασμένου αρχείου (%d KiB) υπερβαίνει το μέγιστο μέγεθος (%d KiB).
+update_avatar_success=To avatar σας έχει ενημερωθεί.
update_user_avatar_success=Το avatar του χρήστη ενημερώθηκε.
-update_password=Ενημέρωση Κωδικού Πρόσβασης
-old_password=Τρέχων Κωδικός Πρόσβασης
-new_password=Νέος Κωδικός Πρόσβασης
-retype_new_password=Επιβεβαίωση Νέου Κωδικού Πρόσβασης
+update_password=Ενημέρωση κωδικού πρόσβασης
+old_password=Τρέχων κωδικός πρόσβασης
+new_password=Νέος κωδικός πρόσβασης
+retype_new_password=Επιβεβαίωση νέου κωδικού
password_incorrect=Ο τρέχων κωδικός πρόσβασης είναι λάθος.
change_password_success=Ο κωδικός πρόσβασής σας έχει ενημερωθεί. Από εδώ και τώρα συνδέεστε χρησιμοποιώντας τον νέο κωδικό πρόσβασής σας.
password_change_disabled=Οι μη τοπικοί χρήστες δεν μπορούν να ενημερώσουν τον κωδικό πρόσβασής τους μέσω του διεπαφής web του Forgejo.
emails=Διευθύνσεις Email
-manage_emails=Διαχείριση Διευθύνσεων Email
+manage_emails=Διαχείριση διευθύνσεων email
manage_themes=Επιλέξτε προεπιλεγμένο θέμα διεπαφής
manage_openid=Διαχείριση Διευθύνσεων OpenID
email_desc=Η κύρια διεύθυνση ηλεκτρονικού ταχυδρομείου σας θα χρησιμοποιηθεί για ειδοποιήσεις, ανάκτηση του κωδικού πρόσβασης και, εφόσον δεν είναι κρυμμένη, λειτουργίες Git στον ιστότοπο.
@@ -719,31 +754,31 @@ theme_update_error=Το επιλεγμένο θέμα διεπαφής δεν υ
openid_deletion=Αφαίρεση Διεύθυνσης OpenID
openid_deletion_desc=Η κατάργηση αυτής της διεύθυνσης OpenID από τον λογαριασμό σας θα σας εμποδίσει να συνδέεστε με αυτό. Συνέχεια;
openid_deletion_success=Η διεύθυνση OpenID αφαιρέθηκε.
-add_new_email=Προσθήκη Νέας Διεύθυνσης Email
+add_new_email=Προσθήκη νέας διεύθυνσης email
add_new_openid=Προσθήκη Νέου OpenID URI
add_email=Προσθήκη Διεύθυνσης Email
add_openid=Προσθήκη OpenID URI
-add_email_confirmation_sent=Μια επιβεβαίωση στάλθηκε στο email "%s". Ελέγξτε τα εισερχόμενα σας μέσα στα επόμενα %s για να επιβεβαιώσετε τη διεύθυνση email σας.
+add_email_confirmation_sent=Ένα email επιβεβαίωσης έχει σταλεί στην διεύθυνση «%s». Για να επιβεβαιώσετε τη διεύθυνση email σας, παρακαλώ ελέγξτε τα εισερχόμενα σας μέσα σε %s.
add_email_success=Η νέα διεύθυνση email έχει προστεθεί.
email_preference_set_success=Οι προτιμήσεις email έχουν οριστεί επιτυχώς.
add_openid_success=Προστέθηκε η νέα διεύθυνση OpenID.
-keep_email_private=Απόκρυψη Διεύθυνσης Email
-keep_email_private_popup=Αυτό θα κρύψει τη διεύθυνση ηλεκτρονικού ταχυδρομείου σας από το προφίλ σας, καθώς και όταν κάνετε ένα pull request ή επεξεργαστείτε ένα αρχείο χρησιμοποιώντας τη διεπαφή ιστού. Οι ωθούμενες υποβολές δεν θα τροποποιηθούν. Χρησιμοποιήστε το %s στις υποβολές για να τις συσχετίσετε με το λογαριασμό σας.
+keep_email_private=Απόκρυψη διεύθυνσης email
+keep_email_private_popup=Αυτό θα κρύψει τη διεύθυνση ηλεκτρονικού ταχυδρομείου σας από το προφίλ σας, καθώς και όταν κάνετε ένα pull request ή επεξεργαστείτε ένα αρχείο χρησιμοποιώντας την ιστοσελίδα. Οι υποβολές που ωθείτε δεν θα τροποποιηθούν. Χρησιμοποιήστε το %s στις υποβολές για να τις συσχετίσετε με το λογαριασμό σας.
openid_desc=Το OpenID σας επιτρέπει να αναθέσετε τον έλεγχο ταυτότητας σε έναν εξωτερικό πάροχο.
-manage_ssh_keys=Διαχείριση SSH Κλειδιών
+manage_ssh_keys=Διαχείριση κλειδιών SSH
manage_ssh_principals=Διαχείριση Των Αρχών Πιστοποιητικού SSH
-manage_gpg_keys=Διαχείριση Κλειδιών GPG
+manage_gpg_keys=Διαχείριση κλειδιών GPG
add_key=Προσθήκη Κλειδιού
-ssh_desc=Αυτά τα δημόσια SSH κλειδιά συνδέονται με το λογαριασμό σας. Τα αντίστοιχα ιδιωτικά κλειδιά επιτρέπουν πλήρη πρόσβαση στα αποθετήριά σας.
+ssh_desc=Αυτά τα δημόσια κλειδιά SSH θα συσχετιθούν με το λογαριασμό σας. Τα ιδιωτικά κλειδιά που τους αντιστοιχούν θα επιτρέπουν πλήρη πρόσβαση στα αποθετήριά σας. Ένα επιβεβαιωμένο κλειδί SSH μπορεί να χρησιμοποιηθεί για την υπογραφή των υποβολών (commits) σας.
principal_desc=Αυτές οι αρχές πιστοποιητικών SSH συνδέονται με το λογαριασμό σας και επιτρέπουν την πλήρη πρόσβαση στα αποθετήριά σας.
-gpg_desc=Αυτά τα δημόσια κλειδιά GPG συνδέονται με το λογαριασμό σας. Κρατήστε τα ιδιωτικά κλειδιά σας ασφαλή καθώς επιτρέπουν την επαλήθευση των υποβολών.
-ssh_helper=Χρειάζεστε βοήθεια; Συμβουλευτείτε τον οδηγό του GitHub για να δημιουργήσετε τα δικά σας SSH κλειδιά ή να επιλύσετε κοινά προβλήματα που ίσως αντιμετωπίσετε με τη χρήση του SSH.
+gpg_desc=Αυτά τα δημόσια κλειδιά GPG συσχετίζονται με το λογαριασμό σας και επιτρέπουν την επικύρωση των υποβολών (commits) σας. Κρατήστε τα ιδιωτικά κλειδιά σας ασφαλή, καθώς επιτρέπουν την υπογραφή των υποβολών (commits) εκ μέρους σας.
+ssh_helper=Χρειάζεστε βοήθεια; Συμβουλευτείτε τον οδηγό του GitHub για να δημιουργήσετε τα δικά σας κλειδιά SSH ή να επιλύσετε κοινά προβλήματα που ίσως αντιμετωπίσετε με τη χρήση του SSH.
gpg_helper=Χρειάζεστε βοήθεια; Συμβουλευτείτε τον οδηγό του GitHub για το GPG.
add_new_key=Προσθήκη SSH Κλειδιού
add_new_gpg_key=Προσθήκη GPG Κλειδιού
-key_content_ssh_placeholder=Ξεκινάει με 'ssh-ed25519', 'ssh-rsa', 'ecdsa-sha2-nistp256', 'ecdsa-sha2-nistp384', 'ecdsa-sha2-nistp521', 'sk-ecdsa-sha2-nistp256@openssh.com', ή 'sk-ssh-ed25519@openssh.com'
-key_content_gpg_placeholder=Ξεκινά με '-----BEGIN PGP PUBLIC KEY BLOCK-----'
+key_content_ssh_placeholder=Αρχίζει με «ssh-ed25519», «ssh-rsa», «ecdsa-sha2-nistp256», «ecdsa-sha2-nistp384», «ecdsa-sha2-nistp521», «sk-ecdsa-sha2-nistp256@openssh.com», ή «sk-ssh-ed25519@openssh.com»
+key_content_gpg_placeholder=Αρχίζει με «-----BEGIN PGP PUBLIC KEY BLOCK-----»
add_new_principal=Προσθήκη Αρχής (Principal)
ssh_key_been_used=Αυτό το κλειδί SSH έχει ήδη προστεθεί στο διακομιστή.
ssh_key_name_used=Υπάρχει ήδη ένα SSH κλειδί με το ίδιο όνομα στο λογαριασμό σας.
@@ -761,8 +796,8 @@ gpg_token=Διακριτικό
gpg_token_help=Μπορείτε να δημιουργήσετε μια υπογραφή χρησιμοποιώντας:
gpg_token_code=echo "%s" | gpg -a --default-key %s --detach-sig
gpg_token_signature=Θωρακισμένη υπογραφή GPG
-key_signature_gpg_placeholder=Ξεκινά με '-----BEGIN PGP SIGNATURE-----'
-verify_gpg_key_success=Το κλειδί GPG "%s" επαληθεύτηκε.
+key_signature_gpg_placeholder=Αρχίζει με «-----BEGIN PGP SIGNATURE-----»
+verify_gpg_key_success=Το κλειδί GPG «%s» επαληθεύτηκε.
ssh_key_verified=Επαληθευμένο Κλειδί
ssh_key_verified_long=Το κλειδί έχει επαληθευτεί με ένα διακριτικό και μπορεί να χρησιμοποιηθεί για να επαληθεύσει τα commits που ταιριάζουν με οποιεσδήποτε ενεργοποιημένες διευθύνσεις ηλεκτρονικού ταχυδρομείου για αυτόν το χρήστη.
ssh_key_verify=Επαλήθευση
@@ -771,16 +806,16 @@ ssh_token_required=Πρέπει να δώσετε μια υπογραφή για
ssh_token=Διακριτικό
ssh_token_help=Μπορείτε να δημιουργήσετε μια υπογραφή χρησιμοποιώντας:
ssh_token_signature=Θωρακισμένη υπογραφή SSH
-key_signature_ssh_placeholder=Ξεκινά με '-----BEGIN SSH SIGNATURE-----'
-verify_ssh_key_success=Το κλειδί SSH "%s" επαληθεύτηκε.
+key_signature_ssh_placeholder=Αρχίζει με «-----BEGIN SSH SIGNATURE-----»
+verify_ssh_key_success=Το κλειδί SSH «%s» επαληθεύτηκε.
subkeys=Υποκλειδιά
key_id=ID Κλειδιού
-key_name=Όνομα Κλειδιού
+key_name=Όνομα κλειδιού
key_content=Περιεχόμενο
principal_content=Περιεχόμενο
-add_key_success=Το κλειδί SSH "%s" προστέθηκε.
-add_gpg_key_success=Το κλειδί GPG "%s" προστέθηκε.
-add_principal_success=Προστέθηκε η αρχή πιστοποίησης SSH "%s".
+add_key_success=Το κλειδί SSH «%s» προστέθηκε.
+add_gpg_key_success=Το κλειδί GPG «%s» προστέθηκε.
+add_principal_success=Προστέθηκε η αρχή πιστοποίησης SSH «%s».
delete_key=Διαγραφή
ssh_key_deletion=Διαγραφή Κλειδιού SSH
gpg_key_deletion=Διαγραφή Κλειδιού GPG
@@ -807,17 +842,17 @@ ssh_disabled=SSH Απενεργοποιημένο
ssh_signonly=Το SSH είναι απενεργοποιημένο αυτή τη στιγμή, έτσι αυτά τα κλειδιά είναι μόνο για την επαλήθευση υπογραφής των υποβολών.
ssh_externally_managed=Αυτό το κλειδί SSH διαχειρίζεται εξωτερικά για αυτόν το χρήστη
manage_social=Διαχείριση Συσχετιζόμενων Λογαριασμών Κοινωνικών Δικτύων
-social_desc=Αυτοί οι κοινωνικοί λογαριασμοί μπορούν να χρησιμοποιηθούν για να συνδεθείτε στο λογαριασμό σας. Βεβαιωθείτε ότι τους αναγνωρίζετε όλους.
+social_desc=Αυτοί οι λογαριασμοί κοινωνικών δικτύων μπορούν να χρησιμοποιηθούν για να συνδεθείτε στο λογαριασμό σας. Βεβαιωθείτε ότι τους αναγνωρίζετε όλους.
unbind=Αποσύνδεση
-unbind_success=Ο κοινωνικός λογαριασμός έχει διαγραφεί επιτυχώς.
+unbind_success=Ο λογαριασμός κοινωνικού δικτύου έχει διαγραφεί επιτυχώς.
-manage_access_token=Διαχείριση Διακριτικών Πρόσβασης
-generate_new_token=Δημιουργία Νέου Διακριτικού
+manage_access_token=Διαχείριση διακριτικών πρόσβασης (tokens)
+generate_new_token=Δημιουργία νέου διακριτικού (token)
tokens_desc=Αυτά τα διακριτικά (tokens) παρέχουν πρόσβαση στο λογαριασμό σας μέσω του API του Forgejo.
-token_name=Όνομα Διακριτικού
+token_name=Όνομα διακριτικού
generate_token=Δημιουργία Διακριτικού
generate_token_success=Το νέο διακριτικό σας έχει δημιουργηθεί. Αντιγράψτε το τώρα καθώς δεν θα εμφανιστεί ξανά.
-generate_token_name_duplicate=Το %s έχει ήδη χρησιμοποιηθεί ως όνομα εφαρμογής. Παρακαλούμε χρησιμοποιήστε ένα νέο.
+generate_token_name_duplicate=Το %s χρησιμοποιείται ήδη ως όνομα εφαρμογής. Παρακαλούμε χρησιμοποιήστε ένα νέο.
delete_token=Διαγραφή
access_token_deletion=Διαγραφή Διακριτικού Πρόσβασης
access_token_deletion_cancel_action=Άκυρο
@@ -831,11 +866,11 @@ select_permissions=Επιλέξτε δικαιώματα
permission_no_access=Καμία Πρόσβαση
permission_read=Αναγνωσμένες
permission_write=Ανάγνωση και Εγγραφή
-access_token_desc=Τα επιλεγμένα δικαιώματα διακριτικών περιορίζουν την άδεια μόνο στις αντίστοιχες διαδρομές API. Διαβάστε την τεκμηρίωση για περισσότερες πληροφορίες.
+access_token_desc=Τα επιλεγμένα δικαιώματα διακριτικών περιορίζουν την άδεια μόνο στις αντίστοιχες διαδρομές API. Διαβάστε το εγχειρίδιο για περισσότερες πληροφορίες.
at_least_one_permission=Πρέπει να επιλέξετε τουλάχιστον ένα δικαίωμα για να δημιουργήσετε ένα διακριτικό
permissions_list=Δικαιώματα:
-manage_oauth2_applications=Διαχείριση Εφαρμογών Oauth2
+manage_oauth2_applications=Διαχείριση εφαρμογών OAuth2
edit_oauth2_application=Επεξεργασία Εφαρμογής Oauth2
oauth2_applications_desc=Οι εφαρμογές OAuth2 επιτρέπουν στην εξωτερική εφαρμογή σας την ασφαλή ταυτοποίηση των χρηστών σε αυτό το Forgejo.
remove_oauth2_application=Αφαίρεση Εφαρμογής Oauth2
@@ -843,9 +878,9 @@ remove_oauth2_application_desc=Η αφαίρεση μιας εφαρμογής O
remove_oauth2_application_success=Η εφαρμογή έχει διαγραφεί.
create_oauth2_application=Δημιουργία νέας εφαρμογής OAuth2
create_oauth2_application_button=Δημιουργία Εφαρμογής
-create_oauth2_application_success=Έχετε δημιουργήσει με επιτυχία μια νέα εφαρμογή OAuth2.
-update_oauth2_application_success=Έχετε ενημερώσει με επιτυχία την εφαρμογή OAuth2.
-oauth2_application_name=Όνομα Εφαρμογής
+create_oauth2_application_success=Δημιουργήσατε επιτυχώς μια νέα εφαρμογή OAuth2.
+update_oauth2_application_success=Ενημερώσατε την εφαρμογή OAuth2 επιτυχώς.
+oauth2_application_name=Όνομα εφαρμογής
oauth2_confidential_client=Εμπιστευτικός Πελάτης. Επιλέξτε το για εφαρμογές που διατηρούν το μυστικό κωδικό κρυφό, όπως πχ οι εφαρμογές ιστού. Μην επιλέγετε για εγγενείς εφαρμογές, συμπεριλαμβανομένων εφαρμογών επιφάνειας εργασίας και εφαρμογών για κινητά.
oauth2_redirect_uris=URI Ανακατεύθυνσης. Χρησιμοποιήστε μια νέα γραμμή για κάθε URI.
save_application=Αποθήκευση
@@ -857,36 +892,36 @@ oauth2_client_secret_hint=Το μυστικό δε θα εμφανιστεί ξ
oauth2_application_edit=Επεξεργασία
oauth2_application_create_description=Οι εφαρμογές OAuth2 δίνει πρόσβαση στην εξωτερική εφαρμογή σας σε λογαριασμούς χρηστών σε αυτή την υπηρεσία.
oauth2_application_remove_description=Αφαιρώντας μια εφαρμογή OAuth2 θα αποτραπεί η πρόσβαση αυτής, σε εξουσιοδοτημένους λογαριασμούς χρηστών σε αυτή την υπηρεσία. Συνέχεια;
-oauth2_application_locked=Το Gitea κάνει προεγγραφή σε μερικές εφαρμογές OAuth2 κατά την εκκίνηση αν είναι ενεργοποιημένες στις ρυθμίσεις. Για την αποφυγή απροσδόκητης συμπεριφοράς, αυτές δεν μπορούν ούτε να επεξεργαστούν ούτε να καταργηθούν. Παρακαλούμε ανατρέξτε στην τεκμηρίωση OAuth2 για περισσότερες πληροφορίες.
+oauth2_application_locked=Το Forgejo κάνει προεγγραφή σε μερικές εφαρμογές OAuth2 κατά την εκκίνηση αν είναι ενεργοποιημένες στις ρυθμίσεις. Για την αποφυγή απροσδόκητης συμπεριφοράς, αυτές δεν μπορούν ούτε να επεξεργαστούν ούτε να καταργηθούν. Παρακαλούμε ανατρέξτε στην τεκμηρίωση OAuth2 για περισσότερες πληροφορίες.
-authorized_oauth2_applications=Εξουσιοδοτημένες Εφαρμογές OAuth2
-authorized_oauth2_applications_description=Έχετε χορηγήσει πρόσβαση στον προσωπικό σας λογαριασμό σε αυτές τις εφαρμογές τρίτων. Ανακαλέστε την πρόσβαση για εφαρμογές που δεν χρειάζεστε πλέον.
+authorized_oauth2_applications=Εξουσιοδοτημένες εφαρμογές OAuth2
+authorized_oauth2_applications_description=Έχετε χορηγήσει πρόσβαση στον προσωπικό σας λογαριασμό σε αυτές τις εφαρμογές τρίτων. Παρακαλείσθε να ανακαλέσετε την πρόσβαση για εφαρμογές που δεν χρειάζεστε πλέον.
revoke_key=Ανάκληση
revoke_oauth2_grant=Ανάκληση Πρόσβασης
-revoke_oauth2_grant_description=Η ανάκληση πρόσβασης για αυτή την εξωτερική εφαρμογή θα αποτρέψει αυτή την εφαρμογή από την πρόσβαση στα δεδομένα σας. Σίγουρα;
+revoke_oauth2_grant_description=Αν ανακαλέσετε την πρόσβαση αυτής της ανεξάρτητης («third-party») εφαρμογής, θα ανακληθεί ταυτόχρονα και η πρόσβασή της στα δεδομένα σας. Είστε βέβαιοι;
revoke_oauth2_grant_success=Η πρόσβαση ανακλήθηκε επιτυχώς.
twofa_desc=Ο έλεγχος ταυτότητας δύο παραγόντων ενισχύει την ασφάλεια του λογαριασμού σας.
twofa_recovery_tip=Αν χάσετε τη συσκευή σας, θα είστε σε θέση να χρησιμοποιήσετε ένα κλειδί ανάκτησης μιας χρήσης για να ανακτήσετε την πρόσβαση στο λογαριασμό σας.
-twofa_is_enrolled=Ο λογαριασμός σας είναι εγγεγραμμένος σε έλεγχο ταυτότητας δύο παραγόντων.
-twofa_not_enrolled=Ο λογαριασμός σας δεν είναι εγγεγραμμένος σε έλεγχο ταυτότητας δύο παραγόντων.
-twofa_disable=Απενεργοποίηση Ταυτοποίησης Δύο Παραμέτρων
+twofa_is_enrolled=Ο λογαριασμός σας είναι εγγεγραμμένος στην πιστοποίηση δύο παραγόντων.
+twofa_not_enrolled=Ο λογαριασμός σας δεν είναι εγγεγραμμένος στην πιστοποιήση δύο παραγόντων.
+twofa_disable=Απενεργοποίηση πιστοποίησης δύο παραγόντων
twofa_scratch_token_regenerate=Αναδημιουργία Διακριτικού Μίας Χρήσης
twofa_scratch_token_regenerated=Το κλειδί ανάκτησης μιας χρήσης είναι τώρα %s. Αποθηκεύστε το σε ασφαλές μέρος, καθώς δε θα εμφανιστεί ξανά.
-twofa_enroll=Εγγραφή στην ταυτοποίηση δύο παραγόντων
-twofa_disable_note=Μπορείτε να απενεργοποιήσετε την ταυτοποίηση δύο παραγόντων αν χρειαστεί.
-twofa_disable_desc=Η απενεργοποίηση της ταυτοποίησης δύο παραγόντων θα καταστήσει τον λογαριασμό σας λιγότερο ασφαλή. Συνέχεια;
+twofa_enroll=Εγγραφή στην πιστοποίηση δύο παραγόντων
+twofa_disable_note=Αν χρειαστεί, θα μπορέσετε να απενεργοποιήσετε την πιστοποίηση δύο παραγόντων μεταγενέστερα.
+twofa_disable_desc=Η απενεργοποίηση της πιστοποίησης δύο παραγόντων θα καταστήσει τον λογαριασμό σας λιγότερο ασφαλή. Είστε βέβαιοι;
regenerate_scratch_token_desc=Αν χάσατε το διακριτικό μίας χρήσης σας ή το έχετε ήδη χρησιμοποιήσει για να συνδεθείτε μπορείτε να το επαναφέρετε εδώ.
-twofa_disabled=Η ταυτοποίηση δύο παραγόντων έχει απενεργοποιηθεί.
+twofa_disabled=Η πιστοποίηση δύο παραγόντων έχει απενεργοποιηθεί.
scan_this_image=Σαρώστε αυτή την εικόνα με την εφαρμογή ταυτοποίησης:
or_enter_secret=Ή εισάγετε το μυστικό: %s
then_enter_passcode=Και εισάγετε τον κωδικό που εμφανίζεται στην εφαρμογή:
passcode_invalid=Ο κωδικός είναι λάθος. Δοκιμάστε ξανά.
-twofa_enrolled=Ο λογαριασμός σας έχει εγγραφεί σε ταυτοποίηση δύο παραγόντων. Αποθηκεύστε το διακριτικό μιας χρήσης (%s) σε ασφαλές μέρος καθώς εμφανίζεται μόνο μία φορά!
+twofa_enrolled=Ο λογαριασμός σας έχει εγγραφεί σε ταυτοποίηση δύο παραγόντων. Αποθηκεύστε το διακριτικό μιας χρήσης (%s) σε ένα ασφαλές μέρος, επειδή δεν θα ξαναεμφανιστεί.
twofa_failed_get_secret=Αποτυχία λήψης μυστικού.
-webauthn_desc=Τα κλειδιά ασφαλείας είναι συσκευές που περιέχουν κρυπτογραφικά κλειδιά. Μπορούν να χρησιμοποιηθούν για έλεγχο ταυτότητας δύο παραγόντων. Τα κλειδιά ασφαλείας πρέπει να υποστηρίζουν το πρότυπο WebAuthn Authn Authenticator.
-webauthn_register_key=Προσθήκη Κλειδιού Ασφαλείας
+webauthn_desc=Τα κλειδιά ασφαλείας είναι συσκευές που περιέχουν κρυπτογραφικά κλειδιά. Μπορούν να χρησιμοποιηθούν για την πιστοποίηση δύο παραγόντων. Τα κλειδιά ασφαλείας πρέπει να συνάδουν με τις προδιαγραφές που ορίζει το πρότυπο WebAuthn.
+webauthn_register_key=Προσθήκη κλειδιού ασφαλείας
webauthn_nickname=Ψευδώνυμο
webauthn_delete_key=Αφαίρεση Κλειδιού Ασφαλείας
webauthn_delete_key_desc=Αν αφαιρέσετε ένα κλειδί ασφαλείας δεν μπορείτε πλέον να συνδεθείτε με αυτό. Συνέχεια;
@@ -897,21 +932,21 @@ manage_account_links=Διαχείριση Συνδεδεμένων Λογαρι
manage_account_links_desc=Αυτοί οι εξωτερικοί λογαριασμοί είναι συνδεδεμένοι στον Forgejo λογαριασμό σας.
account_links_not_available=Προς το παρόν δεν υπάρχουν εξωτερικοί λογαριασμοί συνδεδεμένοι με τον λογαριασμό σας στο Forgejo.
link_account=Σύνδεση Λογαριασμού
-remove_account_link=Αφαίρεση Συνδεδεμένου Λογαριασμού
+remove_account_link=Αφαίρεση συνδεδεμένου λογαριασμού
remove_account_link_desc=Η κατάργηση ενός συνδεδεμένου λογαριασμού θα ανακαλέσει την πρόσβασή του στο λογαριασμό σας στο Forgejo. Συνέχεια;
remove_account_link_success=Ο συνδεδεμένος λογαριασμός έχει αφαιρεθεί.
hooks.desc=Προσθήκη webhooks που θα ενεργοποιούνται για όλα τα αποθετήρια που σας ανήκουν.
orgs_none=Δεν είστε μέλος σε κάποιο οργανισμό.
-repos_none=Δεν κατέχετε κάποιο αποθετήριο.
+repos_none=Δεν σας ανήκει κανένα κάποιο αποθετήριο.
delete_account=Διαγραφή Του Λογαριασμού Σας
delete_prompt=Αυτή η ενέργεια θα διαγράψει μόνιμα το λογαριασμό σας. ΔΕΝ ΘΑ ΜΠΟΡΕΙ να επανέλθει.
delete_with_all_comments=Ο λογαριασμός σας είναι νεότερος από %s. Για να αποφύγετε τα σχόλια φαντάσματα, όλα τα σχόλια σε ζητήματα/PR θα διαγραφούν από αυτόν.
confirm_delete_account=Επιβεβαίωση Διαγραφής
delete_account_title=Διαγραφή Λογαριασμού Χρήστη
-delete_account_desc=Είστε βέβαιοι ότι θέλετε να διαγράψετε μόνιμα αυτό τον λογαριασμό χρήστη;
+delete_account_desc=Είστε βέβαιοι ότι θέλετε να διαγράψετε μόνιμα αυτό τον λογαριασμό;
email_notifications.enable=Ενεργοποίηση Ειδοποιήσεων Μέσω Email
email_notifications.onmention=Email Μόνο κατά την Αναφορά
@@ -923,9 +958,15 @@ visibility=Ορατότητα χρήστη
visibility.public=Δημόσια
visibility.public_tooltip=Ορατό σε όλους
visibility.limited=Περιορισμένη
-visibility.limited_tooltip=Ορατό μόνο στους ταυτοποιημένους χρήστες
+visibility.limited_tooltip=Ορατό μόνο σε ταυτοποιημένους χρήστες
visibility.private=Ιδιωτική
visibility.private_tooltip=Ορατό μόνο στα μέλη των οργανισμών που συμμετέχετε
+blocked_users_none = Δεν έχετε αποκλείσει κανέναν χρήστη.
+blocked_since = Αποκλεισμένος από %s
+user_unblock_success = Η άρση αποκλεισμού του χρήστη ήταν επιτυχής.
+change_password = Αλλαγή κωδικού πρόσβασης
+blocked_users = Αποκλεισμένοι χρήστες
+user_block_success = Ο αποκλεισμός του χρήστη ήταν επιτυχής.
[repo]
new_repo_helper=Ένα αποθετήριο περιέχει όλα τα αρχεία έργου, συμπεριλαμβανομένου του ιστορικού εκδόσεων. Ήδη φιλοξενείται αλλού; Μετεγκατάσταση αποθετηρίου.
@@ -940,7 +981,7 @@ template_helper=Μετατροπή σε πρότυπο αποθετήριο
template_description=Τα πρότυπα αποθετήρια επιτρέπουν στους χρήστες να δημιουργήσουν νέα αποθετήρια με την ίδια δομή, αρχεία και προαιρετικές ρυθμίσεις.
visibility=Ορατότητα
visibility_description=Μόνο ο ιδιοκτήτης ή τα μέλη του οργανισμού εάν έχουν δικαιώματα, θα είναι σε θέση να το δουν.
-visibility_helper=Αλλάξτε το αποθετήριο σε ιδιωτικό
+visibility_helper=Αλλαγή ορατότητας σε «Ιδιωτικό»
visibility_helper_forced=Ο διαχειριστής σας αναγκάζει τα νέα αποθετήρια να είναι ιδιωτικά.
visibility_fork_helper=(Αλλάζοντας αυτό θα επηρεάσει όλα τα forks.)
clone_helper=Χρειάζεστε βοήθεια για τη κλωνοποίηση; Επισκεφθείτε τη Βοήθεια.
@@ -957,7 +998,7 @@ clone_in_vsc=Κλωνοποίηση στο VS Code
download_zip=Λήψη ZIP
download_tar=Λήψη TAR.GZ
download_bundle=Κατεβάστε Το ΔΕΜΑ
-generate_repo=Δημιουργία Αποθετηρίου
+generate_repo=Δημιουργία αποθετηρίου
generate_from=Δημιουργία Από
repo_desc=Περιγραφή
repo_desc_helper=Εισάγετε μια σύντομη περιγραφή (προαιρετικό)
@@ -977,19 +1018,19 @@ trust_model_helper=Επιλέξτε ένα μοντέλο εμπιστοσύνη
trust_model_helper_collaborator=Συνεργάτης: Εμπιστοσύνη υπογραφών από συνεργάτες
trust_model_helper_committer=Υποβολέας: Εμπιστοσύνη των υπογραφών που ταιριάζουν με τους υποβολείς
trust_model_helper_collaborator_committer=Συνεργάτης+Υποβολέας: Εμπιστοσύνη των υπογραφών από συνεργάτες που ταιριάζουν με τον υποβολέα
-trust_model_helper_default=Προεπιλογή: Χρησιμοποιήστε το προεπιλεγμένο μοντέλο εμπιστοσύνης για αυτήν την εγκατάσταση
-create_repo=Δημιουργία Αποθετηρίου
+trust_model_helper_default=Προεπιλογή: Χρήση προεπιλεγμένου μοντέλου εμπιστοσύνης για αυτήν την εγκατάσταση
+create_repo=Δημιουργία αποθετηρίου
default_branch=Προεπιλεγμένος Κλάδος
default_branch_label=προεπιλογή
default_branch_helper=Ο προεπιλεγμένος κλάδος είναι ο βασικός κλάδος για pull requests και υποβολές κώδικα.
mirror_prune=Καθαρισμός
mirror_prune_desc=Αφαίρεση παρωχημένων αναφορών απομακρυσμένης-παρακολούθησης
-mirror_interval=Διάστημα ανανέωσης ειδώλου (έγκυρες μονάδες ώρας είναι 'h', 'm', 's'). 0 για απενεργοποίηση του αυτόματου συγχρονισμού. (Ελάχιστο διάστημα: %s)
+mirror_interval=Διάστημα ανανέωσης ειδώλου (έγκυρες μονάδες ώρας είναι "h", "m", "s"). 0 για απενεργοποίηση του αυτόματου συγχρονισμού. (Ελάχιστο διάστημα: %s)
mirror_interval_invalid=Το χρονικό διάστημα του ειδώλου δεν είναι έγκυρο.
mirror_sync_on_commit=Συγχρονισμός κατά την ώθηση
mirror_address=Κλωνοποίηση Από Το URL
mirror_address_desc=Τοποθετήστε όλα τα απαιτούμενα διαπιστευτήρια στην ενότητα Εξουσιοδότηση.
-mirror_address_url_invalid=Η διεύθυνση URL που δόθηκε δεν είναι έγκυρη. Πρέπει να κάνετε escape όλα τα στοιχεία του url σωστά.
+mirror_address_url_invalid=Η παρεχόμενη διεύθυνση URL δεν είναι έγκυρη. Πρέπει να κάνετε escape όλα τα στοιχεία του url σωστά.
mirror_address_protocol_invalid=Η παρεχόμενη διεύθυνση URL δεν είναι έγκυρη. Μόνο οι τοποθεσίες http(s):// ή git:// μπορούν να χρησιμοποιηθούν για τη δημιουργία ειδώλου.
mirror_lfs=Large File Storage (LFS)
mirror_lfs_desc=Ενεργοποίηση αντικατοπτρισμού δεδομένων LFS.
@@ -1025,9 +1066,9 @@ tree_path_not_found_branch=Η διαδρομή %[1]s δεν υπάρχει στ
tree_path_not_found_tag=Η διαδρομή %[1]s δεν υπάρχει στην ετικέτα %[2]s
transfer.accept=Αποδοχή Μεταφοράς
-transfer.accept_desc=`Μεταφορά στο "%s"`
+transfer.accept_desc=`Μεταφορά στο «%s»`
transfer.reject=Απόρριψη Μεταφοράς
-transfer.reject_desc=`Ακύρωση μεταφοράς σε "%s"`
+transfer.reject_desc=`Ακύρωση μεταφοράς στο «%s»`
transfer.no_permission_to_accept=Δεν έχετε άδεια να αποδεχτείτε αυτή τη μεταφορά.
transfer.no_permission_to_reject=Δεν έχετε άδεια να απορρίψετε αυτή τη μεταφορά.
@@ -1055,11 +1096,11 @@ archive.pull.nocomment=Αυτό το repo αρχειοθετήθηκε. Δεν
form.reach_limit_of_creation_1=Έχετε ήδη συμπληρώσει το όριο του %d αποθετηρίου.
form.reach_limit_of_creation_n=Έχετε ήδη συμπληρώσει το όριο των %d αποθετηρίων.
-form.name_reserved=Το όνομα αποθετηρίου "%s" είναι δεσμευμένο.
-form.name_pattern_not_allowed=Το μοτίβο "%s" δεν επιτρέπεται στο όνομα του αποθετηρίου.
+form.name_reserved=Το όνομα αποθετηρίου «%s» είναι δεσμευμένο.
+form.name_pattern_not_allowed=Το μοτίβο «%s» δεν επιτρέπεται στο όνομα του αποθετηρίου.
need_auth=Εξουσιοδότηση
-migrate_options=Επιλογές Μεταφοράς
+migrate_options=Ρυθμίσεις μεταφοράς
migrate_service=Υπηρεσία Μεταφοράς
migrate_options_mirror_helper=Αυτό το αποθετήριο θα είναι είδωλο
migrate_options_lfs=Μεταφορά αρχείων LFS
@@ -1067,7 +1108,7 @@ migrate_options_lfs_endpoint.label=Άκρο LFS
migrate_options_lfs_endpoint.description=Η μεταφορά θα προσπαθήσει να χρησιμοποιήσει το Git remote για να καθορίσει τον διακομιστή LFS. Μπορείτε επίσης να καθορίσετε ένα δικό σας endpoint αν τα δεδομένα LFS του αποθετηρίου αποθηκεύονται κάπου αλλού.
migrate_options_lfs_endpoint.description.local=Μια διαδρομή στο τοπικό διακομιστή επίσης υποστηρίζεται.
migrate_options_lfs_endpoint.placeholder=Αν αφεθεί κενό, το άκρο θα προκύψει από το URL του κλώνου
-migrate_items=Στοιχεία Μεταφοράς
+migrate_items=Αντικείμενα μεταφοράς
migrate_items_wiki=Wiki
migrate_items_milestones=Ορόσημα
migrate_items_labels=Σήματα
@@ -1076,21 +1117,21 @@ migrate_items_pullrequests=Pull Requests
migrate_items_merge_requests=Merge Requests
migrate_items_releases=Κυκλοφορίες
migrate_repo=Μεταφορά Αποθετηρίου
-migrate.clone_address=Μεταφορά / Κλωνοποίηση Από Το URL
-migrate.clone_address_desc=Το HTTP(S) ή Git URL 'κλωνοποίησης' ενός υπάρχοντος αποθετηρίου
+migrate.clone_address=Μεταφορά / Κλωνοποίηση από το URL
+migrate.clone_address_desc=Το HTTP(S) ή το Git URL «κλωνοποίησης» ενός υπάρχοντος αποθετηρίου
migrate.github_token_desc=Μπορείτε να βάλετε ένα ή περισσότερα διακριτικά εδώ, χωρισμένα με κόμμα, για να κάνετε τη μετεγκατάσταση πιο γρήγορα, λόγω του ορίου ρυθμού του GitHub API. ΠΡΟΣΟΧΗ: Η κατάχρηση αυτής της δυνατότητας μπορεί να παραβιάσει την πολιτική του παρόχου υπηρεσιών και να οδηγήσει σε αποκλεισμό του λογαριασμού σας.
migrate.clone_local_path=ή μια διαδρομή τοπικού διακομιστή
migrate.permission_denied=Δεν επιτρέπεται η εισαγωγή τοπικών αποθετηρίων.
migrate.permission_denied_blocked=Δεν μπορείτε να εισαγάγετε από μη επιτρεπόμενους υπολογιστές, παρακαλούμε ζητήστε από τον διαχειριστή να ελέγξει τις ρυθμίσεις ALLOWED_DOMAINS/ALLOW_LOCALNETWORKS/BLOCKED_DOMAINS.
-migrate.invalid_local_path=Η τοπική διαδρομή δεν είναι έγκυρη. Δεν υπάρχει ή δεν είναι φάκελος.
+migrate.invalid_local_path=Η τοποθεσία αρχείου δεν είναι έγκυρη. Το αρχείο δεν υπάρχει ή δεν είναι φάκελος.
migrate.invalid_lfs_endpoint=Η διεύθυνση LFS δεν είναι έγκυρο.
migrate.failed=Η μεταφορά απέτυχε: %v
migrate.migrate_items_options=Το Διακριτικό Πρόσβασης απαιτείται για τη μεταφορά πρόσθετων στοιχείων
migrated_from=Μεταφέρθηκε από %[2]s
migrated_from_fake=Μεταφέρθηκε από %[1]s
-migrate.migrate=Μεταφορά Από %s
-migrate.migrating=Γίνεται μεταφορά από %s...
-migrate.migrating_failed=Η μετεγρατάσταση από %s απέτυχε.
+migrate.migrate=Μεταφορά από το %s
+migrate.migrating=Γίνεται μεταφορά από το %s...
+migrate.migrating_failed=Η μεταφορά από το %s απέτυχε.
migrate.migrating_failed.error=Αποτυχία μεταφοράς: %s
migrate.migrating_failed_no_addr=Η μεταφορά απέτυχε.
migrate.github.description=Μεταφορά δεδομένων από το github.com ή άλλους διακομιστές GitHub.
@@ -1117,7 +1158,7 @@ generated_from=παράγονται από
fork_from_self=Δεν μπορείτε να κάνετε fork σε ένα αποθετήριο που κατέχετε.
fork_guest_user=Συνδεθείτε για να κάνετε fork αυτό το αποθετήριο.
watch_guest_user=Συνδεθείτε για να παρακολουθήσετε αυτό το αποθετήριο.
-star_guest_user=Συνδεθείτε για να προτιμήσετε αυτό το αποθετήριο.
+star_guest_user=Συνδεθείτε για να δώσετε ένα αστέρι σε αυτό το αποθετήριο.
unwatch=Μη Παρακολούθηση
watch=Παρακολούθηση
unstar=Όχι Αστέρι
@@ -1132,7 +1173,7 @@ clone_this_repo=Κλωνοποίηση αυτού του αποθετηρίου
cite_this_repo=Αναφορά σε αυτό το αποθετήριο
create_new_repo_command=Δημιουργία νέου αποθετηρίου στη γραμμή εντολών
push_exist_repo=Προώθηση ενός υπάρχοντος αποθετηρίου από τη γραμμή εντολών
-empty_message=Αυτό το αποθετήριο δεν περιέχει τίποτα.
+empty_message=Αυτό το αποθετήριο δεν έχει περιεχόμενο.
broken_message=Τα δεδομένα Git που διέπουν αυτό το αποθετήριο δεν μπορούν να διαβαστούν. Επικοινωνήστε με το διαχειριστή ή διαγράψτε αυτό το αποθετήριο.
code=Κώδικας
@@ -1148,7 +1189,7 @@ issues=Ζητήματα
pulls=Pull Requests
project_board=Έργα
packages=Πακέτα
-actions=Δράσεις
+actions=Actions
labels=Σήματα
org_labels_desc=Τα σήματα στο επίπεδο οργανισμού, που μπορούν να χρησιμοποιηθούν με όλα τα αποθετήρια κάτω από αυτόν τον οργανισμό
org_labels_desc_manage=διαχείριση
@@ -1181,8 +1222,8 @@ escape_control_characters=Escape
unescape_control_characters=Unescape
file_copy_permalink=Αντιγραφή Permalink
view_git_blame=Προβολή Git Blame
-video_not_supported_in_browser=Το πρόγραμμα περιήγησής σας δεν υποστηρίζει την ετικέτα HTML5 'video'.
-audio_not_supported_in_browser=Το πρόγραμμα περιήγησής σας δεν υποστηρίζει την ετικέτα HTML5 'audio'.
+video_not_supported_in_browser=Το πρόγραμμα περιήγησής σας δεν υποστηρίζει την ετικέτα HTML5 «video».
+audio_not_supported_in_browser=Το πρόγραμμα περιήγησής σας δεν υποστηρίζει την ετικέτα HTML5 «audio».
stored_lfs=Αποθηκεύτηκε με το Git LFS
symbolic_link=Symbolic link
executable_file=Εκτελέσιμο Αρχείο
@@ -1214,14 +1255,14 @@ editor.must_be_on_a_branch=Πρέπει να βρίσκεστε σε έναν κ
editor.fork_before_edit=Πρέπει να κάνετε fork αυτό το αποθετήριο για να κάνετε ή να προτείνετε αλλαγές σε αυτό το αρχείο.
editor.delete_this_file=Διαγραφή Αρχείου
editor.must_have_write_access=Πρέπει να έχετε πρόσβαση εγγραφής για να κάνετε ή να προτείνετε αλλαγές σε αυτό το αρχείο.
-editor.file_delete_success=Το αρχείο "%s" έχει διαγραφεί.
+editor.file_delete_success=Το αρχείο «%s» έχει διαγραφεί.
editor.name_your_file=Ονομάστε το αρχείο σας…
-editor.filename_help=Προσθέστε έναν φάκελο πληκτρολογώντας το όνομά του, ακολουθούμενο από μια κάθετο ('/'). Αφαιρέστε ένα φάκελο πληκτρολογώντας ένα backspace στην αρχή του πεδίου.
+editor.filename_help=Προσθέστε έναν φάκελο πληκτρολογώντας μια κάθετο ('/') και το όνομα του φακέλου. Αφαιρέστε έναν φάκελο πληκτρολογώντας ένα backspace στην αρχή του πεδίου.
editor.or=ή
editor.cancel_lower=Ακύρωση
editor.commit_signed_changes=Υποβολή Υπογεγραμμένων Αλλαγών
editor.commit_changes=Υποβολή Αλλαγών
-editor.add_tmpl=Προσθήκη ''
+editor.add_tmpl=Προσθήκη «»
editor.add=Προσθήκη %s
editor.update=Ενημέρωση %s
editor.delete=Διαγραφή %s
@@ -1241,36 +1282,36 @@ editor.cancel=Ακύρωση
editor.filename_cannot_be_empty=Το όνομα αρχείου δεν μπορεί να είναι κενό.
editor.filename_is_invalid=Το όνομα αρχείου δεν είναι έγκυρο: "%s".
editor.branch_does_not_exist=Ο κλάδος "%s" δεν υπάρχει σε αυτό το αποθετήριο.
-editor.branch_already_exists=Ο κλάδος "%s" υπάρχει ήδη σε αυτό το αποθετήριο.
-editor.directory_is_a_file=Το όνομα φακέλου "%s" χρησιμοποιείται ήδη ως όνομα αρχείου σε αυτό το αποθετήριο.
-editor.file_is_a_symlink=`Το "%s" είναι συμβολικός σύνδεσμος. Οι συμβολικοί σύνδεσμοι δεν μπορούν να επεξεργαστούν στην ενσωματωμένη εφαρμογή`
-editor.filename_is_a_directory=Το όνομα αρχείου "%s" χρησιμοποιείται ήδη ως όνομα φακέλου σε αυτό το αποθετήριο.
-editor.file_editing_no_longer_exists=Το αρχείο "%s" που επεξεργάζεται, δεν υπάρχει πλέον σε αυτό το αποθετήριο.
-editor.file_deleting_no_longer_exists=Το αρχείο "%s" που διαγράφεται, δεν υπάρχει πλέον σε αυτό το αποθετήριο.
+editor.branch_already_exists=Ο κλάδος «%s» υπάρχει ήδη σε αυτό το αποθετήριο.
+editor.directory_is_a_file=Το όνομα φακέλου «%s» χρησιμοποιείται ήδη ως όνομα αρχείου σε αυτό το αποθετήριο.
+editor.file_is_a_symlink=`Το «%s» είναι συμβολικός σύνδεσμος. Οι συμβολικοί σύνδεσμοι δεν μπορούν να επεξεργαστούν στην ενσωματωμένη εφαρμογή`
+editor.filename_is_a_directory=Το όνομα αρχείου «%s» χρησιμοποιείται ήδη ως όνομα φακέλου σε αυτό το αποθετήριο.
+editor.file_editing_no_longer_exists=Το αρχείο «%s», το οποίο επεξεργάζεστε, δεν υπάρχει πλέον σε αυτό το αποθετήριο.
+editor.file_deleting_no_longer_exists=Το αρχείο «%s», το οποίο διαγράφεται, δεν υπάρχει πλέον σε αυτό το αποθετήριο.
editor.file_changed_while_editing=Τα περιεχόμενα του αρχείου άλλαξαν από τότε που ξεκίνησε η επεξεργασία. Κάντε κλικ εδώ για να τα δείτε ή Υποβολή Αλλαγών ξανά για να τα αντικαταστήσετε.
-editor.file_already_exists=Ένα αρχείο με το όνομα "%s" υπάρχει ήδη σε αυτό το αποθετήριο.
+editor.file_already_exists=Υπάρχει ήδη ένα αρχείο με το όνομα «%s» σε αυτό το αποθετήριο.
editor.commit_empty_file_header=Υποβολή ενός κενού αρχείου
editor.commit_empty_file_text=Το αρχείο που πρόκειται να υποβληθεί είναι κενό. Συνέχεια;
editor.no_changes_to_show=Δεν υπάρχουν αλλαγές για εμφάνιση.
-editor.fail_to_update_file=Αποτυχία ενημέρωσης/δημιουργίας του αρχείου "%s".
+editor.fail_to_update_file=Αποτυχία ενημέρωσης/δημιουργίας του αρχείου «%s».
editor.fail_to_update_file_summary=Μήνυμα Σφάλματος:
editor.push_rejected_no_message=Η αλλαγή απορρίφθηκε από το διακομιστή χωρίς κάποιο μήνυμα. Παρακαλώ ελέγξτε τα Άγκιστρα Git.
editor.push_rejected=Η αλλαγή απορρίφθηκε από τον διακομιστή. Παρακαλώ ελέγξτε τα Άγκιστρα Git.
editor.push_rejected_summary=Μήνυμα Πλήρους Απόρριψης:
editor.add_subdir=Προσθήκη φακέλου…
-editor.unable_to_upload_files=Αποτυχία αποστολής αρχείων στο "%s" με το σφάλμα: %v
-editor.upload_file_is_locked=Το αρχείο "%s" είναι κλειδωμένο από %s.
-editor.upload_files_to_dir=`Μεταφόρτωση αρχείων στο "%s"`
-editor.cannot_commit_to_protected_branch=Δεν είναι δυνατή η υποβολή στον προστατευόμενο κλάδο "%s".
+editor.unable_to_upload_files=Αποτυχία αποστολής αρχείων στο «%s» με το σφάλμα: %v
+editor.upload_file_is_locked=Το αρχείο «%s» είναι κλειδωμένο από %s.
+editor.upload_files_to_dir=Μεταφόρτωση αρχείων στο «%s»
+editor.cannot_commit_to_protected_branch=Δεν είναι δυνατή η υποβολή στον προστατευόμενο κλάδο «%s».
editor.no_commit_to_branch=Δεν είναι δυνατή η απευθείας υποβολή στο κλάδο επειδή:
editor.user_no_push_to_branch=Ο χρήστης δεν μπορεί να κάνει push στο κλάδο
editor.require_signed_commit=Ο κλάδος απαιτεί υπογεγραμμένη υποβολή
-editor.cherry_pick=Ανθολόγηση (cherry-pic) του %s στο:
+editor.cherry_pick=Ανθολόγηση (cherry-pick) του %s σε:
editor.revert=Απόσυρση του %s στο:
commits.desc=Δείτε το ιστορικό αλλαγών του πηγαίου κώδικα.
commits.commits=Υποβολές
-commits.no_commits=Δεν υπάρχουν κοινές υποβολές. Τα "%s" και "%s" έχουν εντελώς διαφορετικές ιστορίες.
+commits.no_commits=Δεν υπάρχουν κοινές υποβολές. Τα «%s» και «%s» έχουν εντελώς διαφορετικές ιστορίες.
commits.nothing_to_compare=Αυτοί οι κλάδοι είναι όμοιοι.
commits.search=Αναζήτηση υποβολών…
commits.search.tooltip=Μπορείτε να προθέτετε τις λέξεις-κλειδιά με "author:", "committer:", "after:", ή "before:", π.χ. "επαναφορά author:Alice before:2019-01-13".
@@ -1293,8 +1334,8 @@ commit.revert=Απόσυρση
commit.revert-header=Απόσυρση: %s
commit.revert-content=Επιλέξτε κλάδο για απόσυρση σε αυτό:
commit.cherry-pick=Cherry-pick
-commit.cherry-pick-header=Ανθολόγηση: %s
-commit.cherry-pick-content=Επιλέξτε κλάδο για να κάνετε ανθολόγηση σε αυτό:
+commit.cherry-pick-header=Cherry-pick: %s
+commit.cherry-pick-content=Επιλέξτε τον κλάδο που θέλετε να ανθολογήσετε (cherry-pick):
commitstatus.error=Σφάλμα
commitstatus.failure=Αποτυχία
@@ -1312,41 +1353,41 @@ projects.create=Δημιουργία Έργου
projects.title=Τίτλος
projects.new=Νέο έργο
projects.new_subheader=Συντονισμός, παρακολούθηση και ενημέρωση της δουλειάς σας σε ένα μέρος, έτσι ώστε τα έργα να παραμένουν διαφανή και μέσα στο χρονοδιάγραμμα.
-projects.create_success=Το έργο "%s" δημιουργήθηκε.
+projects.create_success=Το έργο «%s» δημιουργήθηκε.
projects.deletion=Διαγραφή Έργου
projects.deletion_desc=Η διαγραφή ενός έργου το αφαιρεί από όλα τα σχετιζόμενα ζητήματα. Συνέχεια;
projects.deletion_success=Το έργο έχει διαγραφεί.
projects.edit=Επεξεργασία Έργων
projects.edit_subheader=Τα Έργα οργανώνουν τα ζητήματα και παρακολουθούν τη πρόοδο τους.
projects.modify=Ενημέρωση Έργου
-projects.edit_success=Το έργο "%s" ενημερώθηκε.
+projects.edit_success=Το έργο «%s» ενημερώθηκε.
projects.type.none=Κανένα
projects.type.basic_kanban=Βασικό Kanban
-projects.type.bug_triage=Διαλογή Σφαλμάτων
+projects.type.bug_triage=Διαλογή σφαλμάτων
projects.template.desc=Πρότυπο έργου
projects.template.desc_helper=Επιλέξτε ένα πρότυπο έργου για να ξεκινήσετε
projects.type.uncategorized=Χωρίς Κατηγορία
-projects.column.edit=Επεξεργασία Στήλης
+projects.column.edit=Επεξεργασία στήλης
projects.column.edit_title=Όνομα
projects.column.new_title=Όνομα
-projects.column.new_submit=Δημιουργία Στήλης
-projects.column.new=Νέα Στήλη
-projects.column.set_default=Ορισμός Προεπιλογής
-projects.column.set_default_desc=Ορίστε αυτή τη στήλη ως προεπιλογή για ζητήματα και pull requests χωρίς κατηγορία
-projects.column.unset_default=Αφαίρεση Προεπιλογής
+projects.column.new_submit=Δημιουργία στήλης
+projects.column.new=Νέα στήλη
+projects.column.set_default=Ορισμός προεπιλογής
+projects.column.set_default_desc=Ορίστε αυτή τη στήλη ως προεπιλεγμένη για ζητήματα και pull requests που δεν ανήκουν σε κάποια κατηγορία
+projects.column.unset_default=Αφαίρεση προεπιλογής
projects.column.unset_default_desc=Αφαίρεση της προεπιλογής αυτής της στήλης
-projects.column.delete=Διαγραφή Στήλης
-projects.column.deletion_desc=Η διαγραφή μιας στήλης έργου μετακινεί όλα τα συναφή ζητήματα σε 'Χωρίς Κατηγορία'. Συνέχεια;
+projects.column.delete=Διαγραφή στήλης
+projects.column.deletion_desc=Όταν διαγράφεται μία στήλη έργου, όλα τα ζητήματα που ανήκουν σε αυτή θα μείνουν «Χωρίς Κατηγορία». Συνέχεια;
projects.column.color=Έγχρωμο
projects.open=Άνοιγμα
projects.close=Κλείσιμο
projects.column.assigned_to=Ανατέθηκε σε
-projects.card_type.desc=Προεπισκοπήσεις Καρτών
-projects.card_type.images_and_text=Εικόνες και Κείμενο
-projects.card_type.text_only=Μόνο Κείμενο
+projects.card_type.desc=Προεπισκοπήσεις καρτών
+projects.card_type.images_and_text=Εικόνες και κείμενο
+projects.card_type.text_only=Μόνο κείμενο
issues.desc=Οργανώστε αναφορές σφαλμάτων, εργασίες και ορόσημα.
-issues.filter_assignees=Φίλτρο Αποδέκτη
+issues.filter_assignees=Φίλτρο υπεύθυνων
issues.filter_milestones=Φίλτρο Ορόσημου
issues.filter_projects=Φίλτρο Έργου
issues.filter_labels=Φίλτρο Σημάτων
@@ -1367,9 +1408,9 @@ issues.new.no_milestone=Χωρίς Ορόσημο
issues.new.clear_milestone=Καθαρισμός ορόσημου
issues.new.open_milestone=Ανοιχτά Ορόσημα
issues.new.closed_milestone=Κλειστά Ορόσημα
-issues.new.assignees=Αποδέκτες
-issues.new.clear_assignees=Εκκαθάριση αποδεκτών
-issues.new.no_assignees=Χωρίς Αποδέκτη
+issues.new.assignees=Υπεύθυνοι
+issues.new.clear_assignees=Εκκαθάριση υπεύθυνων
+issues.new.no_assignees=Χωρίς υπεύθυνους
issues.new.no_reviewers=Δεν υπάρχουν εξεταστές
issues.choose.get_started=Ας Αρχίσουμε
issues.choose.open_external_link=Άνοιγμα
@@ -1385,10 +1426,10 @@ issues.new_label_placeholder=Όνομα σήματος
issues.new_label_desc_placeholder=Περιγραφή
issues.create_label=Δημιουργία Σήματος
issues.label_templates.title=Χρήση ενός προκαθορισμένου συνόλου σημάτων
-issues.label_templates.info=Δεν υπάρχουν σήματα ακόμα. Δημιουργήστε ένα σήμα με το 'Νέο Σήμα' ή χρησιμοποιήστε ένα σύνολο προκαθορισμένων σημάτων:
+issues.label_templates.info=Δεν υπάρχουν σήματα ακόμα. Δημιουργήστε ένα σήμα με το κουμπί «Νέο Σήμα» ή χρησιμοποιήστε ένα σετ προκαθορισμένων σημάτων:
issues.label_templates.helper=Επιλέξτε ένα σύνολο σημάτων
issues.label_templates.use=Χρήση Συνόλου Σημάτων
-issues.label_templates.fail_to_load_file=Αποτυχία φόρτωσης των προτύπων σημάτων από το αρχείο "%s": %v
+issues.label_templates.fail_to_load_file=Αποτυχία φόρτωσης των προτύπων σημάτων από το αρχείο «%s»: %v
issues.add_label=πρόσθεσε τη σήμανση %s %s
issues.add_labels=πρόσθεσε τα σήματα %s %s
issues.remove_label=αφαίρεσε το σήμα %s %s
@@ -1403,7 +1444,7 @@ issues.remove_project_at=`το αφαίρεσε από το %s έργο %
issues.deleted_milestone=`(διαγράφηκε)`
issues.deleted_project=`(διαγράφηκε)`
issues.self_assign_at=`ανέθεσε στον εαυτό του το %s`
-issues.add_assignee_at=`ανατέθηκε από %s %s`
+issues.add_assignee_at=`ανατέθηκε ως υπεύθυνος από τον/την %s %s`
issues.remove_assignee_at=`αφαιρέθηκε η ανάθεση από %s %s`
issues.remove_self_assignment=`αφαίρεσαν την ανάθεση τους %s`
issues.change_title_at=`άλλαξε το τίτλο από %s σε %s %s`
@@ -1425,7 +1466,7 @@ issues.filter_project_all=Όλα τα έργα
issues.filter_project_none=Χωρίς έργα
issues.filter_assignee=Αποδέκτης
issues.filter_assginee_no_select=Όλοι οι αποδέκτες
-issues.filter_assginee_no_assignee=Κανένας Αποδέκτης
+issues.filter_assginee_no_assignee=Κανένας αποδέκτης
issues.filter_poster=Συγγραφέας
issues.filter_poster_no_select=Όλοι οι συγγραφείς
issues.filter_type=Τύπος
@@ -1440,15 +1481,15 @@ issues.filter_sort.latest=Νεότερα
issues.filter_sort.oldest=Παλαιότερα
issues.filter_sort.recentupdate=Ενημερώθηκαν πρόσφατα
issues.filter_sort.leastupdate=Ενημερώθηκαν παλαιότερα
-issues.filter_sort.mostcomment=Περισσότερο σχολιασμένα
-issues.filter_sort.leastcomment=Λιγότερο σχολιασμένα
-issues.filter_sort.nearduedate=Πλησιέστερη παράδοση
-issues.filter_sort.farduedate=Απώτερη παράδοση
+issues.filter_sort.mostcomment=Περισσότερα σχόλια
+issues.filter_sort.leastcomment=Λιγότερα σχόλια
+issues.filter_sort.nearduedate=Πλησιέστερη ημερομηνία παράδοσης
+issues.filter_sort.farduedate=Απώτερη ημερομηνία παράδοσης
issues.filter_sort.moststars=Περισσότερα αστέρια
issues.filter_sort.feweststars=Λιγότερα αστέρια
issues.filter_sort.mostforks=Περισσότερα forks
issues.filter_sort.fewestforks=Λιγότερα forks
-issues.keyword_search_unavailable=Η αναζήτηση μέσω λέξεων κλειδιών δεν είναι διαθέσιμη. Παρακαλώ επικοινωνήστε με το διαχειριστή.
+issues.keyword_search_unavailable=Η αναζήτηση με λέξεις κλειδιά δεν είναι διαθέσιμη. Παρακαλώ επικοινωνήστε με τον διαχειριστή.
issues.action_open=Άνοιγμα
issues.action_close=Κλείσιμο
issues.action_label=Σήμα
@@ -1472,7 +1513,7 @@ issues.draft_title=Προσχέδιο
issues.num_comments_1=%d σχόλιο
issues.num_comments=%d σχόλια
issues.commented_at=`σχολίασε %s`
-issues.delete_comment_confirm=Θέλετε σίγουρα να διαγράψετε αυτό το σχόλιο;
+issues.delete_comment_confirm=Είστε βέβαιοι πως θέλετε να διαγράψετε αυτό το σχόλιο;
issues.context.copy_link=Αντιγραφή Συνδέσμου
issues.context.quote_reply=Παράθεση Απάντησης
issues.context.reference_issue=Αναφορά σε νέο ζήτημα
@@ -1503,7 +1544,7 @@ issues.role.owner_helper=Αυτός ο χρήστης είναι ο ιδιοκτ
issues.role.member=Μέλος
issues.role.member_helper=Αυτός ο χρήστης είναι μέλος του οργανισμού που κατέχει αυτό το αποθετήριο.
issues.role.collaborator=Συνεργάτης
-issues.role.collaborator_helper=Αυτός ο χρήστης έχει προσκληθεί να συνεργαστεί στο αποθετήριο.
+issues.role.collaborator_helper=Ο χρήστης έλαβε πρόσκληση συνεργασίας στο αποθετήριο.
issues.role.first_time_contributor=Συντελεστής για πρώτη φορά
issues.role.first_time_contributor_helper=Αυτή είναι η πρώτη συνεισφορά αυτού του χρήστη στο αποθετήριο.
issues.role.contributor=Συντελεστής
@@ -1533,106 +1574,106 @@ issues.label_edit=Επεξεργασία
issues.label_delete=Διαγραφή
issues.label_modify=Επεξεργασία Σήματος
issues.label_deletion=Διαγραφή Σήματος
-issues.label_deletion_desc=Η διαγραφή ενός σήματος την αφαιρεί από όλα τα ζητήματα. Συνέχεια
+issues.label_deletion_desc=Η διαγραφή ενός σήματος θα το αφαιρέσει από όλα τα ζητήματα. Να γίνει συνέχεια;
issues.label_deletion_success=Το σήμα έχει διαγραφεί.
issues.label.filter_sort.alphabetically=Αλφαβητικά
issues.label.filter_sort.reverse_alphabetically=Αντίστροφα αλφαβητικά
issues.label.filter_sort.by_size=Μικρότερο μέγεθος
issues.label.filter_sort.reverse_by_size=Μεγαλύτερο μέγεθος
issues.num_participants=%d Συμμετέχοντες
-issues.attachment.open_tab=`Κάντε κλικ για να δείτε το "%s" σε μια νέα καρτέλα`
-issues.attachment.download=`Κάντε κλικ για να λάβετε το "%s"`
+issues.attachment.open_tab=`Πατήστε εδώ για να ανοίξετε το «%s» σε μια νέα καρτέλα`
+issues.attachment.download=`Πατήστε εδώ για να κατεβάσετε το «%s»`
issues.subscribe=Εγγραφή
issues.unsubscribe=Διαγραφή
issues.unpin_issue=Άφεση Ζητήματος
-issues.max_pinned=Δεν μπορείτε να διατηρήσετε περισσότερα ζητήματα
-issues.pin_comment=διατήρησε αυτό %s
-issues.unpin_comment=άφησε αυτό %s
+issues.max_pinned=Δεν μπορείτε να καρφιτσώσετε περισσότερα ζητήματα
+issues.pin_comment=καρφίτσωσε το %s
+issues.unpin_comment=ξεκαρφίτσωσε το %s
issues.lock=Κλείδωμα συνομιλίας
issues.unlock=Ξεκλείδωμα συνομιλίας
issues.lock.unknown_reason=Αδυναμία κλειδώματος ενός ζητήματος με άγνωστο λόγο.
issues.lock_duplicate=Ένα ζήτημα δεν μπορεί να κλειδωθεί δύο φορές.
issues.unlock_error=Δεν είναι δυνατό να ξεκλειδώσετε ένα ζήτημα που δεν είναι κλειδωμένο.
-issues.lock_with_reason=κλειδωμένο ως %s και περιορισμένη συνομιλία με συνεργάτες %s
-issues.lock_no_reason=κλειδωμένη και περιορισμένη συνομιλία με συνεργάτες %s
-issues.unlock_comment=ξεκλείδωσε αυτή τη συνομιλία %s
+issues.lock_with_reason=κλείδωσε το ζήτημα επειδή είναι %s και περιόρισε την συνομιλία σε συνεργάτες %s
+issues.lock_no_reason=: κλείδωσε το ζήτημα και την περιόρισε σε συνεργάτες %s
+issues.unlock_comment=: ξεκλείδωσε αυτή τη συνομιλία %s
issues.lock_confirm=Κλείδωμα
issues.unlock_confirm=Ξεκλείδωμα
-issues.lock.notice_1=- Άλλοι χρήστες δεν μπορούν να προσθέσουν νέα σχόλια σε αυτό το ζήτημα.
-issues.lock.notice_2=- Εσείς και άλλοι συνεργάτες με πρόσβαση σε αυτό το αποθετήριο μπορούν ακόμα να αφήσουν σχόλια που μπορούν να δουν άλλοι.
-issues.lock.notice_3=- Μπορείτε πάντα να ξεκλειδώσετε αυτό το ζήτημα ξανά στο μέλλον.
-issues.unlock.notice_1=- Όλοι θα ήταν σε θέση να σχολιάσουν αυτό το ζήτημα για άλλη μια φορά.
-issues.unlock.notice_2=- Μπορείτε πάντα να κλειδώσετε αυτό το θέμα ξανά στο μέλλον.
-issues.lock.reason=Λόγος κλειδώματος
+issues.lock.notice_1=- Άλλοι χρήστες δεν μπορούν να αφήσουν νέα σχόλια σε αυτό το ζήτημα.
+issues.lock.notice_2=- Εσείς και άλλοι συνεργάτες που έχουν πρόσβαση στο αποθετήριο θα μπορείτε ακόμα να αφήσετε σχόλια που θα είναι ορατά σε άλλους.
+issues.lock.notice_3=- Θα μπορείτε να ξεκλειδώσετε αυτό το ζήτημα πιο μετά.
+issues.unlock.notice_1=- Όλοι θα βρίσκονται πάλι σε θέση να αφήσουν σχόλιο σε αυτό το ζήτημα.
+issues.unlock.notice_2=- Θα μπορείτε πάντα να ξανακλειδώσετε αυτό το ζήτημα πιο μετά.
+issues.lock.reason=Αιτία κλειδώματος
issues.lock.title=Κλείδωμα συνομιλίας σε αυτό το ζήτημα.
issues.unlock.title=Ξεκλείδωμα συνομιλίας σε αυτό το ζήτημα.
-issues.comment_on_locked=Δεν μπορείτε να σχολιάσετε ένα κλειδωμένο ζήτημα.
+issues.comment_on_locked=Δεν μπορείτε να σχολιάσετε σε ένα κλειδωμένο ζήτημα.
issues.delete=Διαγραφή
-issues.delete.title=Διαγραφή αυτού του ζητήματος;
-issues.delete.text=Θέλετε πραγματικά να διαγράψετε αυτό το ζήτημα; (Αυτό θα σβήσει οριστικά όλο το περιεχόμενο του. Εξετάστε αν θέλετε να το κλείσετε, αν σκοπεύεται να το αρχειοθετήσετε)
-issues.tracker=Καταγραφή Χρόνου
-issues.start_tracking_short=Εκκίνηση Χρονομέτρου
-issues.start_tracking=Εκκίνηση Καταγραφής Χρόνου
+issues.delete.title=Να διαγραφεί αυτό το ζήτημα;
+issues.delete.text=Είστε βέβαιοι πως θέλετε να διαγράψετε αυτό το ζήτημα; (Αυτό θα σβήσει οριστικά όλο το περιεχόμενο του. Εξετάστε αν μήπως θέλετε να κλείσετε το ζήτημα, αν θα θέλατε να το κρατήσετε.)
+issues.tracker=Καταγραφή χρόνου
+issues.start_tracking_short=Εκκίνηση χρονόμετρου
+issues.start_tracking=Εκκίνηση καταγραφής χρόνου
issues.start_tracking_history=`ξεκίνησε να εργάζεται %s`
-issues.tracker_auto_close=Το χρονόμετρο θα σταματήσει αυτόματα όταν κλείσει αυτό το ζήτημα
-issues.tracking_already_started=`Έχετε ήδη ξεκινήσει την καταγραφή του χρόνου σε ένα άλλο ζήτημα!`
-issues.stop_tracking=Διακοπή Χρονομέτρου
+issues.tracker_auto_close=Το χρονόμετρο θα σταματήσει αυτόματα όταν αυτό το ζήτημα κλείσει
+issues.tracking_already_started=`Έχετε ήδη ξεκινήσει να καταγράφετε τον χρόνο σας σε ένα άλλο ζήτημα!`
+issues.stop_tracking=Διακοπή χρονόμετρου
issues.stop_tracking_history=`σταμάτησε να εργάζεται %s`
issues.cancel_tracking=Απόρριψη
-issues.cancel_tracking_history=`ακύρωσε τη παρακολούθηση χρόνου %s`
-issues.add_time=Χειροκίνητη Προσθήκη Ώρας
-issues.del_time=Διαγραφή αυτού του αρχείου χρόνου
-issues.add_time_short=Προσθήκη Χρόνου
+issues.cancel_tracking_history=`ακύρωσε τη καταγραφή χρόνου %s`
+issues.add_time=Χειροκίνητη προσθήκη ώρας
+issues.del_time=Διαγραφή αυτής της καταγραφής χρόνου
+issues.add_time_short=Προσθήκη χρόνου
issues.add_time_cancel=Ακύρωση
issues.add_time_history=`πρόσθεσε χρόνο που δαπανήθηκε %s`
-issues.del_time_history=`διέγραψε το χρόνο που δαπανήθηκε %s`
-issues.add_time_hours=Ώρες
-issues.add_time_minutes=Λεπτά
+issues.del_time_history=`διέγραψε χρόνο που δαπανήθηκε %s`
+issues.add_time_hours=ώρες
+issues.add_time_minutes=λεπτά
issues.add_time_sum_to_small=Δεν εισήχθη χρόνος.
-issues.time_spent_total=Συνολική Δαπάνη Χρόνου
-issues.time_spent_from_all_authors=`Συνολική Δαπάνη Χρόνου: %s`
-issues.due_date=Ημερομηνία Παράδοσης
-issues.invalid_due_date_format=Η μορφή της ημερομηνίας παράδοσης πρέπει να είναι 'yyyy-mm-dd'.
-issues.error_modifying_due_date=Αποτυχία τροποποίησης της ημερομηνίας παράδοσης.
-issues.error_removing_due_date=Αποτυχία κατάργησης της ημερομηνίας παράδοσης.
+issues.time_spent_total=Συνολική δαπάνη χρόνου
+issues.time_spent_from_all_authors=`Συνολική δαπάνη χρόνου: %s`
+issues.due_date=Ημερομηνία παράδοσης
+issues.invalid_due_date_format=Η ημερομηνίας παράδοσης πρέπει να έχει την μορφή «εεεε-μμ-ηη».
+issues.error_modifying_due_date=Προέκυψε σφάλμα κατά την αλλαγή ημερομηνίας παράδοσης.
+issues.error_removing_due_date=Προέκυψε σφάλμα κατά την κατάργηση ημερομηνίας παράδοσης.
issues.push_commit_1=πρόσθεσε %d υποβολή %s
issues.push_commits_n=πρόσθεσε %d υποβολές %s
-issues.force_push_codes=`force-pushed %[1]s από το %[2]s
στο %[4]s
%[6]s`
+issues.force_push_codes=`έκανε force-push %[1]s από το %[2]s
στο %[4]s
%[6]s`
issues.force_push_compare=Σύγκριση
issues.due_date_form=εεεε-μμ-ηη
issues.due_date_form_add=Προσθήκη ημερομηνίας παράδοσης
-issues.due_date_form_edit=Επεξεργασία
-issues.due_date_form_remove=Διαγραφή
-issues.due_date_not_writer=Χρειάζεστε πρόσβαση εγγραφής στο αποθετήριο για να ενημερώσετε την ημερομηνία λήξης ενός προβλήματος.
+issues.due_date_form_edit=Αλλαγή
+issues.due_date_form_remove=Αφαίρεση
+issues.due_date_not_writer=Χρειάζεστε πρόσβαση εγγραφής για να τροποποιήσετε την ημερομηνία παράδοσης του ζητήματος.
issues.due_date_not_set=Δεν ορίστηκε ημερομηνία παράδοσης.
-issues.due_date_added=πρόσθεσε την ημερομηνία παράδοσης %s %s
+issues.due_date_added=όρισε την ημερομηνία παράδοσης %s %s
issues.due_date_modified=τροποποίησε την ημερομηνία παράδοσης από %[2]s σε %[1]s %[3]s
issues.due_date_remove=αφαίρεσε την ημερομηνία παράδοσης %s %s
issues.due_date_overdue=Εκπρόθεσμο
-issues.due_date_invalid=Η ημερομηνία παράδοσης δεν είναι έγκυρη ή εκτός εύρους. Παρακαλούμε χρησιμοποιήστε τη μορφή 'εεεε-μμ-ηη'.
+issues.due_date_invalid=Η ημερομηνία παράδοσης δεν είναι έγκυρη ή εκτός εύρους. Παρακαλούμε χρησιμοποιήστε τη μορφή «εεεε-μμ-ηη».
issues.dependency.title=Εξαρτήσεις
issues.dependency.issue_no_dependencies=Δεν έχουν οριστεί εξαρτήσεις.
issues.dependency.pr_no_dependencies=Δεν έχουν οριστεί εξαρτήσεις.
-issues.dependency.no_permission_1=Δεν έχετε άδεια για ανάγνωση %d εξάρτηση
-issues.dependency.no_permission_n=Δεν έχετε άδεια να ανάγνωση %d εξαρτήσεων
-issues.dependency.no_permission.can_remove=Δεν έχετε άδεια για ανάγνωση αυτής της εξάρτησης, αλλά μπορείτε να τη καταργήσετε
+issues.dependency.no_permission_1=Δεν έχετε άδεια ανάγνωσης για %d εξάρτηση
+issues.dependency.no_permission_n=Δεν έχετε άδεια ανάγνωσης για %d εξαρτήσεις
+issues.dependency.no_permission.can_remove=Δεν έχετε άδεια για ανάγνωση αυτής της εξάρτησης, αλλά μπορείτε να την καταργήσετε
issues.dependency.add=Προσθήκη εξάρτησης…
issues.dependency.cancel=Ακύρωση
issues.dependency.remove=Διαγραφή
issues.dependency.remove_info=Αφαίρεση αυτής της εξάρτησης
issues.dependency.added_dependency=`πρόσθεσε μια νέα εξάρτηση %s`
issues.dependency.removed_dependency=`αφαίρεσε μια εξάρτηση %s`
-issues.dependency.pr_closing_blockedby=Το κλείσιμο αυτού pull request εμποδίζεται από τα ακόλουθα ζητήματα
+issues.dependency.pr_closing_blockedby=Το κλείσιμο αυτού του pull request εμποδίζεται από τα ακόλουθα ζητήματα
issues.dependency.issue_closing_blockedby=Το κλείσιμο αυτού του ζητήματος εμποδίζεται από τα ακόλουθα ζητήματα
issues.dependency.issue_close_blocks=Αυτό το ζήτημα εμποδίζει το κλείσιμο των ακόλουθων ζητημάτων
issues.dependency.pr_close_blocks=Αυτό το pull request εμποδίζει το κλείσιμο των ακόλουθων ζητημάτων
-issues.dependency.issue_close_blocked=Πρέπει να κλείσετε όλα τα ζητήματα που εμποδίζουν αυτό το ζήτημα πριν το κλείσετε.
-issues.dependency.issue_batch_close_blocked=Δεν είναι δυνατό το ομαδικό κλείσιμο ζητημάτων που επιλέξατε, επειδή το ζήτημα #%d ακόμα έχει ανοιχτές εξαρτήσεις
+issues.dependency.issue_close_blocked=Για να κλείσετε το ζήτημα αυτό, πρέπει πρώτα να κλείσετε όλα τα ζητήματα που το εμποδίζουν.
+issues.dependency.issue_batch_close_blocked=Δεν είναι δυνατό το κλείσιμο όλων των ζητημάτων που επιλέξατε, επειδή το ζήτημα #%d έχει ακόμα εξαρτήσεις που δεν έχουν κλειστεί
issues.dependency.pr_close_blocked=Πρέπει να κλείσετε όλα τα ζητήματα που εμποδίζουν αυτό το pull request για να μπορέσετε να το συγχωνεύσετε.
issues.dependency.blocks_short=Μπλοκάρει
issues.dependency.blocked_by_short=Εξαρτάται από
-issues.dependency.remove_header=Αφαίρεση Εξάρτησης
-issues.dependency.issue_remove_text=Αυτό θα αφαιρέσει την εξάρτηση από αυτό το ζήτημα. Συνέχεια;
+issues.dependency.remove_header=Αφαίρεση εξάρτησης
+issues.dependency.issue_remove_text=Αυτό θα αφαιρέσει την εξάρτηση από αυτό το ζήτημα. Να γίνει συνέχεια;
issues.dependency.pr_remove_text=Αυτό θα αφαιρέσει την εξάρτηση από αυτό το pull request. Συνέχεια;
issues.dependency.setting=Ενεργοποίηση Εξαρτήσεων Για Ζητήματα και Pull Requests
issues.dependency.add_error_same_issue=Δεν μπορείτε να εξαρτάτε ένα ζήτημα από τον εαυτό του.
@@ -1645,17 +1686,17 @@ issues.review.self.approval=Δεν μπορείτε να εγκρίνετε το
issues.review.self.rejection=Δεν μπορείτε να ζητήσετε αλλαγές στο δικό σας pull request.
issues.review.approve=ενέκρινε αυτές τις αλλαγές %s
issues.review.comment=αξιολόγησε %s
-issues.review.dismissed=απέρριψε την αξιολόγηση %s %s
+issues.review.dismissed=απέρριψε την αξιολόγηση του/της %s %s
issues.review.dismissed_label=Απορρίφθηκε
issues.review.left_comment=άφησε ένα σχόλιο
issues.review.content.empty=Θα πρέπει να αφήσετε ένα σχόλιο υποδεικνύοντας την ζητούμενη αλλαγή(ές).
issues.review.reject=ζήτησε αλλαγές %s
-issues.review.wait=ζητήθηκε για αναθεώρηση %s
-issues.review.add_review_request=ζητήθηκε αναθεώρηση από %s %s
-issues.review.remove_review_request=αφαιρέθηκε αίτηση αναθεώρησης για %s %s
-issues.review.remove_review_request_self=αρνήθηκε να αναθεωρήσει %s
+issues.review.wait=ζητήθηκε για έλεγχο %s
+issues.review.add_review_request=ζητήθηκε έλεγχος από %s %s
+issues.review.remove_review_request=αφαιρέθηκε αίτημα ελέγχου για %s %s
+issues.review.remove_review_request_self=αρνήθηκε να ελέγξει %s
issues.review.pending=Εκκρεμεί
-issues.review.pending.tooltip=Αυτό το σχόλιο προς το παρόν δεν είναι ορατό από άλλους χρήστες. Για να υποβάλετε τα σχόλιά σας, επιλέξτε "%s" -> "%s/%s/%s" στη κορυφή της σελίδας.
+issues.review.pending.tooltip=Αυτό το σχόλιο προς το παρόν δεν είναι ορατό σε άλλους χρήστες. Για να υποβάλετε τα σχόλιά σας, επιλέξτε "%s" -> "%s/%s/%s" στη κορυφή της σελίδας.
issues.review.review=Αξιολόγηση
issues.review.reviewers=Εξεταστές
issues.review.outdated=Παρωχημένο
@@ -1712,9 +1753,9 @@ pulls.nothing_to_compare=Αυτοί οι κλάδοι είναι όμοιοι.
pulls.nothing_to_compare_and_allow_empty_pr=Αυτοί οι κλάδοι είναι ίσοι. Αυτό το PR θα είναι κενό.
pulls.has_pull_request=`Υπάρχει ήδη pull request μεταξύ αυτών των κλάδων: %[2]s#%[3]d`
pulls.create=Δημιουργία Pull Request
-pulls.title_desc=θέλει να συγχωνεύσει %[1]d υποβολές από %[2]s
σε %[3]s
-pulls.merged_title_desc=συγχώνευσε %[1]d υποβολές από %[2]s
σε %[3]s
%[4]s
-pulls.change_target_branch_at=`άλλαξε τον κλάδο στόχο από %s σε %s %s`
+pulls.title_desc_few=θέλει να συγχωνεύσει %[1]d υποβολές από %[2]s
σε %[3]s
+pulls.merged_title_desc_few=συγχώνευσε %[1]d υποβολές από %[2]s
σε %[3]s
%[4]s
+pulls.change_target_branch_at=`άλλαξε τον κλάδο προορισμού από %s σε %s %s`
pulls.tab_conversation=Συζήτηση
pulls.tab_commits=Υποβολές
pulls.tab_files=Αρχεία Με Αλλαγές
@@ -1733,15 +1774,15 @@ pulls.add_prefix=Προσθήκη %s προθέματος
pulls.remove_prefix=Αφαίρεση %s προθέματος
pulls.data_broken=Αυτό το pull request είναι κατεστραμμένο λόγω των πληροφοριών του fork που λείπουν.
pulls.files_conflicted=Αυτό το pull request περιέχει αλλαγές που συγκρούονται με το κλάδο προορισμού.
-pulls.is_checking=Ο έλεγχος συγκρούσεων κατά την συγχώνευση είναι σε εξέλιξη. Δοκιμάστε ξανά σε λίγα λεπτά.
+pulls.is_checking=Ο έλεγχος συγκρούσεων κατά την συγχώνευση βρίσκεται σε εξέλιξη. Δοκιμάστε ξανά σε λίγα λεπτά.
pulls.is_ancestor=Αυτός ο κλάδος περιλαμβάνεται ήδη στον κλάδο προορισμού. Δεν υπάρχει τίποτα για συγχώνευση.
-pulls.is_empty=Οι αλλαγές σε αυτόν τον κλάδο είναι ήδη στον κλάδο προορισμού. Θα είναι μια κενή υποβολή.
+pulls.is_empty=Οι αλλαγές σε αυτόν τον κλάδο βρίσκονται ήδη στον κλάδο προορισμού. Θα είναι μια κενή υποβολή.
pulls.required_status_check_failed=Ορισμένοι απαιτούμενοι έλεγχοι δεν ήταν επιτυχείς.
pulls.required_status_check_missing=Λείπουν ορισμένοι απαιτούμενοι έλεγχοι.
pulls.required_status_check_administrator=Ως διαχειριστής, μπορείτε ακόμα να συγχωνεύσετε αυτό το pull request.
pulls.blocked_by_approvals=Το pull request δεν έχει ακόμα αρκετές εγκρίσεις. Δόθηκαν %d από %d εγκρίσεις.
-pulls.blocked_by_rejection=Αυτό το Pull Request έχει αλλαγές που ζητούνται από έναν επίσημο εξεταστή.
-pulls.blocked_by_official_review_requests=Αυτό το Pull Request έχει επίσημες αιτήσεις αξιολόγησης.
+pulls.blocked_by_rejection=Αυτό το pull request έχει αλλαγές που ζητούνται από έναν επίσημο εξεταστή.
+pulls.blocked_by_official_review_requests=Αυτό το pull request έχει επίσημες αιτήσεις αξιολόγησης.
pulls.blocked_by_outdated_branch=Αυτό το pull request έχει αποκλειστεί επειδή είναι παρωχημένο.
pulls.blocked_by_changed_protected_files_1=Αυτό το pull request έχει αποκλειστεί επειδή αλλάζει ένα προστατευμένο αρχείο:
pulls.blocked_by_changed_protected_files_n=Αυτό το pull request έχει αποκλειστεί επειδή αλλάζει προστατευμένα αρχεία:
@@ -1754,8 +1795,8 @@ pulls.approve_count_1=%d έγκριση
pulls.approve_count_n=%d εγκρίσεις
pulls.reject_count_1=%d αίτημα αλλαγής
pulls.reject_count_n=%d αιτήματα αλλαγής
-pulls.waiting_count_1=%d αναμονή αναθεώρησης
-pulls.waiting_count_n=%d αναμονή αναθεωρήσεων
+pulls.waiting_count_1=%d αναμονή αξιολόγησης
+pulls.waiting_count_n=%d αναμονές αξιολόγησης
pulls.wrong_commit_id=Το id υποβολής πρέπει να είναι ένα id υποβολής στον κλάδο προορισμού
pulls.no_merge_desc=Αυτό το pull request δεν μπορεί να συγχωνευθεί επειδή όλες οι επιλογές συγχώνευσης αποθετηρίων είναι απενεργοποιημένες.
@@ -1780,9 +1821,9 @@ pulls.unrelated_histories=H Συγχώνευση Απέτυχε: Η κεφαλή
pulls.merge_out_of_date=Η συγχώνευση απέτυχε: Κατά τη δημιουργία της συγχώνευσης, η βάση ενημερώθηκε. Συμβουλή: Δοκιμάστε ξανά.
pulls.head_out_of_date=Η συγχώνευση απέτυχε: Κατά τη δημιουργία της συγχώνευσης, το HEAD ενημερώθηκε. Συμβουλή: Δοκιμάστε ξανά.
pulls.has_merged=Αποτυχία: Το pull request έχει συγχωνευθεί, δεν είναι δυνατή η συγχώνευση ξανά ή να αλλάξει ο κλάδος προορισμού.
-pulls.push_rejected=Η συγχώνευση απέτυχε: Η ώθηση απορρίφθηκε. Ελέγξτε τα Άγκιστρα Git για αυτό το αποθετήριο.
+pulls.push_rejected=Αποτυχία ώθησης: Η ώθηση απορρίφθηκε. Ελέγξτε τα Άγκιστρα Git για αυτό το αποθετήριο.
pulls.push_rejected_summary=Μήνυμα Πλήρους Απόρριψης
-pulls.push_rejected_no_message=H Συγχώνευση Aπέτυχε: Η ώθηση απορρίφθηκε, αλλά δεν υπήρχε απομακρυσμένο μήνυμα.
Ελέγξτε τα Άγκιστρα Git για αυτό το αποθετήριο
+pulls.push_rejected_no_message=H συγχώνευση απέτυχε: Η ώθηση απορρίφθηκε, αλλά δεν υπήρχε απομακρυσμένο μήνυμα.
Ελέγξτε τα Git Hooks για αυτό το αποθετήριο
pulls.open_unmerged_pull_exists=`Δεν μπορείτε να ανοίξετε εκ νέου, επειδή υπάρχει ένα εκκρεμές pull request (#%d) με πανομοιότυπες ιδιότητες.`
pulls.status_checking=Μερικοί έλεγχοι εκκρεμούν
pulls.status_checks_success=Όλοι οι έλεγχοι ήταν επιτυχείς
@@ -1824,7 +1865,7 @@ pulls.auto_merge_canceled_schedule_comment=`ακύρωσε την αυτόματ
pulls.delete.title=Διαγραφή αυτού του pull request;
pulls.delete.text=Θέλετε πραγματικά να διαγράψετε αυτό το pull request; (Αυτό θα σβήσει οριστικά όλο το περιεχόμενο του. Εξετάστε αν θέλετε να το κλείσετε, αν σκοπεύεται να το αρχειοθετήσετε)
-pulls.recently_pushed_new_branches=Ωθήσατε στο κλάδο %[1]s %[2]s
+pulls.recently_pushed_new_branches=Ωθήσατε στο κλάδο %[1]s %[2]s
pull.deleted_branch=(διαγράφηκε):%s
@@ -1835,19 +1876,19 @@ milestones.no_due_date=Δεν υπάρχει ημερομηνία παράδοσ
milestones.open=Άνοιγμα
milestones.close=Κλείσιμο
milestones.new_subheader=Τα ορόσημα μπορούν να σας βοηθήσουν να οργανώσετε τα ζητήματα και να παρακολουθείτε την πρόοδό τους.
-milestones.completeness=%d%% Ολοκληρώθηκε
+milestones.completeness=%d%% ολοκληρωμένο
milestones.create=Δημιουργία Ορόσημου
milestones.title=Τίτλος
milestones.desc=Περιγραφή
milestones.due_date=Ημερομηνία Απαίτησης (Προαιρετικό)
milestones.clear=Εκκαθάριση
-milestones.invalid_due_date_format=Η μορφή ημερομηνίας απαίτησης πρέπει να είναι 'yyyy-mm-dd'.
-milestones.create_success=Το ορόσημο "%s" δημιουργήθηκε.
+milestones.invalid_due_date_format=Η ημερομηνίας απαίτησης πρέπει να έχει την μορφή «εεεε-μμ-ηη».
+milestones.create_success=Το ορόσημο «%s» δημιουργήθηκε.
milestones.edit=Επεξεργασία Ορόσημου
milestones.edit_subheader=Τα Ορόσημα οργανώνουν ζητήματα και καταγράφουν την πρόοδο.
milestones.cancel=Ακύρωση
milestones.modify=Ενημέρωση Ορόσημου
-milestones.edit_success=Το ορόσημο "%s" ενημερώθηκε.
+milestones.edit_success=Το ορόσημο «%s» ενημερώθηκε.
milestones.deletion=Διαγραφή Ορόσημου
milestones.deletion_desc=Η διαγραφή ενός ορόσημου το αφαιρεί από όλα τα συναφή ζητήματα. Συνέχεια;
milestones.deletion_success=Το ορόσημο έχει διαγραφεί.
@@ -1858,7 +1899,7 @@ milestones.filter_sort.most_complete=Περισσότερο πλήρη
milestones.filter_sort.most_issues=Περισσότερα ζητήματα
milestones.filter_sort.least_issues=Λιγότερα ζητήματα
-signing.will_sign=Αυτή η υποβολή θα υπογραφεί με το κλειδί "%s".
+signing.will_sign=Αυτή η υποβολή θα υπογραφεί με το κλειδί «%s».
signing.wont_sign.error=Παρουσιάστηκε σφάλμα κατά τον έλεγχο για το αν η υποβολή μπορεί να υπογραφεί.
signing.wont_sign.nokey=Δεν υπάρχει διαθέσιμο κλειδί για να υπογραφεί αυτή η υποβολή.
signing.wont_sign.never=Οι υποβολές δεν υπογράφονται ποτέ.
@@ -1877,8 +1918,8 @@ ext_wiki.desc=Σύνδεση σε ένα εξωτερικό wiki.
wiki=Wiki
wiki.welcome=Καλώς ήρθατε στο Wiki.
-wiki.welcome_desc=Το wiki σας επιτρέπει να γράψετε και να μοιραστείτε τεκμηρίωση με συνεργάτες.
-wiki.desc=Γράψτε και μοιραστείτε τεκμηρίωση με συνεργάτες.
+wiki.welcome_desc=Το wiki σας επιτρέπει να γράψετε και να μοιραστείτε τεκμηριώσεις (documentation) με άλλους συνεργάτες.
+wiki.desc=Γράψτε και μοιραστείτε τεκμηριώσεις με συνεργάτες.
wiki.create_first_page=Δημιουργία της πρώτης σελίδας
wiki.page=Σελίδα
wiki.filter_page=Φιλτράρισμα σελίδας
@@ -1894,12 +1935,12 @@ wiki.file_revision=Αναθεώρηση Σελίδας
wiki.wiki_page_revisions=Αναθεωρήσεις Σελίδας Wiki
wiki.back_to_wiki=Πίσω στη σελίδα wiki
wiki.delete_page_button=Διαγραφή Σελίδας
-wiki.delete_page_notice_1=Η διαγραφή της σελίδας wiki "%s" δεν μπορεί να αναιρεθεί. Συνέχεια;
+wiki.delete_page_notice_1=Η διαγραφή της σελίδας wiki «%s» δεν μπορεί να αναιρεθεί. Συνέχεια;
wiki.page_already_exists=Υπάρχει ήδη μια σελίδα wiki με το ίδιο όνομα.
-wiki.reserved_page=Το όνομα σελίδας wiki "%s" είναι δεσμευμένο.
+wiki.reserved_page=Το όνομα σελίδας wiki «%s» είναι δεσμευμένο.
wiki.pages=Σελίδες
wiki.last_updated=Τελευταία ενημέρωση %s
-wiki.page_name_desc=Εισάγετε ένα όνομα για αυτή τη σελίδα Wiki. Μερικά ειδικά ονόματα είναι: 'Home', '_Sidebar' και '_Footer'.
+wiki.page_name_desc=Εισάγετε ένα όνομα για αυτή τη σελίδα wiki. Μερικά ειδικά ονόματα είναι: «Home», «_Sidebar» και «_Footer».
wiki.original_git_entry_tooltip=Προβολή του αρχικού αρχείου Git αντί ενός εμφανίσιμου συνδέσμου.
activity=Δραστηριότητα
@@ -1973,11 +2014,11 @@ contributors.contribution_type.commits=Υποβολές
search=Αναζήτηση
search.search_repo=Αναζήτηση αποθετηρίου
search.type.tooltip=Τύπος αναζήτησης
-search.fuzzy=Fuzzy
+search.fuzzy=Όμοιο
search.fuzzy.tooltip=Συμπερίληψη και των αποτελεσμάτων που είναι πλησιέστερα με τον όρο αναζήτησης
search.match=Ταίριασμα
search.match.tooltip=Συμπερίληψη μόνο των αποτελεσμάτων που ταιριάζουν ακριβώς με τον όρο αναζήτησης
-search.results=Αποτελέσματα αναζήτησης για "%s" σε %s
+search.results=Αποτελέσματα αναζήτησης για «%s» σε %s
search.code_no_results=Δεν βρέθηκε πηγαίος κώδικας που να ταιριάζει με τον όρο αναζήτησης.
search.code_search_unavailable=Η αναζήτηση κώδικα δεν είναι διαθέσιμη αυτή τη στιγμή. Παρακαλώ επικοινωνήστε με το διαχειριστή.
@@ -2017,7 +2058,7 @@ settings.mirror_settings.push_mirror.add=Προσθήκη Είδωλου Push
settings.mirror_settings.push_mirror.edit_sync_time=Επεξεργασία διαστήματος συγχρονισμού ειδώλου
settings.sync_mirror=Συγχρονισμός Τώρα
-settings.pull_mirror_sync_in_progress=Έλκονται αλλαγές από το απομακρυσμένο %s αυτή τη στιγμή.
+settings.pull_mirror_sync_in_progress=Έλκονται αλλαγές από την απομακρυσμένη τοποθεσία %s αυτή τη στιγμή.
settings.push_mirror_sync_in_progress=Ώθηση αλλαγών στο απομακρυσμένο %s αυτή τη στιγμή.
settings.site=Ιστοσελίδα
settings.update_settings=Ενημέρωση Ρυθμίσεων
@@ -2047,8 +2088,8 @@ settings.tracker_issue_style.regexp=Κανονική Έκφραση
settings.tracker_issue_style.regexp_pattern=Μοτίβο Κανονικής Έκφρασης
settings.tracker_issue_style.regexp_pattern_desc=Η πρώτη ομάδα θα χρησιμοποιηθεί στη θέση του {index}
.
settings.tracker_url_format_desc=Χρησιμοποιήστε τα {user}
, {repo}
και {index}
για το όνομα χρήστη, το όνομα αποθετηρίου και το ευρετήριο ζητημάτων.
-settings.enable_timetracker=Ενεργοποίηση Καταγραφής Χρόνου
-settings.allow_only_contributors_to_track_time=Μόνο οι Συμμετέχοντες να Καταγράφουν Χρόνο
+settings.enable_timetracker=Ενεργοποίηση καταγραφής χρόνου
+settings.allow_only_contributors_to_track_time=Να επιτρέπεται η καταγραφή χρόνου μόνο από συνεισφέροντες
settings.pulls_desc=Ενεργοποίηση Pull Requests στο Αποθετήριο
settings.pulls.ignore_whitespace=Αγνόηση των Κενών Χαρακτήρων στις Συγκρούσεις
settings.pulls.enable_autodetect_manual_merge=Ενεργοποίηση αυτόματης ανίχνευσης συγχώνευσης (Σημείωση: σε ορισμένες ειδικές περιπτώσεις, μπορεί να προκύψουν εσφαλμένες κρίσεις)
@@ -2102,7 +2143,7 @@ settings.trust_model.default=Προεπιλεγμένο Μοντέλο Εμπι
settings.trust_model.default.desc=Χρησιμοποιήστε το προεπιλεγμένο μοντέλο εμπιστοσύνης αποθετηρίου για αυτήν την εγκατάσταση.
settings.trust_model.collaborator=Συνεργάτης
settings.trust_model.collaborator.long=Συνεργάτης: Εμπιστοσύνη υπογραφών από συνεργάτες
-settings.trust_model.collaborator.desc=Οι έγκυρες υπογραφές από συνεργάτες αυτού του αποθετηρίου θα επισημαίνονται ως "αξιόπιστη" - (είτε ταιριάζουν με τον υποβολέα είτε όχι). Διαφορετικά, οι έγκυρες υπογραφές θα επισημανθούν "μη αξιόπιστη" αν η υπογραφή ταιριάζει με τον υποβολέα και "δεν ταιριάζει" αν όχι.
+settings.trust_model.collaborator.desc=Οι έγκυρες υπογραφές που προέρχονται από συνεργάτες του αποθετηρίου θα επισημαίνονται ως "αξιόπιστες" - (ανεξάρτητα αν ο υπογραφόμενος συνεργάτης είναι και ο υποβολέας ή όχι). Διαφορετικά, οι έγκυρες υπογραφές θα επισημανθούν ως "αξιόπιστες" μόνο αν η υπογραφή ταιριάζει με τον υποβολέα και, αλλιώς θα χαρακτηριστούν ως "αταίριαστες".
settings.trust_model.committer=Υποβολέας
settings.trust_model.committer.long=Υποβολέας: Οι υπογραφές εμπιστοσύνης που ταιριάζουν σε υποβολείς (Αυτό ταιριάζει με το GitHub και θα αναγκάσει τις υπογεγραμμένες υποβολές από το Forgejo να το έχουν ως υποβολέα)
settings.trust_model.committer.desc=Οι έγκυρες υπογραφές θα σημαίνονται ώς "αξιόπιστη" μόνο εάν ταιριάζουν με τον υποβολέα, διαφορετικά θα σημαίνωνται ως "δεν ταιριάζει". Αυτό αναγκάζει το Forgejo να είναι ο υποβολέας στις υπογεγραμμένες υποβολές με τον πραγματικό υποβολέα να αναφέρεται στην σημείωση Co-authored-by: και Co-committed-by: στην υποβολή. Το προεπιλεγμένο κλειδί Forgejo πρέπει να ταιριάζει σε ένα Χρήστη στη βάση δεδομένων.
@@ -2111,29 +2152,29 @@ settings.trust_model.collaboratorcommitter.long=Συνεργάτης+Υποβο
settings.trust_model.collaboratorcommitter.desc=Έγκυρες υπογραφές από συνεργάτες αυτού του αποθετηρίου θα επισημανθούν ως "αξιόπιστες" αν ταιριάζουν με τον υποβολέα. Διαφορετικά, οι έγκυρες υπογραφές θα φέρουν την ένδειξη "μη αξιόπιστη" αν η υπογραφή ταιριάζει με τον υποβολέα και "δεν ταιριάζει" διαφορετικά. Αυτό θα αναγκάσει το Forgejo να επισημανθεί ως ο υποβολέας στις υπογεγραμμένες υποβολές με τον πραγματικό υποβολέα να σημειώνεται ως Co-Authored-By: και Co-Committed-By: στο τέλος της υποβολής. Το προεπιλεγμένο κλειδί Forgejo πρέπει να ταιριάζει με έναν χρήστη στη βάση δεδομένων.
settings.wiki_delete=Διαγραφή Δεδομένων Wiki
settings.wiki_delete_desc=Η διαγραφή των δεδομένων του wiki του αποθετηρίου είναι μόνιμη και δεν μπορεί να αναιρεθεί.
-settings.wiki_delete_notices_1=- Αυτό θα διαγράψει μόνιμα και θα απενεργοποιήσει το wiki του αποθετηρίου για %s.
+settings.wiki_delete_notices_1=- Αυτή η ρύθμιση θα απενεργοποιήσει το wiki του αποθετηρίου για %s και θα το διαγράψει μόνιμα.
settings.confirm_wiki_delete=Διαγραφή Δεδομένων Wiki
settings.wiki_deletion_success=Τα δεδομένα wiki του αποθετηρίου έχουν διαγραφεί.
settings.delete=Διαγραφή Αυτού Του Αποθετηρίου
settings.delete_desc=Η διαγραφή ενός αποθετηρίου είναι μόνιμη και δεν μπορεί να αναιρεθεί.
settings.delete_notices_1=- Αυτή η ενέργεια ΔΕΝ ΜΠΟΡΕΙ να αναιρεθεί.
-settings.delete_notices_2=- Αυτή η ενέργεια θα διαγράψει μόνιμα το αποθετήριο %s συμπεριλαμβανομένου του κώδικα, των προβλημάτων, σχολίων, δεδομένων wiki και των ρυθμίσεων συνεργατών.
+settings.delete_notices_2=- Αυτή η ενέργεια θα διαγράψει μόνιμα το αποθετήριο %s μαζί με τον κώδικα, τα ζητημάτα, τα σχόλια, τα δεδομένα των wiki και τις ρυθμίσεις συνεργατών που βρίσκονται μέσα σε αυτό.
settings.delete_notices_fork_1=- Τα Forks αυτού του αποθετηρίου θα γίνουν ανεξάρτητα μετά τη διαγραφή.
settings.deletion_success=Το αποθετήριο έχει διαγραφεί.
settings.update_settings_success=Οι ρυθμίσεις του αποθετηρίου έχουν ενημερωθεί.
settings.update_settings_no_unit=Το αποθετήριο θα πρέπει να επιτρέπει τουλάχιστον κάποιο είδος αλληλεπίδρασης.
settings.confirm_delete=Διαγραφή Αποθετηρίου
-settings.add_collaborator=Προσθήκη Συνεργάτη
-settings.add_collaborator_success=Έχει προστεθεί ο συνεργάτης.
+settings.add_collaborator=Προσθήκη συνεργάτη
+settings.add_collaborator_success=Ο συνεργάτης προστέθηκε.
settings.add_collaborator_inactive_user=Δεν είναι δυνατή η προσθήκη ενός ανενεργού χρήστη ως συνεργάτη.
settings.add_collaborator_owner=Δεν είναι δυνατή η προσθήκη ενός ιδιοκτήτη σαν συνεργάτη.
settings.add_collaborator_duplicate=Ο συνεργάτης έχει ήδη προστεθεί σε αυτό το αποθετήριο.
-settings.delete_collaborator=Αφαίρεση
-settings.collaborator_deletion=Αφαίρεση Συνεργάτη
-settings.collaborator_deletion_desc=Η κατάργηση ενός συνεργάτη θα ανακαλέσει την πρόσβασή τους σε αυτό το αποθετήριο. Συνέχεια;
-settings.remove_collaborator_success=Ο συνεργάτης έχει αφαιρεθεί.
+settings.delete_collaborator=Κατάργηση
+settings.collaborator_deletion=Κατάργηση συνεργάτη
+settings.collaborator_deletion_desc=Η κατάργηση ενός συνεργάτη θα αφαιρέσει και την πρόσβασή του στο αποθετήριο. Είστε βέβαιοι;
+settings.remove_collaborator_success=Ο συνεργάτης έχει καταργηθεί.
settings.search_user_placeholder=Αναζήτηση χρήστη…
-settings.org_not_allowed_to_be_collaborator=Οι οργανισμοί δεν μπορούν να προστεθούν ως συνεργάτης.
+settings.org_not_allowed_to_be_collaborator=Δεν μπορείτε να προσθέσετε έναν οργανισμό ως συνεργάτη.
settings.change_team_access_not_allowed=Η αλλαγή της πρόσβασης ομάδας για το αποθετήριο έχει περιοριστεί στον ιδιοκτήτη του οργανισμού
settings.team_not_in_organization=Η ομάδα δεν είναι στον ίδιο οργανισμό με το αποθετήριο
settings.teams=Ομάδες
@@ -2270,7 +2311,7 @@ settings.title=Τίτλος
settings.deploy_key_content=Περιεχόμενο
settings.key_been_used=Ένα κλειδί διάθεσης με το ίδιο περιεχόμενο χρησιμοποιείται ήδη.
settings.key_name_used=Ένα κλειδί διάθεσης με το ίδιο όνομα υπάρχει ήδη.
-settings.add_key_success=Το κλειδί διάθεσης '%s' προστέθηκε.
+settings.add_key_success=Το κλειδί διάθεσης «%s» προστέθηκε.
settings.deploy_key_deletion=Αφαίρεση Κλειδιού Διάθεσης
settings.deploy_key_deletion_desc=Η κατάργηση ενός κλειδί διάθεσης θα ανακαλέσει την πρόσβασή του σε αυτό το αποθετήριο. Συνέχεια;
settings.deploy_key_deletion_success=Το κλειδί διάθεσης έχει αφαιρεθεί.
@@ -2281,7 +2322,7 @@ settings.protected_branch.delete_rule=Διαγραφή Κανόνα
settings.protected_branch_can_push=Επιτρέψτε ώθηση;
settings.protected_branch_can_push_yes=Μπορείτε να ωθήσετε
settings.protected_branch_can_push_no=Δεν μπορείτε να ωθήσετε
-settings.branch_protection=Προστασία Κλάδου για το Κλάδο '%s'
+settings.branch_protection=Κανόνες προστασίας για τον κλάδο «%s»
settings.protect_this_branch=Ενεργοποίηση Προστασίας Κλάδου
settings.protect_this_branch_desc=Αποτρέπει τη διαγραφή και περιορίζει το Git push και συγχώνευση στον κλάδο.
settings.protect_disable_push=Απενεργοποίηση Ώθησης
@@ -2328,9 +2369,9 @@ settings.protect_unprotected_file_patterns=Μοτίβα μη προστατευ
settings.protect_unprotected_file_patterns_desc=Μη προστατευμένα αρχεία που επιτρέπεται να αλλάξουν απευθείας εάν ο χρήστης έχει πρόσβαση εγγραφής, παρακάμπτοντας τον περιορισμό ώθησης. Επιπλέων μοτίβα μπορούν να διαχωριστούν με ερωτηματικό (';'). Δείτε την τεκμηρίωση github.com/gobwas/glob για τη σύνταξη του μοτίβου. Πχ: .drone.yml
, /docs/**/*.txt
.
settings.add_protected_branch=Ενεργοποίηση προστασίας
settings.delete_protected_branch=Απενεργοποίηση προστασίας
-settings.update_protect_branch_success=Η προστασία κλάδου για τον κανόνα "%s" ενημερώθηκε.
+settings.update_protect_branch_success=Η προστασία κλάδου για τον κανόνα «%s» ενημερώθηκε.
settings.remove_protected_branch_success=Η προστασία κλάδου για τον κανόνα "%s" αφαιρέθηκε.
-settings.remove_protected_branch_failed=Η αφαίρεση του κανόνα προστασίας κλάδου "%s" απέτυχε.
+settings.remove_protected_branch_failed=Η αφαίρεση του κανόνα προστασίας κλάδου «%s» απέτυχε.
settings.protected_branch_deletion=Απενεργοποίηση Προστασίας Κλάδου
settings.protected_branch_deletion_desc=Η απενεργοποίηση της προστασίας του κλάδου επιτρέπει στους χρήστες με άδεια εγγραφής να κάνουν push στον κλάδο. Συνέχεια;
settings.block_rejected_reviews=Φραγή συγχώνευσης αν υπάρχουν απορριπτικές αξιολογήσεις
@@ -2341,12 +2382,12 @@ settings.block_outdated_branch=Φραγή συγχώνευσης αν το pull
settings.block_outdated_branch_desc=Η συγχώνευση δεν θα είναι δυνατή όταν ο κλάδος κεφαλής είναι πίσω από τον βασικό κλάδο.
settings.default_branch_desc=Επιλέξτε έναν προεπιλεγμένο κλάδο αποθετηρίου για pull requests και υποβολές κώδικα:
settings.merge_style_desc=Συγχώνευση Στυλ
-settings.default_merge_style_desc=Προεπιλεγμένο στυλ συγχώνευσης για pull requests:
+settings.default_merge_style_desc=Προεπιλεγμένο στυλ συγχώνευσης
settings.choose_branch=Επιλέξτε έναν κλάδο…
settings.no_protected_branch=Δεν υπάρχουν προστατευμένοι κλάδοι.
settings.edit_protected_branch=Επεξεργασία
settings.protected_branch_required_rule_name=Απαιτούμενο όνομα κανόνα
-settings.protected_branch_duplicate_rule_name=Διπλότυπο όνομα κανόνα
+settings.protected_branch_duplicate_rule_name=Υπάρχει ήδη ένας κανόνας για αυτούς τους κλάδους
settings.protected_branch_required_approvals_min=Οι απαιτούμενες εγκρίσεις δεν μπορούν να είναι αρνητικές.
settings.tags=Ετικέτες
settings.tags.protection=Προστασία Ετικετών
@@ -2365,14 +2406,14 @@ settings.matrix.homeserver_url=Homeserver URL
settings.matrix.room_id=ID Δωματίου
settings.matrix.message_type=Τύπος Μηνύματος
settings.archive.button=Αρχειοθέτηση Αποθετηρίου
-settings.archive.header=Αρχειοθέτηση Αυτού του Αποθετηρίου
+settings.archive.header=Αρχειοθέτηση αποθετηρίου
settings.archive.text=Η αρχειοθέτηση του αποθετηρίου θα το αλλάξει σε μόνο για ανάγνωση. Δε θα φαίνεται στον αρχικό πίνακα. Κανείς (ακόμα και εσείς!) δε θα μπορεί να κάνει νέες υποβολές, ή να ανοίξει ζητήματα ή pull request.
settings.archive.success=Το αποθετήριο αρχειοθετήθηκε με επιτυχία.
settings.archive.error=Παρουσιάστηκε σφάλμα κατά την προσπάθεια αρχειοθέτησης του αποθετηρίου. Δείτε το αρχείο καταγραφής για περισσότερες λεπτομέρειες.
settings.archive.error_ismirror=Δε μπορείτε να αρχειοθετήσετε ένα είδωλο αποθετηρίου.
settings.archive.branchsettings_unavailable=Οι ρυθμίσεις του κλάδου δεν είναι διαθέσιμες αν το αποθετήριο είναι αρχειοθετημένο.
settings.archive.tagsettings_unavailable=Οι ρυθμίσεις της ετικέτας δεν είναι διαθέσιμες αν το αποθετήριο είναι αρχειοθετημένο.
-settings.unarchive.button=Απο-Αρχειοθέτηση αποθετηρίου
+settings.unarchive.button=Αναίρεση αρχειοθέτησης αποθετηρίου
settings.unarchive.header=Απο-Αρχειοθέτηση του αποθετηρίου
settings.unarchive.text=Η απο-αρχειοθέτηση του αποθετηρίου θα αποκαταστήσει την ικανότητά του να λαμβάνει υποβολές και ωθήσεις, καθώς και νέα ζητήματα και pull-requests.
settings.unarchive.success=Το αποθετήριο απο-αρχειοθετήθηκε με επιτυχία.
@@ -2516,28 +2557,28 @@ release.releases_for=Κυκλοφορίες για %s
release.tags_for=Ετικέτες για %s
branch.name=Όνομα Κλάδου
-branch.already_exists=Ήδη υπάρχει ένας κλάδος με το όνομα "%s".
+branch.already_exists=Ήδη υπάρχει ένας κλάδος με το όνομα «%s».
branch.delete_head=Διαγραφή
-branch.delete=`Διαγραφή του Κλάδου "%s"`
+branch.delete=`Διαγραφή του Κλάδου «%s»`
branch.delete_html=Διαγραφή Κλάδου
branch.delete_desc=Η διαγραφή ενός κλάδου είναι μόνιμη. Αν και ο διαγραμμένος κλάδος μπορεί να συνεχίσει να υπάρχει για σύντομο χρονικό διάστημα πριν να αφαιρεθεί, ΔΕΝ ΜΠΟΡΕΙ να αναιρεθεί στις περισσότερες περιπτώσεις. Συνέχεια;
-branch.deletion_success=Ο κλάδος "%s" διαγράφηκε.
-branch.deletion_failed=Αποτυχία διαγραφής του κλάδου "%s".
-branch.delete_branch_has_new_commits=Ο κλάδος "%s" δεν μπορεί να διαγραφεί επειδή προστέθηκαν νέες υποβολές μετά τη συγχώνευση.
+branch.deletion_success=Ο κλάδος «%s» διαγράφηκε.
+branch.deletion_failed=Η διαγραφή του κλάδου «%s» απέτυχε.
+branch.delete_branch_has_new_commits=Ο κλάδος «%s» δεν μπορεί να διαγραφεί επειδή προστέθηκαν νέες υποβολές μετά τη συγχώνευση.
branch.create_branch=Δημιουργία κλάδου %s
-branch.create_from=`από το "%s"`
-branch.create_success=Ο κλάδος "%s" δημιουργήθηκε.
-branch.branch_already_exists=Ο κλάδος "%s" υπάρχει ήδη σε αυτό το αποθετήριο.
-branch.branch_name_conflict=Το όνομα του κλάδου "%s" συγκρούεται με το ήδη υπάρχον κλάδο "%s".
-branch.tag_collision=Ο κλάδος "%s" δεν μπορεί να δημιουργηθεί επειδή μια ετικέτα με το ίδιο όνομα υπάρχει ήδη στο αποθετήριο.
+branch.create_from=`από το «%s»`
+branch.create_success=Ο κλάδος «%s» δημιουργήθηκε.
+branch.branch_already_exists=Ο κλάδος «%s» υπάρχει ήδη σε αυτό το αποθετήριο.
+branch.branch_name_conflict=Το όνομα του κλάδου «%s» συγκρούεται με το ήδη υπάρχον κλάδο «%s».
+branch.tag_collision=Ο κλάδος «%s» δεν μπορεί να δημιουργηθεί επειδή μια ετικέτα με το ίδιο όνομα υπάρχει ήδη στο αποθετήριο.
branch.deleted_by=Διαγράφηκε από %s
-branch.restore_success=Ο κλάδος "%s" επαναφέρθηκε.
-branch.restore_failed=Αποτυχία επαναφοράς του κλάδου "%s".
-branch.protected_deletion_failed=Ο κλάδος "%s" προστατεύεται. Δεν μπορεί να διαγραφεί.
-branch.default_deletion_failed=Ο κλάδος "%s" είναι ο προεπιλεγμένος κλάδος. Δεν μπορεί να διαγραφεί.
-branch.restore=`Επαναφορά του Κλάδου "%s"`
-branch.download=`Λήψη του Κλάδου "%s"`
-branch.rename=`Μετονομασία Κλάδου "%s"`
+branch.restore_success=Ο κλάδος «%s» επαναφέρθηκε.
+branch.restore_failed=Αποτυχία επαναφοράς του κλάδου «%s».
+branch.protected_deletion_failed=Ο κλάδος «%s» είναι προστατευόμενος. Δεν μπορεί να διαγραφεί.
+branch.default_deletion_failed=Ο κλάδος «%s» είναι προεπιλεγμένος κλάδος. Δεν μπορεί να διαγραφεί.
+branch.restore=`Επαναφορά του κλάδου «%s»`
+branch.download=`Λήψη του κλάδου «%s»`
+branch.rename=`Μετονομασία κλάδου «%s»`
branch.search=Αναζήτηση Κλάδου
branch.included_desc=Αυτός ο κλάδος είναι μέρος του προεπιλεγμένου κλάδου
branch.included=Περιλαμβάνεται
@@ -2548,15 +2589,15 @@ branch.rename_branch_to=Μετονομασία του "%s" σε:
branch.confirm_rename_branch=Μετονομασία κλάδου
branch.create_branch_operation=Δημιουργία κλάδου
branch.new_branch=Δημιουργία νέου κλάδου
-branch.new_branch_from=`Δημιουργία νέου κλάδου από το "%s"`
+branch.new_branch_from=`Δημιουργία νέου κλάδου από το «%s»`
branch.renamed=Ο κλάδος %s μετονομάστηκε σε %s.
tag.create_tag=Δημιουργία ετικέτας %s
tag.create_tag_operation=Δημιουργία ετικέτας
tag.confirm_create_tag=Δημιουργία ετικέτας
-tag.create_tag_from=`Δημιουργία νέας ετικέτας από το "%s"`
+tag.create_tag_from=`Δημιουργία νέας ετικέτας από το «%s»`
-tag.create_success=Η ετικέτα "%s" δημιουργήθηκε.
+tag.create_success=Η ετικέτα «%s» δημιουργήθηκε.
topic.manage_topics=Διαχείριση Θεμάτων
topic.done=Ολοκληρώθηκε
@@ -2569,9 +2610,64 @@ find_file.no_matching=Δεν ταιριάζει κανένα αρχείο
error.csv.too_large=Δεν είναι δυνατή η απόδοση αυτού του αρχείου επειδή είναι πολύ μεγάλο.
error.csv.unexpected=Δεν είναι δυνατή η απόδοση αυτού του αρχείου, επειδή περιέχει έναν μη αναμενόμενο χαρακτήρα στη γραμμή %d και στη στήλη %d.
error.csv.invalid_field_count=Δεν είναι δυνατή η απόδοση αυτού του αρχείου, επειδή έχει λάθος αριθμό πεδίων στη γραμμή %d.
+commits.renamed_from = Μετονομάστηκε από %σ
+settings.wiki_rename_branch_main_desc = Ο κλάδος, ο οποίος χρησιμοποιείται εσωτερικά από το wiki, θα μετονομαστεί σε «%s». Αυτή η αλλαγή είναι μόνιμη και μη αναστρέψιμη.
+issues.comment.blocked_by_user = Δεν μπορείτε να αφήσετε σχόλιο σε αυτό το ζήτημα, επειδή ο κάτοχος του αποθετηρίου ή το άτομο που δημιούργησε το ζήτημα σας έχει αποκλείσει.
+pulls.blocked_by_user = Δεν μπορείτε να δημιουργήσετε pull request σε αυτό το αποθετήριο, επειδή ο κάτοχος του αποθετηρίου σας έχει αποκλείσει.
+pulls.made_using_agit = AGit
+wiki.cancel = Ακύρωση
+settings.units.add_more = Προσθήκη περισσότερων...
+settings.new_owner_blocked_doer = Ο νέος κάτοχος του αποθετηρίου σας έχει αποκλείσει.
+settings.enter_repo_name = Γράψτε το όνομα του κατόχου και του αποθετηρίου ακριβώς όπως το βλέπετε:
+settings.confirmation_string = Κείμενο επιβεβαίωσης
+settings.units.overview = Επισκόπηση
+pulls.commit_ref_at = `ανέφερε το pull request στην υποβολή %[2]s`
+contributors.contribution_type.filter_label = Είδος συνεισφοράς:
+settings.wiki_rename_branch_main_notices_1 = Αυτή η ενέργεια ΔΕΝ αναιρείται.
+activity.navbar.contributors = Συνεισφέροντες
+contributors.contribution_type.additions = Προσθήκες
+contributors.contribution_type.deletions = Διαγραφές
+migrate.forgejo.description = Μεταφορά δεδομένων από το codeberg.org ή άλλων υπηρεσιών Forgejo.
+rss.must_be_on_branch = Για να αποκτήσετε ένα RSS feed, πρέπει να βρίσκεστε σε έναν κλάδο.
+clone_in_vscodium = Κλωνοποίηση στο VSCodium
+editor.invalid_commit_mail = Αυτή η διεύθυνση email δεν είναι έγκυρη για την δημιουργία μίας υποβολής.
+pulls.nothing_to_compare_have_tag = Ο επιλεγμένος κλάδος/tag είναι παρόμοιος.
+issues.blocked_by_user = Δεν μπορείτε να δημιουργήσετε ζητήματα σε αυτό το αποθετήριο, επειδή ο κάτοχος του αποθετηρίου σας έχει αποκλείσει.
+pulls.agit_explanation = Δημιουργημένο μέσω του AGit. Το AGit επιτρέπει σε συνεισφέροντες να προτείνουν αλλαγές χρησιμοποιώντας την εντολή «git push», χωρίς την δημιουργία fork ή έναν νέο κλάδο.
+activity.navbar.recent_commits = Πρόσφατες υποβολές
+settings.wiki_globally_editable = Να επιτρέπεται η επεξεργασία του wiki σε όλους
+admin.manage_flags = Διαχείριση σημάνσεων
+admin.enabled_flags = Το αποθετήριο έχει τις εξής σημάνσεις:
+settings.mirror_settings.pushed_repository = Προοριζόμενο αποθετήριο
+admin.flags_replaced = Οι σημάνσεις του αποθετηρίου αντικαταστάθηκαν
+activity.navbar.code_frequency = Συχνότητα κώδικα
+settings.wiki_branch_rename_success = Το όνομα κλάδου wiki του αποθετηρίου κανονικοποιήθηκε επιτυχώς.
+settings.confirm_wiki_branch_rename = Μετονομασία κλάδου wiki
+admin.update_flags = Ενημέρωση σημάνσεων
+settings.wiki_rename_branch_main = Κανονικοποίηση ονόματος κλάδου wiki
+admin.failed_to_replace_flags = Προέκυψε σφάλμα κατά την αντικατάσταση των σημάνσεων του αποθετηρίου
+mirror_sync = σε συγχρονισμό
+desc.sha256 = SHA256
+pulls.fast_forward_only_merge_pull_request = Μόνο fast-forward
+pulls.reopen_failed.head_branch = Δεν είναι δυνατό το επανάνοιγμα του pull request, επειδή δεν υπάρχει πια ο κλάδος στο οποίο περιέχονται οι αλλαγές του (head branch).
+settings.units.units = Μονάδες αποθετηρίου
+settings.wiki_branch_rename_failure = Προέκυψε σφάλμα κατά την κανονικοποίηση του ονόματος κλάδου wiki του αποθετηρίου.
+settings.ignore_stale_approvals = Να αγνοούνται οι παρωχημένες εγκρίσεις
+pulls.reopen_failed.base_branch = Δεν είναι δυνατό το επανάνοιγμα του pull request, επειδή δεν υπάρχει πια ο κλάδος πάνω στο οποίο βασίζονται οι αλλαγές του (base branch).
+activity.navbar.pulse = Παλμός
+error.broken_git_hook = Τα Git hook του αποθετηρίου δεν φαίνονται να λειτουργούν. Παρακαλώ ακολουθήστε τον οδηγό για να τα διορθώσετε, και μετά ωθήστε μερικές υποβολές (commits) για να γίνει επανέλεγχος.
+settings.add_collaborator_blocked_them = Δεν είναι δυνατή η προσθήκη του χρήστη ως συνεργάτη, καθώς έχει αποκλείσει τον κάτοχο του αποθετηρίου.
+settings.wiki_rename_branch_main_notices_2 = Αυτό θα αλλάξει το όνομα του κλάδου που χρησιμοποιείται εσωτερικά για το wiki του αποθετηρίου %s. Αν έχετε ένα τοπικό αντίγραφο του αποθετηρίου, θα χρειαστεί να αλλάξετε τα checkout του.
+settings.add_collaborator_blocked_our = Δεν είναι δυνατή η προσθήκη του χρήστη ως συνεργάτη, καθώς ο κάτοχος του αποθετηρίου τον έχει αποκλείσει.
[graphs]
component_loading_failed = Δεν ήταν δυνατή η φόρτωση του %s
+component_loading = Γίνεται φόρτωση του %s...
+component_loading_info = Αυτό μπορεί να πάρει λίγη ώρα…
+component_failed_to_load = Προέκυψε ένα απρόσμενο σφάλμα.
+contributors.what = συνεισφορές
+recent_commits.what = πρόσφατες υποβολές
+code_frequency.what = συχνότητα κώδικα
[org]
org_name_holder=Όνομα Οργανισμού
@@ -2596,8 +2692,8 @@ team_permission_desc=Δικαίωμα
team_unit_desc=Να επιτρέπεται η Πρόσβαση σε Τμήματα του Αποθετηρίου
team_unit_disabled=(Απενεργοποιημένο)
-form.name_reserved=Το όνομα οργανισμού "%s" είναι δεσμευμένο.
-form.name_pattern_not_allowed=Το μοτίβο "%s" δεν επιτρέπεται μέσα σε ένα όνομα οργανισμού.
+form.name_reserved=Το όνομα οργανισμού «%s» είναι δεσμευμένο.
+form.name_pattern_not_allowed=Το μοτίβο «%s» δεν επιτρέπεται μέσα σε ένα όνομα οργανισμού.
form.create_org_not_allowed=Δεν επιτρέπεται να δημιουργήσετε έναν οργανισμό.
settings=Ρυθμίσεις
@@ -2647,7 +2743,7 @@ members.invite_now=Πρόσκληση Τώρα
teams.join=Συμμετοχή
teams.leave=Αποχώρηση
-teams.leave.detail=Αποχώρηση από %s;
+teams.leave.detail=Αποχώρηση από την ομάδα %s;
teams.can_create_org_repo=Δημιουργία αποθετηρίων
teams.can_create_org_repo_helper=Τα μέλη μπορούν να δημιουργήσουν νέα αποθετήρια στον οργανισμό. Ο δημιουργός θα αποκτήσει πρόσβαση διαχειριστή στο νέο αποθετήριο.
teams.none_access=Καμία Πρόσβαση
@@ -2659,7 +2755,7 @@ teams.read_access_helper=Τα μέλη μπορούν να δουν και να
teams.write_access=Εγγραφή
teams.write_access_helper=Τα μέλη μπορούν να δουν και να κλωνοποιήσουν τα αποθετήρια της ομάδας.
teams.admin_access=Πρόσβαση Διαχειριστή
-teams.admin_access_helper=Τα μέλη μπορούν να κάνουν push και pull στα αποθετήρια της ομάδας όπως και να προσθέσουν συνεργάτες σε αυτά.
+teams.admin_access_helper=Τα μέλη μπορούν να κάνουν push και pull στα αποθετήρια της ομάδας, καθώς και να προσθέσουν συνεργάτες σε αυτά.
teams.no_desc=Η ομάδα δεν έχει περιγραφή
teams.settings=Ρυθμίσεις
teams.owners_permission_desc=Οι ιδιοκτήτες έχουν πλήρη πρόσβαση σε όλα τα αποθετήρια και έχουν πρόσβαση διαχειριστή στον οργανισμό.
@@ -2667,14 +2763,14 @@ teams.members=Μέλη Ομάδας
teams.update_settings=Ενημέρωση Ρυθμίσεων
teams.delete_team=Διαγραφή Ομάδας
teams.add_team_member=Προσθήκη Μέλους Ομάδας
-teams.invite_team_member=Πρόσκληση στο %s
+teams.invite_team_member=Πρόσκληση στην ομάδα %s
teams.invite_team_member.list=Εκκρεμείς Προσκλήσεις
teams.delete_team_title=Διαγραφή Ομάδας
teams.delete_team_desc=Η διαγραφή μιας ομάδας ανακαλεί τη πρόσβαση στο αποθετήριο από τα μέλη της. Συνέχεια;
teams.delete_team_success=Η ομάδα έχει διαγραφεί.
teams.read_permission_desc=Αυτή η ομάδα χορηγεί πρόσβαση Ανάγνωσης: τα μέλη μπορούν να δουν και να κλωνοποιήσουν τα αποθετήρια της ομάδας.
teams.write_permission_desc=Αυτή η ομάδα χορηγεί πρόσβαση Εγγραφής: τα μέλη μπορούν να διαβάσουν και να κάνουν push στα αποθετήρια της ομάδας.
-teams.admin_permission_desc=Αυτή η ομάδα παρέχει πρόσβαση Διαχειριστή: τα μέλη μπορούν να διαβάσουν, να κάνουν push και να προσθέσουν συνεργάτες στα αποθετήρια της ομάδας.
+teams.admin_permission_desc=Αυτή η ομάδα κατέχει δικαιώματα διαχειριστή: Τα μέλη της μπορούν να δουν αποθετήρια, να κάνουν push σε αυτά καθώς και να προσθέσουν συνεργάτες.
teams.create_repo_permission_desc=Επιπλέον, αυτή η ομάδα χορηγεί άδεια Δημιουργία αποθετηρίου: τα μέλη μπορούν να δημιουργήσουν νέα αποθετήρια στον οργανισμό.
teams.repositories=Αποθετήρια Ομάδας
teams.search_repo_placeholder=Αναζήτηση αποθετηρίου…
@@ -2684,7 +2780,7 @@ teams.add_all_repos_title=Προσθήκη όλων των αποθετηρίω
teams.add_all_repos_desc=Αυτό θα προσθέσει όλα τα αποθετήρια του οργανισμού στην ομάδα.
teams.add_nonexistent_repo=Το αποθετήριο που προσπαθείτε να προσθέσετε δεν υπάρχει, παρακαλώ δημιουργήστε το πρώτα.
teams.add_duplicate_users=Ο χρήστης είναι ήδη μέλος της ομάδας.
-teams.repos.none=Δεν ήταν δυνατή η πρόσβαση στα αποθετήρια από αυτήν την ομάδα.
+teams.repos.none=Αυτή η ομάδα δεν έχει πρόσβαση σε κανένα αποθετήριο.
teams.members.none=Δεν υπάρχουν μέλη σε αυτήν την ομάδα.
teams.specific_repositories=Συγκεκριμένα αποθετήρια
teams.specific_repositories_helper=Τα μέλη θα έχουν πρόσβαση μόνο σε αποθετήρια που προστίθενται ρητά στην ομάδα. Επιλέγοντας το δεν θα θα αφαιρεθούν αυτόματα τα αποθετήρια που έχουν ήδη προστεθεί με το Όλα τα αποθετήρια.
@@ -2692,10 +2788,11 @@ teams.all_repositories=Όλα τα αποθετήρια
teams.all_repositories_helper=Η ομάδα έχει πρόσβαση σε όλα τα αποθετήρια. Επιλέγοντας το θα προσθεθούν όλα τα υπάρχοντα αποθετήρια στην ομάδα.
teams.all_repositories_read_permission_desc=Αυτή η ομάδα χορηγεί πρόσβαση Ανάγνωσης σε όλα τα αποθετήρια: τα μέλη μπορούν να δουν και να κλωνοποιήσουν αποθετήρια.
teams.all_repositories_write_permission_desc=Αυτή η ομάδα χορηγεί πρόσβαση Εγγραφής σε όλα τα αποθετήρια: τα μέλη μπορούν να διαβάσουν και να κάνουν push σε αποθετήρια.
-teams.all_repositories_admin_permission_desc=Αυτή η ομάδα παρέχει πρόσβαση Διαχείρισης σε όλα τα αποθετήρια: τα μέλη μπορούν να διαβάσουν, να κάνουν push και να προσθέσουν συνεργάτες στα αποθετήρια.
+teams.all_repositories_admin_permission_desc=Αυτή η ομάδα παρέχει δικαιώματα διαχειριστή σε όλα τα αποθετήρια: Τα μέλη της μπορούν να δουν αποθετήρια, να κάνουν push σε αυτά, καθώς και να προσθέσουν συνεργάτες.
teams.invite.title=Έχετε προσκληθεί να συμμετάσχετε στην ομάδα %s του οργανισμού %s.
teams.invite.by=Προσκλήθηκε από %s
teams.invite.description=Παρακαλώ κάντε κλικ στον παρακάτω σύνδεσμο για συμμετοχή στην ομάδα.
+follow_blocked_user = Δεν μπορείτε να ακολουθήσετε αυτόν τον οργανισμό, επειδή ο οργανισμός σας έχει αποκλείσει.
[admin]
dashboard=Πίνακας Ελέγχου
@@ -2716,10 +2813,10 @@ last_page=Τελευταίο
total=Σύνολο: %d
settings=Ρυθμίσεις Διαχειριστή
-dashboard.new_version_hint=Το Forgejo %s είναι διαθέσιμο, τώρα εκτελείτε το %s. Ανατρέξτε στο blog για περισσότερες λεπτομέρειες.
+dashboard.new_version_hint=Το Forgejo %s είναι διαθέσιμο, χρησιμοποιείτε το %s. Ανατρέξτε στο blog για περισσότερες λεπτομέρειες.
dashboard.statistic=Περίληψη
-dashboard.operations=Λειτουργίες Συντήρησης
-dashboard.system_status=Κατάσταση Συστήματος
+dashboard.operations=Λειτουργίες συντήρησης
+dashboard.system_status=Κατάσταση συστήματος
dashboard.operation_name=Όνομα Λειτουργίας
dashboard.operation_switch=Αλλαγή
dashboard.operation_run=Εκτέλεση
@@ -2738,7 +2835,7 @@ dashboard.cron.error=Σφάλμα στη Προγραμματισμένη Εργ
dashboard.cron.finished=Προγραμματισμένη Εργασία: %[1]s τελείωσε
dashboard.delete_inactive_accounts=Διαγραφή όλων των μη ενεργοποιημένων λογαριασμών
dashboard.delete_inactive_accounts.started=Η διαγραφή όλων των μη ενεργοποιημένων λογαριασμών ξεκίνησε.
-dashboard.delete_repo_archives=Διαγραφή όλων των αρχείων λήψης του αποθετηρίου (ZIP, TAR.GZ, κλπ..)
+dashboard.delete_repo_archives=Διαγραφή όλων των αρχείων λήψης του αποθετηρίου (ZIP, TAR.GZ, κλπ.)
dashboard.delete_repo_archives.started=Η διαγραφή όλων των αρχείων λήψης του αποθετηρίου ξεκίνησε.
dashboard.delete_missing_repos=Διαγραφή όλων των αποθετηρίων που δεν έχουν τα αρχεία Git τους
dashboard.delete_missing_repos.started=Η διαγραφή όλων των αποθετηρίων που δεν έχουν αρχεία Git τους, ξεκίνησε.
@@ -2751,43 +2848,43 @@ dashboard.archive_cleanup=Διαγραφή παλαιών αρχείων λήψ
dashboard.deleted_branches_cleanup=Εκκαθάριση διαγραμμένων κλάδων
dashboard.update_migration_poster_id=Ενημέρωση των ID συντακτών στη μεταγκατάσταση
dashboard.git_gc_repos=Garbage collect όλων των αποθετηρίων
-dashboard.resync_all_sshkeys=Ενημέρωση του αρχείου '.ssh/authorized_keys' με τα κλειδιά SSH του Forgejo.
-dashboard.resync_all_sshprincipals=Ενημέρωση του αρχείου '.ssh/authorized_principals' με τις αρχές SSH του Forgejo.
-dashboard.resync_all_hooks=Επανασυγχρονισμός των hook pre-receive, update και post-receive όλων των αποθετηρίων.
+dashboard.resync_all_sshkeys=Ενημέρωση του αρχείου «.ssh/authorized_keys» με τα κλειδιά SSH του Forgejo.
+dashboard.resync_all_sshprincipals=Ενημέρωση του αρχείου «.ssh/authorized_principals» με τις αρχές SSH του Forgejo.
+dashboard.resync_all_hooks=Επανασυγχρονισμός των hook pre-receive, update και post-receive όλων των αποθετηρίων
dashboard.reinit_missing_repos=Επανεκκινήστε όλα τα αποθετήρια Git που λείπουν και για τα οποία υπάρχουν εγγραφές
dashboard.sync_external_users=Συγχρονισμός δεδομένων εξωτερικών χρηστών
dashboard.cleanup_hook_task_table=Εκκαθάριση πίνακα hook_task
dashboard.cleanup_packages=Εκκαθάριση ληγμένων πακέτων
-dashboard.cleanup_actions=Οι ενέργειες καθαρισμού καταγραφές και αντικείμενα
-dashboard.server_uptime=Διάρκεια Διακομιστή
+dashboard.cleanup_actions=Καθαρισμός παλιών αρχείων καταγραφής και προϊόντων από Actions
+dashboard.server_uptime=Uptime διακομιστή
dashboard.current_goroutine=Τρέχουσες Goroutines
-dashboard.current_memory_usage=Τρέχουσα Χρήση Μνήμης
-dashboard.total_memory_allocated=Συνολική Μνήμη Που Χρησιμοποιείται
-dashboard.memory_obtained=Μνήμη Που Λαμβάνεται
-dashboard.pointer_lookup_times=Πλήθος Αναζητήσεων Δείκτη
-dashboard.memory_allocate_times=Κατανομές Μνήμης
-dashboard.memory_free_times=Ελευθερώσεις Μνήμης
-dashboard.current_heap_usage=Τρέχουσα Χρήση Heap
-dashboard.heap_memory_obtained=Μνήμη Heap Που Λαμβάνεται
-dashboard.heap_memory_idle=Αδρανής Μνήμη Heap
-dashboard.heap_memory_in_use=Μνήμη Heap Σε Χρήση
-dashboard.heap_memory_released=Μνήμη Heap Που Απελευθερώθηκε
-dashboard.heap_objects=Αντικείμενα στο Heap
-dashboard.bootstrap_stack_usage=Χρήση Στοίβας Bootstrap
-dashboard.stack_memory_obtained=Μνήμη Στοίβας Που Λαμβάνεται
-dashboard.mspan_structures_usage=Χρήση Δομών Mspan
-dashboard.mspan_structures_obtained=Δομές MSpan Που Λαμβάνονται
-dashboard.mcache_structures_usage=Χρήση Δομών MCache
-dashboard.mcache_structures_obtained=Λαμβάνουν Οι Δομές MCache
-dashboard.profiling_bucket_hash_table_obtained=Λαμβάνει ο Profiling Bucket Hash Table
-dashboard.gc_metadata_obtained=Λαμβάνουν Τα Μεταδεδομένα GC
-dashboard.other_system_allocation_obtained=Λαμβάνουν Άλλες Αναθέσεις Συστήματος
-dashboard.next_gc_recycle=Επόμενη Ανακύκλωση GC
+dashboard.current_memory_usage=Τρέχουσα χρήση μνήμης
+dashboard.total_memory_allocated=Συνολική χρησιμοποιούμενη μνήμη
+dashboard.memory_obtained=Μνήμη που λαμβάνεται
+dashboard.pointer_lookup_times=Πλήθος αναζητήσεων δείκτη
+dashboard.memory_allocate_times=Κατανομές μνήμης
+dashboard.memory_free_times=Ελευθερώσεις μνήμης
+dashboard.current_heap_usage=Τρέχουσα χρήση heap
+dashboard.heap_memory_obtained=Μνήμη heap που λαμβάνεται
+dashboard.heap_memory_idle=Αδρανής μνήμη heap
+dashboard.heap_memory_in_use=Μνήμη heap σε χρήση
+dashboard.heap_memory_released=Μνήμη heap που απελευθερώθηκε
+dashboard.heap_objects=Αντικείμενα στο heap
+dashboard.bootstrap_stack_usage=Χρήση στοίβας bootstrap
+dashboard.stack_memory_obtained=Μνήμη στοίβας που λαμβάνεται
+dashboard.mspan_structures_usage=Χρήση δομών MSpan
+dashboard.mspan_structures_obtained=Δομές MSpan που έχουν ληφθεί
+dashboard.mcache_structures_usage=Χρήση δομών MCache
+dashboard.mcache_structures_obtained=Δομές MCache που έχουν ληφθεί
+dashboard.profiling_bucket_hash_table_obtained=Profiling Bucket Hash Table που έχει ληφθεί
+dashboard.gc_metadata_obtained=Μεταδεδομένα GC που έχουν ληφθεί
+dashboard.other_system_allocation_obtained=Άλλες αναθέσεις συστήματος που έχουν ληφθεί
+dashboard.next_gc_recycle=Επόμενη ανακύκλωση GC
dashboard.last_gc_time=Από Την Τελευταία Φορά GC
dashboard.total_gc_time=Σύνολο Παύσης GC
-dashboard.total_gc_pause=Σύνολο Παύσης GC
-dashboard.last_gc_pause=Τελευταία Παύση GC
-dashboard.gc_times=Πλήθος GC
+dashboard.total_gc_pause=Σύνολο παύσης GC
+dashboard.last_gc_pause=Τελευταία παύση GC
+dashboard.gc_times=Χρόνοι GC
dashboard.delete_old_actions=Διαγραφή όλων των παλαιών ενεργειών από τη βάση δεδομένων
dashboard.delete_old_actions.started=Η διαγραφή όλων των παλιών ενεργειών από τη βάση δεδομένων ξεκίνησε.
dashboard.update_checker=Ελεγκτής ενημερώσεων
@@ -2800,7 +2897,7 @@ dashboard.start_schedule_tasks=Έναρξη προγραμματισμένων
dashboard.sync_branch.started=Ο Συγχρονισμός των Κλάδων ξεκίνησε
dashboard.rebuild_issue_indexer=Αναδόμηση ευρετηρίου ζητημάτων
-users.user_manage_panel=Διαχείριση Λογαριασμών Χρηστών
+users.user_manage_panel=Διαχείριση λογαριασμών χρηστών
users.new_account=Δημιουργία Λογαριασμού Χρήστη
users.name=Όνομα Χρήστη
users.full_name=Πλήρες Όνομα
@@ -2808,15 +2905,15 @@ users.activated=Ενεργοποιήθηκε
users.admin=Διαχειριστής
users.restricted=Περιορισμένος
users.reserved=Δεσμευμένο
-users.bot=Bot
+users.bot=Ρομπότ
users.remote=Απομακρυσμένο
users.2fa=2FA
users.repos=Αποθετήρια
users.created=Δημιουργήθηκε
users.last_login=Τελευταία Σύνδεση
users.never_login=Καμία Σύνδεση
-users.send_register_notify=Αποστολή Ειδοποίησης Εγγραφής Χρήστη
-users.new_success=Ο λογαριασμός χρήστη "%s" δημιουργήθηκε.
+users.send_register_notify=Αποστολή ειδοποιήσεων εγγραφής χρήστη
+users.new_success=Ο λογαριασμός χρήστη «%s» δημιουργήθηκε.
users.edit=Επεξεργασία
users.auth_source=Πηγή Ταυτοποίησης
users.local=Τοπική
@@ -2827,11 +2924,11 @@ users.edit_account=Επεξεργασία Λογαριασμού Χρήστη
users.max_repo_creation=Μέγιστος Αριθμός Αποθετηρίων
users.max_repo_creation_desc=(Ορίστε -1 για να χρησιμοποιήσετε το προκαθορισμένο όριο.)
users.is_activated=Ο Λογαριασμός Χρήστη Ενεργοποιήθηκε
-users.prohibit_login=Απενεργοποίηση Σύνδεσης
+users.prohibit_login=Απενεργοποίηση εισόδου
users.is_admin=Είναι Διαχειριστής
users.is_restricted=Είναι Περιορισμένος
users.allow_git_hook=Μπορεί Να Δημιουργεί Git Hooks
-users.allow_git_hook_tooltip=Τα Git Hooks εκτελούνται ως ο χρήστης του ΛΣ που εκτελεί το Forgejo και θα έχουν το ίδιο επίπεδο πρόσβασης στο διακομιστή. Ως αποτέλεσμα, οι χρήστες με αυτό το ειδικό προνόμιο Git Hook μπορούν να έχουν πρόσβαση και να τροποποιήσουν όλα τα αποθετήρια του Forgejo, καθώς και τη βάση δεδομένων που χρησιμοποιεί το Forgejo. Κατά συνέπεια, είναι επίσης σε θέση να αποκτήσουν προνόμια διαχειριστή του Forgejo.
+users.allow_git_hook_tooltip=Τα Git Hooks εκτελούνται μέσω του χρήστη που εκτελεί το Forgejo και θα έχουν το ίδιο επίπεδο πρόσβασης στο διακομιστή. Ως αποτέλεσμα, οι χρήστες με αυτό το ειδικό προνόμιο Git Hook μπορούν να έχουν πρόσβαση και να τροποποιήσουν όλα τα αποθετήρια του Forgejo, καθώς και τη βάση δεδομένων που χρησιμοποιεί το Forgejo. Κατά συνέπεια, αυτοί οι χρήστες θα είναι σε θέση να αποκτήσουν δικαιώματα διαχειριστή στο Forgejo.
users.allow_import_local=Μπορεί Να Εισάγει Τοπικά Αποθετήρια
users.allow_create_organization=Μπορεί Να Δημιουργεί Οργανισμούς
users.update_profile=Ενημέρωση Λογαριασμού Χρήστη
@@ -2840,7 +2937,7 @@ users.cannot_delete_self=Δεν μπορείτε να διαγράψετε το
users.still_own_repo=Αυτός ο χρήστης εξακολουθεί να κατέχει ένα ή περισσότερα αποθετήρια. Διαγράψτε ή μεταφέρετε αυτά τα αποθετήρια πρώτα.
users.still_has_org=Αυτός ο χρήστης είναι μέλος ενός οργανισμού. Αφαιρέστε πρώτα τον χρήστη από οποιονδήποτε οργανισμό.
users.purge=Εκκαθάριση Χρήστη
-users.purge_help=Αναγκαστική διαγραφή χρήστη και των αποθετηρίων, οργανισμών και πακέτων που του ανήκουν. Όλα τα σχόλια επίσης θα διαγραφούν.
+users.purge_help=Εξαναγκαστική διαγραφή χρήστη καθώς και των αποθετηρίων, οργανισμών και πακέτων που του ανήκουν. Όλα τα σχόλια και τα ζητήματα του χρήστη θα διαγραφούν επίσης.
users.still_own_packages=Αυτός ο χρήστης εξακολουθεί να κατέχει ένα ή περισσότερα πακέτα, διαγράψτε αυτά τα πακέτα πρώτα.
users.deletion_success=Ο λογαριασμός χρήστη έχει διαγραφεί.
users.reset_2fa=Επαναφορά 2FA
@@ -2858,7 +2955,7 @@ users.list_status_filter.is_2fa_enabled=2FA Ενεργοποιημένο
users.list_status_filter.not_2fa_enabled=2FA Απενεργοποιημένο
users.details=Λεπτομέρειες Χρήστη
-emails.email_manage_panel=Διαχείριση Email Χρήστη
+emails.email_manage_panel=Διαχείριση email χρηστών
emails.primary=Κύριο
emails.activated=Ενεργοποιήθηκε
emails.filter_sort.email=Email
@@ -2871,13 +2968,13 @@ emails.duplicate_active=Αυτή η διεύθυνση email είναι ήδη
emails.change_email_header=Ενημέρωση Ιδιοτήτων Email
emails.change_email_text=Είστε βέβαιοι ότι θέλετε να ενημερώσετε αυτή τη διεύθυνση email;
-orgs.org_manage_panel=Διαχείριση Οργανισμού
+orgs.org_manage_panel=Διαχείριση οργανισμών
orgs.name=Όνομα
orgs.teams=Ομάδες
orgs.members=Μέλη
orgs.new_orga=Νέος Οργανισμός
-repos.repo_manage_panel=Διαχείριση Αποθετηρίου
+repos.repo_manage_panel=Διαχείριση αποθετηρίων
repos.unadopted=Μη Υιοθετημένα Αποθετήρια
repos.unadopted.no_more=Δεν βρέθηκαν μη υιοθετημένα αποθετήρια
repos.owner=Ιδιοκτήτης
@@ -2890,7 +2987,7 @@ repos.issues=Ζητήματα
repos.size=Μέγεθος
repos.lfs_size=Μέγεθος LFS
-packages.package_manage_panel=Διαχείριση Πακέτων
+packages.package_manage_panel=Διαχείριση πακέτων
packages.total_size=Συνολικό Μέγεθος: %s
packages.unreferenced_size=Μέγεθος Χωρίς Αναφορά: %s
packages.cleanup=Εκκαθάριση ληγμένων δεδομένων
@@ -2904,17 +3001,17 @@ packages.repository=Αποθετήριο
packages.size=Μέγεθος
packages.published=Δημοσιευμένα
-defaulthooks=Προεπιλεγμένα Webhooks
+defaulthooks=Προεπιλεγμένα webhooks
defaulthooks.desc=Τα Webhooks κάνουν αυτόματα αιτήσεις HTTP POST σε ένα διακομιστή όταν ενεργοποιούν ορισμένα γεγονότα στο Gitea. Τα Webhooks που ορίζονται εδώ είναι προκαθορισμένα και θα αντιγραφούν σε όλα τα νέα αποθετήρια. Διαβάστε περισσότερα στον οδηγό webhooks.
defaulthooks.add_webhook=Προσθήκη Προεπιλεγμένου Webhook
defaulthooks.update_webhook=Ενημέρωση Προεπιλεγμένου Webhook
-systemhooks=Webhooks Συστήματος
+systemhooks=Webhooks συστήματος
systemhooks.desc=Τα Webhooks κάνουν αυτόματα αιτήσεις HTTP POST σε ένα διακομιστή όταν ενεργοποιούνται ορισμένα γεγονότα στο Gitea. Τα Webhooks που ορίζονται εδώ θα ενεργούν σε όλα τα αποθετήρια του συστήματος, γι 'αυτό παρακαλώ εξετάστε τυχόν επιπτώσεις απόδοσης που μπορεί να έχει. Διαβάστε περισσότερα στον οδηγό webhooks.
systemhooks.add_webhook=Προσθήκη Webhook Συστήματος
systemhooks.update_webhook=Ενημέρωση Webhook Συστήματος
-auths.auth_manage_panel=Διαχείριση ΠηγήςΤαυτοποίησης
+auths.auth_manage_panel=Διαχείριση πηγών ταυτοποίησης
auths.new=Προσθήκη Πηγής Ταυτοποίησης
auths.name=Όνομα
auths.type=Τύπος
@@ -2945,7 +3042,7 @@ auths.search_page_size=Μέγεθος Σελίδας
auths.filter=Φίλτρο Χρηστών
auths.admin_filter=Φίλτρο Διαχειριστών
auths.restricted_filter=Φίλτρο Περιορισμένων
-auths.restricted_filter_helper=Αφήστε κενό για να μην ορίσετε κανέναν χρήστη ως περιορισμένο. Χρησιμοποιήστε έναν αστερίσκο ('*') για να ορίσετε όλους τους χρήστες που δεν ταιριάζουν με το φίλτρο διαχειριστή ως περιορισμένους.
+auths.restricted_filter_helper=Αφήστε κενό για να μην περιορίσετε κανέναν χρήστη. Χρησιμοποιήστε έναν αστερίσκο ('*') για να περιορίσετε όλους τους χρήστες που δεν είναι διαχειριστές.
auths.verify_group_membership=Επαλήθευση της συμμετοχής σε ομάδα στο LDAP (αφήστε το φίλτρο κενό για παράλειψη)
auths.group_search_base=DN Βάσης Αναζήτησης Ομάδων
auths.group_attribute_list_users=Χαρακτηριστικό Ομάδας Που Περιέχει Τη Λίστα Χρηστών
@@ -2954,12 +3051,12 @@ auths.map_group_to_team=Αντιστοίχιση ομάδων LDAP σε ομάδ
auths.map_group_to_team_removal=Αφαίρεση χρηστών από τις συγχρονισμένες ομάδες αν ο χρήστης δεν ανήκει στην αντίστοιχη ομάδα LDAP
auths.enable_ldap_groups=Ενεργοποίηση ομάδων LDAP
auths.ms_ad_sa=Χαρακτηριστικά Αναζήτησης Στο MS AD
-auths.smtp_auth=Τύπος Ταυτοποίησης SMTP
+auths.smtp_auth=Τύπος ταυτοποίησης SMTP
auths.smtphost=Διακομιστής SMTP
auths.smtpport=Θύρα SMTP
auths.allowed_domains=Επιτρεπόμενα Domains
auths.allowed_domains_helper=Αφήστε κενό για να επιτρέψετε όλα τα domains. Διαχωρίστε τα πολλαπλά domains με κόμμα (',').
-auths.skip_tls_verify=Παράλειψη TLS Verify
+auths.skip_tls_verify=Παράλειψη επαλήθευσης TLS
auths.force_smtps=Αναγκαστικό SMTPS
auths.force_smtps_helper=Το SMTPS χρησιμοποιείται συνήθως στη θύρα 465. Ορίστε αυτό το πεδίο για χρήση του SMTPS σε άλλες θύρες. (Αλλιώς το STARTTLS θα χρησιμοποιηθεί σε άλλες θύρες αν υποστηρίζεται από τον διακομιστή.)
auths.helo_hostname=Όνομα διακομιστή στο HELO
@@ -2990,7 +3087,7 @@ auths.oauth2_admin_group=Τιμή Group Claim για διαχειριστές. (
auths.oauth2_restricted_group=Τιμή Group Claim για περιορισμένους χρήστες (Προαιρετικό - απαιτεί όνομα claim παραπάνω)
auths.oauth2_map_group_to_team=Αντιστοίχιση των απαιτούμενων ομάδων σε ομάδες Οργανισμού. (Προαιρετικό - απαιτείται το όνομα της απαίτησης παραπάνω)
auths.oauth2_map_group_to_team_removal=Αφαίρεση χρηστών από τις συγχρονισμένες ομάδες, εάν ένας χρήστης δεν ανήκει στην αντίστοιχη ομάδα.
-auths.enable_auto_register=Ενεργοποίηση Αυτόματης Εγγραφής
+auths.enable_auto_register=Ενεργοποίηση αυτόματης εγγραφής
auths.sspi_auto_create_users=Αυτόματη δημιουργία χρηστών
auths.sspi_auto_create_users_helper=Επιτρέψτε στη μέθοδο πιστοποίησης SSPI να δημιουργεί αυτόματα νέους λογαριασμούς για χρήστες που συνδέονται για πρώτη φορά
auths.sspi_auto_activate_users=Αυτόματη ενεργοποίηση χρηστών
@@ -3005,10 +3102,10 @@ auths.tips=Συμβουλές
auths.tips.oauth2.general=Ταυτοποίηση OAuth2
auths.tips.oauth2.general.tip=Κατά την εγγραφή μιας νέας ταυτοποίησης OAuth2, το URL κλήσης/ανακατεύθυνσης πρέπει να είναι:
auths.tip.oauth2_provider=Πάροχος OAuth2
-auths.tip.bitbucket=Καταχωρήστε ένα νέο καταναλωτή OAuth στο https://bitbucket.org/account/user//oauth-consumers/new και προσθέστε το δικαίωμα 'Account' - 'Read'
-auths.tip.nextcloud=`Καταχωρήστε ένα νέο καταναλωτή OAuth στην υπηρεσία σας χρησιμοποιώντας το παρακάτω μενού "Settings -> Security -> OAuth 2.0 client"`
+auths.tip.bitbucket=Καταχωρήστε έναν νέο καταναλωτή OAuth στο https://bitbucket.org/account/user//oauth-consumers/new και προσθέστε το δικαίωμα 'Account' - 'Read'
+auths.tip.nextcloud=Καταχωρήστε ένα νέο καταναλωτή OAuth στην υπηρεσία σας χρησιμοποιώντας το παρακάτω μενού "Settings -> Security -> OAuth 2.0 client"
auths.tip.dropbox=Δημιουργήστε μια νέα εφαρμογή στο https://www.dropbox.com/developers/apps
-auths.tip.facebook=`Καταχωρήστε μια νέα εφαρμογή στο https://developers.facebook.com/apps και προσθέστε το προϊόν "Facebook Login"`
+auths.tip.facebook=Καταχωρήστε μια νέα εφαρμογή στο https://developers.facebook.com/apps και προσθέστε το προϊόν "Facebook Login"
auths.tip.github=Καταχωρήστε μια νέα εφαρμογή OAuth στο https://github.com/settings/applications/new
auths.tip.gitlab=Καταχωρήστε μια νέα εφαρμογή στο https://gitlab.com/profile/applications
auths.tip.google_plus=Αποκτήστε τα διαπιστευτήρια πελάτη OAuth2 από την κονσόλα API της Google στο https://console.developers.google.com/
@@ -3019,57 +3116,57 @@ auths.tip.gitea=Καταχωρήστε μια νέα εφαρμογή OAuth2. Μ
auths.tip.yandex=`Δημιουργήστε μια νέα εφαρμογή στο https://oauth.yandex.com/client/new. Επιλέξτε τα ακόλουθα δικαιώματα από την ενότητα "Yandex.Passport API": "Access to email address", "Access to user avatar" και "Access to username, first name and surname, gender"`
auths.tip.mastodon=Εισαγάγετε ένα προσαρμομένο URL για την υπηρεσία mastodon με την οποία θέλετε να πιστοποιήσετε (ή να χρησιμοποιήσετε την προεπιλεγμένη)
auths.edit=Επεξεργασία Πηγής Ταυτοποίησης
-auths.activated=Αυτή η Πηγή Ταυτοποίησης είναι Ενεργοποιημένη
-auths.new_success=Ο ταυτοποίηση "%s" προστέθηκε.
-auths.update_success=Η πηγή ταυτοποίησης έχει ενημερωθεί.
+auths.activated=Αυτή η πηγή είναι ενεργοποιημένη
+auths.new_success=Το μέσο ταυτοποίησης «%s» προστέθηκε.
+auths.update_success=Η πηγή ενημερώθηκε.
auths.update=Ενημέρωση Πηγής Ταυτοποίησης
auths.delete=Διαγραφή Πηγής Ταυτοποίησης
auths.delete_auth_title=Διαγραφή Πηγής Ταυτοποίησης
-auths.delete_auth_desc=Η διαγραφή μιας πηγής ταυτοποίησης αποτρέπει τους χρήστες να τη χρησιμοποιούν για να συνδεθούν. Συνέχεια;
-auths.still_in_used=Η πηγή ταυτοποίησης είναι ακόμα σε χρήση. Μετατρέψτε ή διαγράψτε χρηστών που χρησιμοποιούν αυτήν την πηγή πρώτα.
+auths.delete_auth_desc=Αν διαγράψετε την πηγής ταυτοποίησης, οι χρήστες σας δεν θα μπορέσουν να τη χρησιμοποιήσουν πλέον για να συνδεθούν. Συνέχεια;
+auths.still_in_used=Η πηγή ταυτοποίησης βρίσκεται ακόμα σε χρήση. Για να συνεχίσετε, πρέπει πρώτα να διαγράψετε ή να μετατρέψετε τους χρήστες που χρησιμοποιούν αυτήν την πηγή.
auths.deletion_success=Η πηγή ταυτοποίησης έχει διαγραφεί.
-auths.login_source_exist=Υπάρχει ήδη η πηγή ταυτοποίησης "%s".
-auths.login_source_of_type_exist=Υπάρχει ήδη πηγή ταυτοποίησης αυτού του τύπου.
+auths.login_source_exist=Η πηγή ταυτοποίησης «%s» υπάρχει ήδη.
+auths.login_source_of_type_exist=Υπάρχει ήδη μία πηγή ταυτοποίησης αυτού του τύπου.
auths.unable_to_initialize_openid=Αδυναμία εκκίνησης του παρόχου OpenID Connect: %s
auths.invalid_openIdConnectAutoDiscoveryURL=Μη έγκυρο Auto Discovery URL (πρέπει να είναι ένα έγκυρο URL που ξεκινά με http:// ή https://)
-config.server_config=Ρυθμίσεις Διακομιστή
-config.app_name=Τίτλος Ιστοτόπου
+config.server_config=Ρυθμίσεις διακομιστή
+config.app_name=Τίτλος ιστοτόπου
config.app_ver=Έκδοση Forgejo
-config.app_url=Βασικό URL Του Forgejo
-config.custom_conf=Διαδρομή Αρχείου Ρυθμίσεων
-config.custom_file_root_path=Προσαρμοσμένη Βασική Διαδρομή Αρχείου
-config.domain=Domain Διακομιστή
-config.offline_mode=Τοπική Λειτουργία
-config.disable_router_log=Απενεργοποίηση Καταγραφής Δρομολογητή
-config.run_user=Εκτέλεση Σαν Χρήστη
-config.run_mode=Λειτουργία Εκτέλεσης
+config.app_url=Βασικό URL
+config.custom_conf=Τοποθεσία αρχείου ρυθμίσεων
+config.custom_file_root_path=Προσαρμοσμένη τοποθεσία αρχείων
+config.domain=Domain διακομιστή
+config.offline_mode=Τοπική λειτουργία
+config.disable_router_log=Απενεργοποίηση καταγραφής δρομολογητή
+config.run_user=Εκτέλεση ως
+config.run_mode=Λειτουργία εκτέλεσης
config.git_version=Έκδοση Git
-config.app_data_path=Διαδρομή Δεδομένων Εφαρμογής
-config.repo_root_path=Ριζική Διαδρομή Αποθετηρίων
-config.lfs_root_path=Ριζική Διαδρομή LFS
-config.log_file_root_path=Διαδρομή Καταγραφών
-config.script_type=Τύπος Σεναρίου
-config.reverse_auth_user=Χρήστης ΑντίστροφηςΠιστοποίησης
+config.app_data_path=Τοποθεσία δεδομένων εφαρμογής
+config.repo_root_path=Τοποθεσία αποθετηρίων
+config.lfs_root_path=Τοποθεσία LFS
+config.log_file_root_path=Τοποθεσία αρχείων καταγραφής
+config.script_type=Τύπος σεναρίου
+config.reverse_auth_user=Χρήστης αντίστροφης πιστοποίησης
-config.ssh_config=Ρύθμιση SSH
+config.ssh_config=Ρυθμίσεις SSH
config.ssh_enabled=Ενεργοποιημένο
-config.ssh_start_builtin_server=Χρήση Ενσωματωμένου Διακομιστή
-config.ssh_domain=Domain Διακομιστή SSH
+config.ssh_start_builtin_server=Χρήση ενσωματωμένου διακομιστή
+config.ssh_domain=Domain διακομιστή SSH
config.ssh_port=Θύρα
config.ssh_listen_port=Θύρα Ακρόασης
config.ssh_root_path=Ριζική Διαδρομή
-config.ssh_key_test_path=Διαδρομή Δοκιμής Κλειδιού
-config.ssh_keygen_path=Διαδρομή Keygen ('ssh-keygen')
-config.ssh_minimum_key_size_check=Έλεγχος Ελάχιστου Μεγέθους Κλειδιού
-config.ssh_minimum_key_sizes=Ελάχιστα Μεγέθη Κλειδιών
+config.ssh_key_test_path=Διαδρομή δοκιμής κλειδιού
+config.ssh_keygen_path=Διαδρομή keygen («ssh-keygen»)
+config.ssh_minimum_key_size_check=Έλεγχος ελάχιστου μεγέθους κλειδιού
+config.ssh_minimum_key_sizes=Ελάχιστα μεγέθη κλειδιών
-config.lfs_config=Ρύθμιση LFS
+config.lfs_config=Ρυθμίσεις LFS
config.lfs_enabled=Ενεργοποιημένο
-config.lfs_content_path=Διαδρομή Περιεχομένου LFS
-config.lfs_http_auth_expiry=LFS Λήξη Ταυτοποίησης HTTP
+config.lfs_content_path=Τοποθεσία περιεχομένου LFS
+config.lfs_http_auth_expiry=Χρονικό όριο ταυτοποίησης HTTP LFS
-config.db_config=Ρύθμιση Βάσης Δεδομένων
+config.db_config=Ρυθμίσεις βάσης δεδομένων
config.db_type=Τύπος
config.db_host=Διακομιστής
config.db_name=Όνομα
@@ -3078,34 +3175,34 @@ config.db_schema=Σχήμα
config.db_ssl_mode=SSL
config.db_path=Διαδρομή
-config.service_config=Ρυθμίσεις Υπηρεσίας
-config.register_email_confirm=Απαιτείται Επιβεβαίωση του Email για Εγγραφή
-config.disable_register=Απενεργοποίηση Αυτοεγγραφής
-config.allow_only_internal_registration=Να Επιτρέπεται η Εγγραφή Μόνο Μέσω του Forgejo
-config.allow_only_external_registration=Να Επιτρέπεται Η Εγγραφή Μόνο Μέσω Εξωτερικών Υπηρεσιών
-config.enable_openid_signup=Ενεργοποίηση Αυτο-Εγγραφής OpenID
-config.enable_openid_signin=Ενεργοποίηση Σύνδεσης μέσω OpenID
-config.show_registration_button=Εμφάνιση Κουμπιού Εγγραφής
-config.require_sign_in_view=Απαιτείται Είσοδος για Προβολή Σελίδων
-config.mail_notify=Ενεργοποίηση Ειδοποιήσεων Email
+config.service_config=Ρυθμίσεις υπηρεσίας
+config.register_email_confirm=Να απαιτείται η επιβεβαίωση της διεύθυνσης email για την δημιουργία ενός λογαριασμού
+config.disable_register=Απενεργοποίηση αυτο-εγγραφής
+config.allow_only_internal_registration=Να επιτρέπονται εγγραφές μόνο μέσω του Forgejo
+config.allow_only_external_registration=Να επιτρέπονται εγγραφές μόνο με την χρήση εξωτερικών υπηρεσιών
+config.enable_openid_signup=Ενεργοποίηση αυτο-εγγραφής OpenID
+config.enable_openid_signin=Ενεργοποίηση σύνδεσης μέσω OpenID
+config.show_registration_button=Εμφάνιση κουμπιού εγγραφής
+config.require_sign_in_view=Να απαιτείται είσοδος για την προβολή σελίδων
+config.mail_notify=Ενεργοποίηση ειδοποιήσεων email
config.enable_captcha=Ενεργοποίηση CAPTCHA
-config.active_code_lives=Ζωή Ενεργού Κωδικού
-config.reset_password_code_lives=Λήξη Χρόνου Κωδικού Ανάκτησης του Λογαριασμού
-config.default_keep_email_private=Απόκρυψη Διευθύνσεων Email από Προεπιλογή
-config.default_allow_create_organization=Να Επιτρέπεται η Δημιουργία Οργανισμών από Προεπιλογή
-config.enable_timetracking=Ενεργοποίηση Καταγραφής Χρόνου
-config.default_enable_timetracking=Ενεργοποίηση Καταγραφής Χρόνου σαν Προεπιλογή
-config.default_allow_only_contributors_to_track_time=Επιτρέπονται Μόνο οι Συμμετέχοντες να Καταγράφουν Χρόνο
-config.no_reply_address=Κρυφό Email Domain
-config.default_visibility_organization=Προεπιλεγμένη ορατότητα για νέους οργανισμούς
-config.default_enable_dependencies=Ενεργοποίηση Εξαρτήσεων Ζητημάτων από Προεπιλογή
+config.active_code_lives=Χρόνος λήξης κωδικών ενεργοποίησης
+config.reset_password_code_lives=Χρόνος λήξης κωδικού ανάκτησης ενός λογαριασμού
+config.default_keep_email_private=Να αποκρύπτονται οι διευθύνσεις email από προεπιλογή
+config.default_allow_create_organization=Να επιτρέπεται η δημιουργία οργανισμών από προεπιλογή
+config.enable_timetracking=Ενεργοποίηση καταγραφής χρόνου
+config.default_enable_timetracking=Ενεργοποίηση καταγραφής χρόνου από προεπιλογή
+config.default_allow_only_contributors_to_track_time=Να επιτρέπεται η καταγραφή χρόνου μόνο από συνεισφέροντες
+config.no_reply_address=Κρυφό email domain
+config.default_visibility_organization=Προεπιλεγμένη ορατότητα νέων οργανισμών
+config.default_enable_dependencies=Ενεργοποίηση εξαρτήσεων ζητημάτων από προεπιλογή
-config.webhook_config=Ρύθμιση Webhook
-config.queue_length=Μέγεθος Ουράς
-config.deliver_timeout=Χρονικό Όριο Παράδοσης
-config.skip_tls_verify=Παράλειψη Επαλήθευσης TLS
+config.webhook_config=Ρύθμιση webhook
+config.queue_length=Μέγεθος ουράς
+config.deliver_timeout=Χρονικό όριο παράδοσης
+config.skip_tls_verify=Παράλειψη επαλήθευσης TLS
-config.mailer_config=Ρυθμίσεις Αλληλογραφίας
+config.mailer_config=Ρυθμίσεις αλληλογραφίας
config.mailer_enabled=Ενεργοποιημένο
config.mailer_enable_helo=Ενεργοποίηση HELO
config.mailer_name=Όνομα
@@ -3121,56 +3218,56 @@ config.mailer_use_dummy=Ψεύτικο
config.test_email_placeholder=Email (π.χ. test@example.com)
config.send_test_mail=Αποστολή Δοκιμαστικού Email
config.send_test_mail_submit=Αποστολή
-config.test_mail_failed=Αποτυχία αποστολής ενός δοκιμαστικού email στο"%s": %v
-config.test_mail_sent=Στάλθηκε ένα δοκιμαστικό email στο "%s".
+config.test_mail_failed=Η αποστολή δοκιμαστικού email στο «%s» απέτυχε: %v
+config.test_mail_sent=Στάλθηκε ένα δοκιμαστικό email στο «%s».
config.oauth_config=Ρύθμιση Oauth
config.oauth_enabled=Ενεργό
-config.cache_config=Ρύθμιση Προσωρινής Αποθήκευσης
-config.cache_adapter=Προσαρμογέας Προσωρινής Αποθήκευσης
-config.cache_interval=Διάστημα Προσωρινής Αποθήκευσης
+config.cache_config=Ρύθμιση προσωρινής αποθήκευσης
+config.cache_adapter=Προσαρμογέας προσωρινής αποθήκευσης
+config.cache_interval=Διάστημα προσωρινής αποθήκευσης
config.cache_conn=Σύνδεση Προσωρινής Αποθήκευσης
config.cache_item_ttl=TTL Στοιχείων Προσωρινής Αποθήκευσης
-config.session_config=Ρύθμιση Συνεδρίας
-config.session_provider=Πάροχος Συνεδρίας
-config.provider_config=Ρυθμίσεις Πάροχου
-config.cookie_name=Όνομα Cookie
-config.gc_interval_time=Χρόνος Διαστήματος GC
-config.session_life_time=Χρόνος Ζωής Συνεδρίας
+config.session_config=Ρυθμίσεις συνεδρίας
+config.session_provider=Πάροχος συνεδρίας
+config.provider_config=Ρυθμίσεις παρόχου
+config.cookie_name=Όνομα cookie
+config.gc_interval_time=Χρόνος διαστήματος GC
+config.session_life_time=Χρόνος ζωής συνεδρίας
config.https_only=Μόνο HTTPS
-config.cookie_life_time=Χρόνος Ζωής Cookie
+config.cookie_life_time=Χρόνος ζωής Cookie
-config.picture_config=Ρύθμιση Εικόνας και Avatar
-config.picture_service=Υπηρεσία Εικόνας
+config.picture_config=Ρυθμίσεις εικόνας και avatar
+config.picture_service=Υπηρεσία εικόνας
config.disable_gravatar=Απενεργοποίηση Gravatar
-config.enable_federated_avatar=Ενεργοποίηση Ομόσπονδων Avatars
+config.enable_federated_avatar=Ενεργοποίηση αποκεντρωμένων avatar
-config.git_config=Ρύθμιση Git
-config.git_disable_diff_highlight=Απενεργοποίηση Επισήμανσης Σύνταξης Diff
-config.git_max_diff_lines=Μέγιστες γραμμές Diff (για ένα μόνο αρχείο)
-config.git_max_diff_line_characters=Μέγιστος αριθμός χαρακτήρων Diff (για μία γραμμή)
-config.git_max_diff_files=Μέγιστος αριθμός Diff αρχείων (για εμφάνιση)
+config.git_config=Ρυθμίσεις Git
+config.git_disable_diff_highlight=Απενεργοποίηση επισήμανσης σύνταξης diff
+config.git_max_diff_lines=Μέγιστες γραμμές diff ανά αρχείο
+config.git_max_diff_line_characters=Μέγιστος αριθμός χαρακτήρων diff ανά γραμμή
+config.git_max_diff_files=Μέγιστος αριθμός εμφανιζόμενων αρχείων ανά diff
config.git_gc_args=Παράμετροι GC
-config.git_migrate_timeout=Χρονικό Όριο Μεταφοράς
-config.git_mirror_timeout=Χρονικό Όριο Ενημέρωσης Ειδώλου
-config.git_clone_timeout=Χρονικό Όριο Κλωνοποίησης
-config.git_pull_timeout=Χρονικό Όριο Pull
-config.git_gc_timeout=Χρονικό Όριο Λειτουργίας GC
+config.git_migrate_timeout=Χρονικό όριο μεταφοράς
+config.git_mirror_timeout=Χρονικό όριο ενημέρωσης ειδώλου
+config.git_clone_timeout=Χρονικό όριο κλωνοποίησης
+config.git_pull_timeout=Χρονικό όριο pull
+config.git_gc_timeout=Χρονικό όριο λειτουργίας GC
-config.log_config=Ρύθμιση Καταγραφών
+config.log_config=Ρυθμίσεις Καταγραφών
config.logger_name_fmt=Καταγραφέας: %s
config.disabled_logger=Απενεργοποιημένο
-config.access_log_mode=Λειτουργία Καταγραφών Πρόσβασης
-config.access_log_template=Πρότυπο Καταγραφής Προσβάσεων
+config.access_log_mode=Λειτουργία καταγραφών πρόσβασης
+config.access_log_template=Πρότυπο καταγραφής προσβάσεων
config.xorm_log_sql=Καταγραφή SQL
-config.set_setting_failed=Αποτυχία ορισμού της ρύθμισης %s
+config.set_setting_failed=Ο ορισμός της ρύθμισης %s απέτυχε
monitor.stats=Στατιστικά
-monitor.cron=Προγραμματισμένες Εργασίες
+monitor.cron=Προγραμματισμένες εργασίες
monitor.name=Όνομα
monitor.schedule=Πρόγραμμα
monitor.next=Επόμενη Ώρα
@@ -3209,8 +3306,8 @@ monitor.queue.settings.changed=Οι Ρυθμίσεις Ενημερώθηκαν
monitor.queue.settings.remove_all_items=Αφαίρεση όλων
monitor.queue.settings.remove_all_items_done=Όλα τα αντικείμενα στην ουρά αφαιρέθηκαν.
-notices.system_notice_list=Ειδοποιήσεις Συστήματος
-notices.view_detail_header=Προβολή Λεπτομερειών Ειδοποίησης
+notices.system_notice_list=Ειδοποιήσεις συστήματος
+notices.view_detail_header=Προβολή λεπτομερειών ειδοποίησης
notices.operations=Λειτουργίες
notices.select_all=Επιλογή Όλων
notices.deselect_all=Αποεπιλογή Όλων
@@ -3223,6 +3320,13 @@ notices.type_2=Εργασία
notices.desc=Περιγραφή
notices.op=Λειτ.
notices.delete_success=Οι ειδοποιήσεις του συστήματος έχουν διαγραφεί.
+self_check.no_problem_found = Μέχρι τώρα, δεν έχει βρεθεί κάποιο πρόβλημα.
+self_check.database_fix_mssql = Προς το παρόν, οι χρήστες του MSSQL μπορούν να διορθώσουν το πρόβλημα αυτό χειροκίνητα χρησιμοποιώντας τις εντολές SQL «ALTER ... COLLATE ...».
+self_check = Αυτοέλεγχος
+dashboard.sync_repo_tags = Συγχρονισμός tag από δεδομένα git στην βάση δεδομένων
+dashboard.sync_tag.started = Ο συγχρονισμός tag έχει ξεκινήσει
+self_check.database_inconsistent_collation_columns = Η βάση δεδομένων χρησιμοποιεί το collation %s, αλλά οι στήλες του χρησιμοποιούν collations που δεν αντιστοιχούν σε εκείνο το collation. Αυτό ενδέχεται να προκαλέσει μερικά απρόσμενα θέματα.
+self_check.database_fix_mysql = Για τους χρήστες του MySQL/MariaDB: Μπορείτε να χρησιμοποιήσετε την εντολή «git doctor convert» για να διορθώσετε το collation ή να το διορθώσετε χειροκίνητα με τις εντολές «ALTER ... COLLATE ...».
[action]
@@ -3304,8 +3408,8 @@ error.extract_sign=Αποτυχία εξαγωγής υπογραφής
error.generate_hash=Αποτυχία δημιουργίας του κατακερματισμού (hash) της υποβολής
error.no_committer_account=Δεν υπάρχει λογαριασμός συνδεδεμένος με τη διεύθυνση email του υποβολέα
error.no_gpg_keys_found=Δεν βρέθηκε γνωστό κλειδί για αυτήν την υπογραφή στη βάση δεδομένων
-error.not_signed_commit=Δεν είναι υπογεγραμμένη υποβολή
-error.failed_retrieval_gpg_keys=Αποτυχία ανάκτησης ενός κλειδιού που είναι συνδεδεμένο στο λογαριασμό του υποβολέα
+error.not_signed_commit=Η υποβολή δεν είναι υπογεγραμμένη
+error.failed_retrieval_gpg_keys=Αποτυχία ανάκτησης κλειδιού που είναι συνδεδεμένο στο λογαριασμό του υποβολέα
error.probable_bad_signature=ΠΡΟΣΟΧΗ! Αν και υπάρχει ένα κλειδί με αυτό το ID στη βάση δεδομένων δεν επαληθεύει αυτή την υποβολή! Αυτή η υποβολή είναι ΥΠΟΠΤΗ.
error.probable_bad_default_signature=ΠΡΟΣΟΧΗ! Αν και το προεπιλεγμένο κλειδί έχει αυτό το ID, δεν επαληθεύει αυτή την υποβολή! Αυτή η υποβολή είναι ΥΠΟΠΤΗ.
@@ -3318,9 +3422,9 @@ error.unit_not_allowed=Δεν σας επιτρέπεται να έχετε πρ
title=Πακέτα
desc=Διαχείριση πακέτων μητρώου.
empty=Δεν υπάρχουν πακέτα ακόμα.
-empty.documentation=Για περισσότερες πληροφορίες σχετικά με το μητρώο πακέτων, ανατρέξτε στην τεκμηρίωση.
+empty.documentation=Για περισσότερες πληροφορίες σχετικά με το μητρώο πακέτων, συμβουλευτείτε τον οδηγό.
empty.repo=Μήπως ανεβάσατε ένα πακέτο, αλλά δεν εμφανίζεται εδώ; Πηγαίνετε στις ρυθμίσεις πακέτων και συνδέστε το σε αυτό το αποθετήριο.
-registry.documentation=Για περισσότερες πληροφορίες σχετικά με το μητρώο %s, ανατρέξτε στη τεκμηρίωση .
+registry.documentation=Για περισσότερες πληροφορίες σχετικά με το μητρώο %s, συμβουλευτείτε τον οδηγό.
filter.type=Τύπος
filter.type.all=Όλα
filter.no_result=Το φίλτρο δεν παρήγαγε αποτελέσματα.
@@ -3429,10 +3533,10 @@ settings.link.success=Ο σύνδεσμος αποθετηρίου ενημερ
settings.link.error=Αποτυχία ενημέρωσης συνδέσμου αποθετηρίου.
settings.delete=Διαγραφή πακέτου
settings.delete.description=Η διαγραφή ενός πακέτου είναι μόνιμη και δεν μπορεί να αναιρεθεί.
-settings.delete.notice=Πρόκειται να διαγράψετε %s (%s). Αυτή η λειτουργία είναι μη αναστρέψιμη, είστε σίγουροι;
+settings.delete.notice=Πρόκειται να διαγράψετε το %s (%s). Αυτή η διαδικασία είναι μη αναστρέψιμη, είστε σίγουροι;
settings.delete.success=Το πακέτο έχει διαγραφεί.
settings.delete.error=Αποτυχία διαγραφής του πακέτου.
-owner.settings.cargo.title=Ευρετήριο Μητρώου Cargo
+owner.settings.cargo.title=Ευρετήριο μητρώου Cargo
owner.settings.cargo.initialize=Αρχικοποίηση Ευρετηρίου
owner.settings.cargo.initialize.description=Απαιτείται ένα ειδικό αποθετήριο ευρετηρίου Git για τη χρήση του μητρώου Cargo. Χρησιμοποιώντας αυτή την επιλογή θα δημιουργηθεί ξανά το αποθετήριο και θα ρυθμιστεί αυτόματα.
owner.settings.cargo.initialize.error=Αποτυχία αρχικοποίησης ευρετηρίου Cargo: %v
@@ -3441,7 +3545,7 @@ owner.settings.cargo.rebuild=Αναδημιουργία Ευρετηρίου
owner.settings.cargo.rebuild.description=Η ανοικοδόμηση μπορεί να είναι χρήσιμη εάν ο δείκτης δεν είναι συγχρονισμένος με τα αποθηκευμένα πακέτα Cargo.
owner.settings.cargo.rebuild.error=Αποτυχία αναδόμησης του ευρετηρίου Cargo: %v
owner.settings.cargo.rebuild.success=Το ευρετήριο Cargo αναδομήθηκε με επιτυχία.
-owner.settings.cleanuprules.title=Διαχείριση Κανόνων Εκκαθάρισης
+owner.settings.cleanuprules.title=Διαχείριση κανόνων εκκαθάρισης
owner.settings.cleanuprules.add=Προσθήκη Κανόνα Εκκαθάρισης
owner.settings.cleanuprules.edit=Επεξεργασία Κανόνα Εκκαθάρισης
owner.settings.cleanuprules.none=Δεν υπάρχουν διαθέσιμοι κανόνες εκκαθάρισης. Παρακαλούμε συμβουλευτείτε την τεκμηρίωση.
@@ -3464,6 +3568,7 @@ owner.settings.cleanuprules.success.delete=Ο κανόνας καθαρισμο
owner.settings.chef.title=Μητρώο Chef
owner.settings.chef.keypair=Δημιουργία ζεύγους κλειδιών
owner.settings.chef.keypair.description=Ένα ζεύγος κλειδιών είναι απαραίτητο για ταυτοποίηση στο μητρώο Chef. Αν έχετε δημιουργήσει ένα ζεύγος κλειδιών πριν, η δημιουργία ενός νέου ζεύγους κλειδιών θα απορρίψει το παλιό ζεύγος κλειδιών.
+rpm.repository.multiple_groups = Αυτό το πακέτο είναι διαθέσιμο σε διαφορετικά group.
[secrets]
secrets=Μυστικά
@@ -3472,7 +3577,7 @@ none=Δεν υπάρχουν ακόμα μυστικά.
creation=Προσθήκη Μυστικού
creation.name_placeholder=αλφαριθμητικοί χαρακτήρες ή κάτω παύλες μόνο, δεν μπορούν να ξεκινούν με GITEA_ ή GITHUB_
creation.value_placeholder=Εισάγετε οποιοδήποτε περιεχόμενο. Τα κενά στην αρχή παραλείπονται.
-creation.success=Το μυστικό "%s" προστέθηκε.
+creation.success=Το μυστικό «%s» προστέθηκε.
creation.failed=Αποτυχία δημιουργίας μυστικού.
deletion=Αφαίρεση μυστικού
deletion.description=Η αφαίρεση ενός μυστικού είναι μόνιμη και δεν μπορεί να αναιρεθεί. Συνέχεια;
@@ -3481,21 +3586,21 @@ deletion.failed=Αποτυχία αφαίρεσης μυστικού.
management=Διαχείριση Μυστικών
[actions]
-actions=Δράσεις
+actions=Actions
unit.desc=Διαχείριση δράσεων
-status.unknown=Άγνωστη
-status.waiting=Αναμονή
-status.running=Εκτελείται
-status.success=Επιτυχές
+status.unknown=Απροσδιόριστη
+status.waiting=Σε αναμονή
+status.running=Σε εκτέλεση
+status.success=Επιτυχία
status.failure=Αποτυχία
status.cancelled=Ακυρώθηκε
status.skipped=Παρακάμφθηκε
status.blocked=Αποκλείστηκε
runners=Εκτελεστές
-runners.runner_manage_panel=Διαχείριση Εκτελεστών
+runners.runner_manage_panel=Διαχείριση εκτελεστών
runners.new=Δημιουργία νέου Εκτελεστή
runners.new_notice=Πώς να ξεκινήσετε έναν εκτελεστή
runners.status=Κατάσταση
@@ -3547,9 +3652,9 @@ runs.no_runs=Η ροή εργασίας δεν έχει τρέξει ακόμα.
runs.empty_commit_message=(κενό μήνυμα υποβολής)
workflow.disable=Απενεργοποίηση Ροής Εργασιών
-workflow.disable_success=Η ροή εργασίας '%s' απενεργοποιήθηκε επιτυχώς.
+workflow.disable_success=Η ροή εργασίας «%s» απενεργοποιήθηκε επιτυχώς.
workflow.enable=Ενεργοποίηση Ροής Εργασίας
-workflow.enable_success=Η ροή εργασίας '%s' ενεργοποιήθηκε επιτυχώς.
+workflow.enable_success=Η ροή εργασίας «%s» ενεργοποιήθηκε επιτυχώς.
workflow.disabled=Η ροή εργασιών είναι απενεργοποιημένη.
need_approval_desc=Πρέπει να εγκριθεί η εκτέλεση ροών εργασίας για pull request από fork.
@@ -3565,12 +3670,13 @@ variables.edit=Επεξεργασία Μεταβλητής
variables.deletion.failed=Αποτυχία αφαίρεσης της μεταβλητής.
variables.deletion.success=Η μεταβλητή έχει αφαιρεθεί.
variables.creation.failed=Αποτυχία προσθήκης μεταβλητής.
-variables.creation.success=Η μεταβλητή "%s" έχει προστεθεί.
+variables.creation.success=Η μεταβλητή «%s» προστέθηκε.
variables.update.failed=Αποτυχία επεξεργασίας μεταβλητής.
variables.update.success=Η μεταβλητή έχει τροποποιηθεί.
variables.id_not_exist = Η μεταβλητή με id %d δεν υπάρχει.
-runs.no_workflows.documentation = Για περισσότερες πληροφορίες σχετικά με τη Δράση Gitea, ανατρέξτε στην τεκμηρίωση.
-runs.no_workflows.quick_start = Δεν ξέρετε πώς να ξεκινήσετε με τις Δράσεις Gitea; Συμβουλευτείτε τον οδηγό για γρήγορη αρχή.
+runs.no_workflows.documentation = Για περισσότερες πληροφορίες σχετικά με το Forgejo Actions, συμβουλευτείτε τον οδηγό.
+runs.no_workflows.quick_start = Δεν ξέρετε από που να πρωτοξεκινήσετε με το Forgejo Actions; Για μια γρήγορη αρχή, συμβουλευτείτε τον οδηγό μας.
+runs.workflow = Ροή εργασίας
[projects]
type-1.display_name=Ατομικό Έργο
diff --git a/options/locale/locale_en-US.ini b/options/locale/locale_en-US.ini
index 07ad19aa7a..50871be86d 100644
--- a/options/locale/locale_en-US.ini
+++ b/options/locale/locale_en-US.ini
@@ -34,8 +34,8 @@ password = Password
access_token = Access token
re_type = Confirm password
captcha = CAPTCHA
-twofa = Two-Factor Authentication
-twofa_scratch = Two-Factor Scratch Code
+twofa = Two-factor authentication
+twofa_scratch = Two-factor scratch code
passcode = Passcode
webauthn_insert_key = Insert your security key
@@ -55,15 +55,15 @@ webauthn_reload = Reload
repository = Repository
organization = Organization
mirror = Mirror
-new_repo = New Repository
-new_migrate = New Migration
-new_mirror = New Mirror
-new_fork = New Repository Fork
-new_org = New Organization
-new_project = New Project
-new_project_column = New Column
-admin_panel = Site Administration
-account_settings = Account Settings
+new_repo = New repository
+new_migrate = New migration
+new_mirror = New mirror
+new_fork = New repository fork
+new_org = New organization
+new_project = New project
+new_project_column = New column
+admin_panel = Site administration
+account_settings = Account settings
settings = Settings
your_profile = Profile
your_starred = Starred
@@ -76,7 +76,7 @@ collaborative = Collaborative
forks = Forks
activities = Activities
-pull_requests = Pull Requests
+pull_requests = Pull requests
issues = Issues
milestones = Milestones
@@ -164,7 +164,10 @@ footer.links = Links
[heatmap]
number_of_contributions_in_the_last_12_months = %s contributions in the last 12 months
-no_contributions = No contributions
+contributions_zero = No contributions
+contributions_format = {contributions} on {month} {day}, {year}
+contributions_one = contribution
+contributions_few = contributions
less = Less
more = More
@@ -210,15 +213,15 @@ license_desc = Go get documentation before changing any settings.
require_db_desc = Forgejo requires MySQL, PostgreSQL, MSSQL, SQLite3 or TiDB (MySQL protocol).
-db_title = Database Settings
-db_type = Database Type
+db_title = Database settings
+db_type = Database type
host = Host
user = Username
password = Password
-db_name = Database Name
+db_name = Database name
db_schema = Schema
db_schema_helper = Leave blank for database default ("public").
ssl_mode = SSL
@@ -237,61 +240,62 @@ err_admin_name_is_reserved = Administrator Username is invalid, username is rese
err_admin_name_pattern_not_allowed = Administrator username is invalid, the username matches a reserved pattern
err_admin_name_is_invalid = Administrator Username is invalid
-general_title = General Settings
-app_name = Site Title
+general_title = General settings
+app_name = Instance title
app_name_helper = You can enter your company name here.
-repo_path = Repository Root Path
+repo_path = Repository root path
repo_path_helper = Remote Git repositories will be saved to this directory.
-lfs_path = Git LFS Root Path
+lfs_path = Git LFS root path
lfs_path_helper = Files tracked by Git LFS will be stored in this directory. Leave empty to disable.
-run_user = Run As Username
+run_user = User to run as
run_user_helper = The operating system username that Forgejo runs as. Note that this user must have access to the repository root path.
-domain = Server Domain
+domain = Server domain
domain_helper = Domain or host address for the server.
-ssh_port = SSH Server Port
-ssh_port_helper = Port number your SSH server listens on. Leave empty to disable.
-http_port = Forgejo HTTP Listen Port
-http_port_helper = Port number the Forgejos web server will listen on.
-app_url = Forgejo Base URL
+ssh_port = SSH server port
+ssh_port_helper = Port number that will be used by the SSH server. Leave empty to disable SSH server.
+http_port = HTTP listen port
+http_port_helper = Port number that will be used by the Forgejo web server.
+app_url = Base URL
app_url_helper = Base address for HTTP(S) clone URLs and email notifications.
-log_root_path = Log Path
+log_root_path = Log path
log_root_path_helper = Log files will be written to this directory.
-optional_title = Optional Settings
-email_title = Email Settings
-smtp_addr = SMTP Host
-smtp_port = SMTP Port
-smtp_from = Send Email As
+optional_title = Optional settings
+email_title = Email settings
+smtp_addr = SMTP host
+smtp_port = SMTP port
+smtp_from = Send email as
smtp_from_invalid = The "Send Email As" address is invalid
smtp_from_helper = Email address Forgejo will use. Enter a plain email address or use the "Name" format.
-mailer_user = SMTP Username
-mailer_password = SMTP Password
-register_confirm = Require Email Confirmation to Register
-mail_notify = Enable Email Notifications
-server_service_title = Server and Third-Party Service Settings
-offline_mode = Enable Local Mode
+mailer_user = SMTP username
+mailer_password = SMTP password
+register_confirm = Require email confirmation to register
+mail_notify = Enable email notifications
+server_service_title = Server and third-party service settings
+offline_mode = Enable local mode
offline_mode_popup = Disable third-party content delivery networks and serve all resources locally.
disable_gravatar = Disable Gravatar
disable_gravatar_popup = Disable Gravatar and third-party avatar sources. A default avatar will be used unless a user locally uploads an avatar.
-federated_avatar_lookup = Enable Federated Avatars
+federated_avatar_lookup = Enable federated avatars
federated_avatar_lookup_popup = Enable federated avatar lookup using Libravatar.
-disable_registration = Disable Self-Registration
+disable_registration = Disable self-registration
disable_registration_popup = Disable user self-registration. Only administrators will be able to create new user accounts.
-allow_only_external_registration_popup = Allow Registration Only Through External Services
-openid_signin = Enable OpenID Sign-In
+allow_only_external_registration_popup = Allow registration only through external services
+openid_signin = Enable OpenID sign-in
openid_signin_popup = Enable user sign-in via OpenID.
-openid_signup = Enable OpenID Self-Registration
+openid_signup = Enable OpenID self-registration
openid_signup_popup = Enable OpenID-based user self-registration.
enable_captcha = Enable registration CAPTCHA
enable_captcha_popup = Require a CAPTCHA for user self-registration.
-require_sign_in_view = Require Sign-In to View Pages
+require_sign_in_view = Require to sign-in to view instance content
require_sign_in_view_popup = Limit page access to signed-in users. Visitors will only see the sign-in and registration pages.
admin_setting_desc = Creating an administrator account is optional. The first registered user will automatically become an administrator.
-admin_title = Administrator Account Settings
-admin_name = Administrator Username
+admin_title = Administrator account settings
+admin_name = Administrator username
admin_password = Password
-confirm_password = Confirm Password
-admin_email = Email Address
+confirm_password = Confirm password
+admin_email = Email address
+config_location_hint = These configuration options will be saved in:
install_btn_confirm = Install Forgejo
test_git_failed = Could not test "git" command: %v
sqlite3_not_available = This Forgejo version does not support SQLite3. Please download the official binary version from %s (not the "gobuild" version).
@@ -299,26 +303,26 @@ invalid_db_setting = The database settings are invalid: %v
invalid_db_table = The database table "%s" is invalid: %v
invalid_repo_path = The repository root path is invalid: %v
invalid_app_data_path = The app data path is invalid: %v
-run_user_not_match = The "run as" username is not the current username: %s -> %s
+run_user_not_match = The "user to run as" username is not the current username: %s -> %s
internal_token_failed = Failed to generate internal token: %v
secret_key_failed = Failed to generate secret key: %v
save_config_failed = Failed to save configuration: %v
-enable_update_checker_helper_forgejo = Periodically checks for new Forgejo versions by checking a DNS TXT record at release.forgejo.org.
+enable_update_checker_helper_forgejo = It will periodically check for new Forgejo versions by checking a TXT DNS record at release.forgejo.org.
invalid_admin_setting = Administrator account setting is invalid: %v
invalid_log_root_path = The log path is invalid: %v
-default_keep_email_private = Hide Email Addresses by Default
+default_keep_email_private = Hide email addresses by default
default_keep_email_private_popup = Hide email addresses of new user accounts by default.
-default_allow_create_organization = Allow Creation of Organizations by Default
+default_allow_create_organization = Allow creation of organizations by default
default_allow_create_organization_popup = Allow new user accounts to create organizations by default.
-default_enable_timetracking = Enable Time Tracking by Default
+default_enable_timetracking = Enable time tracking by default
default_enable_timetracking_popup = Enable time tracking for new repositories by default.
allow_dots_in_usernames = Allow users to use dots in their usernames. Doesn't affect existing accounts.
-no_reply_address = Hidden Email Domain
+no_reply_address = Hidden email domain
no_reply_address_helper = Domain name for users with a hidden email address. For example, the username "joe" will be logged in Git as "joe@noreply.example.org" if the hidden email domain is set to "noreply.example.org".
-password_algorithm = Password Hash Algorithm
+password_algorithm = Password hash algorithm
invalid_password_algorithm = Invalid password hash algorithm
password_algorithm_helper = Set the password hashing algorithm. Algorithms have differing requirements and strength. The argon2 algorithm is rather secure but uses a lot of memory and may be inappropriate for small systems.
-enable_update_checker = Enable Update Checker
+enable_update_checker = Enable update checker
enable_update_checker_helper = Checks for new version releases periodically by connecting to gitea.io.
env_config_keys = Environment Configuration
env_config_keys_prompt = The following environment variables will also be applied to your configuration file:
@@ -328,10 +332,9 @@ uname_holder = Username or Email address
password_holder = Password
switch_dashboard_context = Switch Dashboard Context
my_repos = Repositories
+my_orgs = Organizations
show_more_repos = Show more repositories…
collaborative_repos = Collaborative Repositories
-my_orgs = My Organizations
-my_mirrors = My Mirrors
view_home = View %s
search_repos = Find a repository…
filter = Other Filters
@@ -353,6 +356,10 @@ issues.in_your_repos = In your repositories
[explore]
repos = Repositories
users = Users
+stars_one = %d star
+stars_few = %d stars
+forks_one = %d fork
+forks_few = %d forks
organizations = Organizations
search = Search
go_to = Go to
@@ -391,7 +398,7 @@ allow_password_change = Require user to change password (recommended)
reset_password_mail_sent_prompt = A confirmation email has been sent to %s. 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 = Sign In Prohibited
+prohibit_login = Signing in is prohibited
prohibit_login_desc = Your account is prohibited from signing in, please contact your site administrator.
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 (%s). If you haven't received a confirmation email or need to resend a new one, please click on the button below.
@@ -416,7 +423,9 @@ twofa_scratch_used = You have used your scratch code. You have been redirected t
twofa_passcode_incorrect = Your passcode is incorrect. If you misplaced your device, use your scratch code to sign in.
twofa_scratch_token_incorrect = Your scratch code is incorrect.
login_userpass = Sign In
-login_openid = OpenID
+tab_signin = Sign In
+tab_signup = Sign Up
+tab_openid = OpenID
oauth_signup_tab = Register New Account
oauth_signup_title = Complete New Account
oauth_signup_submit = Complete Account
@@ -463,7 +472,7 @@ activate_email.title = %s, please verify your email address
activate_email.text = Please click the following link to verify your email address within %s:
admin.new_user.subject = New user %s just signed up
-admin.new_user.user_info = User Information
+admin.new_user.user_info = User information
admin.new_user.text = Please click here to manage this user from the admin panel.
register_notify = Welcome to Forgejo
@@ -504,13 +513,13 @@ release.downloads = Downloads:
release.download.zip = Source Code (ZIP)
release.download.targz = Source Code (TAR.GZ)
-repo.transfer.subject_to = %s would like to transfer "%s" to %s
-repo.transfer.subject_to_you = %s would like to transfer "%s" to you
+repo.transfer.subject_to = %s wants to transfer repository "%s" to %s
+repo.transfer.subject_to_you = %s wants to transfer repository "%s" to you
repo.transfer.to_you = you
repo.transfer.body = To accept or reject it visit %s or just ignore it.
-repo.collaborator.added.subject = %s added you to %s
-repo.collaborator.added.text = You have been added as a collaborator of repository:
+repo.collaborator.added.subject = %s added you to %s as collaborator
+repo.collaborator.added.text = You have been added as a collaborator to repository:
team_invite.subject = %[1]s has invited you to join the %[2]s organization
team_invite.text_1 = %[1]s has invited you to join team %[2]s in organization %[3]s.
@@ -529,7 +538,7 @@ UserName = Username
RepoName = Repository name
Email = Email address
Password = Password
-Retype = Confirm Password
+Retype = Confirm password
SSHTitle = SSH key name
HttpsUrl = HTTPS URL
PayloadUrl = Payload URL
@@ -594,6 +603,8 @@ enterred_invalid_repo_name = The repository name you entered is incorrect.
enterred_invalid_org_name = The organization name you entered is incorrect.
enterred_invalid_owner_name = The new owner name is not valid.
enterred_invalid_password = The password you entered is incorrect.
+unset_password = The login user has not set the password.
+unsupported_login_type = The login type is not supported to delete account.
user_not_exist = The user does not exist.
team_not_exist = The team does not exist.
last_org_owner = You cannot remove the last user from the "owners" team. There must be at least one owner for an organization.
@@ -622,16 +633,16 @@ admin_cannot_delete_self = You cannot delete yourself when you are an admin. Ple
change_avatar = Change your avatar…
joined_on = Joined on %s
repositories = Repositories
-activity = Public Activity
+activity = Public activity
followers = Followers
-block_user = Block User
+block_user = Block user
block_user.detail = Please understand that if you block this user, other actions will be taken. Such as:
block_user.detail_1 = You are being unfollowed from this user.
block_user.detail_2 = This user cannot interact with your repositories, created issues and comments.
block_user.detail_3 = This user cannot add you as a collaborator, nor can you add them as a collaborator.
follow_blocked_user = You cannot follow this user because you have blocked this user or this user has blocked you.
-starred = Starred Repositories
-watched = Watched Repositories
+starred = Starred repositories
+watched = Watched repositories
code = Code
projects = Projects
overview = Overview
@@ -645,7 +656,7 @@ disabled_public_activity = This user has disabled the public visibility of the a
email_visibility.limited = Your email address is visible to all authenticated users
email_visibility.private = Your email address is only visible to you and administrators
show_on_map = Show this place on a map
-settings = User Settings
+settings = User settings
form.name_reserved = The username "%s" is reserved.
form.name_pattern_not_allowed = The pattern "%s" is not allowed in a username.
@@ -658,30 +669,30 @@ appearance = Appearance
password = Password
security = Security
avatar = Avatar
-ssh_gpg_keys = SSH / GPG Keys
+ssh_gpg_keys = SSH / GPG keys
social = Social Accounts
applications = Applications
orgs = Manage organizations
repos = Repositories
delete = Delete Account
-twofa = Two-Factor Authentication (TOTP)
+twofa = Two-factor authentication (TOTP)
account_link = Linked Accounts
organization = Organizations
uid = UID
-webauthn = Two-Factor Authentication (Security Keys)
-blocked_users = Blocked Users
+webauthn = Two-factor authentication (Security keys)
+blocked_users = Blocked users
public_profile = Public profile
biography_placeholder = Tell us a little bit about yourself! (You can use Markdown)
location_placeholder = Share your approximate location with others
profile_desc = Control how your profile is shown to other users. Your primary email address will be used for notifications, password recovery and web-based Git operations.
password_username_disabled = Non-local users are not allowed to change their username. Please contact your site administrator for more details.
-full_name = Full Name
+full_name = Full name
website = Website
location = Location
-update_theme = Update Theme
-update_profile = Update Profile
-update_language = Update Language
+update_theme = Change theme
+update_profile = Update profile
+update_language = Change language
update_language_not_found = Language "%s" is not available.
update_language_success = Language has been updated.
update_profile_success = Your profile has been updated.
@@ -702,32 +713,32 @@ comment_type_group_milestone = Milestone
comment_type_group_assignee = Assignee
comment_type_group_title = Title
comment_type_group_branch = Branch
-comment_type_group_time_tracking = Time Tracking
+comment_type_group_time_tracking = Time tracking
comment_type_group_deadline = Deadline
comment_type_group_dependency = Dependency
-comment_type_group_lock = Lock Status
+comment_type_group_lock = Lock status
comment_type_group_review_request = Review request
comment_type_group_pull_request_push = Added commits
comment_type_group_project = Project
comment_type_group_issue_ref = Issue reference
saved_successfully = Your settings were saved successfully.
privacy = Privacy
-keep_activity_private = Hide Activity from profile page
-keep_activity_private_popup = Makes the activity visible only for you and the admins
+keep_activity_private = Hide activity from profile page
+keep_activity_private_popup = Your activity will only be visible to you and the instance admins
-lookup_avatar_by_mail = Look Up Avatar by Email Address
-federated_avatar_lookup = Federated Avatar Lookup
+lookup_avatar_by_mail = Lookup avatar by email address
+federated_avatar_lookup = Federated avatar lookup
enable_custom_avatar = Use custom avatar
choose_new_avatar = Choose new avatar
-update_avatar = Update Avatar
-delete_current_avatar = Delete Current Avatar
+update_avatar = Update avatar
+delete_current_avatar = Delete current avatar
uploaded_avatar_not_a_image = The uploaded file is not an image.
uploaded_avatar_is_too_big = The uploaded file size (%d KiB) exceeds the maximum size (%d KiB).
update_avatar_success = Your avatar has been updated.
update_user_avatar_success = The user's avatar has been updated.
change_password = Change password
-update_password = Update Password
+update_password = Update password
old_password = Current password
new_password = New password
retype_new_password = Confirm new password
@@ -735,10 +746,10 @@ password_incorrect = The current password is incorrect.
change_password_success = Your password has been updated. Sign in using your new password from now on.
password_change_disabled = Non-local users cannot update their password through the Forgejo web interface.
-emails = Email Addresses
+emails = Email addresses
manage_emails = Manage email addresses
manage_themes = Select default theme
-manage_openid = Manage OpenID Addresses
+manage_openid = Manage OpenID addresses
email_desc = Your primary email address will be used for notifications, password recovery and, provided that it is not hidden, web-based Git operations.
theme_desc = This will be your default theme across the site.
primary = Primary
@@ -759,7 +770,7 @@ openid_deletion_desc = Removing this OpenID address from your account will preve
openid_deletion_success = The OpenID address has been removed.
add_new_email = Add email address
add_new_openid = Add New OpenID URI
-add_email = Add Email Address
+add_email = Add email address
add_openid = Add OpenID URI
add_email_confirmation_sent = A confirmation email has been sent to "%s". Please check your inbox within the next %s to confirm your email address.
add_email_success = The new email address has been added.
@@ -772,14 +783,14 @@ openid_desc = OpenID lets you delegate authentication to an external provider.
manage_ssh_keys = Manage SSH keys
manage_ssh_principals = Manage SSH Certificate Principals
manage_gpg_keys = Manage GPG keys
-add_key = Add Key
+add_key = Add key
ssh_desc = These public SSH keys are associated with your account. The corresponding private keys allow full access to your repositories. SSH keys that have been verified can be used to verify SSH-signed Git commits.
principal_desc = These SSH certificate principals are associated with your account and allow full access to your repositories.
gpg_desc = These public GPG keys are associated with your account and used to verify your commits. Keep your private keys safe as they allow to sign commits with your identity.
ssh_helper = Need help? Have a look at the guide to create your own SSH keys or solve common problems you may encounter using SSH.
gpg_helper = Need help? Have a look at the guide about GPG.
-add_new_key = Add SSH Key
-add_new_gpg_key = Add GPG Key
+add_new_key = Add SSH key
+add_new_gpg_key = Add GPG key
key_content_ssh_placeholder = Begins with "ssh-ed25519", "ssh-rsa", "ecdsa-sha2-nistp256", "ecdsa-sha2-nistp384", "ecdsa-sha2-nistp521", "sk-ecdsa-sha2-nistp256@openssh.com", or "sk-ssh-ed25519@openssh.com"
key_content_gpg_placeholder = Begins with "-----BEGIN PGP PUBLIC KEY BLOCK-----"
add_new_principal = Add Principal
@@ -790,7 +801,7 @@ gpg_key_id_used = A public GPG key with same ID already exists.
gpg_no_key_email_found = This GPG key does not match any activated email address associated with your account. It may still be added if you sign the provided token.
gpg_key_matched_identities = Matched Identities:
gpg_key_matched_identities_long=The embedded identities in this key match the following activated email addresses for this user. Commits matching these email addresses can be verified with this key.
-gpg_key_verified=Verified Key
+gpg_key_verified=Verified key
gpg_key_verified_long=Key has been verified with a token and can be used to verify commits matching any activated email addresses for this user in addition to any matched identities for this key.
gpg_key_verify=Verify
gpg_invalid_token_signature = The provided GPG key, signature and token do not match or token is out-of-date.
@@ -801,7 +812,7 @@ gpg_token_code = echo "%s" | gpg -a --default-key %s --detach-sig
gpg_token_signature = Armored GPG signature
key_signature_gpg_placeholder = Begins with "-----BEGIN PGP SIGNATURE-----"
verify_gpg_key_success = GPG key "%s" has been verified.
-ssh_key_verified=Verified Key
+ssh_key_verified=Verified key
ssh_key_verified_long=Key has been verified with a token and can be used to verify commits matching any activated email addresses for this user.
ssh_key_verify=Verify
ssh_invalid_token_signature = The provided SSH key, signature or token do not match or token is out-of-date.
@@ -820,8 +831,8 @@ add_key_success = The SSH key "%s" has been added.
add_gpg_key_success = The GPG key "%s" has been added.
add_principal_success = The SSH certificate principal "%s" has been added.
delete_key = Remove
-ssh_key_deletion = Remove SSH Key
-gpg_key_deletion = Remove GPG Key
+ssh_key_deletion = Remove SSH key
+gpg_key_deletion = Remove GPG key
ssh_principal_deletion = Remove SSH Certificate Principal
ssh_key_deletion_desc = Removing an SSH key revokes its access to your account. Continue?
gpg_key_deletion_desc = Removing a GPG key un-verifies commits signed by it. Continue?
@@ -853,11 +864,11 @@ manage_access_token = Manage access tokens
generate_new_token = Generate new token
tokens_desc = These tokens grant access to your account using the Forgejo API.
token_name = Token name
-generate_token = Generate Token
+generate_token = Generate token
generate_token_success = Your new token has been generated. Copy it now as it will not be shown again.
generate_token_name_duplicate = %s has been used as an application name already. Please use a new one.
delete_token = Delete
-access_token_deletion = Delete Access Token
+access_token_deletion = Delete access token
access_token_deletion_cancel_action = Cancel
access_token_deletion_confirm_action = Delete
access_token_deletion_desc = Deleting a token will revoke access to your account for applications using it. This cannot be undone. Continue?
@@ -880,11 +891,11 @@ remove_oauth2_application = Remove OAuth2 Application
remove_oauth2_application_desc = Removing an OAuth2 application will revoke access to all signed access tokens. Continue?
remove_oauth2_application_success = The application has been deleted.
create_oauth2_application = Create a new OAuth2 application
-create_oauth2_application_button = Create Application
+create_oauth2_application_button = Create application
create_oauth2_application_success = You have successfully created a new OAuth2 application.
update_oauth2_application_success = You have successfully updated the OAuth2 application.
oauth2_application_name = Application name
-oauth2_confidential_client = Confidential Client. Select for apps that keep the secret confidential, such as web apps. Do not select for native apps including desktop and mobile apps.
+oauth2_confidential_client = Confidential client. Select for apps that keep the secret confidential, such as web apps. Do not select for native apps including desktop and mobile apps.
oauth2_redirect_uris = Redirect URIs. Please use a new line for every URI.
save_application = Save
oauth2_client_id = Client ID
@@ -908,10 +919,10 @@ twofa_desc = To protect your account against password theft, you can use a smart
twofa_recovery_tip = If you lose your device, you will be able to use a single-use recovery key to regain access to your account.
twofa_is_enrolled = Your account is currently enrolled in two-factor authentication.
twofa_not_enrolled = Your account is not currently enrolled in two-factor authentication.
-twofa_disable = Disable Two-Factor Authentication
-twofa_scratch_token_regenerate = Regenerate Single-Use Recovery Key
+twofa_disable = Disable two-factor authentication
+twofa_scratch_token_regenerate = Regenerate single-use recovery key
twofa_scratch_token_regenerated = Your single-use recovery key is now %s. Store it in a safe place, as it will not be shown again.
-twofa_enroll = Enroll into Two-Factor Authentication
+twofa_enroll = Enroll into two-factor authentication
twofa_disable_note = You can disable two-factor authentication if needed.
twofa_disable_desc = Disabling two-factor authentication will make your account less secure. Continue?
regenerate_scratch_token_desc = If you misplaced your recovery key or have already used it to sign in, you can reset it here.
@@ -924,9 +935,9 @@ twofa_enrolled = Your account has been successfully enrolled. Store your single-
twofa_failed_get_secret = Failed to get secret.
webauthn_desc = Security keys are hardware devices containing cryptographic keys. They can be used for two-factor authentication. Security keys must support the WebAuthn Authenticator standard.
-webauthn_register_key = Add Security Key
+webauthn_register_key = Add security key
webauthn_nickname = Nickname
-webauthn_delete_key = Remove Security Key
+webauthn_delete_key = Remove security key
webauthn_delete_key_desc = If you remove a security key you can no longer sign in with it. Continue?
webauthn_key_loss_warning = If you lose your security keys, you will lose access to your account.
webauthn_alternative_tip = You may want to configure an additional authentication method.
@@ -945,18 +956,18 @@ orgs_none = You are not a member of any organizations.
repos_none = You do not own any repositories.
blocked_users_none = There are no blocked users.
-delete_account = Delete Your Account
+delete_account = Delete your account
delete_prompt = This operation will permanently delete your user account. It CANNOT be undone.
delete_with_all_comments = Your account is younger than %s. To avoid ghost comments, all issue/PR comments will be deleted with it.
-confirm_delete_account = Confirm Deletion
-delete_account_title = Delete User Account
+confirm_delete_account = Confirm deletion
+delete_account_title = Delete user account
delete_account_desc = Are you sure you want to permanently delete this user account?
-email_notifications.enable = Enable Email Notifications
-email_notifications.onmention = Only Email on Mention
-email_notifications.disable = Disable Email Notifications
-email_notifications.submit = Set Email Preference
-email_notifications.andyourown = And Your Own Notifications
+email_notifications.enable = Enable email notifications
+email_notifications.onmention = Only email on mention
+email_notifications.disable = Disable email notifications
+email_notifications.submit = Set email preference
+email_notifications.andyourown = And your own notifications
visibility = User visibility
visibility.public = Public
@@ -993,10 +1004,10 @@ visibility = Visibility
visibility_description = Only the owner or the organization members if they have rights, will be able to see it.
visibility_helper = Make repository private
visibility_helper_forced = Your site administrator forces new repositories to be private.
-visibility_fork_helper = (Changing this will affect all forks.)
+visibility_fork_helper = (Changing this will affect visibility of all forks.)
clone_helper = Need help cloning? Visit Help.
-fork_repo = Fork Repository
-fork_from = Fork From
+fork_repo = Fork repository
+fork_from = Fork from
already_forked = You've already forked %s
fork_to_different_account = Fork to a different account
fork_visibility_helper = The visibility of a forked repository cannot be changed.
@@ -1004,53 +1015,52 @@ fork_branch = Branch to be cloned to the fork
all_branches = All branches
fork_no_valid_owners = This repository can not be forked because there are no valid owners.
use_template = Use this template
-clone_in_vsc = Clone in VS Code
-clone_in_vscodium = Clone in VSCodium
+open_with_editor = Open with %s
download_zip = Download ZIP
download_tar = Download TAR.GZ
download_bundle = Download BUNDLE
-generate_repo = Generate Repository
-generate_from = Generate From
+generate_repo = Generate repository
+generate_from = Generate from
repo_desc = Description
repo_desc_helper = Enter short description (optional)
repo_lang = Language
repo_gitignore_helper = Select .gitignore templates.
repo_gitignore_helper_desc = Choose which files not to track from a list of templates for common languages. Typical artifacts generated by each language's build tools are included on .gitignore by default.
-issue_labels = Issue Labels
+issue_labels = Issue labels
issue_labels_helper = Select an issue label set.
license = License
license_helper = Select a license file.
license_helper_desc = A license governs what others can and can't do with your code. Not sure which one is right for your project? See Choose a license.
-object_format = Object Format
+object_format = Object format
object_format_helper = Object format of the repository. Cannot be changed later. SHA1 is most compatible.
readme = README
readme_helper = Select a README file template.
readme_helper_desc = This is the place where you can write a complete description for your project.
-auto_init = Initialize Repository (Adds .gitignore, License and README)
+auto_init = Initialize repository (Adds .gitignore, License and README)
trust_model_helper = Select trust model for signature verification. Possible options are:
trust_model_helper_collaborator = Collaborator: Trust signatures by collaborators
trust_model_helper_committer = Committer: Trust signatures that match committers
trust_model_helper_collaborator_committer = Collaborator+Committer: Trust signatures by collaborators which match the committer
trust_model_helper_default = Default: Use the default trust model for this installation
-create_repo = Create Repository
-default_branch = Default Branch
+create_repo = Create repository
+default_branch = Default branch
default_branch_label = default
default_branch_helper = The default branch is the base branch for pull requests and code commits.
mirror_prune = Prune
mirror_prune_desc = Remove obsolete remote-tracking references
-mirror_interval = Mirror Interval (valid time units are "h", "m", "s"). 0 to disable periodic sync. (Minimum interval: %s)
+mirror_interval = Mirror interval (valid time units are "h", "m", "s"). 0 to disable periodic sync. (Minimum interval: %s)
mirror_interval_invalid = The mirror interval is not valid.
mirror_sync = synced
mirror_sync_on_commit = Sync when commits are pushed
-mirror_address = Clone From URL
+mirror_address = Clone from URL
mirror_address_desc = Put any required credentials in the Authorization section.
mirror_address_url_invalid = The provided URL is invalid. You must escape all components of the URL correctly.
mirror_address_protocol_invalid = The provided URL is invalid. Only http(s):// or git:// locations can be used for mirroring.
mirror_lfs = Large File Storage (LFS)
mirror_lfs_desc = Activate mirroring of LFS data.
-mirror_lfs_endpoint = LFS Endpoint
+mirror_lfs_endpoint = LFS endpoint
mirror_lfs_endpoint_desc = Sync will attempt to use the clone url to determine the LFS server. You can also specify a custom endpoint if the repository LFS data is stored somewhere else.
-mirror_last_synced = Last Synchronized
+mirror_last_synced = Last synchronized
mirror_password_placeholder = (Unchanged)
mirror_password_blank_placeholder = (Unset)
mirror_password_help = Change the username to erase a stored password.
@@ -1062,7 +1072,7 @@ reactions_more = and %d more
unit_disabled = The site administrator has disabled this repository section.
language_other = Other
adopt_search = Enter username to search for unadopted repositories... (leave blank to find all)
-adopt_preexisting_label = Adopt Files
+adopt_preexisting_label = Adopt files
adopt_preexisting = Adopt pre-existing files
adopt_preexisting_content = Create repository from %s
adopt_preexisting_success = Adopted files and created repository from %s
@@ -1079,9 +1089,9 @@ tree_path_not_found_commit = Path %[1]s doesn't exist in commit %[2]s
tree_path_not_found_branch = Path %[1]s doesn't exist in branch %[2]s
tree_path_not_found_tag = Path %[1]s doesn't exist in tag %[2]s
-transfer.accept = Accept Transfer
+transfer.accept = Accept transfer
transfer.accept_desc = Transfer to "%s"
-transfer.reject = Reject Transfer
+transfer.reject = Reject transfer
transfer.reject_desc = Cancel transfer to "%s"
transfer.no_permission_to_accept = You do not have permission to accept this transfer.
transfer.no_permission_to_reject = You do not have permission to reject this transfer.
@@ -1093,14 +1103,14 @@ desc.internal = Internal
desc.archived = Archived
desc.sha256 = SHA256
-template.items = Template Items
-template.git_content = Git Content (Default Branch)
-template.git_hooks = Git Hooks
-template.git_hooks_tooltip = You are currently unable to modify or remove Git Hooks once added. Select this only if you trust the template repository.
+template.items = Template items
+template.git_content = Git content (Default branch)
+template.git_hooks = Git hooks
+template.git_hooks_tooltip = You are currently unable to modify or remove Git hooks once added. Select this only if you trust the template repository.
template.webhooks = Webhooks
template.topics = Topics
template.avatar = Avatar
-template.issue_labels = Issue Labels
+template.issue_labels = Issue labels
template.one_item = Must select at least one template item
template.invalid = Must select a template repository
@@ -1116,10 +1126,10 @@ form.name_pattern_not_allowed = The pattern "%s" is not allowed in a repository
need_auth = Authorization
migrate_options = Migration options
-migrate_service = Migration Service
+migrate_service = Migration service
migrate_options_mirror_helper = This repository will be a mirror
migrate_options_lfs = Migrate LFS files
-migrate_options_lfs_endpoint.label = LFS Endpoint
+migrate_options_lfs_endpoint.label = LFS endpoint
migrate_options_lfs_endpoint.description = Migration will attempt to use your Git remote to determine the LFS server. You can also specify a custom endpoint if the repository LFS data is stored somewhere else.
migrate_options_lfs_endpoint.description.local = A local server path is supported too.
migrate_options_lfs_endpoint.placeholder = If left blank, the endpoint will be derived from the clone URL
@@ -1128,10 +1138,10 @@ migrate_items_wiki = Wiki
migrate_items_milestones = Milestones
migrate_items_labels = Labels
migrate_items_issues = Issues
-migrate_items_pullrequests = Pull Requests
-migrate_items_merge_requests = Merge Requests
+migrate_items_pullrequests = Pull requests
+migrate_items_merge_requests = Merge requests
migrate_items_releases = Releases
-migrate_repo = Migrate Repository
+migrate_repo = Migrate repository
migrate.clone_address = Migrate / Clone from URL
migrate.clone_address_desc = The HTTP(S) or Git "clone" URL of an existing repository
migrate.github_token_desc = You can put one or more tokens with comma separated here to make migrating faster because of GitHub API rate limit. WARN: Abusing this feature may violate the service provider's policy and lead to account blocking.
@@ -1141,15 +1151,15 @@ migrate.permission_denied_blocked = You cannot import from disallowed hosts, ple
migrate.invalid_local_path = The local path is invalid. It doesn't exist or is not a directory.
migrate.invalid_lfs_endpoint = The LFS endpoint is not valid.
migrate.failed = Migration failed: %v
-migrate.migrate_items_options = Access Token is required to migrate additional items
+migrate.migrate_items_options = Access token is required to migrate additional items
migrated_from = Migrated from %[2]s
-migrated_from_fake = Migrated From %[1]s
-migrate.migrate = Migrate From %s
+migrated_from_fake = Migrated from %[1]s
+migrate.migrate = Migrate from %s
migrate.migrating = Migrating from %s ...
migrate.migrating_failed = Migrating from %s failed.
migrate.migrating_failed.error = Failed to migrate: %s
migrate.migrating_failed_no_addr = Migration failed.
-migrate.github.description = Migrate data from github.com or other GitHub instances.
+migrate.github.description = Migrate data from github.com or GitHub Enterprise server.
migrate.git.description = Migrate a repository only from any Git service.
migrate.gitlab.description = Migrate data from gitlab.com or other GitLab instances.
migrate.forgejo.description = Migrate data from codeberg.org or other Forgejo instances.
@@ -1158,14 +1168,14 @@ migrate.gogs.description = Migrate data from notabug.org or other Gogs instances
migrate.onedev.description = Migrate data from code.onedev.io or other OneDev instances.
migrate.codebase.description = Migrate data from codebasehq.com.
migrate.gitbucket.description = Migrate data from GitBucket instances.
-migrate.migrating_git = Migrating Git Data
-migrate.migrating_topics = Migrating Topics
-migrate.migrating_milestones = Migrating Milestones
-migrate.migrating_labels = Migrating Labels
-migrate.migrating_releases = Migrating Releases
-migrate.migrating_issues = Migrating Issues
-migrate.migrating_pulls = Migrating Pull Requests
-migrate.cancel_migrating_title = Cancel Migration
+migrate.migrating_git = Migrating Git data
+migrate.migrating_topics = Migrating topics
+migrate.migrating_milestones = Migrating milestones
+migrate.migrating_labels = Migrating labels
+migrate.migrating_releases = Migrating releases
+migrate.migrating_issues = Migrating issues
+migrate.migrating_pulls = Migrating pull requests
+migrate.cancel_migrating_title = Cancel migration
migrate.cancel_migrating_confirm = Do you want to cancel this migration?
mirror_from = mirror of
@@ -1180,11 +1190,11 @@ watch = Watch
unstar = Unstar
star = Star
fork = Fork
-download_archive = Download Repository
-more_operations = More Operations
+download_archive = Download repository
+more_operations = More operations
-no_desc = No Description
-quick_guide = Quick Guide
+no_desc = No description
+quick_guide = Quick guide
clone_this_repo = Clone this repository
cite_this_repo = Cite this repository
create_new_repo_command = Creating a new repository on the command line
@@ -1202,7 +1212,7 @@ find_tag = Find tag
branches = Branches
tags = Tags
issues = Issues
-pulls = Pull Requests
+pulls = Pull requests
project_board = Projects
packages = Packages
actions = Actions
@@ -1236,18 +1246,18 @@ ambiguous_character = `%[1]c [U+%04[1]X] can be confused with %[2]c [U+%04[2]X]`
escape_control_characters = Escape
unescape_control_characters = Unescape
-file_copy_permalink = Copy Permalink
-view_git_blame = View Git Blame
+file_copy_permalink = Copy permalink
+view_git_blame = View git blame
video_not_supported_in_browser = Your browser does not support the HTML5 "video" tag.
audio_not_supported_in_browser = Your browser does not support the HTML5 "audio" tag.
stored_lfs = Stored with Git LFS
symbolic_link = Symbolic link
-executable_file = Executable File
+executable_file = Executable file
vendored = Vendored
generated = Generated
-commit_graph = Commit Graph
+commit_graph = Commit graph
commit_graph.select = Select branches
-commit_graph.hide_pr_refs = Hide Pull Requests
+commit_graph.hide_pr_refs = Hide pull requests
commit_graph.monochrome = Mono
commit_graph.color = Color
commit.contained_in = This commit is contained in:
@@ -1260,18 +1270,18 @@ line = line
lines = lines
from_comment = (comment)
-editor.add_file = Add File
-editor.new_file = New File
-editor.upload_file = Upload File
-editor.edit_file = Edit File
-editor.preview_changes = Preview Changes
+editor.add_file = Add file
+editor.new_file = New file
+editor.upload_file = Upload file
+editor.edit_file = Edit file
+editor.preview_changes = Preview changes
editor.cannot_edit_lfs_files = LFS files cannot be edited in the web interface.
editor.cannot_edit_non_text_files = Binary files cannot be edited in the web interface.
-editor.edit_this_file = Edit File
+editor.edit_this_file = Edit file
editor.this_file_locked = File is locked
editor.must_be_on_a_branch = You must be on a branch to make or propose changes to this file.
editor.fork_before_edit = You must fork this repository to make or propose changes to this file.
-editor.delete_this_file = Delete File
+editor.delete_this_file = Delete file
editor.must_have_write_access = You must have write access to make or propose changes to this file.
editor.file_delete_success = File "%s" has been deleted.
editor.name_your_file = Name your file…
@@ -1314,8 +1324,8 @@ editor.commit_empty_file_text = The file you're about to commit is empty. Procee
editor.no_changes_to_show = There are no changes to show.
editor.fail_to_update_file = Failed to update/create file "%s".
editor.fail_to_update_file_summary = Error Message:
-editor.push_rejected_no_message = The change was rejected by the server without a message. Please check Git Hooks.
-editor.push_rejected = The change was rejected by the server. Please check Git Hooks.
+editor.push_rejected_no_message = The change was rejected by the server without a message. Please check Git hooks.
+editor.push_rejected = The change was rejected by the server. Please check Git hooks.
editor.push_rejected_summary = Full Rejection Message:
editor.add_subdir = Add a directory…
editor.unable_to_upload_files = Failed to upload files to "%s" with error: %v
@@ -1346,8 +1356,8 @@ commits.newer = Newer
commits.signed_by = Signed by
commits.signed_by_untrusted_user = Signed by untrusted user
commits.signed_by_untrusted_user_unmatched = Signed by untrusted user who does not match committer
-commits.gpg_key_id = GPG Key ID
-commits.ssh_key_fingerprint = SSH Key Fingerprint
+commits.gpg_key_id = GPG key ID
+commits.ssh_key_fingerprint = SSH key fingerprint
commits.view_path=View at this point in history
commit.operations = Operations
@@ -1363,24 +1373,24 @@ commitstatus.failure = Failure
commitstatus.pending = Pending
commitstatus.success = Success
-ext_issues = Access to External Issues
+ext_issues = Access to external issues
ext_issues.desc = Link to an external issue tracker.
projects = Projects
projects.desc = Manage issues and pulls in project boards.
projects.description = Description (optional)
projects.description_placeholder = Description
-projects.create = Create Project
+projects.create = Create project
projects.title = Title
-projects.new = New Project
+projects.new = New project
projects.new_subheader = Coordinate, track, and update your work in one place, so projects stay transparent and on schedule.
projects.create_success = The project "%s" has been created.
-projects.deletion = Delete Project
+projects.deletion = Delete project
projects.deletion_desc = Deleting a project removes it from all related issues. Continue?
projects.deletion_success = The project has been deleted.
-projects.edit = Edit Project
+projects.edit = Edit project
projects.edit_subheader = Projects organize issues and track progress.
-projects.modify = Edit Project
+projects.modify = Edit project
projects.edit_success = Project "%s" has been updated.
projects.type.none = None
projects.type.basic_kanban = Basic Kanban
@@ -1413,43 +1423,43 @@ issues.filter_milestones = Filter Milestone
issues.filter_projects = Filter Project
issues.filter_labels = Filter Label
issues.filter_reviewers = Filter Reviewer
-issues.new = New Issue
+issues.new = New issue
issues.new.title_empty = Title cannot be empty
issues.new.labels = Labels
-issues.new.no_label = No Label
+issues.new.no_label = No label
issues.new.clear_labels = Clear labels
issues.new.projects = Projects
issues.new.clear_projects = Clear projects
issues.new.no_projects = No project
-issues.new.open_projects = Open Projects
-issues.new.closed_projects = Closed Projects
+issues.new.open_projects = Open projects
+issues.new.closed_projects = Closed projects
issues.new.no_items = No items
issues.new.milestone = Milestone
-issues.new.no_milestone = No Milestone
+issues.new.no_milestone = No milestone
issues.new.clear_milestone = Clear milestone
-issues.new.open_milestone = Open Milestones
-issues.new.closed_milestone = Closed Milestones
+issues.new.open_milestone = Open milestones
+issues.new.closed_milestone = Closed milestones
issues.new.assignees = Assignees
issues.new.clear_assignees = Clear assignees
-issues.new.no_assignees = No Assignees
+issues.new.no_assignees = No assignees
issues.new.no_reviewers = No reviewers
-issues.choose.get_started = Get Started
+issues.choose.get_started = Get started
issues.choose.open_external_link = Open
issues.choose.blank = Default
issues.choose.blank_about = Create an issue from default template.
issues.choose.ignore_invalid_templates = Invalid templates have been ignored
issues.choose.invalid_templates = %v invalid template(s) found
issues.choose.invalid_config = The issue config contains errors:
-issues.no_ref = No Branch/Tag Specified
-issues.create = Create Issue
-issues.new_label = New Label
+issues.no_ref = No Branch/Tag specified
+issues.create = Create issue
+issues.new_label = New label
issues.new_label_placeholder = Label name
issues.new_label_desc_placeholder = Description
-issues.create_label = Create Label
-issues.label_templates.title = Load a predefined set of labels
-issues.label_templates.info = No labels exist yet. Create a label with "New Label" or use a predefined label set:
-issues.label_templates.helper = Select a label set
-issues.label_templates.use = Use Label Set
+issues.create_label = Create label
+issues.label_templates.title = Load a label preset
+issues.label_templates.info = No labels exist yet. Create a label with "New label" or use a label preset:
+issues.label_templates.helper = Select a label preset
+issues.label_templates.use = Use label preset
issues.label_templates.fail_to_load_file = Failed to load label template file "%s": %v
issues.add_label = added the %s label %s
issues.add_labels = added the %s labels %s
@@ -1535,18 +1545,18 @@ issues.num_comments_1 = %d comment
issues.num_comments = %d comments
issues.commented_at = `commented %s`
issues.delete_comment_confirm = Are you sure you want to delete this comment?
-issues.context.copy_link = Copy Link
-issues.context.quote_reply = Quote Reply
-issues.context.reference_issue = Reference in New Issue
+issues.context.copy_link = Copy link
+issues.context.quote_reply = Quote reply
+issues.context.reference_issue = Reference in a new issue
issues.context.edit = Edit
issues.context.delete = Delete
issues.no_content = No description provided.
-issues.close = Close Issue
+issues.close = Close issue
issues.comment_pull_merged_at = merged commit %[1]s into %[2]s %[3]s
issues.comment_manually_pull_merged_at = manually merged commit %[1]s into %[2]s %[3]s
-issues.close_comment_issue = Comment and Close
+issues.close_comment_issue = Comment and close
issues.reopen_issue = Reopen
-issues.reopen_comment_issue = Comment and Reopen
+issues.reopen_comment_issue = Comment and reopen
issues.create_comment = Comment
issues.closed_at = `closed this issue %[2]s`
issues.reopened_at = `reopened this issue %[2]s`
@@ -1584,7 +1594,7 @@ issues.label_title = Name
issues.label_description = Description
issues.label_color = Color
issues.label_exclusive = Exclusive
-issues.label_archive = Archive Label
+issues.label_archive = Archive label
issues.label_archived_filter = Show archived labels
issues.label_archive_tooltip = Archived labels are excluded by default from the suggestions when searching by label.
issues.label_exclusive_desc = Name the label scope/item
to make it mutually exclusive with other scope/
labels.
@@ -1593,20 +1603,20 @@ issues.label_count = %d labels
issues.label_open_issues = %d open issues/pull requests
issues.label_edit = Edit
issues.label_delete = Delete
-issues.label_modify = Edit Label
-issues.label_deletion = Delete Label
+issues.label_modify = Edit label
+issues.label_deletion = Delete label
issues.label_deletion_desc = Deleting a label removes it from all issues. Continue?
issues.label_deletion_success = The label has been deleted.
issues.label.filter_sort.alphabetically = Alphabetically
issues.label.filter_sort.reverse_alphabetically = Reverse alphabetically
issues.label.filter_sort.by_size = Smallest size
issues.label.filter_sort.reverse_by_size = Largest size
-issues.num_participants = %d Participants
+issues.num_participants = %d participants
issues.attachment.open_tab = `Click to see "%s" in a new tab`
issues.attachment.download = `Click to download "%s"`
issues.subscribe = Subscribe
issues.unsubscribe = Unsubscribe
-issues.unpin_issue = Unpin Issue
+issues.unpin_issue = Unpin issue
issues.max_pinned = You can't pin more issues
issues.pin_comment = pinned this %s
issues.unpin_comment = unpinned this %s
@@ -1632,28 +1642,28 @@ issues.comment_on_locked = You cannot comment on a locked issue.
issues.delete = Delete
issues.delete.title = Delete this issue?
issues.delete.text = Do you really want to delete this issue? (This will permanently remove all content. Consider closing it instead, if you intend to keep it archived)
-issues.tracker = Time Tracker
-issues.start_tracking_short = Start Timer
-issues.start_tracking = Start Time Tracking
+issues.tracker = Time tracker
+issues.start_tracking_short = Start timer
+issues.start_tracking = Start time tracking
issues.start_tracking_history = `started working %s`
issues.tracker_auto_close = Timer will be stopped automatically when this issue gets closed
issues.tracking_already_started = `You have already started time tracking on another issue!`
-issues.stop_tracking = Stop Timer
+issues.stop_tracking = Stop timer
issues.stop_tracking_history = `stopped working %s`
issues.cancel_tracking = Discard
issues.cancel_tracking_history = `canceled time tracking %s`
-issues.add_time = Manually Add Time
+issues.add_time = Manually add time
issues.del_time = Delete this time log
-issues.add_time_short = Add Time
+issues.add_time_short = Add time
issues.add_time_cancel = Cancel
issues.add_time_history = `added spent time %s`
issues.del_time_history= `deleted spent time %s`
issues.add_time_hours = Hours
issues.add_time_minutes = Minutes
issues.add_time_sum_to_small = No time was entered.
-issues.time_spent_total = Total Time Spent
-issues.time_spent_from_all_authors = `Total Time Spent: %s`
-issues.due_date = Due Date
+issues.time_spent_total = Total time spent
+issues.time_spent_from_all_authors = `Total time spent: %s`
+issues.due_date = Due date
issues.invalid_due_date_format = Due date format must be "yyyy-mm-dd".
issues.error_modifying_due_date = Failed to modify the due date.
issues.error_removing_due_date = Failed to remove the due date.
@@ -1696,7 +1706,7 @@ issues.dependency.blocked_by_short = Depends on
issues.dependency.remove_header = Remove Dependency
issues.dependency.issue_remove_text = This will remove the dependency from this issue. Continue?
issues.dependency.pr_remove_text = This will remove the dependency from this pull request. Continue?
-issues.dependency.setting = Enable Dependencies For Issues and Pull Requests
+issues.dependency.setting = Enable dependencies for issues and pull requests
issues.dependency.add_error_same_issue = You cannot make an issue depend on itself.
issues.dependency.add_error_dep_issue_not_exist = Dependent issue does not exist.
issues.dependency.add_error_dep_not_exist = Dependency does not exist.
@@ -1747,9 +1757,9 @@ compare.compare_base = base
compare.compare_head = compare
pulls.desc = Enable pull requests and code reviews.
-pulls.new = New Pull Request
-pulls.view = View Pull Request
-pulls.compare_changes = New Pull Request
+pulls.new = New pull request
+pulls.view = View pull request
+pulls.compare_changes = New pull request
pulls.allow_edits_from_maintainers = Allow edits from maintainers
pulls.allow_edits_from_maintainers_desc = Users with write access to the base branch can also push to this branch
pulls.allow_edits_from_maintainers_err = Updating failed
@@ -1776,13 +1786,15 @@ pulls.nothing_to_compare = These branches are equal. There is no need to create
pulls.nothing_to_compare_have_tag = The selected branch/tag are equal.
pulls.nothing_to_compare_and_allow_empty_pr = These branches are equal. This PR will be empty.
pulls.has_pull_request = `A pull request between these branches already exists: %[2]s#%[3]d`
-pulls.create = Create Pull Request
-pulls.title_desc = wants to merge %[1]d commits from %[2]s
into %[3]s
-pulls.merged_title_desc = merged %[1]d commits from %[2]s
into %[3]s
%[4]s
+pulls.create = Create pull request
+pulls.title_desc_one = wants to merge %[1]d commit from %[2]s
into %[3]s
+pulls.title_desc_few = wants to merge %[1]d commits from %[2]s
into %[3]s
+pulls.merged_title_desc_one = merged %[1]d commit from %[2]s
into %[3]s
%[4]s
+pulls.merged_title_desc_few = merged %[1]d commits from %[2]s
into %[3]s
%[4]s
pulls.change_target_branch_at = `changed target branch from %s to %s %s`
pulls.tab_conversation = Conversation
pulls.tab_commits = Commits
-pulls.tab_files = Files Changed
+pulls.tab_files = Files changed
pulls.reopen_to_merge = Please reopen this pull request to perform a merge.
pulls.cant_reopen_deleted_branch = This pull request cannot be reopened because the branch was deleted.
pulls.merged = Merged
@@ -1847,9 +1859,9 @@ pulls.unrelated_histories = Merge Failed: The merge head and base do not share a
pulls.merge_out_of_date = Merge Failed: Whilst generating the merge, the base was updated. Hint: Try again.
pulls.head_out_of_date = Merge Failed: Whilst generating the merge, the head was updated. Hint: Try again.
pulls.has_merged = Failed: The pull request has been merged, you cannot merge again or change the target branch.
-pulls.push_rejected = Push Failed: The push was rejected. Review the Git Hooks for this repository.
+pulls.push_rejected = Push Failed: The push was rejected. Review the Git hooks for this repository.
pulls.push_rejected_summary = Full Rejection Message
-pulls.push_rejected_no_message = Push Failed: The push was rejected but there was no remote message. Review the Git Hooks for this repository
+pulls.push_rejected_no_message = Push Failed: The push was rejected but there was no remote message. Review the Git hooks for this repository
pulls.open_unmerged_pull_exists = `You cannot perform a reopen operation because there is a pending pull request (#%d) with identical properties.`
pulls.status_checking = Some checks are pending
pulls.status_checks_success = All checks were successful
@@ -1865,7 +1877,7 @@ pulls.update_branch_rebase = Update branch by rebase
pulls.update_branch_success = Branch update was successful
pulls.update_not_allowed = You are not allowed to update branch
pulls.outdated_with_base_branch = This branch is out-of-date with the base branch
-pulls.close = Close Pull Request
+pulls.close = Close pull request
pulls.closed_at = `closed this pull request %[2]s`
pulls.reopened_at = `reopened this pull request %[2]s`
pulls.commit_ref_at = `referenced this pull request from a commit %[2]s`
@@ -1901,7 +1913,7 @@ pulls.recently_pushed_new_branches = You pushed on branch %d%% Completed
-milestones.create = Create Milestone
+milestones.create = Create milestone
milestones.title = Title
milestones.desc = Description
-milestones.due_date = Due Date (optional)
+milestones.due_date = Due date (optional)
milestones.clear = Clear
milestones.invalid_due_date_format = Due date format must be "yyyy-mm-dd".
milestones.create_success = The milestone "%s" has been created.
-milestones.edit = Edit Milestone
+milestones.edit = Edit milestone
milestones.edit_subheader = Milestones organize issues and track progress.
milestones.cancel = Cancel
-milestones.modify = Update Milestone
+milestones.modify = Update milestone
milestones.edit_success = Milestone "%s" has been updated.
-milestones.deletion = Delete Milestone
+milestones.deletion = Delete milestone
milestones.deletion_desc = Deleting a milestone removes it from all related issues. Continue?
milestones.deletion_success = The milestone has been deleted.
-milestones.filter_sort.earliest_due_data = Earliest due date
-milestones.filter_sort.latest_due_date = Latest due date
+milestones.filter_sort.earliest_due_data = Nearest due date
+milestones.filter_sort.latest_due_date = Farthest due date
milestones.filter_sort.least_complete = Least complete
milestones.filter_sort.most_complete = Most complete
milestones.filter_sort.most_issues = Most issues
@@ -1978,9 +1990,9 @@ wiki.original_git_entry_tooltip = View original Git file instead of using friend
activity = Activity
activity.navbar.pulse = Pulse
-activity.navbar.code_frequency = Code Frequency
+activity.navbar.code_frequency = Code frequency
activity.navbar.contributors = Contributors
-activity.navbar.recent_commits = Recent Commits
+activity.navbar.recent_commits = Recent commits
activity.period.filter_label = Period:
activity.period.daily = 1 day
activity.period.halfweekly = 3 days
@@ -1990,38 +2002,38 @@ activity.period.quarterly = 3 months
activity.period.semiyearly = 6 months
activity.period.yearly = 1 year
activity.overview = Overview
-activity.active_prs_count_1 = %d Active Pull Request
-activity.active_prs_count_n = %d Active Pull Requests
-activity.merged_prs_count_1 = Merged Pull Request
-activity.merged_prs_count_n = Merged Pull Requests
-activity.opened_prs_count_1 = Proposed Pull Request
-activity.opened_prs_count_n = Proposed Pull Requests
+activity.active_prs_count_1 = %d Active pull request
+activity.active_prs_count_n = %d Active pull requests
+activity.merged_prs_count_1 = Merged pull request
+activity.merged_prs_count_n = Merged pull requests
+activity.opened_prs_count_1 = Proposed pull request
+activity.opened_prs_count_n = Proposed pull requests
activity.title.user_1 = %d user
activity.title.user_n = %d users
-activity.title.prs_1 = %d Pull request
-activity.title.prs_n = %d Pull requests
+activity.title.prs_1 = %d pull request
+activity.title.prs_n = %d pull requests
activity.title.prs_merged_by = %s merged by %s
activity.title.prs_opened_by = %s proposed by %s
activity.merged_prs_label = Merged
activity.opened_prs_label = Proposed
-activity.active_issues_count_1 = %d Active Issue
-activity.active_issues_count_n = %d Active Issues
-activity.closed_issues_count_1 = Closed Issue
-activity.closed_issues_count_n = Closed Issues
-activity.title.issues_1 = %d Issue
-activity.title.issues_n = %d Issues
+activity.active_issues_count_1 = %d active issue
+activity.active_issues_count_n = %d active issues
+activity.closed_issues_count_1 = Closed issue
+activity.closed_issues_count_n = Closed issues
+activity.title.issues_1 = %d issue
+activity.title.issues_n = %d issues
activity.title.issues_closed_from = %s closed from %s
activity.title.issues_created_by = %s created by %s
activity.closed_issue_label = Closed
-activity.new_issues_count_1 = New Issue
-activity.new_issues_count_n = New Issues
+activity.new_issues_count_1 = New issue
+activity.new_issues_count_n = New issues
activity.new_issue_label = Opened
-activity.title.unresolved_conv_1 = %d Unresolved Conversation
-activity.title.unresolved_conv_n = %d Unresolved Conversations
+activity.title.unresolved_conv_1 = %d unresolved conversation
+activity.title.unresolved_conv_n = %d unresolved conversations
activity.unresolved_conv_desc = These recently changed issues and pull requests have not been resolved yet.
activity.unresolved_conv_label = Open
-activity.title.releases_1 = %d Release
-activity.title.releases_n = %d Releases
+activity.title.releases_1 = %d release
+activity.title.releases_n = %d releases
activity.title.releases_published_by = %s published by %s
activity.published_release_label = Published
activity.no_git_activity = There has not been any commit activity in this period.
@@ -2072,9 +2084,9 @@ settings.collaboration.read = Read
settings.collaboration.owner = Owner
settings.collaboration.undefined = Undefined
settings.hooks = Webhooks
-settings.githooks = Git Hooks
-settings.basic_settings = Basic Settings
-settings.mirror_settings = Mirror Settings
+settings.githooks = Git hooks
+settings.basic_settings = Basic settings
+settings.mirror_settings = Mirror settings
settings.mirror_settings.docs = Set up your repository to automatically synchronize commits, tags and branches with another repository.
settings.mirror_settings.docs.disabled_pull_mirror.instructions = Set up your project to automatically push commits, tags and branches to another repository. Pull mirrors have been disabled by your site administrator.
settings.mirror_settings.docs.disabled_push_mirror.instructions = Set up your project to automatically pull commits, tags and branches from another repository.
@@ -2094,81 +2106,81 @@ settings.mirror_settings.direction.pull = Pull
settings.mirror_settings.direction.push = Push
settings.mirror_settings.last_update = Last update
settings.mirror_settings.push_mirror.none = No push mirrors configured
-settings.mirror_settings.push_mirror.remote_url = Git Remote Repository URL
-settings.mirror_settings.push_mirror.add = Add Push Mirror
+settings.mirror_settings.push_mirror.remote_url = Git remote repository URL
+settings.mirror_settings.push_mirror.add = Add push mirror
settings.mirror_settings.push_mirror.edit_sync_time = Edit mirror sync interval
-settings.units.units = Repository Units
+settings.units.units = Repository units
settings.units.overview = Overview
settings.units.add_more = Add more...
-settings.sync_mirror = Synchronize Now
+settings.sync_mirror = Synchronize now
settings.pull_mirror_sync_in_progress = Pulling changes from the remote %s at the moment.
settings.push_mirror_sync_in_progress = Pushing changes to the remote %s at the moment.
settings.site = Website
-settings.update_settings = Update Settings
-settings.update_mirror_settings = Update Mirror Settings
-settings.branches.switch_default_branch = Switch Default Branch
-settings.branches.update_default_branch = Update Default Branch
-settings.branches.add_new_rule = Add New Rule
-settings.advanced_settings = Advanced Settings
-settings.wiki_desc = Enable Repository Wiki
-settings.wiki_globally_editable = Allow anyone to edit the Wiki
-settings.use_internal_wiki = Use Built-In Wiki
-settings.use_external_wiki = Use External Wiki
-settings.external_wiki_url = External Wiki URL
+settings.update_settings = Update settings
+settings.update_mirror_settings = Update mirror settings
+settings.branches.switch_default_branch = Switch default branch
+settings.branches.update_default_branch = Update default branch
+settings.branches.add_new_rule = Add new rule
+settings.advanced_settings = Advanced settings
+settings.wiki_desc = Enable repository wiki
+settings.wiki_globally_editable = Allow anyone to edit the wiki
+settings.use_internal_wiki = Use built-in wiki
+settings.use_external_wiki = Use external wiki
+settings.external_wiki_url = External wiki URL
settings.external_wiki_url_error = The external wiki URL is not a valid URL.
settings.external_wiki_url_desc = Visitors are redirected to the external wiki URL when clicking the wiki tab.
-settings.issues_desc = Enable Repository Issue Tracker
-settings.use_internal_issue_tracker = Use Built-In Issue Tracker
-settings.use_external_issue_tracker = Use External Issue Tracker
-settings.external_tracker_url = External Issue Tracker URL
+settings.issues_desc = Enable repository issue tracker
+settings.use_internal_issue_tracker = Use built-in issue tracker
+settings.use_external_issue_tracker = Use external issue tracker
+settings.external_tracker_url = External issue tracker URL
settings.external_tracker_url_error = The external issue tracker URL is not a valid URL.
settings.external_tracker_url_desc = Visitors are redirected to the external issue tracker URL when clicking on the issues tab.
-settings.tracker_url_format = External Issue Tracker URL Format
+settings.tracker_url_format = External issue tracker URL Format
settings.tracker_url_format_error = The external issue tracker URL format is not a valid URL.
-settings.tracker_issue_style = External Issue Tracker Number Format
+settings.tracker_issue_style = External issue tracker Number Format
settings.tracker_issue_style.numeric = Numeric
settings.tracker_issue_style.alphanumeric = Alphanumeric
settings.tracker_issue_style.regexp = Regular Expression
settings.tracker_issue_style.regexp_pattern = Regular Expression Pattern
settings.tracker_issue_style.regexp_pattern_desc = The first captured group will be used in place of {index}
.
settings.tracker_url_format_desc = Use the placeholders {user}
, {repo}
and {index}
for the username, repository name and issue index.
-settings.enable_timetracker = Enable Time Tracking
-settings.allow_only_contributors_to_track_time = Let Only Contributors Track Time
-settings.pulls_desc = Enable Repository Pull Requests
-settings.pulls.ignore_whitespace = Ignore Whitespace for Conflicts
+settings.enable_timetracker = Enable time tracking
+settings.allow_only_contributors_to_track_time = Let only contributors track time
+settings.pulls_desc = Enable repository pull requests
+settings.pulls.ignore_whitespace = Ignore whitespace for conflicts
settings.pulls.enable_autodetect_manual_merge = Enable autodetect manual merge (Note: In some special cases, misjudgments can occur)
settings.pulls.allow_rebase_update = Enable updating pull request branch by rebase
settings.pulls.default_delete_branch_after_merge = Delete pull request branch after merge by default
settings.pulls.default_allow_edits_from_maintainers = Allow edits from maintainers by default
-settings.releases_desc = Enable Repository Releases
-settings.packages_desc = Enable Repository Packages Registry
-settings.projects_desc = Enable Repository Projects
-settings.actions_desc = Enable Repository Actions
-settings.admin_settings = Administrator Settings
-settings.admin_enable_health_check = Enable Repository Health Checks (git fsck)
-settings.admin_code_indexer = Code Indexer
+settings.releases_desc = Enable repository releases
+settings.packages_desc = Enable repository package registry
+settings.projects_desc = Enable repository projects
+settings.actions_desc = Enable repository actions
+settings.admin_settings = Administrator settings
+settings.admin_enable_health_check = Enable repository health checks (git fsck)
+settings.admin_code_indexer = Code indexer
settings.admin_stats_indexer = Code statistics indexer
-settings.admin_indexer_commit_sha = Last Indexed SHA
+settings.admin_indexer_commit_sha = Last indexed SHA
settings.admin_indexer_unindexed = Unindexed
-settings.reindex_button = Add to Reindex Queue
-settings.reindex_requested=Reindex Requested
+settings.reindex_button = Add to reindex queue
+settings.reindex_requested=Reindex requested
settings.admin_enable_close_issues_via_commit_in_any_branch = Close an issue via a commit made in a non default branch
-settings.danger_zone = Danger Zone
+settings.danger_zone = Danger zone
settings.new_owner_has_same_repo = The new owner already has a repository with same name. Please choose another name.
settings.new_owner_blocked_doer = The new owner has blocked you.
-settings.convert = Convert to Regular Repository
+settings.convert = Convert to regular repository
settings.convert_desc = You can convert this mirror into a regular repository. This cannot be undone.
settings.convert_notices_1 = This operation will convert the mirror into a regular repository and cannot be undone.
-settings.convert_confirm = Convert Repository
+settings.convert_confirm = Convert repository
settings.convert_succeed = The mirror has been converted into a regular repository.
-settings.convert_fork = Convert to Regular Repository
+settings.convert_fork = Convert to regular repository
settings.convert_fork_desc = You can convert this fork into a regular repository. This cannot be undone.
settings.convert_fork_notices_1 = This operation will convert the fork into a regular repository and cannot be undone.
-settings.convert_fork_confirm = Convert Repository
+settings.convert_fork_confirm = Convert repository
settings.convert_fork_succeed = The fork has been converted into a regular repository.
-settings.transfer = Transfer Ownership
+settings.transfer = Transfer ownership
settings.transfer.rejected = Repository transfer was rejected.
settings.transfer.success = Repository transfer was successful.
settings.transfer_abort = Cancel transfer
@@ -2181,13 +2193,13 @@ settings.transfer_in_progress = There is currently an ongoing transfer. Please c
settings.transfer_notices_1 = - You will lose access to the repository if you transfer it to an individual user.
settings.transfer_notices_2 = - You will keep access to the repository if you transfer it to an organization that you (co-)own.
settings.transfer_notices_3 = - If the repository is private and is transferred to an individual user, this action makes sure that the user does have at least read permission (and changes permissions if necessary).
-settings.transfer_owner = New Owner
-settings.transfer_perform = Perform Transfer
+settings.transfer_owner = New owner
+settings.transfer_perform = Perform transfer
settings.transfer_started = This repository has been marked for transfer and awaits confirmation from "%s"
settings.transfer_succeed = The repository has been transferred.
-settings.signing_settings = Signing Verification Settings
-settings.trust_model = Signature Trust Model
-settings.trust_model.default = Default Trust Model
+settings.signing_settings = Signing verification settings
+settings.trust_model = Signature trust model
+settings.trust_model.default = Default trust model
settings.trust_model.default.desc= Use the default repository trust model for this installation.
settings.trust_model.collaborator = Collaborator
settings.trust_model.collaborator.long = Collaborator: Trust signatures by collaborators
@@ -2201,16 +2213,16 @@ settings.trust_model.collaboratorcommitter.desc = Valid signatures by collaborat
settings.wiki_rename_branch_main = Normalize the Wiki branch name
settings.wiki_rename_branch_main_desc = Rename the branch used internally by the Wiki to "%s". This is a permanent and cannot be undone.
settings.wiki_rename_branch_main_notices_1 = This operation CANNOT be undone.
-settings.wiki_rename_branch_main_notices_2 = This will premanently rename the the internal branch of %s's repository wiki. Existing checkouts will need to be updated.
+settings.wiki_rename_branch_main_notices_2 = This will permanently rename the the internal branch of %s's repository wiki. Existing checkouts will need to be updated.
settings.wiki_branch_rename_success = The repository wiki's branch name has been successfully normalized.
settings.wiki_branch_rename_failure = Failed to normalize the repository wiki's branch name.
settings.confirm_wiki_branch_rename = Rename the wiki branch
-settings.wiki_delete = Delete Wiki Data
+settings.wiki_delete = Delete wiki data
settings.wiki_delete_desc = Deleting repository wiki data is permanent and cannot be undone.
settings.wiki_delete_notices_1 = - This will permanently delete and disable the repository wiki for %s.
-settings.confirm_wiki_delete = Delete Wiki Data
+settings.confirm_wiki_delete = Delete wiki data
settings.wiki_deletion_success = The repository wiki data has been deleted.
-settings.delete = Delete This Repository
+settings.delete = Delete this repository
settings.delete_desc = Deleting a repository is permanent and cannot be undone.
settings.delete_notices_1 = - This operation CANNOT be undone.
settings.delete_notices_2 = - This operation will permanently delete the %s repository including code, issues, comments, wiki data and collaborator settings.
@@ -2218,8 +2230,8 @@ settings.delete_notices_fork_1 = - Forks of this repository will become independ
settings.deletion_success = The repository has been deleted.
settings.update_settings_success = The repository settings have been updated.
settings.update_settings_no_unit = The repository should allow at least some sort of interaction.
-settings.confirm_delete = Delete Repository
-settings.add_collaborator = Add Collaborator
+settings.confirm_delete = Delete repository
+settings.add_collaborator = Add collaborator
settings.add_collaborator_success = The collaborator has been added.
settings.add_collaborator_inactive_user = Cannot add an inactive user as a collaborator.
settings.add_collaborator_owner = Cannot add an owner as a collaborator.
@@ -2235,20 +2247,20 @@ settings.org_not_allowed_to_be_collaborator = Organizations cannot be added as a
settings.change_team_access_not_allowed = Changing team access for repository has been restricted to organization owner
settings.team_not_in_organization = The team is not in the same organization as the repository
settings.teams = Teams
-settings.add_team = Add Team
+settings.add_team = Add team
settings.add_team_duplicate = Team already has the repository
settings.add_team_success = The team now have access to the repository.
-settings.search_team = Search Team…
+settings.search_team = Search team…
settings.change_team_permission_tip = Team's permission is set on the team setting page and can't be changed per repository
settings.delete_team_tip = This team has access to all repositories and can't be removed
settings.remove_team_success = The team's access to the repository has been removed.
-settings.add_webhook = Add Webhook
+settings.add_webhook = Add webhook
settings.add_webhook.invalid_channel_name = Webhook channel name cannot be empty and cannot contain only a # character.
settings.hooks_desc = Webhooks automatically make HTTP POST requests to a server when certain Forgejo events trigger. Read more in the webhooks guide.
-settings.webhook_deletion = Remove Webhook
+settings.webhook_deletion = Remove webhook
settings.webhook_deletion_desc = Removing a webhook deletes its settings and delivery history. Continue?
settings.webhook_deletion_success = The webhook has been removed.
-settings.webhook.test_delivery = Test Delivery
+settings.webhook.test_delivery = Test delivery
settings.webhook.test_delivery_desc = Test this webhook with a fake event.
settings.webhook.test_delivery_desc_disabled = To test this webhook with a fake event, activate it.
settings.webhook.request = Request
@@ -2259,26 +2271,26 @@ settings.webhook.body = Body
settings.webhook.replay.description = Replay this webhook.
settings.webhook.replay.description_disabled = To replay this webhook, activate it.
settings.webhook.delivery.success = An event has been added to the delivery queue. It may take few seconds before it shows up in the delivery history.
-settings.githooks_desc = Git Hooks are powered by Git itself. You can edit hook files below to set up custom operations.
+settings.githooks_desc = Git hooks are powered by Git itself. You can edit hook files below to set up custom operations.
settings.githook_edit_desc = If the hook is inactive, sample content will be presented. Leaving content to an empty value will disable this hook.
-settings.githook_name = Hook Name
-settings.githook_content = Hook Content
-settings.update_githook = Update Hook
-settings.add_webhook_desc = Forgejo will send POST
requests with a specified content type to the target URL. Read more in the webhooks guide.
+settings.githook_name = Hook name
+settings.githook_content = Hook content
+settings.update_githook = Update hook
+settings.add_webhook_desc = Forgejo will send POST
requests with a specified Content-Type to the target URL. Read more in the webhooks guide.
settings.payload_url = Target URL
-settings.http_method = HTTP Method
-settings.content_type = POST Content Type
+settings.http_method = HTTP method
+settings.content_type = POST content type
settings.secret = Secret
settings.slack_username = Username
settings.slack_icon_url = Icon URL
settings.slack_color = Color
settings.discord_username = Username
settings.discord_icon_url = Icon URL
-settings.event_desc = Trigger On:
-settings.event_push_only = Push Events
-settings.event_send_everything = All Events
-settings.event_choose = Custom Events…
-settings.event_header_repository = Repository Events
+settings.event_desc = Trigger on:
+settings.event_push_only = Push events
+settings.event_send_everything = All events
+settings.event_choose = Custom events…
+settings.event_header_repository = Repository events
settings.event_create = Create
settings.event_create_desc = Branch or tag created.
settings.event_delete = Delete
@@ -2293,50 +2305,50 @@ settings.event_push = Push
settings.event_push_desc = Git push to a repository.
settings.event_repository = Repository
settings.event_repository_desc = Repository created or deleted.
-settings.event_header_issue = Issue Events
+settings.event_header_issue = Issue events
settings.event_issues = Issues
settings.event_issues_desc = Issue opened, closed, reopened, or edited.
-settings.event_issue_assign = Issue Assigned
+settings.event_issue_assign = Issue assigned
settings.event_issue_assign_desc = Issue assigned or unassigned.
-settings.event_issue_label = Issue Labeled
+settings.event_issue_label = Issue labeled
settings.event_issue_label_desc = Issue labels updated or cleared.
-settings.event_issue_milestone = Issue Milestoned
+settings.event_issue_milestone = Issue milestoned
settings.event_issue_milestone_desc = Issue milestoned or demilestoned.
-settings.event_issue_comment = Issue Comment
+settings.event_issue_comment = Issue comment
settings.event_issue_comment_desc = Issue comment created, edited, or deleted.
-settings.event_header_pull_request = Pull Request Events
-settings.event_pull_request = Pull Request
+settings.event_header_pull_request = Pull request events
+settings.event_pull_request = Pull request
settings.event_pull_request_desc = Pull request opened, closed, reopened, or edited.
-settings.event_pull_request_assign = Pull Request Assigned
+settings.event_pull_request_assign = Pull request assigned
settings.event_pull_request_assign_desc = Pull request assigned or unassigned.
-settings.event_pull_request_label = Pull Request Labeled
+settings.event_pull_request_label = Pull request labeled
settings.event_pull_request_label_desc = Pull request labels updated or cleared.
-settings.event_pull_request_milestone = Pull Request Milestoned
+settings.event_pull_request_milestone = Pull request milestoned
settings.event_pull_request_milestone_desc = Pull request milestoned or demilestoned.
-settings.event_pull_request_comment = Pull Request Comment
+settings.event_pull_request_comment = Pull request comment
settings.event_pull_request_comment_desc = Pull request comment created, edited, or deleted.
-settings.event_pull_request_review = Pull Request Reviewed
+settings.event_pull_request_review = Pull request reviewed
settings.event_pull_request_review_desc = Pull request approved, rejected, or review comment.
-settings.event_pull_request_sync = Pull Request Synchronized
+settings.event_pull_request_sync = Pull request synchronized
settings.event_pull_request_sync_desc = Pull request synchronized.
-settings.event_pull_request_review_request = Pull Request Review Requested
+settings.event_pull_request_review_request = Pull request review requested
settings.event_pull_request_review_request_desc = Pull request review requested or review request removed.
-settings.event_pull_request_approvals = Pull Request Approvals
-settings.event_pull_request_merge = Pull Request Merge
+settings.event_pull_request_approvals = Pull request approvals
+settings.event_pull_request_merge = Pull request merge
settings.event_package = Package
settings.event_package_desc = Package created or deleted in a repository.
settings.branch_filter = Branch filter
settings.branch_filter_desc = Branch whitelist for push, branch creation and branch deletion events, specified as glob pattern. If empty or *
, events for all branches are reported. See github.com/gobwas/glob documentation for syntax. Examples: master
, {master,release*}
.
-settings.authorization_header = Authorization Header
+settings.authorization_header = Authorization header
settings.authorization_header_desc = Will be included as authorization header for requests when present. Examples: %s.
settings.active = Active
settings.active_helper = Information about triggered events will be sent to this webhook URL.
settings.add_hook_success = The webhook has been added.
-settings.update_webhook = Update Webhook
+settings.update_webhook = Update webhook
settings.update_hook_success = The webhook has been updated.
-settings.delete_webhook = Remove Webhook
-settings.recent_deliveries = Recent Deliveries
-settings.hook_type = Hook Type
+settings.delete_webhook = Remove webhook
+settings.recent_deliveries = Recent deliveries
+settings.hook_type = Hook type
settings.slack_token = Token
settings.slack_domain = Domain
settings.slack_channel = Channel
@@ -2358,10 +2370,10 @@ settings.web_hook_name_packagist = Packagist
settings.packagist_username = Packagist username
settings.packagist_api_token = API token
settings.packagist_package_url = Packagist package URL
-settings.deploy_keys = Deploy Keys
-settings.add_deploy_key = Add Deploy Key
+settings.deploy_keys = Deploy keys
+settings.add_deploy_key = Add deploy key
settings.deploy_key_desc = Deploy keys have read-only pull access to the repository.
-settings.is_writable = Enable Write Access
+settings.is_writable = Enable write access
settings.is_writable_info = Allow this deploy key to push to the repository.
settings.no_deploy_keys = There are no deploy keys yet.
settings.title = Title
@@ -2369,37 +2381,37 @@ settings.deploy_key_content = Content
settings.key_been_used = A deploy key with identical content is already in use.
settings.key_name_used = A deploy key with the same name already exists.
settings.add_key_success = The deploy key "%s" has been added.
-settings.deploy_key_deletion = Remove Deploy Key
+settings.deploy_key_deletion = Remove reploy key
settings.deploy_key_deletion_desc = Removing a deploy key will revoke its access to this repository. Continue?
settings.deploy_key_deletion_success = The deploy key has been removed.
settings.branches = Branches
-settings.protected_branch = Branch Protection
-settings.protected_branch.save_rule = Save Rule
-settings.protected_branch.delete_rule = Delete Rule
+settings.protected_branch = Branch protection
+settings.protected_branch.save_rule = Save rule
+settings.protected_branch.delete_rule = Delete rule
settings.protected_branch_can_push = Allow push?
settings.protected_branch_can_push_yes = You can push
settings.protected_branch_can_push_no = You cannot push
-settings.branch_protection = Branch Protection Rules for Branch "%s"
-settings.protect_this_branch = Enable Branch Protection
+settings.branch_protection = Branch protection rules for branch "%s"
+settings.protect_this_branch = Enable branch protection
settings.protect_this_branch_desc = Prevents deletion and restricts Git pushing and merging to the branch.
-settings.protect_disable_push = Disable Push
+settings.protect_disable_push = Disable push
settings.protect_disable_push_desc = No pushing will be allowed to this branch.
-settings.protect_enable_push = Enable Push
+settings.protect_enable_push = Enable push
settings.protect_enable_push_desc = Anyone with write access will be allowed to push to this branch (but not force push).
-settings.protect_enable_merge = Enable Merge
+settings.protect_enable_merge = Enable merge
settings.protect_enable_merge_desc = Anyone with write access will be allowed to merge the pull requests into this branch.
-settings.protect_whitelist_committers = Whitelist Restricted Push
+settings.protect_whitelist_committers = Whitelist restricted push
settings.protect_whitelist_committers_desc = Only whitelisted users or teams will be allowed to push to this branch (but not force push).
settings.protect_whitelist_deploy_keys = Whitelist deploy keys with write access to push.
settings.protect_whitelist_users = Whitelisted users for pushing:
settings.protect_whitelist_search_users = Search users…
settings.protect_whitelist_teams = Whitelisted teams for pushing:
settings.protect_whitelist_search_teams = Search teams…
-settings.protect_merge_whitelist_committers = Enable Merge Whitelist
+settings.protect_merge_whitelist_committers = Enable merge whitelist
settings.protect_merge_whitelist_committers_desc = Allow only whitelisted users or teams to merge pull requests into this branch.
settings.protect_merge_whitelist_users = Whitelisted users for merging:
settings.protect_merge_whitelist_teams = Whitelisted teams for merging:
-settings.protect_check_status_contexts = Enable Status Check
+settings.protect_check_status_contexts = Enable status check
settings.protect_status_check_patterns = Status check patterns:
settings.protect_status_check_patterns_desc = Enter patterns to specify which status checks must pass before branches can be merged into a branch that matches this rule. Each line specifies a pattern. Patterns cannot be empty.
settings.protect_check_status_contexts_desc = Require status checks to pass before merging. When enabled, commits must first be pushed to another branch, then merged or pushed directly to a branch that matches this rule after status checks have passed. If no contexts are matched, the last commit must be successful regardless of context.
@@ -2417,9 +2429,9 @@ settings.dismiss_stale_approvals = Dismiss stale approvals
settings.dismiss_stale_approvals_desc = When new commits that change the content of the pull request are pushed to the branch, old approvals will be dismissed.
settings.ignore_stale_approvals = Ignore stale approvals
settings.ignore_stale_approvals_desc = Do not count approvals that were made on older commits (stale reviews) towards how many approvals the PR has. Irrelevant if stale reviews are already dismissed.
-settings.require_signed_commits = Require Signed Commits
+settings.require_signed_commits = Require signed commits
settings.require_signed_commits_desc = Reject pushes to this branch if they are unsigned or unverifiable.
-settings.protect_branch_name_pattern = Protected Branch Name Pattern
+settings.protect_branch_name_pattern = Protected branch name pattern
settings.protect_branch_name_pattern_desc = Protected branch name patterns. See the documentation for pattern syntax. Examples: main, release/**
settings.protect_patterns = Patterns
settings.protect_protected_file_patterns = Protected file patterns (separated using semicolon ";"):
@@ -2431,7 +2443,7 @@ settings.delete_protected_branch = Disable protection
settings.update_protect_branch_success = Branch protection for rule "%s" has been updated.
settings.remove_protected_branch_success = Branch protection for rule "%s" has been removed.
settings.remove_protected_branch_failed = Removing branch protection rule "%s" failed.
-settings.protected_branch_deletion = Delete Branch Protection
+settings.protected_branch_deletion = Delete branch protection
settings.protected_branch_deletion_desc = Disabling branch protection allows users with write permission to push to the branch. Continue?
settings.block_rejected_reviews = Block merge on rejected reviews
settings.block_rejected_reviews_desc = Merging will not be possible when changes are requested by official reviewers, even if there are enough approvals.
@@ -2440,8 +2452,8 @@ settings.block_on_official_review_requests_desc = Merging will not be possible w
settings.block_outdated_branch = Block merge if pull request is outdated
settings.block_outdated_branch_desc = Merging will not be possible when head branch is behind base branch.
settings.default_branch_desc = Select a default repository branch for pull requests and code commits:
-settings.merge_style_desc = Merge Styles
-settings.default_merge_style_desc = Default Merge Style
+settings.merge_style_desc = Merge styles
+settings.default_merge_style_desc = Default merge style
settings.choose_branch = Choose a branch…
settings.no_protected_branch = There are no protected branches.
settings.edit_protected_branch = Edit
@@ -2449,23 +2461,23 @@ settings.protected_branch_required_rule_name = Required rule name
settings.protected_branch_duplicate_rule_name = There is already a rule for this set of branches
settings.protected_branch_required_approvals_min = Required approvals cannot be negative.
settings.tags = Tags
-settings.tags.protection = Tag Protection
-settings.tags.protection.pattern = Tag Pattern
+settings.tags.protection = Tag protection
+settings.tags.protection.pattern = Tag pattern
settings.tags.protection.allowed = Allowed
settings.tags.protection.allowed.users = Allowed users
settings.tags.protection.allowed.teams = Allowed teams
-settings.tags.protection.allowed.noone = No One
-settings.tags.protection.create = Protect Tag
+settings.tags.protection.allowed.noone = No one
+settings.tags.protection.create = Add rule
settings.tags.protection.none = There are no protected tags.
settings.tags.protection.pattern.description = You can use a single name or a glob pattern or regular expression to match multiple tags. Read more in the protected tags guide.
-settings.bot_token = Bot Token
+settings.bot_token = Bot token
settings.chat_id = Chat ID
settings.thread_id = Thread ID
settings.matrix.homeserver_url = Homeserver URL
settings.matrix.room_id = Room ID
-settings.matrix.message_type = Message Type
-settings.archive.button = Archive Repo
-settings.archive.header = Archive This Repo
+settings.matrix.message_type = Message type
+settings.archive.button = Archive repo
+settings.archive.header = Archive this repo
settings.archive.text = Archiving the repo will make it entirely read-only. It will be hidden from the dashboard. Nobody (not even you!) will be able to make new commits, or open any issues or pull requests.
settings.archive.success = The repo was successfully archived.
settings.archive.error = An error occurred while trying to archive the repo. See the log for more details.
@@ -2511,17 +2523,17 @@ settings.rename_branch_from=old branch name
settings.rename_branch_to=new branch name
settings.rename_branch=Rename branch
-diff.browse_source = Browse Source
+diff.browse_source = Browse source
diff.parent = parent
diff.commit = commit
diff.git-notes = Notes
-diff.data_not_available = Diff Content Not Available
-diff.options_button = Diff Options
-diff.show_diff_stats = Show Stats
-diff.download_patch = Download Patch File
-diff.download_diff = Download Diff File
-diff.show_split_view = Split View
-diff.show_unified_view = Unified View
+diff.data_not_available = Diff content is not available
+diff.options_button = Diff options
+diff.show_diff_stats = Show stats
+diff.download_patch = Download patch file
+diff.download_diff = Download diff file
+diff.show_split_view = Split view
+diff.show_unified_view = Unified view
diff.whitespace_button = Whitespace
diff.whitespace_show_everything = Show all changes
diff.whitespace_ignore_all_whitespace = Ignore whitespace when comparing lines
@@ -2531,7 +2543,7 @@ diff.stats_desc = %d changed files with %d additions
diff.stats_desc_file = %d changes: %d additions and %d deletions
diff.bin = BIN
diff.bin_not_shown = Binary file not shown.
-diff.view_file = View File
+diff.view_file = View file
diff.file_before = Before
diff.file_after = After
diff.file_image_width = Width
@@ -2540,8 +2552,8 @@ diff.file_byte_size = Size
diff.file_suppressed = File diff suppressed because it is too large
diff.file_suppressed_line_too_long = File diff suppressed because one or more lines are too long
diff.too_many_files = Some files were not shown because too many files have changed in this diff
-diff.show_more = Show More
-diff.load = Load Diff
+diff.show_more = Show more
+diff.load = Load diff
diff.generated = generated
diff.vendored = vendored
diff.comment.add_line_comment = Add line comment
@@ -2616,11 +2628,11 @@ release.add_tag = Create Tag Only
release.releases_for = Releases for %s
release.tags_for = Tags for %s
-branch.name = Branch Name
+branch.name = Branch name
branch.already_exists = A branch named "%s" already exists.
branch.delete_head = Delete
-branch.delete = Delete Branch "%s"
-branch.delete_html = Delete Branch
+branch.delete = Delete branch "%s"
+branch.delete_html = Delete branch
branch.delete_desc = Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
branch.deletion_success = Branch "%s" has been deleted.
branch.deletion_failed = Failed to delete branch "%s".
@@ -2636,10 +2648,10 @@ branch.restore_success = Branch "%s" has been restored.
branch.restore_failed = Failed to restore branch "%s".
branch.protected_deletion_failed = Branch "%s" is protected. It cannot be deleted.
branch.default_deletion_failed = Branch "%s" is the default branch. It cannot be deleted.
-branch.restore = Restore Branch "%s"
-branch.download = Download Branch "%s"
-branch.rename = Rename Branch "%s"
-branch.search = Search Branch
+branch.restore = Restore branch "%s"
+branch.download = Download branch "%s"
+branch.rename = Rename branch "%s"
+branch.search = Search branch
branch.included_desc = This branch is part of the default branch
branch.included = Included
branch.create_new_branch = Create branch from branch:
@@ -2670,6 +2682,7 @@ find_file.no_matching = No matching file found
error.csv.too_large = Can't render this file because it is too large.
error.csv.unexpected = Can't render this file because it contains an unexpected character in line %d and column %d.
error.csv.invalid_field_count = Can't render this file because it has a wrong number of fields in line %d.
+error.broken_git_hook = Git hooks of this repository seem to be broken. Please follow the documentation to fix them, then push some commits to refresh the status.
[graphs]
component_loading = Loading %s...
@@ -2681,26 +2694,26 @@ contributors.what = contributions
recent_commits.what = recent commits
[org]
-org_name_holder = Organization Name
-org_full_name_holder = Organization Full Name
+org_name_holder = Organization name
+org_full_name_holder = Organization full name
org_name_helper = Organization names should be short and memorable.
-create_org = Create Organization
+create_org = Create organization
repo_updated = Updated
members = Members
teams = Teams
code = Code
lower_members = members
lower_repositories = repositories
-create_new_team = New Team
-create_team = Create Team
+create_new_team = New team
+create_team = Create team
org_desc = Description
-team_name = Team Name
+team_name = Team name
team_desc = Description
team_name_helper = Team names should be short and memorable.
team_desc_helper = Describe the purpose or role of the team.
team_access_desc = Repository access
team_permission_desc = Permission
-team_unit_desc = Allow Access to Repository Sections
+team_unit_desc = Allow access to tepository sections
team_unit_disabled = (Disabled)
follow_blocked_user = You cannot follow this organisation because this organisation has blocked you.
@@ -2710,40 +2723,40 @@ form.create_org_not_allowed = You are not allowed to create an organization.
settings = Settings
settings.options = Organization
-settings.full_name = Full Name
-settings.email = Contact Email
+settings.full_name = Full name
+settings.email = Contact email
settings.website = Website
settings.location = Location
settings.permission = Permissions
settings.repoadminchangeteam = Repository admin can add and remove access for teams
settings.visibility = Visibility
settings.visibility.public = Public
-settings.visibility.limited = Limited (Visible to authenticated users only)
+settings.visibility.limited = Limited (visible only to authenticated users)
settings.visibility.limited_shortname = Limited
-settings.visibility.private = Private (Visible only to organization members)
+settings.visibility.private = Private (visible only to organization members)
settings.visibility.private_shortname = Private
-settings.update_settings = Update Settings
+settings.update_settings = Update settings
settings.update_setting_success = Organization settings have been updated.
settings.change_orgname_prompt = Note: Changing the organization name will also change your organization's URL and free the old name.
settings.change_orgname_redirect_prompt = The old name will redirect until it is claimed.
settings.update_avatar_success = The organization's avatar has been updated.
-settings.delete = Delete Organization
-settings.delete_account = Delete This Organization
+settings.delete = Delete organization
+settings.delete_account = Delete this organization
settings.delete_prompt = The organization will be permanently removed. This CANNOT be undone!
-settings.confirm_delete_account = Confirm Deletion
-settings.delete_org_title = Delete Organization
+settings.confirm_delete_account = Confirm deletion
+settings.delete_org_title = Delete organization
settings.delete_org_desc = This organization will be deleted permanently. Continue?
settings.hooks_desc = Add webhooks which will be triggered for all repositories under this organization.
settings.labels_desc = Add labels which can be used on issues for all repositories under this organization.
-members.membership_visibility = Membership Visibility:
+members.membership_visibility = Membership visibility:
members.public = Visible
members.public_helper = make hidden
members.private = Hidden
members.private_helper = make visible
-members.member_role = Member Role:
+members.member_role = Member role:
members.owner = Owner
members.member = Member
members.remove = Remove
@@ -2751,40 +2764,40 @@ members.remove.detail = Remove %[1]s from %[2]s?
members.leave = Leave
members.leave.detail = Leave %s?
members.invite_desc = Add a new member to %s:
-members.invite_now = Invite Now
+members.invite_now = Invite now
teams.join = Join
teams.leave = Leave
teams.leave.detail = Leave %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
+teams.none_access = No access
teams.none_access_helper = Members cannot view or do any other action on this unit. It has no effect for public repositories.
-teams.general_access = General Access
+teams.general_access = General access
teams.general_access_helper = Members permissions will be decided by below permission table.
teams.read_access = Read
teams.read_access_helper = Members can view and clone team repositories.
teams.write_access = Write
teams.write_access_helper = Members can read and push to team repositories.
-teams.admin_access = Administrator Access
+teams.admin_access = Administrator access
teams.admin_access_helper = Members can pull and push to team repositories and add collaborators to them.
teams.no_desc = This team has no description
teams.settings = Settings
teams.owners_permission_desc = Owners have full access to all repositories and have administrator access to the organization.
-teams.members = Team Members
-teams.update_settings = Update Settings
-teams.delete_team = Delete Team
-teams.add_team_member = Add Team Member
+teams.members = Team members
+teams.update_settings = Update settings
+teams.delete_team = Delete team
+teams.add_team_member = Add team member
teams.invite_team_member = Invite to %s
-teams.invite_team_member.list = Pending Invitations
-teams.delete_team_title = Delete Team
+teams.invite_team_member.list = Pending invitations
+teams.delete_team_title = Delete team
teams.delete_team_desc = Deleting a team revokes repository access from its members. Continue?
teams.delete_team_success = The team has been deleted.
teams.read_permission_desc = This team grants Read access: members can view and clone team repositories.
teams.write_permission_desc = This team grants Write access: members can read from and push to team repositories.
teams.admin_permission_desc = This team grants Admin access: members can read from, push to and add collaborators to team repositories.
teams.create_repo_permission_desc = Additionally, this team grants Create repository permission: members can create new repositories in organization.
-teams.repositories = Team Repositories
+teams.repositories = Team repositories
teams.search_repo_placeholder = Search repository…
teams.remove_all_repos_title = Remove all team repositories
teams.remove_all_repos_desc = This will remove all repositories from the team.
@@ -2807,28 +2820,30 @@ teams.invite.description = Please click the button below to join the team.
[admin]
dashboard = Dashboard
-self_check = Self Check
-identity_access = Identity & Access
-users = User Accounts
+self_check = Self check
+identity_access = Identity & access
+users = User accounts
organizations = Organizations
-assets = Code Assets
+assets = Code assets
repositories = Repositories
hooks = Webhooks
integrations = Integrations
-authentication = Authentication Sources
-emails = User Emails
+authentication = Authentication sources
+emails = User emails
config = Configuration
-notices = System Notices
+notices = System notices
+config_summary = Summary
+config_settings = Settings
monitor = Monitoring
first_page = First
last_page = Last
total = Total: %d
-settings = Admin Settings
+settings = Admin settings
dashboard.new_version_hint = Forgejo %s is now available, you are running %s. Check the blog for more details.
dashboard.statistic = Summary
-dashboard.operations = Maintenance Operations
-dashboard.system_status = System Status
+dashboard.operations = Maintenance operations
+dashboard.system_status = System status
dashboard.operation_name = Operation Name
dashboard.operation_switch = Switch
dashboard.operation_run = Run
@@ -2852,9 +2867,9 @@ dashboard.delete_repo_archives.started = Delete all repository archives task sta
dashboard.delete_missing_repos = Delete all repositories missing their Git files
dashboard.delete_missing_repos.started = Delete all repositories missing their Git files task started.
dashboard.delete_generated_repository_avatars = Delete generated repository avatars
-dashboard.sync_repo_branches = Sync missed branches from git data to database
-dashboard.sync_repo_tags = Sync tags from git data to database
-dashboard.update_mirrors = Update Mirrors
+dashboard.sync_repo_branches = Sync missed branches from Git data to database
+dashboard.sync_repo_tags = Sync tags from Git data to database
+dashboard.update_mirrors = Update mirrors
dashboard.repo_health_check = Health check all repositories
dashboard.check_repo_stats = Check all repository statistics
dashboard.archive_cleanup = Delete old repository archives
@@ -2869,35 +2884,34 @@ dashboard.sync_external_users = Synchronize external user data
dashboard.cleanup_hook_task_table = Cleanup hook_task table
dashboard.cleanup_packages = Cleanup expired packages
dashboard.cleanup_actions = Cleanup expired logs and artifacts from actions
-dashboard.server_uptime = Server Uptime
-dashboard.current_goroutine = Current Goroutines
-dashboard.current_memory_usage = Current Memory Usage
-dashboard.total_memory_allocated = Total Memory Allocated
-dashboard.memory_obtained = Memory Obtained
-dashboard.pointer_lookup_times = Pointer Lookup Times
-dashboard.memory_allocate_times = Memory Allocations
-dashboard.memory_free_times = Memory Frees
-dashboard.current_heap_usage = Current Heap Usage
-dashboard.heap_memory_obtained = Heap Memory Obtained
-dashboard.heap_memory_idle = Heap Memory Idle
-dashboard.heap_memory_in_use = Heap Memory In Use
-dashboard.heap_memory_released = Heap Memory Released
-dashboard.heap_objects = Heap Objects
-dashboard.bootstrap_stack_usage = Bootstrap Stack Usage
-dashboard.stack_memory_obtained = Stack Memory Obtained
-dashboard.mspan_structures_usage = MSpan Structures Usage
-dashboard.mspan_structures_obtained = MSpan Structures Obtained
-dashboard.mcache_structures_usage = MCache Structures Usage
-dashboard.mcache_structures_obtained = MCache Structures Obtained
-dashboard.profiling_bucket_hash_table_obtained = Profiling Bucket Hash Table Obtained
-dashboard.gc_metadata_obtained = GC Metadata Obtained
-dashboard.other_system_allocation_obtained = Other System Allocation Obtained
-dashboard.next_gc_recycle = Next GC Recycle
-dashboard.last_gc_time = Since Last GC Time
-dashboard.total_gc_time = Total GC Pause
-dashboard.total_gc_pause = Total GC Pause
-dashboard.last_gc_pause = Last GC Pause
-dashboard.gc_times = GC Times
+dashboard.server_uptime = Server uptime
+dashboard.current_goroutine = Current goroutines
+dashboard.current_memory_usage = Current memory usage
+dashboard.total_memory_allocated = Total memory allocated
+dashboard.memory_obtained = Memory obtained
+dashboard.pointer_lookup_times = Pointer lookup times
+dashboard.memory_allocate_times = Memory allocations
+dashboard.memory_free_times = Memory frees
+dashboard.current_heap_usage = Current heap usage
+dashboard.heap_memory_obtained = Heap memory obtained
+dashboard.heap_memory_idle = Heap memory idle
+dashboard.heap_memory_in_use = Heap memory in use
+dashboard.heap_memory_released = Heap memory released
+dashboard.heap_objects = Heap objects
+dashboard.bootstrap_stack_usage = Bootstrap stack usage
+dashboard.stack_memory_obtained = Stack memory obtained
+dashboard.mspan_structures_usage = MSpan structures usage
+dashboard.mspan_structures_obtained = MSpan structures obtained
+dashboard.mcache_structures_usage = MCache structures usage
+dashboard.mcache_structures_obtained = MCache structures obtained
+dashboard.profiling_bucket_hash_table_obtained = Profiling bucket hash table obtained
+dashboard.gc_metadata_obtained = GC metadata obtained
+dashboard.other_system_allocation_obtained = Other system allocation obtained
+dashboard.next_gc_recycle = Next GC recycle
+dashboard.last_gc_time = Time since last GC
+dashboard.total_gc_pause = Total GC pause
+dashboard.last_gc_pause = Last GC pause
+dashboard.gc_times = GC times
dashboard.delete_old_actions = Delete all old actions from database
dashboard.delete_old_actions.started = Delete all old actions from database started.
dashboard.update_checker = Update checker
@@ -2911,10 +2925,10 @@ dashboard.sync_branch.started = Branches Sync started
dashboard.sync_tag.started = Tags Sync started
dashboard.rebuild_issue_indexer = Rebuild issue indexer
-users.user_manage_panel = User Account Management
+users.user_manage_panel = Manage user accounts
users.new_account = Create User Account
users.name = Username
-users.full_name = Full Name
+users.full_name = Full name
users.activated = Activated
users.admin = Admin
users.restricted = Restricted
@@ -2924,29 +2938,29 @@ users.remote = Remote
users.2fa = 2FA
users.repos = Repos
users.created = Created
-users.last_login = Last Sign-In
-users.never_login = Never Signed-In
-users.send_register_notify = Send User Registration Notification
+users.last_login = Last sign-in
+users.never_login = Never signed in
+users.send_register_notify = Send user registration notification
users.new_success = The user account "%s" has been created.
users.edit = Edit
-users.auth_source = Authentication Source
+users.auth_source = Authentication source
users.local = Local
-users.auth_login_name = Authentication Sign-In Name
+users.auth_login_name = Authentication sign-in name
users.password_helper = Leave the password empty to keep it unchanged.
users.update_profile_success = The user account has been updated.
-users.edit_account = Edit User Account
-users.max_repo_creation = Maximum Number of Repositories
+users.edit_account = Edit user account
+users.max_repo_creation = Maximum number of repositories
users.max_repo_creation_desc = (Enter -1 to use the global default limit.)
users.is_activated = User Account Is Activated
-users.prohibit_login = Disable Sign-In
-users.is_admin = Is Administrator
-users.is_restricted = Is Restricted
-users.allow_git_hook = May Create Git Hooks
-users.allow_git_hook_tooltip = Git Hooks are executed as the OS user running Forgejo and will have the same level of host access. As a result, users with this special Git Hook privilege can access and modify all Forgejo repositories as well as the database used by Forgejo. Consequently they are also able to gain Forgejo administrator privileges.
-users.allow_import_local = May Import Local Repositories
-users.allow_create_organization = May Create Organizations
-users.update_profile = Update User Account
-users.delete_account = Delete User Account
+users.prohibit_login = Disable sign-in
+users.is_admin = Is administrator
+users.is_restricted = Is restricted
+users.allow_git_hook = Can create Git hooks
+users.allow_git_hook_tooltip = Git hooks are executed as the OS user running Forgejo and will have the same level of host access. As a result, users with this special Git hook privilege can access and modify all Forgejo repositories as well as the database used by Forgejo. Consequently they are also able to gain Forgejo administrator privileges.
+users.allow_import_local = Can import local repositories
+users.allow_create_organization = Can create organizations
+users.update_profile = Update user account
+users.delete_account = Delete user account
users.cannot_delete_self = You cannot delete yourself
users.still_own_repo = This user still owns one or more repositories. Delete or transfer these repositories first.
users.still_has_org = This user is a member of an organization. Remove the user from any organizations first.
@@ -2969,27 +2983,27 @@ users.list_status_filter.is_2fa_enabled = 2FA Enabled
users.list_status_filter.not_2fa_enabled = 2FA Disabled
users.details = User Details
-emails.email_manage_panel = User Email Management
+emails.email_manage_panel = Manage user emails
emails.primary = Primary
emails.activated = Activated
emails.filter_sort.email = Email
emails.filter_sort.email_reverse = Email (reverse)
-emails.filter_sort.name = User Name
-emails.filter_sort.name_reverse = User Name (reverse)
+emails.filter_sort.name = Username
+emails.filter_sort.name_reverse = Username (reverse)
emails.updated = Email updated
emails.not_updated = Failed to update the requested email address: %v
emails.duplicate_active = This email address is already active for a different user.
emails.change_email_header = Update Email Properties
emails.change_email_text = Are you sure you want to update this email address?
-orgs.org_manage_panel = Organization Management
+orgs.org_manage_panel = Manage organizations
orgs.name = Name
orgs.teams = Teams
orgs.members = Members
-orgs.new_orga = New Organization
+orgs.new_orga = New organization
-repos.repo_manage_panel = Repository Management
-repos.unadopted = Unadopted Repositories
+repos.repo_manage_panel = Manage repositories
+repos.unadopted = Unadopted repositories
repos.unadopted.no_more = No more unadopted repositories found
repos.owner = Owner
repos.name = Name
@@ -3001,7 +3015,7 @@ repos.issues = Issues
repos.size = Size
repos.lfs_size = LFS Size
-packages.package_manage_panel = Package Management
+packages.package_manage_panel = Manage packages
packages.total_size = Total Size: %s
packages.unreferenced_size = Unreferenced Size: %s
packages.cleanup = Clean up expired data
@@ -3015,70 +3029,70 @@ packages.repository = Repository
packages.size = Size
packages.published = Published
-defaulthooks = Default Webhooks
+defaulthooks = Default webhooks
defaulthooks.desc = Webhooks automatically make HTTP POST requests to a server when certain Forgejo events trigger. Webhooks defined here are defaults and will be copied into all new repositories. Read more in the webhooks guide.
defaulthooks.add_webhook = Add Default Webhook
defaulthooks.update_webhook = Update Default Webhook
-systemhooks = System Webhooks
+systemhooks = System webhooks
systemhooks.desc = Webhooks automatically make HTTP POST requests to a server when certain Forgejo events trigger. Webhooks defined here will act on all repositories on the system, so please consider any performance implications this may have. Read more in the webhooks guide.
systemhooks.add_webhook = Add System Webhook
systemhooks.update_webhook = Update System Webhook
-auths.auth_manage_panel = Authentication Source Management
-auths.new = Add Authentication Source
+auths.auth_manage_panel = Manage authentication sources
+auths.new = Add authentication source
auths.name = Name
auths.type = Type
auths.enabled = Enabled
-auths.syncenabled = Enable User Synchronization
+auths.syncenabled = Enable user synchronization
auths.updated = Updated
-auths.auth_type = Authentication Type
-auths.auth_name = Authentication Name
-auths.security_protocol = Security Protocol
+auths.auth_type = Authentication type
+auths.auth_name = Authentication name
+auths.security_protocol = Security protocol
auths.domain = Domain
auths.host = Host
auths.port = Port
auths.bind_dn = Bind DN
-auths.bind_password = Bind Password
-auths.user_base = User Search Base
+auths.bind_password = Bind password
+auths.user_base = User search base
auths.user_dn = User DN
-auths.attribute_username = Username Attribute
+auths.attribute_username = Username attribute
auths.attribute_username_placeholder = Leave empty to use the username entered in Forgejo.
-auths.attribute_name = First Name Attribute
-auths.attribute_surname = Surname Attribute
-auths.attribute_mail = Email Attribute
-auths.attribute_ssh_public_key = Public SSH Key Attribute
-auths.attribute_avatar = Avatar Attribute
-auths.attributes_in_bind = Fetch Attributes in Bind DN Context
+auths.attribute_name = First name attribute
+auths.attribute_surname = Surname attribute
+auths.attribute_mail = Email attribute
+auths.attribute_ssh_public_key = Public SSH key attribute
+auths.attribute_avatar = Avatar attribute
+auths.attributes_in_bind = Fetch attributes in nind DN context
auths.allow_deactivate_all = Allow an empty search result to deactivate all users
-auths.use_paged_search = Use Paged Search
-auths.search_page_size = Page Size
-auths.filter = User Filter
-auths.admin_filter = Admin Filter
-auths.restricted_filter = Restricted Filter
-auths.restricted_filter_helper = Leave empty to not set any users as restricted. Use an asterisk ("*") to set all users that do not match Admin Filter as restricted.
+auths.use_paged_search = Use paged search
+auths.search_page_size = Page size
+auths.filter = User filter
+auths.admin_filter = Admin filter
+auths.restricted_filter = Restricted filter
+auths.restricted_filter_helper = Leave empty to not set any users as restricted. Use an asterisk ("*") to set all users that do not match Admin filter as restricted.
auths.verify_group_membership = Verify group membership in LDAP (leave the filter empty to skip)
-auths.group_search_base = Group Search Base DN
-auths.group_attribute_list_users = Group Attribute Containing List Of Users
-auths.user_attribute_in_group = User Attribute Listed In Group
+auths.group_search_base = Group search base DN
+auths.group_attribute_list_users = Group attribute containing list of users
+auths.user_attribute_in_group = User attribute listed in group
auths.map_group_to_team = Map LDAP groups to Organization teams (leave the field empty to skip)
auths.map_group_to_team_removal = Remove users from synchronized teams if user does not belong to corresponding LDAP group
auths.enable_ldap_groups = Enable LDAP groups
-auths.ms_ad_sa = MS AD Search Attributes
-auths.smtp_auth = SMTP Authentication Type
-auths.smtphost = SMTP Host
-auths.smtpport = SMTP Port
-auths.allowed_domains = Allowed Domains
+auths.ms_ad_sa = MS AD search attributes
+auths.smtp_auth = SMTP authentication type
+auths.smtphost = SMTP host
+auths.smtpport = SMTP port
+auths.allowed_domains = Allowed domains
auths.allowed_domains_helper = Leave empty to allow all domains. Separate multiple domains with a comma (",").
-auths.skip_tls_verify = Skip TLS Verify
+auths.skip_tls_verify = Skip TLS verification
auths.force_smtps = Force SMTPS
auths.force_smtps_helper = SMTPS is always used on port 465. Set this to force SMTPS on other ports. (Otherwise STARTTLS will be used on other ports if it is supported by the host.)
-auths.helo_hostname = HELO Hostname
+auths.helo_hostname = HELO hostname
auths.helo_hostname_helper = Hostname sent with HELO. Leave blank to send current hostname.
auths.disable_helo = Disable HELO
-auths.pam_service_name = PAM Service Name
-auths.pam_email_domain = PAM Email Domain (optional)
-auths.oauth2_provider = OAuth2 Provider
+auths.pam_service_name = PAM service name
+auths.pam_email_domain = PAM email domain (optional)
+auths.oauth2_provider = OAuth2 provider
auths.oauth2_icon_url = Icon URL
auths.oauth2_clientID = Client ID (Key)
auths.oauth2_clientSecret = Client Secret
@@ -3091,17 +3105,17 @@ auths.oauth2_emailURL = Email URL
auths.skip_local_two_fa = Skip local 2FA
auths.skip_local_two_fa_helper = Leaving unset means local users with 2FA set will still have to pass 2FA to log on
auths.oauth2_tenant = Tenant
-auths.oauth2_scopes = Additional Scopes
-auths.oauth2_required_claim_name = Required Claim Name
+auths.oauth2_scopes = Additional scopes
+auths.oauth2_required_claim_name = Required claim name
auths.oauth2_required_claim_name_helper = Set this name to restrict login from this source to users with a claim with this name
-auths.oauth2_required_claim_value = Required Claim Value
+auths.oauth2_required_claim_value = Required claim value
auths.oauth2_required_claim_value_helper = Set this value to restrict login from this source to users with a claim with this name and value
auths.oauth2_group_claim_name = Claim name providing group names for this source. (Optional)
-auths.oauth2_admin_group = Group Claim value for administrator users. (Optional - requires claim name above)
-auths.oauth2_restricted_group = Group Claim value for restricted users. (Optional - requires claim name above)
-auths.oauth2_map_group_to_team = Map claimed groups to Organization teams. (Optional - requires claim name above)
+auths.oauth2_admin_group = Group claim value for administrator users. (Optional - requires claim name above)
+auths.oauth2_restricted_group = Group claim value for restricted users. (Optional - requires claim name above)
+auths.oauth2_map_group_to_team = Map claimed groups to organization teams. (Optional - requires claim name above)
auths.oauth2_map_group_to_team_removal = Remove users from synchronized teams if user does not belong to corresponding group.
-auths.enable_auto_register = Enable Auto Registration
+auths.enable_auto_register = Enable auto registration
auths.sspi_auto_create_users = Automatically create users
auths.sspi_auto_create_users_helper = Allow SSPI auth method to automatically create new accounts for users that login for the first time
auths.sspi_auto_activate_users = Automatically activate users
@@ -3113,9 +3127,10 @@ auths.sspi_separator_replacement_helper = The character to use to replace the se
auths.sspi_default_language = Default user language
auths.sspi_default_language_helper = Default language for users automatically created by SSPI auth method. Leave empty if you prefer language to be automatically detected.
auths.tips = Tips
-auths.tips.oauth2.general = OAuth2 Authentication
+auths.tips.gmail_settings = Gmail settings:
+auths.tips.oauth2.general = OAuth2 authentication
auths.tips.oauth2.general.tip = When registering a new OAuth2 authentication, the callback/redirect URL should be:
-auths.tip.oauth2_provider = OAuth2 Provider
+auths.tip.oauth2_provider = OAuth2 provider
auths.tip.bitbucket = Register a new OAuth consumer on https://bitbucket.org/account/user//oauth-consumers/new and add the permission "Account" - "Read"
auths.tip.nextcloud = Register a new OAuth consumer on your instance using the following menu "Settings -> Security -> OAuth 2.0 client"
auths.tip.dropbox = Create a new application at https://www.dropbox.com/developers/apps
@@ -3129,13 +3144,13 @@ auths.tip.discord = Register a new application on https://discordapp.com/develop
auths.tip.gitea = Register a new OAuth2 application. Guide can be found at https://docs.gitea.com/development/oauth2-provider
auths.tip.yandex = Create a new application at https://oauth.yandex.com/client/new. Select following permissions from the "Yandex.Passport API" section: "Access to email address", "Access to user avatar" and "Access to username, first name and surname, gender"
auths.tip.mastodon = Input a custom instance URL for the mastodon instance you want to authenticate with (or use the default one)
-auths.edit = Edit Authentication Source
-auths.activated = This Authentication Source is Activated
+auths.edit = Edit authentication source
+auths.activated = This authentication source is activated
auths.new_success = The authentication "%s" has been added.
auths.update_success = The authentication source has been updated.
-auths.update = Update Authentication Source
-auths.delete = Delete Authentication Source
-auths.delete_auth_title = Delete Authentication Source
+auths.update = Update authentication source
+auths.delete = Delete authentication source
+auths.delete_auth_title = Delete authentication source
auths.delete_auth_desc = Deleting an authentication source prevents users from using it to sign in. Continue?
auths.still_in_used = The authentication source is still in use. Convert or delete any users using this authentication source first.
auths.deletion_success = The authentication source has been deleted.
@@ -3144,43 +3159,43 @@ auths.login_source_of_type_exist = An authentication source of this type already
auths.unable_to_initialize_openid = Unable to initialize OpenID Connect Provider: %s
auths.invalid_openIdConnectAutoDiscoveryURL = Invalid Auto Discovery URL (this must be a valid URL starting with http:// or https://)
-config.server_config = Server Configuration
-config.app_name = Site Title
-config.app_ver = Forgejo Version
-config.app_url = Forgejo Base URL
-config.custom_conf = Configuration File Path
-config.custom_file_root_path = Custom File Root Path
-config.domain = Server Domain
-config.offline_mode = Local Mode
-config.disable_router_log = Disable Router Log
-config.run_user = Run As Username
-config.run_mode = Run Mode
-config.git_version = Git Version
-config.app_data_path = App Data Path
-config.repo_root_path = Repository Root Path
-config.lfs_root_path = LFS Root Path
-config.log_file_root_path = Log Path
-config.script_type = Script Type
-config.reverse_auth_user = Reverse Authentication User
+config.server_config = Server configuration
+config.app_name = Instance title
+config.app_ver = Forgejo version
+config.app_url = Base URL
+config.custom_conf = Configuration file path
+config.custom_file_root_path = Custom file root path
+config.domain = Server domain
+config.offline_mode = Local mode
+config.disable_router_log = Disable router log
+config.run_user = User to run as
+config.run_mode = Run mode
+config.git_version = Git version
+config.app_data_path = App data path
+config.repo_root_path = Repository root path
+config.lfs_root_path = LFS root path
+config.log_file_root_path = Log path
+config.script_type = Script type
+config.reverse_auth_user = Reverse authentication user
-config.ssh_config = SSH Configuration
+config.ssh_config = SSH configuration
config.ssh_enabled = Enabled
-config.ssh_start_builtin_server = Use Built-In Server
-config.ssh_domain = SSH Server Domain
+config.ssh_start_builtin_server = Use built-in server
+config.ssh_domain = SSH server domain
config.ssh_port = Port
-config.ssh_listen_port = Listen Port
-config.ssh_root_path = Root Path
-config.ssh_key_test_path = Key Test Path
-config.ssh_keygen_path = Keygen ("ssh-keygen") Path
-config.ssh_minimum_key_size_check = Minimum Key Size Check
-config.ssh_minimum_key_sizes = Minimum Key Sizes
+config.ssh_listen_port = Listen port
+config.ssh_root_path = Root path
+config.ssh_key_test_path = Key test path
+config.ssh_keygen_path = Keygen ("ssh-keygen") path
+config.ssh_minimum_key_size_check = Minimum key size check
+config.ssh_minimum_key_sizes = Minimum key sizes
-config.lfs_config = LFS Configuration
+config.lfs_config = LFS configuration
config.lfs_enabled = Enabled
-config.lfs_content_path = LFS Content Path
-config.lfs_http_auth_expiry = LFS HTTP Auth Expiry
+config.lfs_content_path = LFS content path
+config.lfs_http_auth_expiry = LFS HTTP auth expiration time
-config.db_config = Database Configuration
+config.db_config = Database configuration
config.db_type = Type
config.db_host = Host
config.db_name = Name
@@ -3189,99 +3204,100 @@ config.db_schema = Schema
config.db_ssl_mode = SSL
config.db_path = Path
-config.service_config = Service Configuration
-config.register_email_confirm = Require Email Confirmation to Register
-config.disable_register = Disable Self-Registration
-config.allow_only_internal_registration = Allow Registration Only Through Forgejo itself
-config.allow_only_external_registration = Allow Registration Only Through External Services
-config.enable_openid_signup = Enable OpenID Self-Registration
-config.enable_openid_signin = Enable OpenID Sign-In
-config.show_registration_button = Show Register Button
-config.require_sign_in_view = Require Sign-In to View Pages
-config.mail_notify = Enable Email Notifications
+config.service_config = Service configuration
+config.register_email_confirm = Require email confirmation to register
+config.disable_register = Disable self-registration
+config.allow_only_internal_registration = Allow registration only through Forgejo itself
+config.allow_only_external_registration = Allow registration only through external Services
+config.enable_openid_signup = Enable OpenID self-registration
+config.enable_openid_signin = Enable OpenID sign-in
+config.show_registration_button = Show register button
+config.require_sign_in_view = Require to sign-in to view content
+config.mail_notify = Enable email notifications
config.enable_captcha = Enable CAPTCHA
-config.active_code_lives = Active Code Lives
-config.reset_password_code_lives = Recover Account Code Expiry Time
-config.default_keep_email_private = Hide Email Addresses by Default
-config.default_allow_create_organization = Allow Creation of Organizations by Default
-config.enable_timetracking = Enable Time Tracking
-config.default_enable_timetracking = Enable Time Tracking by Default
-config.default_allow_only_contributors_to_track_time = Let Only Contributors Track Time
-config.no_reply_address = Hidden Email Domain
-config.default_visibility_organization = Default visibility for new Organizations
-config.default_enable_dependencies = Enable Issue Dependencies by Default
+config.active_code_lives = Activation code expiration time
+config.reset_password_code_lives = Recovery code expiration time
+config.default_keep_email_private = Hide email addresses by default
+config.default_allow_create_organization = Allow creation of organizations by default
+config.enable_timetracking = Enable time tracking
+config.default_enable_timetracking = Enable time tracking by default
+config.default_allow_only_contributors_to_track_time = Let only contributors track time
+config.no_reply_address = Hidden email domain
+config.default_visibility_organization = Default visibility of new organizations
+config.default_enable_dependencies = Enable issue dependencies by default
-config.webhook_config = Webhook Configuration
-config.queue_length = Queue Length
-config.deliver_timeout = Deliver Timeout
-config.skip_tls_verify = Skip TLS Verification
+config.webhook_config = Webhook configuration
+config.queue_length = Queue length
+config.deliver_timeout = Deliver timeout
+config.skip_tls_verify = Skip TLS verification
-config.mailer_config = Mailer Configuration
+config.mailer_config = Mailer configuration
config.mailer_enabled = Enabled
config.mailer_enable_helo = Enable HELO
config.mailer_name = Name
config.mailer_protocol = Protocol
-config.mailer_smtp_addr = SMTP Addr
-config.mailer_smtp_port = SMTP Port
+config.mailer_smtp_addr = SMTP host
+config.mailer_smtp_port = SMTP port
config.mailer_user = User
config.mailer_use_sendmail = Use Sendmail
-config.mailer_sendmail_path = Sendmail Path
+config.mailer_sendmail_path = Sendmail path
config.mailer_sendmail_args = Extra Arguments to Sendmail
-config.mailer_sendmail_timeout = Sendmail Timeout
+config.mailer_sendmail_timeout = Sendmail timeout
config.mailer_use_dummy = Dummy
config.test_email_placeholder = Email (e.g. test@example.com)
-config.send_test_mail = Send Testing Email
+config.send_test_mail = Send test email
config.send_test_mail_submit = Send
-config.test_mail_failed = Failed to send a testing email to "%s": %v
-config.test_mail_sent = A testing email has been sent to "%s".
+config.test_mail_failed = Failed to send a test email to "%s": %v
+config.test_mail_sent = A test email has been sent to "%s".
-config.oauth_config = OAuth Configuration
+config.oauth_config = OAuth configuration
config.oauth_enabled = Enabled
-config.cache_config = Cache Configuration
-config.cache_adapter = Cache Adapter
-config.cache_interval = Cache Interval
-config.cache_conn = Cache Connection
-config.cache_item_ttl = Cache Item TTL
+config.cache_config = Cache configuration
+config.cache_adapter = Cache adapter
+config.cache_interval = Cache interval
+config.cache_conn = Cache connection
+config.cache_item_ttl = Cache item TTL
-config.session_config = Session Configuration
-config.session_provider = Session Provider
-config.provider_config = Provider Config
-config.cookie_name = Cookie Name
-config.gc_interval_time = GC Interval Time
-config.session_life_time = Session Life Time
-config.https_only = HTTPS Only
-config.cookie_life_time = Cookie Life Time
+config.session_config = Session configuration
+config.session_provider = Session provider
+config.provider_config = Provider config
+config.cookie_name = Cookie name
+config.gc_interval_time = GC interval time
+config.session_life_time = Session lifetime
+config.https_only = HTTPS only
+config.cookie_life_time = Cookie lifetime
-config.picture_config = Picture and Avatar Configuration
-config.picture_service = Picture Service
+config.picture_config = Picture and avatar configuration
+config.picture_service = Picture service
config.disable_gravatar = Disable Gravatar
-config.enable_federated_avatar = Enable Federated Avatars
+config.enable_federated_avatar = Enable federated avatars
+config.open_with_editor_app_help = The "Open with" editors for the clone menu. If left empty, the default will be used. Expand to see the default.
-config.git_config = Git Configuration
-config.git_disable_diff_highlight = Disable Diff Syntax Highlight
-config.git_max_diff_lines = Max Diff Lines (for a single file)
-config.git_max_diff_line_characters = Max Diff Characters (for a single line)
-config.git_max_diff_files = Max Diff Files (to be shown)
-config.git_gc_args = GC Arguments
-config.git_migrate_timeout = Migration Timeout
-config.git_mirror_timeout = Mirror Update Timeout
-config.git_clone_timeout = Clone Operation Timeout
-config.git_pull_timeout = Pull Operation Timeout
-config.git_gc_timeout = GC Operation Timeout
+config.git_config = Git configuration
+config.git_disable_diff_highlight = Disable diff syntax highlighting
+config.git_max_diff_lines = Max diff lines per file
+config.git_max_diff_line_characters = Max diff characters per line
+config.git_max_diff_files = Max diff files shown
+config.git_gc_args = GC arguments
+config.git_migrate_timeout = Migration timeout
+config.git_mirror_timeout = Mirror Update timeout
+config.git_clone_timeout = Clone Operation timeout
+config.git_pull_timeout = Pull Operation timeout
+config.git_gc_timeout = GC Operation timeout
-config.log_config = Log Configuration
+config.log_config = Log configuration
config.logger_name_fmt = Logger: %s
config.disabled_logger = Disabled
-config.access_log_mode = Access Log Mode
-config.access_log_template = Access Log Template
+config.access_log_mode = Access log mode
+config.access_log_template = Access log template
config.xorm_log_sql = Log SQL
config.set_setting_failed = Set setting %s failed
monitor.stats = Stats
-monitor.cron = Cron Tasks
+monitor.cron = Cron tasks
monitor.name = Name
monitor.schedule = Schedule
monitor.next = Next Time
@@ -3305,29 +3321,29 @@ monitor.queue = Queue: %s
monitor.queue.name = Name
monitor.queue.type = Type
monitor.queue.exemplar = Exemplar Type
-monitor.queue.numberworkers = Number of Workers
-monitor.queue.activeworkers = Active Workers
-monitor.queue.maxnumberworkers = Max Number of Workers
-monitor.queue.numberinqueue = Number in Queue
-monitor.queue.review_add = Review / Add Workers
-monitor.queue.settings.title = Pool Settings
+monitor.queue.numberworkers = Number of workers
+monitor.queue.activeworkers = Active workers
+monitor.queue.maxnumberworkers = Max Number of workers
+monitor.queue.numberinqueue = Number in queue
+monitor.queue.review_add = Review / add workers
+monitor.queue.settings.title = Pool settings
monitor.queue.settings.desc = Pools dynamically grow in response to their worker queue blocking.
monitor.queue.settings.maxnumberworkers = Max Number of workers
monitor.queue.settings.maxnumberworkers.placeholder = Currently %[1]d
monitor.queue.settings.maxnumberworkers.error = Max number of workers must be a number
-monitor.queue.settings.submit = Update Settings
-monitor.queue.settings.changed = Settings Updated
+monitor.queue.settings.submit = Update settings
+monitor.queue.settings.changed = Settings updated
monitor.queue.settings.remove_all_items = Remove all
monitor.queue.settings.remove_all_items_done = All items in the queue have been removed.
-notices.system_notice_list = System Notices
-notices.view_detail_header = View Notice Details
+notices.system_notice_list = System notices
+notices.view_detail_header = Notice details
notices.operations = Operations
-notices.select_all = Select All
-notices.deselect_all = Deselect All
-notices.inverse_selection = Inverse Selection
-notices.delete_selected = Delete Selected
-notices.delete_all = Delete All Notices
+notices.select_all = Select all
+notices.deselect_all = Deselect all
+notices.inverse_selection = Inverse selection
+notices.delete_selected = Delete selected
+notices.delete_all = Delete all notices
notices.type = Type
notices.type_1 = Repository
notices.type_2 = Task
@@ -3452,9 +3468,9 @@ dependencies = Dependencies
keywords = Keywords
details = Details
details.author = Author
-details.project_site = Project Site
-details.repository_site = Repository Site
-details.documentation_site = Documentation Site
+details.project_site = Project website
+details.repository_site = Repository website
+details.documentation_site = Documentation website
details.license = License
assets = Assets
versions = Versions
@@ -3551,19 +3567,20 @@ settings.delete.notice = You are about to delete %s (%s). This operation is irre
settings.delete.success = The package has been deleted.
settings.delete.error = Failed to delete the package.
owner.settings.cargo.title = Cargo registry index
-owner.settings.cargo.initialize = Initialize Index
+owner.settings.cargo.initialize = Initialize index
owner.settings.cargo.initialize.description = A special index Git repository is needed to use the Cargo registry. Using this option will (re-)create the repository and configure it automatically.
owner.settings.cargo.initialize.error = Failed to initialize Cargo index: %v
owner.settings.cargo.initialize.success = The Cargo index was successfully created.
-owner.settings.cargo.rebuild = Rebuild Index
+owner.settings.cargo.rebuild = Rebuild index
owner.settings.cargo.rebuild.description = Rebuilding can be useful if the index is not synchronized with the stored Cargo packages.
owner.settings.cargo.rebuild.error = Failed to rebuild Cargo index: %v
owner.settings.cargo.rebuild.success = The Cargo index was successfully rebuild.
+owner.settings.cargo.rebuild.no_index = Cannot rebuild, no index is initialized.
owner.settings.cleanuprules.title = Manage cleanup rules
-owner.settings.cleanuprules.add = Add Cleanup Rule
-owner.settings.cleanuprules.edit = Edit Cleanup Rule
+owner.settings.cleanuprules.add = Add cleanup rule
+owner.settings.cleanuprules.edit = Edit cleanup rule
owner.settings.cleanuprules.none = There are no cleanup rules yet.
-owner.settings.cleanuprules.preview = Cleanup Rule Preview
+owner.settings.cleanuprules.preview = Cleanup rule preview
owner.settings.cleanuprules.preview.overview = %d packages are scheduled to be removed.
owner.settings.cleanuprules.preview.none = Cleanup rule does not match any packages.
owner.settings.cleanuprules.enabled = Enabled
@@ -3596,7 +3613,7 @@ deletion = Remove secret
deletion.description = Removing a secret is permanent and cannot be undone. Continue?
deletion.success = The secret has been removed.
deletion.failed = Failed to remove secret.
-management = Secrets Management
+management = Manage secrets
[actions]
actions = Actions
@@ -3613,8 +3630,8 @@ status.skipped = Skipped
status.blocked = Blocked
runners = Runners
-runners.runner_manage_panel = Runners Management
-runners.new = Create new Runner
+runners.runner_manage_panel = Manage runners
+runners.new = Create new runner
runners.new_notice = How to start a runner
runners.status = Status
runners.id = ID
@@ -3622,7 +3639,7 @@ runners.name = Name
runners.owner_type = Type
runners.description = Description
runners.labels = Labels
-runners.last_online = Last Online Time
+runners.last_online = Last online time
runners.runner_title = Runner
runners.task_list = Recent tasks on this runner
runners.task_list.no_tasks = There is no task yet.
@@ -3632,7 +3649,7 @@ runners.task_list.repository = Repository
runners.task_list.commit = Commit
runners.task_list.done_at = Done At
runners.edit_runner = Edit Runner
-runners.update_runner = Update Changes
+runners.update_runner = Update changes
runners.update_runner_success = Runner updated successfully
runners.update_runner_failed = Failed to update runner
runners.delete_runner = Delete this runner
@@ -3649,7 +3666,7 @@ runners.version = Version
runners.reset_registration_token = Reset registration token
runners.reset_registration_token_success = Runner registration token reset successfully
-runs.all_workflows = All Workflows
+runs.all_workflows = All workflows
runs.commit = Commit
runs.scheduled = Scheduled
runs.pushed_by = pushed by
@@ -3667,17 +3684,17 @@ runs.no_workflows.documentation = For more information on Forgejo Actions, see <
runs.no_runs = The workflow has no runs yet.
runs.empty_commit_message = (empty commit message)
-workflow.disable = Disable Workflow
+workflow.disable = Disable workflow
workflow.disable_success = Workflow "%s" disabled successfully.
-workflow.enable = Enable Workflow
+workflow.enable = Enable workflow
workflow.enable_success = Workflow "%s" enabled successfully.
workflow.disabled = Workflow is disabled.
need_approval_desc = Need approval to run workflows for fork pull request.
variables = Variables
-variables.management = Variables Management
-variables.creation = Add Variable
+variables.management = Manage variables
+variables.creation = Add variable
variables.none = There are no variables yet.
variables.deletion = Remove variable
variables.deletion.description = Removing a variable is permanent and cannot be undone. Continue?
@@ -3692,9 +3709,9 @@ variables.update.failed = Failed to edit variable.
variables.update.success = The variable has been edited.
[projects]
-type-1.display_name = Individual Project
-type-2.display_name = Repository Project
-type-3.display_name = Organization Project
+type-1.display_name = Individual project
+type-2.display_name = Repository project
+type-3.display_name = Organization project
[git.filemode]
changed_filemode = %[1]s → %[2]s
diff --git a/options/locale/locale_eo.ini b/options/locale/locale_eo.ini
index 0f3f2ea010..0f03a1b9ba 100644
--- a/options/locale/locale_eo.ini
+++ b/options/locale/locale_eo.ini
@@ -92,7 +92,7 @@ copy_error = Malsukcesis kopii
copy = Kopii
enabled = Ŝaltita
rerun = Reruli
-milestones = Celpunktoj
+milestones = Celoj
show_timestamps = Montri datojn
rss_feed = RSS-fluo
never = Neniam
@@ -118,6 +118,23 @@ new_project_column = Novan kolumnon
new_migrate = Novan enporton
mirror = Spegulo
powered_by = Servas vin %s
+remove = Forigi
+filter = Filtri
+filter.is_archived = Arĥivita
+filter.not_archived = Nearĥivita
+filter.is_fork = Disbranĉigita
+filter.not_fork = Nedisbranĉigita
+filter.is_mirror = Spegulita
+filter.not_mirror = Nespegulita
+filter.is_template = Ŝablono
+filter.not_template = Neŝablono
+filter.public = Publika
+filter.private = Privata
+dashboard = Labortablo
+toggle_menu = Baskuli menuon
+access_token = Alira ĵetono
+remove_all = Forigi ĉion
+remove_label_str = Forigi «%s»
[editor]
buttons.list.ordered.tooltip = Aldoni nombran liston
@@ -152,11 +169,12 @@ network_error = Reteraro
invalid_csrf = Malvalida peto: malvalida CSRF-kodo
occurred = Eraris iel
missing_csrf = Malvalida peto: neniu CSRF-kodo
+server_internal = Eraris interno de servilo
[heatmap]
less = Malpli
number_of_contributions_in_the_last_12_months = %s kontribuoj dum la pasintaj 12 monatoj
-no_contributions = Neniu kontribuo
+contributions_zero = Neniu kontribuo
more = Pli
[startpage]
@@ -280,6 +298,8 @@ env_config_keys = Mediagordoj
enable_update_checker_helper = Foje kontrolas ĉu estas novaj versioj per konektiĝo al gitea.io.
invalid_password_algorithm = Malvalida pasvorthakeita algoritmo
password_algorithm_helper = Agordas la pasvorthaketigan algoritmon. Algoritmoj havas malsamajn postulojn kaj efikecojn. La algoritmo argon2 sufiĉe sekuras, sed postulas multan memoron kaj eble ne taŭgas por nepotencaj serviloj.
+internal_token_failed = Malsukcesis krei internan ĵetonon: %v
+smtp_from_invalid = La «Sendu retleterojn kiel» adreso malvalidas
[admin]
config.app_data_path = Programdatuja doseiervojo
@@ -306,6 +326,7 @@ show_only_unarchived = Montras sole nearĥivitajn
my_mirrors = Miaj speguloj
show_only_archived = Montras sole arĥivitajn
view_home = Vidi %s
+switch_dashboard_context = Ŝanĝi labortablon
[explore]
search.match.tooltip = Inkluzivu sole rezultojn kiuj akordas precize la serĉomendon
@@ -345,7 +366,7 @@ invalid_password = Via pasvorto ne samas tiun uzitan dum kreiĝo de via konto.
send_reset_mail = Sendi retleteron por rehavigo de konto
oauth_signin_title = Salutu por aprobi kontligiĝon
reset_password_helper = Rehavigi konton
-login_openid = OpenID
+tab_openid = OpenID
openid_connect_submit = Konekti
authorization_failed = Aprobo malsukcesis
oauth_signup_tab = Registri novan konton
@@ -389,6 +410,13 @@ openid_register_desc = La elektita OpenID URI estas nekonata. Ligi ĝin al nova
reset_password = Rehavigo de konto
sspi_auth_failed = SSPI aŭtentikigo malsukcesis
must_change_password = Ŝanĝu vian pasvorton
+remember_me = Memoru ĉi tiun aparaton
+account_activated = Konto aktivigita
+resent_limit_prompt = Vi jam petis freŝe aktivigan retleteron. Bonvolu atendi 3 minutojn kaj reprovu.
+change_unconfirmed_email_summary = Ŝanĝi al retpoŝtadreson al kiu la aktiviga retletero sendiĝu.
+invalid_code_forgot_password = Via konfirmkodo malvalidas aŭ jam eksdatiĝis. Klaku ĉi tien por komenci novan saluton.
+authorize_redirect_notice = Vi alidirektiĝos al %s se vi aprobus ĉi tiun programon.
+active_your_account = Aktivigi vian konton
[mail]
activate_account.text_1 = Saluton %[1]s, dankon pro via registriĝo ĉe %[2]s!
@@ -437,6 +465,9 @@ reset_password = Rehavigi vian konton
issue.action.merge = @%[1]s kunfandis #%[2]d al %[3]s.
issue.action.push_1 = @%[1]s puŝis %[3]d enmeton al %[2]s
issue.action.push_n = @%[1]s puŝis %[3]d enmetojn al %[2]s
+activate_account = Bonvolu aktivigi vian konton
+activate_account.title = %s, bonvolu aktivigi vian konton
+activate_account.text_2 = Bonvolu klaki la jenan ligilon por aktivigi vian konton antaŭ %s:
[form]
TeamName = Gruponomo
@@ -715,3 +746,60 @@ followers = Abonantoj
block_user.detail_2 = La uzanto ne povos interagi viajn deponejojn, erarojn, kaj komentojn.
block_user = Bloki uzanton
change_avatar = Ŝanĝi vian profilbildon…
+
+
+[repo]
+editor.add_file = Aldoni dosieron
+settings.tags = Etikedoj
+archive.title_date = Ĉi tiu deponejo arĥiviĝis je %s. Vi povas vidi kaj elŝuti dosierojn, sed ne povas puŝi nek raporti problemojn nek tirpeti.
+archive.pull.nocomment = Ĉi tiu deponejo estas arĥivigita. Vi ne povas respondi tirpetojn.
+migrate_items_pullrequests = Tirpetoj
+migrate.migrating_pulls = Migrante tirpetojn
+unwatch = Malspuri
+watch = Spuri
+star = Stelumi
+unstar = Malstelumi
+fork = Disbranĉigi
+code = Fontkodo
+branch = Branĉo
+pulls = Tirpetoj
+commits = Enmetoj
+releases = Eldonoj
+commit_graph.hide_pr_refs = Kaŝi tirpetojn
+activity.title.prs_n = %d tirpetoj
+activity.opened_prs_count_n = Proponitaj tirpetoj
+contributors.contribution_type.commits = Enmetoj
+settings = Agordoj
+settings.pulls_desc = Ŝalti tirpetojn por deponejo
+settings.event_fork = Disbranĉigi
+release.tags = Etikedoj
+release.releases = Eldonoj
+release.tag_name = Etikeda nomo
+release.delete_tag = Forigi etikedon
+find_file.go_to_file = Iri al dosiero
+settings.archive.tagsettings_unavailable = Etikedaj agordoj neredakteblas je arĥivita deponejo.
+pulls.tab_commits = Enmetoj
+topic.manage_topics = Mastrumi temojn
+tag.create_success = Etikedo «%s» kreita.
+default_branch_helper = La implicita branĉo estas la baza branĉo por tirpetoj kaj enmetoj.
+tags = Etikedoj
+issues.no_ref = Neniu branĉo/etikedo donita
+release.tags_for = Etikedoj por %s
+tag = Etikedo
+settings.tags.protection = Gardado de etikedoj
+settings.tags.protection.create = Gardi etikedon
+release.add_tag = Krei sole etikedon
+settings.default_branch_desc = Elekti implicutan deponejan branĉon por tirpetoj kaj enmetoj:
+archive.title = Ĉi tiu deponejo estas arĥivigita. Vi povas vidi kaj elŝuti dosierojn, sed ne povas puŝi nek raporti problemojn nek tirpeti.
+activity.active_prs_count_n = %d aktivaj tirpetoj
+settings.archive.text = Arĥivigi la deponejon igus ĝin sole legebla. Ĝi kaŝiĝos de la labortablo. Neniu (ne eĉ vi!) povos fari enmetojn, raportojn, kaj tirpetojn.
+migrate_items_releases = Eldonoj
+commits.commits = Enmetoj
+
+[org]
+code = Fontkodo
+settings = Agordoj
+teams.settings = Agordoj
+
+[packages]
+npm.details.tag = Etikedo
\ No newline at end of file
diff --git a/options/locale/locale_es-ES.ini b/options/locale/locale_es-ES.ini
index 57ab69b255..0b4f0bef33 100644
--- a/options/locale/locale_es-ES.ini
+++ b/options/locale/locale_es-ES.ini
@@ -150,7 +150,7 @@ footer.links=Enlaces
[heatmap]
number_of_contributions_in_the_last_12_months=%s contribuciones en los últimos 12 meses
-no_contributions=No hay contribuciones
+contributions_zero=No hay contribuciones
less=Menos
more=Más
@@ -396,7 +396,7 @@ twofa_scratch_used=Ya ha utilizado su código de respaldo. Ha sido redirigido a
twofa_passcode_incorrect=Su código de acceso es incorrecta. Si extravió el dispositivo, use su código de respaldo para iniciar sesión.
twofa_scratch_token_incorrect=El código de respaldo es incorrecto.
login_userpass=Iniciar sesión
-login_openid=OpenID
+tab_openid=OpenID
oauth_signup_tab=Registrar nueva cuenta
oauth_signup_title=Completar Cuenta Nueva
oauth_signup_submit=Completar Cuenta
@@ -1734,8 +1734,8 @@ pulls.nothing_to_compare=Estas ramas son iguales. No hay necesidad para crear un
pulls.nothing_to_compare_and_allow_empty_pr=Estas ramas son iguales. Este PR estará vacío.
pulls.has_pull_request=`Ya existe un pull request entre estas ramas: %[2]s#%[3]d`
pulls.create=Crear Pull Request
-pulls.title_desc=desea fusionar %[1]d commits de %[2]s
en %[3]s
-pulls.merged_title_desc=fusionados %[1]d commits de %[2]s
en %[3]s
%[4]s
+pulls.title_desc_few=desea fusionar %[1]d commits de %[2]s
en %[3]s
+pulls.merged_title_desc_few=fusionados %[1]d commits de %[2]s
en %[3]s
%[4]s
pulls.change_target_branch_at=`cambió la rama objetivo de %s a %s %s`
pulls.tab_conversation=Conversación
pulls.tab_commits=Commits
diff --git a/options/locale/locale_fa-IR.ini b/options/locale/locale_fa-IR.ini
index 64d29cbda7..598c1636dc 100644
--- a/options/locale/locale_fa-IR.ini
+++ b/options/locale/locale_fa-IR.ini
@@ -24,12 +24,12 @@ licenses=گواهینامه ها
return_to_gitea=بازگشت به Forgejo
username=نام کاربری
-email=آدرس ایمیل
+email=نشانی رایانامه
password=رمز عبور
access_token=ژتون دسترسی
-re_type=تکرارگذواژه
+re_type=تأیید گذرواژه
captcha=کپچا
-twofa=احراز هویت دوگانه
+twofa=احراز هویت دو مرحلهای
twofa_scratch=کد احراز هویت
passcode=رمز عبور
@@ -39,7 +39,7 @@ organization=سازمان
mirror=قرینه
new_repo=مخزن جدید
new_migrate=انتقال جدید
-new_mirror=قرینه ای جدید
+new_mirror=آینه جدید
new_fork=انشعاب مخزن جدید
new_org=سازمان جدید
new_project=پروژه جدید
@@ -100,6 +100,25 @@ concept_user_organization=سازمان
name=نام
+logo = نشان
+sign_in_with_provider = ورود با %s
+enable_javascript = این وبگاه به جاوا اسکریپت نیاز دارد.
+webauthn_press_button = لطفاً دکمۀ روی کلید امنیتی را فشار دهید…
+webauthn_unsupported_browser = مرورگر شما در حال حاضر از WebAuthn پشتیبانی نمیکند.
+webauthn_error_unknown = خطایی ناشناخته رخ داد. لطفاً دوباره سعی کنید.
+webauthn_error_unable_to_process = کارساز نتوانست درخواست شما را پردازش کند.
+webauthn_reload = تازهسازی
+new_project_column = ستون جدید
+retry = سعی دوباره
+rerun = اجرای دوباره
+rerun_all = اجرای دوباره تمام کارها
+rss_feed = خوراک RSS
+pin = سنجاق
+unpin = حذف سنجاق
+locked = قفل شده
+copy_hash = رونوشت هش
+unknown = نامشخص
+copy_type_unsupported = این نوع از فایل نمیتواند رونوشت شود.
[aria]
@@ -299,7 +318,7 @@ twofa_scratch_used=شما کد ابتدا خود استفاده کرده اند.
twofa_passcode_incorrect=گذرواژه شما اشتباه است. اگر شما دستگاه خود را در جای اشتباه قرار داده اید, از کد ابتدای خود برای ورود به سیستم استفاده کنید.
twofa_scratch_token_incorrect=کد ابتدا شما نادرست است.
login_userpass=ورود
-login_openid=OpenID
+tab_openid=OpenID
oauth_signup_tab=ثبت نام یک حساب جدید
oauth_signup_title=تکمیل حساب جدید
oauth_signup_submit=تکمیل حساب کاربری
@@ -1307,8 +1326,8 @@ pulls.nothing_to_compare=این شاخهها یکی هستند. نیازی ب
pulls.nothing_to_compare_and_allow_empty_pr=این شاخه ها برابر هستند. این PR خالی خواهد بود.
pulls.has_pull_request=`A درخواست pull بین این شاخه ها از قبل وجود دارد: %[2]s#%[3]d`
pulls.create=ایجاد تقاضای واکشی
-pulls.title_desc=قصد ادغام %[1]d تغییر را از %[2]s
به %[3]s
دارد
-pulls.merged_title_desc=%[1]d کامیت ادغام شده از %[2]s
به %[3]s
%[4]s
+pulls.title_desc_few=قصد ادغام %[1]d تغییر را از %[2]s
به %[3]s
دارد
+pulls.merged_title_desc_few=%[1]d کامیت ادغام شده از %[2]s
به %[3]s
%[4]s
pulls.change_target_branch_at=`هدف شاخه از %s به %s %s تغییر کرد`
pulls.tab_conversation=گفتگو
pulls.tab_commits=کامیتها
diff --git a/options/locale/locale_fi-FI.ini b/options/locale/locale_fi-FI.ini
index ad45e55ade..c6c64ad6ce 100644
--- a/options/locale/locale_fi-FI.ini
+++ b/options/locale/locale_fi-FI.ini
@@ -308,7 +308,7 @@ twofa_scratch_used=Olet käyttänyt kertakäyttökoodisi. Sinut on uudelleenohja
twofa_passcode_incorrect=Salasanasi on väärä. Jos olet hukannut laitteesi, käytäthän kertakäyttökoodia sisäänkirjautumiseen.
twofa_scratch_token_incorrect=Kertakäyttökoodisi on virheellinen.
login_userpass=Kirjaudu sisään
-login_openid=OpenID
+tab_openid=OpenID
oauth_signup_tab=Rekisteröi uusi tili
oauth_signup_title=Viimeistele tili
oauth_signup_submit=Viimeistele tili
@@ -989,8 +989,8 @@ pulls.nothing_to_compare=Nämä haarat vastaavat toisiaan. Ei ole tarvetta luoda
pulls.nothing_to_compare_and_allow_empty_pr=Nämä haarat vastaavat toisiaan. Vetopyyntö tulee olemaan tyhjä.
pulls.has_pull_request=`Vetopyyntö haarojen välillä on jo olemassa: %[2]s#%[3]d`
pulls.create=Luo Pull-pyyntö
-pulls.title_desc=haluaa yhdistää %[1]d committia lähteestä %[2]s
kohteeseen %[3]s
-pulls.merged_title_desc=yhdistetty %[1]d committia lähteestä %[2]s
kohteeseen %[3]s
%[4]s
+pulls.title_desc_few=haluaa yhdistää %[1]d committia lähteestä %[2]s
kohteeseen %[3]s
+pulls.merged_title_desc_few=yhdistetty %[1]d committia lähteestä %[2]s
kohteeseen %[3]s
%[4]s
pulls.tab_conversation=Keskustelu
pulls.tab_commits=Commitit
pulls.tab_files=Muuttuneet tiedostot
diff --git a/options/locale/locale_fil.ini b/options/locale/locale_fil.ini
new file mode 100644
index 0000000000..afe3d1cb8e
--- /dev/null
+++ b/options/locale/locale_fil.ini
@@ -0,0 +1,899 @@
+
+
+
+[common]
+page = Pahina
+language = Wika
+mirrors = Mga Mirror
+forks = Mga Fork
+activities = Mga Aktibidad
+pull_requests = Mga Pull Request
+issues = Mga Isyu
+milestones = Mga Milestone
+ok = OK
+cancel = Kanselahin
+retry = Subukan Muli
+rerun = Patakbuhin Muli
+save = I-save
+add = Magdagdag
+remove_all = Tanggalin lahat
+remove_label_str = Tanggalin ang item "%s"
+edit = I-edit
+enabled = Naka-enable
+copy = Kopyahin
+copy_content = Kopyahin ang content
+copy_branch = Kopyahin ang pangalan ng branch
+copy_success = Kinopya!
+copy_error = Nabigo ang pagkopya
+write = Magsulat
+register = Magrehistro
+enable_javascript = Nangangailangan ng JavaScript ang website na ito.
+twofa_scratch = Scratch Code ng Two-Factor
+sources = Mga Source
+collaborative = Pagtutulungan
+copy_type_unsupported = Hindi makokopya ang itong uri ng file
+error404 = Ang pahina na sinusubukan mong bisitahin ay alinman hindi umiiral o wala kang pahintulot para itignan.
+version = Bersyon
+powered_by = Pinapatakbo ng %s
+explore = Mag-explore
+help = Tulong
+logo = Logo
+sign_in = Mag-Sign In
+sign_in_with_provider = Mag-sign in gamit ng %s
+sign_in_or = o
+sign_out = Mag-Sign Out
+sign_up = Magrehistro
+link_account = Mag-link ng Account
+template = Template
+tracked_time_summary = Buod ng mga nakasubaybay na oras base sa filter ng listahan ng isyu
+webauthn_sign_in = Pindutin ang button ng iyong security key. Kung walang button ang iyong security key, ilagay muli.
+webauthn_error_insecure = Sinusuportahan lamang ng WebAuthn ang mga secure na koneksyon. Para sa pagsubok sa HTTP, pwede mo gamitin ang origin na "localhost" o "127.0.0.1"
+webauthn_error_timeout = Naabot ang timeout bago mabasa ang iyong key. Mangyaring i-reload ang page na ito at subukan muli.
+view = Itignan
+disabled = Naka-disable
+copy_url = Kopyahin ang URL
+create_new = Gumawa…
+user_profile_and_more = Profile at Mga Setting…
+signed_in_as = Naka-sign in bilang
+toc = Talaan ng Mga Nilalaman
+licenses = Mga Lisensya
+return_to_gitea = Bumalik sa Forgejo
+toggle_menu = I-toggle ang Menu
+username = Username
+email = Email address
+password = Password
+access_token = Token ng pag-access
+re_type = Kumpirmahin ang password
+captcha = CAPTCHA
+twofa = Two-Factor Authentication
+passcode = Passcode
+webauthn_insert_key = Ilagay ang iyong security key
+webauthn_press_button = Pindutin ang button ng iyong security key…
+webauthn_use_twofa = Gumamit ng two-factor code galing sa iyong telepono
+webauthn_error = Hindi mabasa ang iyong security key.
+webauthn_unsupported_browser = Kasalukuyang hindi sinusuportahan ng iyong browser ang WebAuthn.
+webauthn_error_unknown = May nangyaring hindi alam na error. Magyaring subukan muli.
+webauthn_error_unable_to_process = Hindi maproseso ng server ang iyong hiling.
+webauthn_error_duplicated = Hindi pinapayagan ang security key na ito para sa hiling na ito. Mangyaring siguraduhin na ang key na ito ay hindi ito nakarehistro na.
+webauthn_error_empty = Kailangan mong maglapat ng pangalan para sa key na ito.
+webauthn_reload = I-reload
+repository = Repository
+organization = Organisasyon
+mirror = Mirror
+new_repo = Bagong Repository
+new_migrate = Bagong Migration
+new_mirror = Bagong Mirror
+new_fork = Bagong Repository Fork
+new_org = Bagong Organisasyon
+new_project = Bagong Proyekto
+new_project_column = Bagong Column
+admin_panel = Pangangasiwa ng Site
+account_settings = Mga Setting ng Account
+settings = Mga Setting
+your_profile = Profile
+your_starred = Naka-star
+your_settings = Mga Setting
+all = Lahat
+go_back = Bumalik
+never = Hindi Kailanman
+unknown = Hindi Alam
+rss_feed = Feed ng RSS
+pin = I-pin
+unpin = I-unpin
+artifacts = Mga Artifact
+archived = Naka-archive
+concept_system_global = Global
+concept_user_individual = Indibidwal
+concept_code_repository = Repository
+concept_user_organization = Organisasyon
+show_timestamps = Ipakita ang mga timestamp
+show_log_seconds = Ipakita ang segundo
+show_full_screen = Ipakita ng full screen
+download_logs = I-download ang mga log
+name = Pangalan
+value = Value
+filter = I-filter
+filter.clear = I-clear ang Filter
+filter.is_archived = Naka-archive
+filter.not_archived = Hindi naka-archive
+filter.is_fork = Naka-fork
+filter.not_fork = Hindi naka-fork
+filter.is_mirror = Naka-mirror
+filter.not_mirror = Hindi naka-mirror
+filter.is_template = Template
+filter.not_template = Hindi Template
+filter.public = Publiko
+filter.private = Pribado
+notifications = Mga Abiso
+active_stopwatch = Aktibong Tagasubaybay ng Oras
+locked = Naka-lock
+preview = I-preview
+confirm_delete_artifact = Sigurado ka bang gusto mong burahin ang artifact na "%s"?
+rerun_all = Patakbuhin muli ang lahat ng mga job
+add_all = Idagdag lahat
+copy_hash = Kopyahin ang hash
+error = Error
+remove = Tanggalin
+loading = Naglo-load…
+confirm_delete_selected = Kumpirmahin na burahin ang lahat ng piniling item?
+home = Panimula
+dashboard = Dashboard
+
+[home]
+search_repos = Maghanap ng Repository…
+switch_dashboard_context = Palitan ang Dashboard Context
+show_only_unarchived = Pinapakita lang ang hindi naka-archive
+password_holder = Password
+my_repos = Mga Repository
+show_more_repos = Magpakita ng higit pang repository…
+collaborative_repos = Mga Collaboritive Repository
+my_orgs = Aking Mga Organisasyon
+my_mirrors = Aking Mga Mirror
+view_home = Itignan ang %s
+filter = Iba pang Mga Filter
+filter_by_team_repositories = I-filter sa mga team repository
+feed_of = Feed ng "%s"
+show_archived = Naka-archive
+show_both_archived_unarchived = Pinapakita ang naka-archive at hindi naka-archive
+show_only_archived = Pinapakita lang ang naka-archive
+show_private = Pribado
+show_both_private_public = Pinapakita ang publiko at pribado
+show_only_private = Pinapakita lang ang pribado
+show_only_public = Pinapakita lang ang publiko
+issues.in_your_repos = Sa iyong mga repository
+uname_holder = Username o Email address
+
+[explore]
+organizations = Mga Organisasyon
+search.fuzzy.tooltip = Isali ang mga resulta na tumutugma sa search term nang malapit
+repos = Mga Repository
+users = Mga User
+search = Maghanap
+go_to = Pumunta sa
+code = Code
+search.type.tooltip = Uri ng paghahanap
+search.fuzzy = Fuzzy
+search.match = Tugma
+search.match.tooltip = Isali lamang ang mga resulta na tugma sa eksaktong search term
+repo_no_results = Walang tugmang repository na nahanap.
+user_no_results = Walang tugmang user na nahanap.
+org_no_results = Walang tugmang mga organisasyon na nahanap.
+code_search_results = Mga resulta ng paghahanap para sa "%s"
+code_last_indexed_at = Huling na-index %s
+relevant_repositories_tooltip = Mga repository na isang fork o walang topic, icon, at deskripsyon ay nakatago.
+code_search_unavailable = Kasalukuyang hindi available ang code search. Mangyaring makipag-ugnayan sa site administrator.
+code_no_results = Walang source code na tumutugma sa iyong search term na nahanap.
+relevant_repositories = Ang mga kaugnay na repository ay pinapakita, ipakita ang hindi naka-filter na resulta.
+
+[aria]
+footer.software = Tungkol sa Software
+navbar = Bar ng Nabigasyon
+footer = Footer
+footer.links = Mga Link
+
+[error]
+report_message = Kung naniniwala kang ito ay isang bug ng Forgejo, mangyaring maghanap ng mga isyu sa Codeberg magbukas ng bagong isyu kapag kailangan.
+occurred = May nangyaring error
+missing_csrf = Masamang Kahilingan: walang CSRF token
+invalid_csrf = Masamang Kahilingan: hindi angkop na CSRF token
+not_found = Hindi mahanap ang target.
+network_error = Error sa network
+server_internal = Internal Server Error
+
+[install]
+reinstall_error = Sinusubukan mong mag-install sa umiiral na Forgejo database
+install = Pag-install
+title = Paunang pagsasaayos
+docker_helper = Kapag tinatakbo mo ang Forgejo sa loob ng Docker, mangyaring basahin ang dokumentasyon bago baguhin ang anumang mga setting.
+require_db_desc = Kinakailangan ng Forgejo ang MySQL, PostgreSQL, MSSQL, SQLite3 o TiDB (MySQL protocol).
+db_title = Mga setting ng database
+db_type = Uri ng database
+host = Host
+user = Username
+password = Password
+db_name = Pangalan ng database
+db_schema = Schema
+db_schema_helper = Iwanang walang laman para sa default ng database ("public").
+ssl_mode = SSL
+path = Path
+sqlite_helper = File path para sa SQLite3 database.
Maglagay ng absolute path kapag tinatakbo mo ang Forgejo bilang serbisyo.
+reinstall_confirm_check_3 = Kinukumprima mo na sigurado ka talaga na ang Forgejo na ito ay tumatakbo sa tamang app.ini na lokasyon at sigurado ka na kailangan mo mag-reinstall. Kinukumpirma mo na kilalanin ang mga panganib sa itaas.
+err_empty_db_path = Hindi maaring walang laman ang path ng SQLite database.
+no_admin_and_disable_registration = Hindi mo maaring i-disable ang user self-registration nang hindi gumawa ng isang administrator account.
+err_empty_admin_password = Hindi maaring walang laman ang administrator password.
+err_empty_admin_email = Hindi maaring walang laman ang administrator email.
+err_admin_name_is_reserved = Hindi angkop ang Administrator Username, naka-reserve ang username
+err_admin_name_is_invalid = Hindi angkop ang Administrator Username
+general_title = Mga General Setting
+app_name = Pangalan ng Instansya
+app_name_helper = Maari mong ilagay ang pangalan ng iyong kompanya dito.
+repo_path_helper = Ang mga remote Git repository ay mase-save sa directory na ito.
+repo_path = Root path ng Repository
+lfs_path = Root path ng Git LFS
+run_user = User na tatakbuhin bilang
+run_user_helper = Ang operating system username na ang Forgejo ay tatakbo bilang. Tandaan mo na ang user ay kailangang may access sa repository root path.
+domain = Domain ng server
+domain_helper = Domain o host para sa server na ito.
+ssh_port = Port ng SSH Server
+http_port = HTTP listen port
+lfs_path_helper = Ang mga file na naka-track sa Git LFS ay ilalagay sa directory na ito. Iwanang walang laman para i-disable.
+reinstall_confirm_message = Ang pag-install muli na may umiiral na Forgejo database ay maaring magdulot ng mga problema. Sa karamihan ng mga kaso, dapat mong gamitin ang iyong umiiral na "app.ini" para patakbuhin ang Forgejo. Kung alam mo ang ginagawa mo, kumpirmahin ang mga sumusunod:
+reinstall_confirm_check_1 = Ang data na naka-encrypt sa pamamagitan ng SECRET_KEY sa app.ini ay maaring mawala: baka hindi maka-log in ang mga user gamit ng 2FA/OTP at ang mga mirror ay maaring hindi gumana mg maayos. Sa pamamagitan ng pag-check ng box na ito kinukumpirma mo na ang kasalukuyang app.ini file ay naglalaman ng tamang SECRET_KEY.
+reinstall_confirm_check_2 = Ang mga repository at mga setting ay maaring kailangang i-resynchronize. Sa pamamagitan ng pag-check ng box na ito kinukumprima mo na ire-resynchronize mo ang mga hook para sa mga repository at authorized_keys ng mano-mano. Kinukumpirma mo na sisiguraduhin mo na tama ang mga setting ng repository at mirror.
+err_admin_name_pattern_not_allowed = Hindi angkop ang administrator username, ang username ay tumutugma sa reserved pattern
+ssh_port_helper = Numero ng port na gagamitin ng SSH server. Iwanang walang laman para i-disable ang SSH server.
+server_service_title = Mga setting ng server at third-party na serbisyo
+offline_mode = Paganahin ang local mode
+http_port_helper = Port number na gagamitin ng Forgejo web server.
+app_url = Base URL
+app_url_helper = Base address para sa mga HTTP(S) clone URL at mga email notification.
+log_root_path = Path ng log
+log_root_path_helper = Ang mga log file ay ilalagay sa directory na ito.
+optional_title = Mga opsyonal na setting
+email_title = Mga setting ng email
+smtp_addr = Host ng SMTP
+smtp_port = Port ng SMTP
+smtp_from = Magpadala ng email bilang
+smtp_from_invalid = Hindi angkop ang address ng "Magpadala ang Email Bilang"
+smtp_from_helper = Ang email address na gagamitin ng Forgejo. Maglagay ng plain email address o gamitin ang "Pangalan" na format.
+mailer_user = Username ng SMTP
+mailer_password = Password ng SMTP
+register_confirm = Kailanganin ang kumpirmasyon sa email para magrehistro
+mail_notify = Paganahin ang mga email notification
+disable_gravatar = I-disable ang Gravatar
+federated_avatar_lookup = I-enable ang mga naka-federate na avatar
+federated_avatar_lookup_popup = I-enable ang naka-federate na paghahanap ng avatar gamit ng Libravatar.
+disable_registration = I-disable ang pansariling pagrehistro
+allow_only_external_registration_popup = Payagan lang ang pagrehistro sa pamamagitan ng mga external na serbisyo
+openid_signin = I-enable ang OpenID sign-in
+openid_signin_popup = I-enable ang pag-sign in ng user gamit ng OpenID.
+openid_signup = I-enable ang OpenID na pansariling pagrehistro
+openid_signup_popup = I-enable ang OpenID-based na pansariling pagrehistro ng user.
+enable_captcha = I-enable ang CAPTCHA sa pagrehistro
+enable_captcha_popup = Kailanganin ang CAPTCHA sa pansariling pagrehistro ng user.
+require_sign_in_view_popup = Limitahan ang access ng pahina sa mga naka-sign in na user. Makikita lang ng mga bisita ang sign-in at pagrehistro na mga pahina.
+admin_title = Mga setting ng administrator account
+admin_name = Username ng administrator
+admin_password = Password
+confirm_password = Kumpirmahin ang password
+admin_email = Email address
+config_location_hint = Ang mga opsyon sa configuration ay mase-save sa:
+install_btn_confirm = I-install ang Forgejo
+test_git_failed = Hindi masubukan ang "git" command: %v
+invalid_db_setting = Hindi angkop ang mga database setting: %v
+invalid_db_table = Hindi angkop ang database table na "%s": %v
+invalid_repo_path = Hindi angkop ang repository root path: %v
+invalid_app_data_path = Hindi angkop ang app data path: %v
+run_user_not_match = Ang "tumakbo bilang" na username ay hindi ang kasulukuyang username: %s -> %s
+internal_token_failed = Nabigong maka-generate ng internal token: %v
+secret_key_failed = Nabigong maka-generate ng secret key: %v
+save_config_failed = Nabigong i-save ang configuration: %v
+invalid_admin_setting = Hindi angkop ang setting ng administrator account: %v
+invalid_log_root_path = Hindi angkop ang log path: %v
+default_keep_email_private = Itago ang mga email address bilang default
+default_keep_email_private_popup = Itago ang mga email address ng mga bagong user account bilang default.
+default_allow_create_organization_popup = Payagan ang mga bagong user account ng gumawa ng mga organisasyon bilang default.
+default_enable_timetracking = I-enable ang pagsubaybay ng oras bilang default
+default_enable_timetracking_popup = I-enable ang pagsubaybay ng oras sa mga bagong repository bilang default.
+allow_dots_in_usernames = Payagan ang mga user na gamitin ang mga tuldok sa kanilang username. Hindi inaapektuhan ang mga umiiral na account.
+no_reply_address = Domain ng nakatagong email
+no_reply_address_helper = Domain name para sa mga user na may nakatagong email address. Halimbawa, ang username na "kita" ay mala-log sa Git bilang "kita@noreply.example.org" kapag ang nakatagong email domain ay nakatakda sa "noreply.example.org".
+password_algorithm = Algorithm ng password hash
+invalid_password_algorithm = Hindi angkop na algorithm ng password hash
+password_algorithm_helper = Itakda ang password hashing algorithm. Ang mga algorithm ay may magkakaibang mga kinakailangan at lakas. Ang algorithm ng Argon2 ay sa halip ay ligtas ngunit gumagamit ng maraming memory at maaaring hindi naaangkop para sa mga maliliit na sistema.
+enable_update_checker = I-enable ang tagasuri ng update
+env_config_keys = Configuration ng Environment
+env_config_keys_prompt = Ang mga sumusunod na mga environment variable ay ia-apply rin sa iyong configuration file:
+offline_mode_popup = I-disable ang lahat ng mga third-party na content delivery network at ibahagi ang lahat ng mga resources ng locally.
+require_sign_in_view = Kailanganin ang pag-sign in para tignan ang nilalaman ng instansya
+enable_update_checker_helper_forgejo = Pansamantalang susuriin ito para sa mga bagong bersyon ng Forgejo sa pamamagitan ng pagsuri sa isang tala ng TXT DNS sa release.forgejo.org.
+sqlite3_not_available = Ang itong bersyon ng Forgejo ay hindi sinusuportahan ang SQLite3. Paki-download ang opisyal na bersyon ng binary sa %s (hindi ang "gobuild" na bersyon).
+default_allow_create_organization = Payagan ang paggawa ng mga organisasyon bilang default
+disable_registration_popup = I-disable ang pansariling pagrehistro ng user. Ang mga administrator lamang ang makakagawa ng mga bagong user account.
+disable_gravatar_popup = I-disable ang Gravatar at mga third-party na avatar source. Ang isang default na avatar ay gagamitin maliban kung maga-upload ng avatar ang user.
+admin_setting_desc = Ang paggawa ng administrator account ay opsyonal. Ang pinakaunang nakarehistro na user ay awtomatikong magiging administrator.
+
+[heatmap]
+number_of_contributions_in_the_last_12_months = %s mga kontribusyon sa nakalipas na 12 buwan
+no_contributions = Walang mga kontribusyon
+less = Kaunti
+more = Marami
+
+[editor]
+buttons.bold.tooltip = Magdagdag ng bold na text
+buttons.italic.tooltip = Magdagdag ng italic text
+buttons.quote.tooltip = I-quote ang text
+buttons.code.tooltip = Magdagdag ng code
+buttons.link.tooltip = Magdagdag ng link
+buttons.list.unordered.tooltip = Magdagdag ng bullet na listahan
+buttons.list.task.tooltip = Magdagdag ng listahan ng mga gawain
+buttons.mention.tooltip = Magmensyon ng user o koponan
+buttons.enable_monospace_font = I-enable ang monospace font
+buttons.disable_monospace_font = I-disable ang monospace font
+buttons.list.ordered.tooltip = Magdagdag ng nakanumerong listahan
+buttons.ref.tooltip = Magsangguni ng isyu o pull request
+buttons.switch_to_legacy.tooltip = Gamitin ang legacy editor sa halip
+buttons.heading.tooltip = Magdagdag ng heading
+
+[filter]
+string.asc = A - Z
+string.desc = Z - A
+
+[startpage]
+app_desc = Isang hindi masakit, at naka self-host na Git service
+install = Madaling i-install
+platform = Cross-platform
+platform_desc = Tumatakbo kahit saan ang Forgejo na ang Go ay nakaka-compile para sa: Windows, macOS, Linux, ARM, atbp. Piliin ang isa na gusto mo!
+lightweight = Hindi Mabigat
+lightweight_desc = Mababa ang minimal requirements ng Forgejo at tatakbo sa isang murang Raspberry Pi. Tipirin ang enerhiya ng iyong machine!
+license = Open Source
+install_desc = Patakbuhin ang binary para sa iyong platform, i-ship gamit ang Docker, o kunin ito nang naka-package.
+license_desc = Kunin ang Forgejo! Sumali ka sa pamamagitan ng pag-contribute para gawing mas mahusay ang proyekto. Wag kang mahiya para maging isang contributor!
+
+[auth]
+create_new_account = Magrehistro ng Account
+register_helper_msg = May account ka na? Mag-sign in ngayon!
+social_register_helper_msg = May account ka na? I-link ngayon!
+disable_register_prompt = Naka-disable ang pagrehistro. Mangyaring makipag-ugnayan sa site administrator.
+disable_register_mail = Ang kumpirmasyon sa pamamagitan ng Email sa pagrehistro ay naka-disable.
+remember_me = Tandaan ang device na ito
+forgot_password_title = Nakalimutan ang Password
+forgot_password = Nakalimutan ang password?
+sign_up_now = Kailangan ng isang account? Magrehistro ngayon.
+sign_up_successful = Matagumpay na nagawa ang account. Maligayang pagdating!
+must_change_password = Baguhin ang iyong password
+allow_password_change = Kailanganin ang user na palitan ang password (inirerekomenda)
+reset_password_mail_sent_prompt = Ang isang bagong email pang-kumpirma ay ipinadala sa %s. Pakisuri ang iyong inbox sa loob ng %s para tapusin ang proseso ng pag-recover ng account.
+active_your_account = Aktibahin Ang Iyong Account
+account_activated = Naaktiba na ang account
+prohibit_login = Ipinagbawalan ang Pag-Sign In
+prohibit_login_desc = Pinagbawalan ang iyong account sa pag-sign in, mangyaring makipag-ugnayan sa site administrator.
+resent_limit_prompt = Humiling ka na ng activation email kamakailan. Mangyaring maghintay ng 3 minuto at subukang muli.
+change_unconfirmed_email_summary = Palitan ang email address kung saan ipapadala ang activation email.
+change_unconfirmed_email = Kung nagbigay ka ng maling email address habang nagpaparehistro, pwede mong palitan sa ibaba, at ang isang kumpirmasyon ay ipapadala sa bagong address sa halip.
+change_unconfirmed_email_error = Hindi mapalitan ang email address: %v
+resend_mail = Pindutin dito para ipadala muli ang activation email
+email_not_associate = Ang email address ay hindi nauugnay sa anumang account.
+send_reset_mail = Magpadala ng Account Recovery Email
+reset_password = Pag-recover ng Account
+reset_password_helper = I-recover ang Account
+reset_password_wrong_user = Naka-sign in ka bilang %s, pero ang account recovery link ay para kay %s
+password_too_short = Ang haba ng password ay hindi maaaring mas mababa sa %d character.
+non_local_account = Ang mga non-local na user ay hindi makakabago ng kanilang password sa pamamagitan ng Forgejo web interface.
+verify = I-verify
+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_openid = OpenID
+oauth_signup_tab = Mag-rehistro ng Bagong Account
+oauth_signup_title = Kumpletuhin ang Bagong Account
+oauth_signup_submit = Kumpletuhin ang Account
+oauth_signin_tab = I-link sa Umiiral na Account
+oauth_signin_submit = I-link ang Account
+oauth.signin.error.access_denied = Tinanggihan ang hiling ng pahintulutan.
+oauth.signin.error.temporarily_unavailable = Nabigo ang awtorisasyon dahil pansamantalang hindi available ang authentication server. Mangyaring subukan muli sa ibang pagkakataon.
+openid_connect_submit = Kumonekta
+openid_connect_title = Kumonekta sa umiiral na account
+openid_connect_desc = Ang piniling OpenID URI ay hindi alam. Iugnay iyan sa bagong account dito.
+invalid_code = Ang iyong confirmation code ay hindi wasto o nag-expire na.
+oauth_signin_title = Mag-sign In para Pahintulutan ang Naka-link na Account
+invalid_code_forgot_password = Ang iyong confirmation code ay hindi wasto o nag-expire na. Mag-click dito para magsimula ng bagong session.
+confirmation_mail_sent_prompt = Ang isang bagong email pang-kumpirma ay ipinadala sa %s. Pakisuri ang iyong inbox sa loob ng %s para tapusin ang proseso ng pagrehistro. Kung mali ang email, maari kang mag-log in, at humingi ng isa pang email pang-kumpirma na ipapadala sa ibang address.
+invalid_password = Ang iyong password ay hindi tugma sa password na ginamit para gawin ang account.
+twofa_scratch_used = Ginamit mo na ang scratch code. Na-redirect ka sa two-factor settings page para tanggalin ang device enrollment o mag-generate ng bagong scratch code.
+manual_activation_only = Makipag-ugnayan sa site administrator para kumpletuhin ang pagrehistro.
+oauth.signin.error = Nagkaroon ng error sa pagproseso ng iyong hiling sa pahintulutan. Kung magpapatuloy ang error, mangyaring makipag-ugnayan sa site administrator.
+remember_me.compromised = Ang login token ay hindi na wasto na maaaring magpahiwatig ng isang nakompromisong account. Pakisuri ang iyong account para sa mga hindi pangkaraniwang aktibidad.
+has_unconfirmed_mail = Kamusta %s, mayroon kang isang hindi kinumpirmang email address (%s). Kung hindi ka pa nakatanggap ng email na pang-kumpirma o kailangang muling magpadala ng bago, mangyaring i-click ang button sa ibaba.
+openid_register_title = Gumawa ng bagong account
+openid_register_desc = Ang piniling OpenID URI ay hindi alam. Iugnay iyan sa bagong account dito.
+openid_signin_desc = Ilagay ang iyong OpenID URI. Halimbawa: kita.openid.example.org o https://openid.example.org/kita.
+disable_forgot_password_mail = Naka-disable ang account recovery dahil walang nakatakda na email. Mangyaring makipag-ugnayan sa site administrator.
+disable_forgot_password_mail_admin = Available lamang ang account recovery kung may nakatakda na email. I-set up ang email para i-enable ang account recovery.
+email_domain_blacklisted = Hindi ka makakapagrehistro gamit ng iyong email address.
+authorize_application = Pahintulutan ang Aplikasyon
+authorize_redirect_notice = Mare-redirect ka sa %s kapag pinahintulutan mo ang aplikasyon na ito.
+authorize_application_created_by = Ginawa ni %s ang aplikasyon na ito.
+authorize_application_description = Kung payagan mo ang access, maa-access at mababago nito ang lahat ng iyong impormasyon sa account, kasama ang mga pribadong repo at organisasyon.
+authorize_title = Pahintulutan ang "%s" na i-access ang iyong account?
+authorization_failed = Nabigo ang awtorisasyon
+authorization_failed_desc = Nabigo ang awtorisasyon dahil may na-detect kami ng hindi angkop na hiling. Mangyaring makipag-ugnayan sa maintainer ng app na sinusubukan mong pahintulutan.
+sspi_auth_failed = Nabigo ang SSPI authentication
+password_pwned = Ang pinili mong password ay nasa listahan ng mga ninakaw na password na kasalukuyang napakita sa mga publikong data breach. Mangyaring subukang muli gamit ng ibang password at isaalang-alang palitan din ang password sa ibang lugar.
+password_pwned_err = Hindi makumpleto ang request sa HaveIBeenPwned
+last_admin = Hindi mo matatanggal ang pinakahuling admin. Kailangan may hindi bababa sa isang admin.
+
+[mail]
+reply = o direktang tumugon sa email na ito
+view_it_on = Tignan sa %s
+issue.in_tree_path = Sa %s:
+release.new.subject = Ang %s sa %s ay inilabas
+link_not_working_do_paste = Hindi ba gumagana ang link? Subukang kopyahin at i-paste sa URL bar ng iyong browser.
+hi_user_x = Kamusta %s,
+activate_account = Paki-activate ang iyong account
+activate_account.text_1 = Kamusta %[1]s, salamat sa pagrehistro sa %[2]s!
+activate_account.text_2 = Paki-click ang sumusunod na link para i-activate ang iyong account sa loob ng %s:
+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 mag-click dito para ipamahala ang user na ito sa admin panel.
+register_notify = Maligayang Pagdating sa Forgejo
+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
+reset_password = I-recover ang iyong account
+reset_password.title = %s, nagkaroon kami ng hiling para i-recover ang iyong account
+reset_password.text = Kung ikaw ito, paki-click ang sumusunod na link para i-recover ang iyong account sa loob ng %s:
+register_success = Matagumpay ang pag-rehistro
+issue_assigned.issue = Itinalaga ka ni @%[1]s sa isyu na %[2]s sa repository na %[3]s.
+issue.x_mentioned_you = Binanggit ka ni %s:
+issue.action.force_push = Na-force push ni %[1]s ang %[2]s mula %[3]s sa %[4]s.
+issue.action.push_n = Nag-push si @%[1]s ng %[3]d (mga) commit sa %[2]s
+issue.action.close = Sinara ni @%[1]s ang #%[2]d.
+issue.action.reopen = Binuksan muli ni @%[1]s ang #%[2]d.
+issue.action.merge = Minerge ni @%[1]s ang #%[2]d sa %[3]s.
+issue.action.approve = Inaprubahan ni @%[1]s ang pull request na ito.
+issue.action.review = Nagkomento si @%[1]s sa pull request na ito.
+issue.action.review_dismissed = Binalewala ni @%[1]s ang huling review galing sa %[2]s para sa pull request na ito.
+issue.action.new = Ginawa ni @%[1]s ang #%[2]d.
+release.title = Pamagat: %s
+release.note = Note:
+release.downloads = Mga Download:
+release.download.zip = Source Code (ZIP)
+release.download.targz = Source Code (TAR.GZ)
+repo.transfer.subject_to_you = Gusto ilipat ni %s ang repository na "%s" sa iyo
+repo.transfer.to_you = ikaw
+repo.transfer.body = Para tanggapin o tanggihan bisitahin ang %s o huwag na lang pansinin.
+repo.collaborator.added.subject = Dinagdag ka ni %s sa %s bilang tagaambag
+team_invite.subject = Inimbitahan ka ni %[1]s para sumali sa organisasyong %[2]s
+team_invite.text_1 = Inimbitahan ka ni %[1]s para sumali sa koponang %[2]s sa organisasyong %[3]s.
+team_invite.text_2 = Paki-click ang sumusunod na link para sumali sa koponan:
+activate_email.text = Paki-click ang sumusunod na link para i-verify ang iyong email address sa loob ng %s:
+repo.collaborator.added.text = Dinagdag ka bilang tagaambag sa repository:
+activate_email.title = %s, paki-verify ang iyong email address
+issue.action.reject = Humingi ng mga pagbabago si @%[1]s sa pull request na ito.
+activate_account.title = %s, paki-activate ang iyong account
+register_notify.text_3 = Kung ginawa ng ibang tao ang account na ito para sa iyo, kailangan mong itakda ang iyong password muna.
+issue_assigned.pull = Itinalaga ka ni @%[1]s sa pull request na %[2]s sa repository na %[3]s.
+issue.action.push_1 = Nag-push si @%[1]s ng %[3]d commit sa %[2]s
+issue.action.ready_for_review = Minarkahan ni @%[1]s ang pull request na ito bilang handa para suriin.
+release.new.text = Inilabas ni @%[1]s ang %[2]s sa %[3]s
+repo.transfer.subject_to = Gusto ni %s na ilipat ang repository na "%s" sa %s
+team_invite.text_3 = Tandaan: Ang imbitasyong ito ay inilaan para sa %[1]s. Kung hindi mo inaasahan ang imbitasyong ito, maaari mong balewalain ang email na ito.
+
+[modal]
+yes = Oo
+no = Hindi
+confirm = Kumpirmahin
+cancel = Kanselahin
+modify = Baguhin
+
+[form]
+UserName = Username
+RepoName = Pangalan ng repository
+Email = Email address
+Password = Password
+Retype = Kumpirmahin ang Password
+SSHTitle = Pangalan ng SSH key
+HttpsUrl = HTTPS URL
+PayloadUrl = Payload URL
+TeamName = Pangalan ng koponan
+AuthName = Pangalan ng awtorisasyon
+AdminEmail = Admin email
+NewBranchName = Bagong pangalan ng branch
+CommitMessage = Mensahe ng commit
+CommitChoice = Pagpili ng commit
+TreeName = Path ng file
+Content = Nilalaman
+SSPISeparatorReplacement = Separator
+SSPIDefaultLanguage = Default na Wika
+CommitSummary = Pangkalahatang-ideya ng commit
+glob_pattern_error = ` hindi angkop ang glob pattern: %s`
+require_error = ` hindi maaring walang laman.`
+alpha_dash_error = ` dapat maglaman lamang ng alphanumeric, dash ("-") at underscore ("_") na mga character.`
+alpha_dash_dot_error = ` dapat maglaman lamang ng alphanumeric, dash ("-"), underscore ("_") at tuldok (".") na mga character.`
+git_ref_name_error = ` dapat na mahusay na nabuong pangalan ng Git reference`
+size_error = ` dapat sa laking %s.`
+min_size_error = ` dapat maglaman ng hindi bababa sa %s (mga) character`
+max_size_error = ` dapat maglaman ng hindi lalagpas sa %s (mga) character`
+email_error = ` ay hindi angkop na email address.`
+invalid_group_team_map_error = ` hindi angkop ang mapping: %s`
+unknown_error = Hindi kilalang error:
+captcha_incorrect = Mali ang CAPTCHA code.
+password_not_match = Hindi tumutugma ang mga password.
+lang_select_error = Pumili ng wika sa listahan.
+username_been_taken = Kinuha na ang username.
+username_change_not_local_user = Ang mga hindi lokal na user ay hindi pinapayagang palitan ang kanilang username.
+username_has_not_been_changed = Hindi pinalitan ang username
+repo_name_been_taken = Ginamit na ang pangalan ng repository.
+repository_force_private = Naka-enable ang Force Private: hindi maaaring gawing pampubliko ang mga pribadong repository.
+repository_files_already_exist = Ang mga file ay umiiral na sa repository na ito. Makipag-ugnayan sa system administrator.
+repository_files_already_exist.delete = Ang mga file ay umiiral na sa repository na ito. Kailangan mo silang burahin.
+repository_files_already_exist.adopt_or_delete = Umiiral na ang mga file para sa repository na ito. Alinman pagtibayin sila o burahin sila.
+username_error_no_dots = ` maaari lamang maglaman ng mga alphanumeric na character ("0-9","a-z","A-Z"), gitling ("-") at underscore ("_"). Hindi ito maaaring magsimula o magtatapos sa mga hindi alphanumeric na character, at ipinagbabawal din ang magkakasunod na non-alphanumeric na character.`
+include_error = ` dapat maglaman ng substring na "%s".`
+regex_pattern_error = ` hindi angkop ang regex pattern: %s.`
+url_error = ` hindi angkop na URL ang "%s".`
+username_error = ` maaari lamang maglaman ng mga alphanumeric na character ("0-9","a-z","A-Z"), gitling ("-"), underscore ("_") at tuldok ("."). Hindi ito maaaring magsimula o magtatapos sa mga hindi alphanumeric na character, at ipinagbabawal din ang magkakasunod na non-alphanumeric na character.`
+repository_files_already_exist.adopt = Umiiral na ang mga file para sa repository na ito at maaari lamang Pagtibayin.
+2fa_auth_required = Kinailangan ng remote visit ng two factors authentication.
+org_name_been_taken = Kinuha na ang pangalan ng organisasyon.
+team_name_been_taken = Kinuha na ang pangalan ng koponan.
+team_no_units_error = Payagan ang access sa kahit isang seksyon ng repository.
+email_been_used = Ginamit na ang email address.
+email_invalid = Hindi angkop ang email address.
+openid_been_used = KInuha na ang OpenID address na "%s".
+username_password_incorrect = Mali ang username o password.
+password_complexity = Hindi napasa ng password ang kinakailangan na kahirapan:
+password_lowercase_one = Kahit isang lowercase na character
+password_uppercase_one = Kahit isang uppercase na character
+password_digit_one = Kahit isang numero
+password_special_one = Kahit isang espesyal na character (bantas, mga bracket, mga quote, atbp.)
+enterred_invalid_repo_name = Mali ang inalagay mong pangalan ng repository.
+enterred_invalid_org_name = Mali ang inalagay mong pangalan ng organisasyon.
+enterred_invalid_owner_name = Hindi angkop ang pangalan ng bagong owner.
+enterred_invalid_password = Mali ang password na inilagay mo.
+unset_password = Hindi nagtakda ng password ang login user.
+unsupported_login_type = Hindi sinusuportahan ang uri ng pag-login para burahin ang account.
+user_not_exist = Hindi umiiral ang user.
+team_not_exist = Hindi umiiral ang koponan.
+last_org_owner = Hindi mo maaring tanggalin ang pinakahuling user sa "mga may-ari" na koponan. Kailangan may kahit isang may-ari para sa organisasyon.
+cannot_add_org_to_team = Hindi maaring madagdag ang isang organisasyon bilang miyembro ng koponan.
+duplicate_invite_to_team = Inimbita na ang user bilang miyembro ng koponan.
+organization_leave_success = Matagumpay kang umalis sa organisasyon na %s.
+invalid_ssh_key = Hindi ma-verify ang iyong SSH key: %s
+invalid_gpg_key = Hindi ma-verify ang GPG key: %s
+invalid_ssh_principal = Hindi angkop ang principal: %s
+must_use_public_key = Ang key na ibinigay mo ay isang pribadong key. Huwag mong i-upload ang iyong pribadong key kahit saan. Gamitin ang iyong pampublikong key sa halip.
+unable_verify_ssh_key = Hindi ma-verify ang SSH key, tiyakin ulit para sa mga pagkakamali.
+auth_failed = Nabigo ang autentikasyon: %v
+still_own_repo = Ang iyong account ay nagmamay-ari ng isa o higit pang mga repository, burahin o ilipat sila muna.
+still_has_org = Ang iyong account ay isang miyembro ng isa o higit pang organisasyon, alisin muna sila.
+still_own_packages = Ang iyong account ay nagmamay-ari ng isa o higit pang package, burahin sila muna.
+org_still_own_repo = Ang organisasyon na ito ay nagmamay-ari ng isa o higit pang mga repository, burahin o ilipat sila muna.
+org_still_own_packages = Ang organisasyon na ito ay nagmamay-ari ng isa o higit pang mga package, burahin sila muna.
+target_branch_not_exist = Hindi umiiral ang target branch.
+admin_cannot_delete_self = Hindi mo maaring burahin ang sarili mo kapag isa kang tagapangasiwa. Paki-tanggal ang iyong pribilehiyong tagapangasiwa muna.
+
+[user]
+joined_on = Sumali sa %s
+repositories = Mga Repository
+activity = Pampublikong Aktibidad
+followers = Mga Follower
+block_user = I-block ang User
+change_avatar = Palitan ang iyong avatar…
+block_user.detail = Pakiunawa na kung i-block mo ang user na ito, isasagawa ang iba pang mga aksyon. Gaya ng:
+block_user.detail_1 = Ina-unfollow ka sa user na ito.
+block_user.detail_2 = Ang user na ito ay hindi maaaring makipag-ugnayan sa iyong mga repository, ginawang isyu at komento.
+block_user.detail_3 = Hindi ka maaaring idagdag ng user na ito bilang isang collaborator, at hindi mo rin sila maidaragdag bilang isang collaborator.
+follow_blocked_user = Hindi mo mapa-follow ang user na ito dahil na-block mo ang user na ito o na-block ka ng user na ito.
+starred = Mga Naka-star na Repository
+watched = Mga Sinusubaybayan na Repository
+code = Code
+projects = Mga Proyekto
+overview = Pangkalahatang Ideya
+following = Pina-follow
+follow = I-follow
+unfollow = I-unfollow
+block = I-block
+unblock = I-unblock
+user_bio = Byograpya
+email_visibility.limited = Ang iyong email address ay makikita ng lahat ng mga naka-authenticate na user
+email_visibility.private = Makikita mo lang at mga administrator ang iyong email address
+show_on_map = Ipakita ang lugar na ito sa mapa
+settings = Mga Setting ng User
+form.name_pattern_not_allowed = Ang pattern na "%s" ay hindi pinapayagan sa username.
+disabled_public_activity = Hindi pinagana ng user na ito ang publikong kakayahang pagpakita ng aktibidad.
+form.name_reserved = Nakareserba ang username na "%s".
+form.name_chars_not_allowed = Naglalaman ng mga hindi angkop na character ang username.
+
+[settings]
+profile = Profile
+account = Account
+appearance = Hitsura
+password = Password
+security = Seguridad
+avatar = Avatar
+ssh_gpg_keys = Mga SSH / GPG Key
+applications = Mga Aplikasyon
+orgs = Pamahalaan ng mga organisasyon
+repos = Mga Repository
+delete = Burahin ang Account
+twofa = Authentikasyong Two-Factor (TOTP)
+account_link = Mga Naka-link na Account
+uid = UID
+webauthn = Authentikasyong Two-Factor (Mga Security Key)
+blocked_users = Mga Naka-block na User
+public_profile = Pampublikong Profile
+location_placeholder = Ibahagi ang iyong tinatayang lokasyon sa iba
+password_username_disabled = Ang mga di-lokal na gumagamit ay hindi pinapayagan na baguhin ang kanilang username. Mangyaring makipag-ugnayan sa iyong tagapangasiwa ng site para sa higit pang mga detalye.
+full_name = Punong Pangalan
+website = Website
+location = Lokasyon
+update_theme = I-update ang Theme
+update_profile = I-update ang Profile
+update_language = I-update ang Wika
+update_language_not_found = Hindi available ang wikang "%s".
+update_language_success = Pinalitan na ang wika.
+update_profile_success = Pinalitan na ang iyong profile.
+change_username = Pinalitan na ang iyong username.
+change_username_redirect_prompt = Magre-redirect ang lumang username hanggat may kumuha niyan.
+continue = Magpatuloy
+cancel = Kanselahin
+language = Wika
+ui = Tema
+hidden_comment_types = Mga nakatagong uri ng komento
+hidden_comment_types.ref_tooltip = Mga komento kung saan sinangguni ang isyu na ito galing sa ibang isyu/commit/…
+hidden_comment_types.issue_ref_tooltip = Mga komento kung saan pinalitan ng user ang branch/tag na nakaugnay sa isyu
+comment_type_group_reference = Sangguni
+comment_type_group_label = Label
+comment_type_group_title = Pamagat
+comment_type_group_branch = Branch
+comment_type_group_time_tracking = Pagsubaybay ng Oras
+comment_type_group_deadline = Deadline
+comment_type_group_dependency = Dependency
+comment_type_group_lock = Estado ng Lock
+comment_type_group_review_request = Hiling sa Pagsuri
+comment_type_group_pull_request_push = Mga nadagdag na commit
+comment_type_group_project = Proyekto
+saved_successfully = Matagumpay na na-save ang iyong mga setting.
+privacy = Privacy
+keep_activity_private = Itago ang Aktibidad mula sa pahina ng profile
+lookup_avatar_by_mail = Hanapin Ang Avatar sa pamamagitan ng Email Address
+federated_avatar_lookup = Naka-federate na Paghahanap ng Avatar
+enable_custom_avatar = Gumamit ng custom na avatar
+choose_new_avatar = Pumili ng bagong avatar
+update_avatar = I-update ang avatar
+delete_current_avatar = Burahin ang Kasalukuyang Avatar
+uploaded_avatar_not_a_image = Ang na-upload na file ay hindi isang larawan.
+comment_type_group_assignee = Mangangasiwa
+social = Mga Social Account
+biography_placeholder = Sabihin sa amin ng kaunti tungkol sa iyong sarili! (Maaari mong gamitin ang Markdown)
+change_username_prompt = Tandaan: Ang pagpalit ng username ay papalitan din ang URL ng iyong account.
+organization = Mga Organisasyon
+profile_desc = Kontrolin kung paano ipinapakita ang iyong profile sa ibang mga gumagamit. Ang iyong pangunahing email address ay gagamitin para sa mga abiso, pagbawi ng password at mga Git operation na batay sa web.
+hidden_comment_types_description = Ang mga uri ng komento na naka-check dito ay hindi ipapakita sa loob ng mga pahina ng isyu. Halimbawa ang pag-check ng "Label" ay tatanggalin lahat ng mga "Dinagdag/tinanggal ni ang de cette organisation.
members.membership_visibility=Visibilité des membres:
-members.public=Public
+members.public=Visible
members.public_helper=rendre caché
members.private=Caché
members.private_helper=rendre visible
@@ -2856,7 +2886,7 @@ dashboard.update_migration_poster_id=Actualiser les ID des affiches de migration
dashboard.git_gc_repos=Exécuter le ramasse-miette des dépôts
dashboard.resync_all_sshkeys=Mettre à jour le fichier « ssh/authorized_keys » avec les clés SSH Forgejo.
dashboard.resync_all_sshprincipals=Mettre à jour le fichier « .ssh/authorized_principals » avec les principaux de Forgejo SSH.
-dashboard.resync_all_hooks=Re-synchroniser les déclencheurs Git pre-receive, update et post-receive de tous les dépôts.
+dashboard.resync_all_hooks=Re-synchroniser les déclencheurs Git pre-receive, update et post-receive de tous les dépôts
dashboard.reinit_missing_repos=Réinitialiser tous les dépôts Git manquants pour lesquels un enregistrement existe
dashboard.sync_external_users=Synchroniser les données de l’utilisateur externe
dashboard.cleanup_hook_task_table=Nettoyer la table hook_task
@@ -2871,25 +2901,25 @@ dashboard.pointer_lookup_times=Nombre de Consultations Pointeur
dashboard.memory_allocate_times=Allocations de mémoire
dashboard.memory_free_times=Nombre de libérations de mémoire
dashboard.current_heap_usage=Utilisation Tas (Heap)
-dashboard.heap_memory_obtained=Mémoire Tas (Heap) obtenue
-dashboard.heap_memory_idle=Mémoire Tas (Heap) au Repos
-dashboard.heap_memory_in_use=Utilisation Mémoire Tas (Heap)
-dashboard.heap_memory_released=Mémoire Tas (Heap) libérée
-dashboard.heap_objects=Objets Tas (Heap)
-dashboard.bootstrap_stack_usage=Utilisation Pile Bootstrap
-dashboard.stack_memory_obtained=Mémoire Pile obtenue
+dashboard.heap_memory_obtained=Mémoire tas (Heap) obtenue
+dashboard.heap_memory_idle=Mémoire tas (Heap) au repos
+dashboard.heap_memory_in_use=Utilisation mémoire tas (Heap)
+dashboard.heap_memory_released=Mémoire tas (Heap) libérée
+dashboard.heap_objects=Objets tas (Heap)
+dashboard.bootstrap_stack_usage=Utilisation pile bootstrap
+dashboard.stack_memory_obtained=Mémoire pile obtenue
dashboard.mspan_structures_usage=Utilisation des Structures MSpan
dashboard.mspan_structures_obtained=Structures MSpan obtenues
-dashboard.mcache_structures_usage=Utilisation des Structures MCache
+dashboard.mcache_structures_usage=Utilisation des structures MCache
dashboard.mcache_structures_obtained=Structures MCache obtenues
-dashboard.profiling_bucket_hash_table_obtained=Profilage de Seau de Table de Hashage obtenu
+dashboard.profiling_bucket_hash_table_obtained=Profilage de seau de table de hashage obtenu
dashboard.gc_metadata_obtained=Métadonnées GC obtenues
-dashboard.other_system_allocation_obtained=Allocation de l'autre Système obtenue
-dashboard.next_gc_recycle=Traitement GC suivant
-dashboard.last_gc_time=Depuis le dernier GC
+dashboard.other_system_allocation_obtained=Autres allocation système obtenue
+dashboard.next_gc_recycle=Prochain recyclage GC
+dashboard.last_gc_time=Temps depuis le dernier GC
dashboard.total_gc_time=Pause GC
-dashboard.total_gc_pause=Pause GC
-dashboard.last_gc_pause=Dernière Pause GC
+dashboard.total_gc_pause=Pause totale GC
+dashboard.last_gc_pause=Dernière pause GC
dashboard.gc_times=Nombres de GC
dashboard.delete_old_actions=Supprimer toutes les anciennes actions de la base de données
dashboard.delete_old_actions.started=Suppression de toutes les anciennes actions de la base de données démarrée.
@@ -2962,7 +2992,7 @@ users.list_status_filter.is_2fa_enabled=2FA Activé
users.list_status_filter.not_2fa_enabled=2FA désactivé
users.details=Informations de l’utilisateur
-emails.email_manage_panel=Gestion des emails des utilisateurs
+emails.email_manage_panel=Gestion des courriels des utilisateurs
emails.primary=Principale
emails.activated=Activée
emails.filter_sort.email=Courriel
@@ -3013,7 +3043,7 @@ defaulthooks.desc=Les webhooks font automatiquement des requêtes POST HTTP à u
defaulthooks.add_webhook=Ajouter un déclencheur web par défaut
defaulthooks.update_webhook=Mettre à jour le déclencheur web par défaut
-systemhooks=Webhooks système
+systemhooks=Déclencheurs système
systemhooks.desc=Les webhooks font automatiquement des requêtes POST HTTP à un serveur spécifié lorsque certains événements Forgejo se déclenchent. Ceux créé ici agiront sur tous les dépôts, ce qui peux impacter les performances du système. Pour plus d’information, consultez le guide des webhooks.
systemhooks.add_webhook=Ajouter un rappel système
systemhooks.update_webhook=Mettre à jour un rappel système
@@ -3049,7 +3079,7 @@ auths.search_page_size=Taille de la page
auths.filter=Filtre utilisateur
auths.admin_filter=Filtre administrateur
auths.restricted_filter=Filtre restrictif
-auths.restricted_filter_helper=Laisser vide pour ne définir aucun utilisateur comme restreint. Utilisez un astérisque ('*') pour définir tous les utilisateurs qui ne correspondent pas au filtre Admin comme restreint.
+auths.restricted_filter_helper=Laisser vide pour ne définir aucun utilisateur comme restreint. Utilisez un astérisque ("*") pour définir tous les utilisateurs qui ne correspondent pas au filtre Admin comme restreint.
auths.verify_group_membership=Vérifier l’appartenance au groupe LDAP (laisser vide pour ignorer)
auths.group_search_base=DN de recherche du groupe
auths.group_attribute_list_users=Attribut de groupe contenant la liste des utilisateurs
@@ -3062,7 +3092,7 @@ auths.smtp_auth=Type d'authentification SMTP
auths.smtphost=Hôte SMTP
auths.smtpport=Port SMTP
auths.allowed_domains=Domaines autorisés
-auths.allowed_domains_helper=Laisser ce champ vide autorise tous les domaines. Separez les domaines multiples avec une virgule (",").
+auths.allowed_domains_helper=Laisser ce champ vide autorise tous les domaines. Séparez les domaines multiples avec une virgule (",").
auths.skip_tls_verify=Ne pas vérifier TLS
auths.force_smtps=Forcer SMTPS
auths.force_smtps_helper=SMTPS est toujours utilisé sur le port 465. Définissez ceci pour forcer SMTPS sur d'autres ports. (STARTTLS sera utilisé sur d'autres ports si cela est supporté par l'hôte.)
@@ -3145,16 +3175,16 @@ config.custom_conf=Chemin du fichier de configuration
config.custom_file_root_path=Emplacement personnalisé du fichier racine
config.domain=Domaine du serveur
config.offline_mode=Mode hors-ligne
-config.disable_router_log=Désactiver la Journalisation du Routeur
+config.disable_router_log=Désactiver la journalisation du routeur
config.run_user=Exécuter avec l'utilisateur
-config.run_mode=Mode d'Éxécution
+config.run_mode=Mode d’exécution
config.git_version=Version de Git
-config.app_data_path=Chemin App Data
+config.app_data_path=Chemin des données d'application
config.repo_root_path=Emplacement des Dépôts
config.lfs_root_path=Répertoire racine LFS
config.log_file_root_path=Chemin des fichiers logs
-config.script_type=Type de Script
-config.reverse_auth_user=Annuler l'Authentification de l'Utilisateur
+config.script_type=Type de script
+config.reverse_auth_user=Annuler l'authentification de l'utilisateur
config.ssh_config=Configuration SSH
config.ssh_enabled=Activé
@@ -3170,7 +3200,7 @@ config.ssh_minimum_key_sizes=Tailles de clé minimales
config.lfs_config=Configuration LFS
config.lfs_enabled=Activé
-config.lfs_content_path=Chemin de contenu LFS
+config.lfs_content_path=Chemin du contenu LFS
config.lfs_http_auth_expiry=Expiration de l'authentification HTTP LFS
config.db_config=Configuration de la base de données
@@ -3191,22 +3221,22 @@ 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
config.require_sign_in_view=Exiger la connexion pour afficher les pages
-config.mail_notify=Activer les notifications par e-mail
+config.mail_notify=Activer les notifications par courriel
config.enable_captcha=Activer le CAPTCHA
-config.active_code_lives=Limites de Code Actif
+config.active_code_lives=Date d'expiration du code d'activation
config.reset_password_code_lives=Durée d'expiration du code de récupération de compte
-config.default_keep_email_private=Masquer les adresses e-mail par défaut
+config.default_keep_email_private=Masquer les adresses courriel par défaut
config.default_allow_create_organization=Autoriser la création d'organisations par défaut
config.enable_timetracking=Activer le suivi du temps
config.default_enable_timetracking=Activer le suivi de temps par défaut
config.default_allow_only_contributors_to_track_time=Restreindre le suivi de temps aux contributeurs
-config.no_reply_address=Domaine pour les e-mails cachés
+config.no_reply_address=Domaine pour les courriels cachés
config.default_visibility_organization=Visibilité par défaut des nouvelles organisations
config.default_enable_dependencies=Activer les dépendances pour les tickets par défaut
-config.webhook_config=Configuration Webhook
+config.webhook_config=Configuration des déclencheurs
config.queue_length=Longueur de la file d'attente
-config.deliver_timeout=Expiration d'Envoi
+config.deliver_timeout=Expiration d'envoi
config.skip_tls_verify=Passer la vérification TLS
config.mailer_config=Configuration du service SMTP
@@ -3232,8 +3262,8 @@ config.oauth_config=Configuration OAuth
config.oauth_enabled=Activé
config.cache_config=Configuration du cache
-config.cache_adapter=Adaptateur du Cache
-config.cache_interval=Intervales du Cache
+config.cache_adapter=Adaptateur du cache
+config.cache_interval=Intervales du cache
config.cache_conn=Liaison du Cache
config.cache_item_ttl=Durée de vie des éléments dans le cache
@@ -3241,27 +3271,27 @@ config.session_config=Configuration de session
config.session_provider=Fournisseur de session
config.provider_config=Configuration du fournisseur
config.cookie_name=Nom du cookie
-config.gc_interval_time=Intervals GC
+config.gc_interval_time=Intervalles GC
config.session_life_time=Durée des sessions
config.https_only=HTTPS uniquement
config.cookie_life_time=Expiration du cookie
config.picture_config=Configuration de l'avatar
-config.picture_service=Service d'Imagerie
+config.picture_service=Service d'imagerie
config.disable_gravatar=Désactiver Gravatar
-config.enable_federated_avatar=Activer les avatars unifiés
+config.enable_federated_avatar=Activer les avatars fédérés
config.git_config=Configuration de Git
-config.git_disable_diff_highlight=Désactiver la surbrillance syntaxique de Diff
-config.git_max_diff_lines=Lignes de Diff Max (pour un seul fichier)
-config.git_max_diff_line_characters=Nombre max de caractères de Diff (pour une seule ligne)
-config.git_max_diff_files=Nombre max de fichiers de Diff (à afficher)
+config.git_disable_diff_highlight=Désactiver la surbrillance syntaxique de diff
+config.git_max_diff_lines=Lignes de diff Max (pour un seul fichier)
+config.git_max_diff_line_characters=Nombre max de caractères de diff (pour une seule ligne)
+config.git_max_diff_files=Nombre max de fichiers de diff (à afficher)
config.git_gc_args=Arguments de GC
config.git_migrate_timeout=Délai imparti pour une migration
config.git_mirror_timeout=Délai imparti pour mettre à jour le miroir
-config.git_clone_timeout=`Délai imparti pour l'opération "Clone"`
-config.git_pull_timeout=`Délai imparti pour l'opération "Pull"`
-config.git_gc_timeout=`Délai imparti pour l'opération "GC"`
+config.git_clone_timeout=Délai imparti pour l'opération "clone"
+config.git_pull_timeout=Délai imparti pour l'opération "Pull"
+config.git_gc_timeout=Délai imparti pour l'opération "GC"
config.log_config=Configuration du journal
config.logger_name_fmt=Logger: %s
@@ -3313,8 +3343,8 @@ monitor.queue.settings.changed=Paramètres mis à jour
monitor.queue.settings.remove_all_items=Tout effacer
monitor.queue.settings.remove_all_items_done=Tous les éléments de la file d'attente ont été effacés.
-notices.system_notice_list=Informations
-notices.view_detail_header=Voir les détails de l'information système
+notices.system_notice_list=Notifications systèmes
+notices.view_detail_header=Voir les détails de la notification
notices.operations=Opérations
notices.select_all=Tout Sélectionner
notices.deselect_all=Tout désélectionner
@@ -3422,11 +3452,11 @@ default_key=Signé avec la clé par défaut
error.extract_sign=Impossible d'extraire la signature
error.generate_hash=Impossible de générer la chaine de hachage de la révision
error.no_committer_account=Aucun compte lié à l'adresse e-mail de l'auteur
-error.no_gpg_keys_found=Signature inconnue de Forgejo
+error.no_gpg_keys_found=Aucune clé n'a été trouvée pour cette signature dans la base de données
error.not_signed_commit=Révision non signée
error.failed_retrieval_gpg_keys=Impossible de récupérer la clé liée au compte de l'auteur
-error.probable_bad_signature=AVERTISSEMENT ! Bien qu'il y ait une clé avec cet ID dans la base de données, il ne vérifie pas cette livraison ! Cette livraison est SUSPECTE.
-error.probable_bad_default_signature=AVERTISSEMENT ! Bien que la clé par défaut ait cet ID, elle ne vérifie pas cette livraison ! Cette livraison est SUSPECTE.
+error.probable_bad_signature=AVERTISSEMENT ! Bien qu'il y ait une clé avec cet ID dans la base de données, il ne vérifie pas ce commit ! Ce commit est SUSPECT.
+error.probable_bad_default_signature=AVERTISSEMENT ! Bien que la clé par défaut ait cet ID, elle ne vérifie pas ce commit ! Ce commit est SUSPECT.
[units]
unit=Unité
@@ -3552,7 +3582,7 @@ settings.delete.description=Supprimer un paquet est permanent et irréversible.
settings.delete.notice=Vous êtes sur le point de supprimer %s (%s). Cette opération est irréversible, êtes-vous sûr ?
settings.delete.success=Le paquet a été supprimé.
settings.delete.error=Impossible de supprimer le paquet.
-owner.settings.cargo.title=Index du Registre Cargo
+owner.settings.cargo.title=Index du registre cargo
owner.settings.cargo.initialize=Initialiser l'index
owner.settings.cargo.initialize.description=Un dépôt Git d’index spécial est nécessaire pour utiliser le registre Cargo. Utiliser cette option va (re)créer le dépôt et le configurer automatiquement.
owner.settings.cargo.initialize.error=Impossible d'initialiser l'index de Cargo : %v
@@ -3674,7 +3704,7 @@ runs.empty_commit_message=(message de révision vide)
workflow.disable=Désactiver le flux de travail
workflow.disable_success=Le flux de travail « %s » a bien été désactivé.
workflow.enable=Activer le flux de travail
-workflow.enable_success=Le flux de travail « %s » a bien été activé.
+workflow.enable_success=Le workflow « %s » a bien été activé.
workflow.disabled=Le flux de travail est désactivé.
need_approval_desc=Besoin d’approbation pour exécuter des flux de travail pour une demande d’ajout de bifurcation.
@@ -3697,6 +3727,7 @@ variables.update.success=La variable a bien été modifiée.
runs.no_workflows.quick_start = Vous ne savez pas comment commencer avec Forgejo Action ? Consultez le guide de démarrage rapide.
runs.no_workflows.documentation = Pour plus d’informations sur les Actions Forgejo, voir la documentation.
variables.id_not_exist = La variable numéro %d n’existe pas.
+runs.workflow = Workflow
[projects]
type-1.display_name=Projet personnel
@@ -3719,4 +3750,6 @@ component_loading_info = Cela peut prendre du temps…
component_failed_to_load = Une erreur inattendue s'est produite.
contributors.what = contributions
component_loading = Chargement %s...
-component_loading_failed = Échec de chargement de %s
\ No newline at end of file
+component_loading_failed = Échec de chargement de %s
+code_frequency.what = fŕequence de code
+recent_commits.what = commits récents
diff --git a/options/locale/locale_gl.ini b/options/locale/locale_gl.ini
index 3ccdfc2bbc..7c77357e3b 100644
--- a/options/locale/locale_gl.ini
+++ b/options/locale/locale_gl.ini
@@ -131,7 +131,7 @@ footer.software = Sobre o Software
footer.links = Ligazóns
[heatmap]
-no_contributions = Sen Achegas
+contributions_zero = Sen Achegas
less = Menos
more = Máis
number_of_contributions_in_the_last_12_months = %s de contribucións nos últimos 12 meses
@@ -140,4 +140,4 @@ number_of_contributions_in_the_last_12_months = %s de contribucións nos último
buttons.heading.tooltip = Engadir Título
buttons.italic.tooltip = Engade texto en cursiva
buttons.quote.tooltip = Texto de cita
-buttons.bold.tooltip = Engadir texto en negriña
\ No newline at end of file
+buttons.bold.tooltip = Engadir texto en negriña
diff --git a/options/locale/locale_hu-HU.ini b/options/locale/locale_hu-HU.ini
index 17f5310276..3764f6fa61 100644
--- a/options/locale/locale_hu-HU.ini
+++ b/options/locale/locale_hu-HU.ini
@@ -265,7 +265,7 @@ twofa_scratch_used=Ön már használta a kaparós kódját. Visszairányítottuk
twofa_passcode_incorrect=A kód hibás. Ha nem találja az eszközét, akkor használja a kaparós kódját a bejelentkezéshez.
twofa_scratch_token_incorrect=A kaparós kód nem megfelelő.
login_userpass=Bejelentkezés
-login_openid=OpenID
+tab_openid=OpenID
oauth_signup_tab=Új fiók létrehozása
oauth_signup_submit=Fiók befejezése
oauth_signin_tab=Csatlakoztatás egy már meglévő fiókhoz
@@ -933,8 +933,8 @@ pulls.filter_branch=Ágra szűrés
pulls.no_results=Nincs találat.
pulls.nothing_to_compare=Ezek az ágak egyenlőek. Nincs szükség egyesítési kérésre.
pulls.create=Egyesítési kérés létrehozása
-pulls.title_desc=egyesíteni szeretné %[1]d változás(oka)t a(z) %[2]s
-ból %[3]s
-ba
-pulls.merged_title_desc=egyesítve %[1]d változás(ok) a %[2]s
-ból %[3]s
-ba %[4]s
+pulls.title_desc_few=egyesíteni szeretné %[1]d változás(oka)t a(z) %[2]s
-ból %[3]s
-ba
+pulls.merged_title_desc_few=egyesítve %[1]d változás(ok) a %[2]s
-ból %[3]s
-ba %[4]s
pulls.tab_conversation=Beszélgetés
pulls.tab_commits=Commit-ok
pulls.tab_files=Módosított fájlok
diff --git a/options/locale/locale_id-ID.ini b/options/locale/locale_id-ID.ini
index 5c5632474a..574063bcaa 100644
--- a/options/locale/locale_id-ID.ini
+++ b/options/locale/locale_id-ID.ini
@@ -186,7 +186,7 @@ twofa_scratch_used=Anda telah menggunakan kode coretan anda. Anda telah dialihka
twofa_passcode_incorrect=Kata sandi Anda salah. Jika Anda salah tempatkan perangkat Anda, gunakan kode gosok Anda untuk masuk.
twofa_scratch_token_incorrect=Kode coretan anda tidak tepat.
login_userpass=Masuk
-login_openid=OpenID
+tab_openid=OpenID
oauth_signup_tab=Daftar Akun Baru
oauth_signup_submit=Akun Lengkap
oauth_signin_tab=Tautkan ke Akun yang Tersedia
@@ -752,8 +752,8 @@ pulls.compare_changes=Permintaan Tarik Baru
pulls.filter_branch=Penyaringan cabang
pulls.no_results=Hasil tidak ditemukan.
pulls.create=Buat Permintaan Tarik
-pulls.title_desc=ingin menggabungkan komit %[1]d dari %[2]s
menuju %[3]s
-pulls.merged_title_desc=commit %[1]d telah digabungkan dari %[2]s
menjadi %[3]s
%[4]s
+pulls.title_desc_few=ingin menggabungkan komit %[1]d dari %[2]s
menuju %[3]s
+pulls.merged_title_desc_few=commit %[1]d telah digabungkan dari %[2]s
menjadi %[3]s
%[4]s
pulls.tab_conversation=Percakapan
pulls.tab_commits=Melakukan
pulls.reopen_to_merge=Tolong buka kembali permintaan tarik ini untuk melaksanakan penggabungan.
diff --git a/options/locale/locale_is-IS.ini b/options/locale/locale_is-IS.ini
index fb39bfbf3d..27b9a4b17c 100644
--- a/options/locale/locale_is-IS.ini
+++ b/options/locale/locale_is-IS.ini
@@ -272,7 +272,7 @@ scratch_code=Skrapkóði
use_scratch_code=Nota skrapkóða
twofa_scratch_token_incorrect=Skrapkóði þinn er rangur.
login_userpass=Skrá Inn
-login_openid=OpenID
+tab_openid=OpenID
oauth_signup_tab=Skrá Nýjan Notanda
oauth_signup_title=Klára Nýjum Notanda
oauth_signup_submit=Klára Notanda
@@ -889,7 +889,7 @@ pulls.new=Ný Sameiningarbeiðni
pulls.view=Skoða Sameiningarbeiðni
pulls.compare_changes=Ný Sameiningarbeiðni
pulls.create=Skapa Sameiningarbeiðni
-pulls.title_desc=vill sameina %[1]d framlög frá %[2]s
í %[3]s
+pulls.title_desc_few=vill sameina %[1]d framlög frá %[2]s
í %[3]s
pulls.tab_conversation=Umræða
pulls.tab_commits=Framlög
pulls.tab_files=Skráum Breytt
diff --git a/options/locale/locale_it-IT.ini b/options/locale/locale_it-IT.ini
index 9a3979808a..2d41edf59d 100644
--- a/options/locale/locale_it-IT.ini
+++ b/options/locale/locale_it-IT.ini
@@ -51,14 +51,14 @@ webauthn_reload=Ricarica
repository=Repository
organization=Organizzazione
mirror=Mirror
-new_repo=Nuovo Repository
-new_migrate=Nuova Migrazione
-new_mirror=Nuovo Mirror
-new_fork=Nuovo Fork
+new_repo=Nuovo progetto
+new_migrate=Nuova migrazione
+new_mirror=Nuovo mirror
+new_fork=Nuovo fork
new_org=Nuova organizzazione
new_project=Nuovo progetto
manage_org=Gestisci le organizzazioni
-admin_panel=Amministrazione Sito
+admin_panel=Amministrazione sito
account_settings=Impostazioni dell'account
settings=Impostazioni
your_profile=Profilo
@@ -72,7 +72,7 @@ collaborative=Condivisi
forks=Fork
activities=Attivitá
-pull_requests=Pull Request
+pull_requests=Pull request
issues=Problemi
milestones=Milestones
@@ -141,8 +141,20 @@ show_full_screen = Mostra a schermo intero
download_logs = Scarica logs
confirm_delete_selected = Confermare l'eliminazione di tutti gli elementi selezionati?
sign_in_with_provider = Accedi con %s
-new_project_column = Nuova Colonna
+new_project_column = Nuova colonna
toggle_menu = Mostra/Nascondi Menu
+filter.not_fork = Non derivato
+filter = Filtro
+filter.clear = Azzera filtro
+filter.is_archived = Archiviato
+filter.not_archived = Non archiviato
+filter.is_fork = Derivato
+filter.is_mirror = Specchiato
+filter.not_mirror = Non specchiato
+filter.is_template = Modello base
+filter.not_template = Non modello base
+filter.public = Pubblico
+filter.private = Privato
[aria]
footer.links = Collegamenti
@@ -152,9 +164,12 @@ footer.software = A proposito del Software
[heatmap]
more = Più
-no_contributions = Nessun contributo
+contributions_zero = Nessun contributo
less = Meno
number_of_contributions_in_the_last_12_months = %s contributi negli ultimi 12 mesi
+contributions_format = {contributions} il {day} {month} {year}
+contributions_one = contribuzione
+contributions_few = contribuzioni
[editor]
buttons.heading.tooltip = Aggiungi intestazione
@@ -198,10 +213,10 @@ install_desc = Semplicemente la documentazione prima di cambiare qualsiasi impostazione.
require_db_desc=Forgejo requires MySQL, PostgreSQL, MSSQL, SQLite3 or TiDB (MySQL protocol).
-db_title=Impostazioni Database
+db_title=Impostazioni database
db_type=Tipo di database
host=Host
user=Nome utente
@@ -225,84 +240,84 @@ err_admin_name_is_reserved=Nome utente Administrator non valido, nome utente ris
err_admin_name_pattern_not_allowed=Nome utente dell'amministratore non valido. Il nome utente fornito corrisponde ad un pattern riservato
err_admin_name_is_invalid=Il nome utente Administrator non è valido
-general_title=Impostazioni Generali
-app_name=Titolo del Sito
+general_title=Impostazioni generali
+app_name=Titolo dell'istanza
app_name_helper=Qui puoi inserire il nome della tua società.
-repo_path=Percorso Root del Repository
+repo_path=Percorso radice del progetto
repo_path_helper=Le Remote Git repositories saranno salvate in questa directory.
-lfs_path=Percorso radice di Git LFS
+lfs_path=Percorso radice di git LFS
lfs_path_helper=I file trovati da Git LFS saranno salvati in questa directory. Lasciare vuoto per disattivare.
-run_user=Esegui come Nome utente
-domain=Dominio Server
+run_user=Nome utente col quale eseguire
+domain=Dominio server
domain_helper=Dominio o indirizzo host per il server.
-ssh_port=Porta Server SSH
-ssh_port_helper=Numero di porta in ascolto sul server SSH. Lasciare vuoto per disattivare.
-http_port=Porta in ascolto HTTP Forgejo
-http_port_helper=Numero della porta sul quale i server web Forgejo ascolteranno.
-app_url=URL di base di Forgejo
+ssh_port=Porta server SSH
+ssh_port_helper=Numero della porta che verrà usata dal server SSH, Lasciare vuoto per disattivare.
+http_port=Porta in ascolto HTTP
+http_port_helper=Numero della porta che sarà usata dal server web Forgejo.
+app_url=URL di base
app_url_helper=URL di base per gli HTTP(S) clone URLs e notifiche email.
log_root_path=Percorso dei log
log_root_path_helper=I file di log saranno scritti in questa directory.
-optional_title=Impostazioni Facoltative
-email_title=Impostazioni Email
+optional_title=Impostazioni facoltative
+email_title=Impostazioni e-mail
smtp_addr=Host SMTP
smtp_port=Porta SMTP
-smtp_from=Invia Email come
+smtp_from=Invia e-mail come
smtp_from_helper=Indirizzo Email che Forgejo utilizzerà. Inserisci un indirizzo email o usa il formato "Name" .
mailer_user=Nome utente SMTP
mailer_password=Password SMTP
-register_confirm=Richiedere la conferma Email per registrarsi
-mail_notify=Attiva le notifiche Email
-server_service_title=Impostazioni Server e Servizi di Terza Parte
-offline_mode=Attiva la Modalità in Locale
+register_confirm=Richiedere conferma e-mail per registrarsi
+mail_notify=Attiva le notifiche e-mail
+server_service_title=Impostazioni server e servizi di terze parti
+offline_mode=Attiva modalità in locale
offline_mode_popup=Disattiva le reti di distribuzione dei contenuti di terze parti e fornisci tutte le risorse localmente.
disable_gravatar=Disattiva Gravatar
disable_gravatar_popup=Disattiva Gravatar e le fonti di avatar di terze parti. Verrà usato un avatar predefinito almeno che un utente non carichi un avatar in locale.
-federated_avatar_lookup=Attiva i Federated Avatar
+federated_avatar_lookup=Attiva le immagini profilo federate
federated_avatar_lookup_popup=Enable federated avatars lookup to use federated open source service based on libravatar.
-disable_registration=Disattiva Self-Registration
+disable_registration=Disattiva auto-registrazione
disable_registration_popup=Disattiva la user self-registration. Solo gli amministratori saranno in grado di creare account.
allow_only_external_registration_popup=Attiva la registrazione solo tramite servizi esterni
-openid_signin=Attiva l'accesso OpenID
+openid_signin=Attiva l'accesso con OpenID
openid_signin_popup=Attiva registrazione utente via OpenID.
-openid_signup=Attiva OpenID Self-Registration
+openid_signup=Attiva auto-registrazione con OpenID
openid_signup_popup=Attiva OpenID-based user self-registration.
enable_captcha=Abilita CAPTCHA per registrazione
enable_captcha_popup=Richiedi convalida captcha per i nuovi utenti.
-require_sign_in_view=Richiedi l'accesso per visualizzare le pagine
+require_sign_in_view=Richiedi l'accesso per visualizzare il contenuto dell'istanza
admin_setting_desc=Creare un account amministratore è opzionale. Il primo utente registrato sarà automaticamente un amministratore.
-admin_title=Impostazioni Account Amministratore
-admin_name=Nome utente dell'Amministratore
+admin_title=Impostazioni profilo amministratorə
+admin_name=Nome utente dell'amministratorə
admin_password=Password
-confirm_password=Conferma Password
-admin_email=Indirizzo Email
+confirm_password=Conferma password
+admin_email=Indirizzo e-mail
install_btn_confirm=Installare Forgejo
test_git_failed=Non è stato possibile testare il comando "git": %v
sqlite3_not_available=Questa versione di Forgejo non supporta SQLite3. Si prega di scaricare la versione binaria ufficiale da %s (non la versione "gobuild").
invalid_db_setting=Le impostazioni del database sono invalide: %v
invalid_repo_path=Il percorso radice del Repository è invalido: %v
invalid_app_data_path=Il percorso dati dell'app non è valido: %v
-run_user_not_match=Il nome utente "Esegui come Nome Utente" non è il nome utente attuale: %s -> %s
+run_user_not_match=Il nome utente "utente con cui eseguire" non è il nome utente attuale: %s -> %s
internal_token_failed=Generazione del token interno non riuscita: %v
secret_key_failed=Generazione della chiave segreta non riuscita: %v
save_config_failed=Salvataggio della configurazione non riuscito: %v
invalid_admin_setting=Le impostazioni dell'account amministratore sono invalide: %v
invalid_log_root_path=Il percorso del log non è valido: %v
-default_keep_email_private=Nascondi Indirizzo Email di Default
+default_keep_email_private=Nascondi Indirizzo e-mail come impostazione predefinita
default_keep_email_private_popup=Nasconi l'indirizzo email dei nuovi account utente di default.
-default_allow_create_organization=Consenti la Creazione di Organizzazioni di Default
+default_allow_create_organization=Consenti la creazione di organizzazioni come impostazione predefinita
default_allow_create_organization_popup=Consenti ai nuovi account utente di creare organizzazioni di default.
-default_enable_timetracking=Attiva il cronografo di Default
+default_enable_timetracking=Attiva il cronografo come impostazione predefinita
default_enable_timetracking_popup=Attiva il cronografo per le nuove repositories di default.
-no_reply_address=Dominio email nascosto
+no_reply_address=Dominio e-mail nascosto
no_reply_address_helper=Nome di dominio per utenti con un indirizzo email nascosto. Ad esempio, il nome utente "joe" accederà a Git come "joe@noreply.example.org" se il dominio email nascosto è impostato a "noreply.example.org".
-password_algorithm=Algoritmo Password Hash
+password_algorithm=Algoritmo per hash delle password
smtp_from_invalid = L'indirizzo "Invia Email come" non è valido
-enable_update_checker_helper_forgejo = Verifica periodicamente nuove versioni di Forgejo controllando il record DNS TXT di release.forgejo.org.
+enable_update_checker_helper_forgejo = Verificherà periodicamente nuove versioni di Forgejo controllando il record DNS TXT di release.forgejo.org.
invalid_db_table = La tabella del database "%s" non è valida: %v
invalid_password_algorithm = Algoritmo di hash della password non valido
-enable_update_checker = Attiva il Controllo degli Aggiornamenti
+enable_update_checker = Attiva il controllo degli aggiornamenti
enable_update_checker_helper = Verifica periodicamente la presenza di nuove versioni tramite gitea.io.
env_config_keys = Configurazione Ambiente
env_config_keys_prompt = Le seguenti variabili di ambiente saranno anche applicate al tuo file di configurazione:
@@ -310,6 +325,7 @@ run_user_helper = Il nome utente del sistema operativo con il quale Forgejo vien
password_algorithm_helper = Imposta l'algoritmo di hashing della password. Gli algoritmi hanno requisiti e punti di forza diversi. L'algoritmo argon2 è relativamente sicuro ma usa un sacco di memoria e potrebbe non essere appropriato a piccoli sistemi.
require_sign_in_view_popup = Limita l'accesso ad utenti autenticati. I visitatori vedranno solo le pagine di accesso e registrazione.
allow_dots_in_usernames = Consenti l'uso del punto nel nome utente. Non impatta gli account già esistenti.
+config_location_hint = Queste opzioni di configurazione saranno salvate in:
[home]
uname_holder=Nome utente o indirizzo Email
@@ -318,7 +334,7 @@ switch_dashboard_context=Cambia Dashboard Context
my_repos=Repositories
show_more_repos=Mostra altre repositories…
collaborative_repos=Repository Condivisi
-my_orgs=Le mie Organizzazioni
+my_orgs=Organizzazioni
my_mirrors=I miei Mirror
view_home=Vedi %s
search_repos=Trova un repository…
@@ -359,6 +375,10 @@ code_search_results = Risultati di ricerca per "%s"
relevant_repositories_tooltip = Repository che sono fork o che non hanno un argomento, icona, né descrizione sono nascosti.
relevant_repositories = Solo le repository pertinenti sono visibili, mostra risultati non filtrati.
search.match.tooltip = Includi solo risultati che combaciano perfettamente con i termini di ricerca
+stars_few = %d stelle
+forks_one = %d fork
+forks_few = %d fork
+stars_one = %d stella
[auth]
create_new_account=Registra un account
@@ -377,7 +397,7 @@ allow_password_change=Richiede all'utente di cambiare la password (scelta consig
reset_password_mail_sent_prompt=Una email di conferma è stata inviata a %s. Per favore controlla la tua posta in arrivo nelle prossime %s per completare il processo di reset della password.
active_your_account=Attiva il tuo Account
account_activated=L'account è stato attivato
-prohibit_login=Accesso proibito
+prohibit_login=Accedere è proibito
resent_limit_prompt=Hai già richiesto un'e-mail d'attivazione recentemente. Si prega di attenere 3 minuti e poi riprovare.
has_unconfirmed_mail=Ciao %s, hai un indirizzo di posta elettronica non confermato (%s). Se non hai ricevuto una e-mail di conferma o vuoi riceverla nuovamente, fare clic sul pulsante qui sotto.
resend_mail=Clicca qui per inviare nuovamente l'e-mail di attivazione
@@ -395,7 +415,7 @@ twofa_scratch_used=Hai usato il tuo codice zero. Sei stato reindirizzato alla pa
twofa_passcode_incorrect=Il tuo passcode non è corretto. Se hai smarrito il tuo dispositivo, utilizza il tuo scratch code per accedere.
twofa_scratch_token_incorrect=I tuo codice scratch non è corretto.
login_userpass=Accedi
-login_openid=OpenID
+tab_openid=OpenID
oauth_signup_tab=Creare nuovo account
oauth_signup_title=Completa Nuovo Account
oauth_signup_submit=Completa l'Account
@@ -434,6 +454,8 @@ last_admin = Non puoi rimuovere l'ultimo amministratore. Deve esserci almeno un
prohibit_login_desc = Al tuo account non è consentito effettuare il login, contatta l'amministratore del sito.
openid_signin_desc = Inserisci il tuo URI OpenID. Per esempio: alice.openid.example.org o https://openid.example.org/alice.
password_pwned = La password che hai scelto è in un elenco di password rubate precedentemente esposte a violazioni di dati pubblici. Riprova con una password diversa e valuta di modificare questa password anche altrove.
+tab_signup = Registrati
+tab_signin = Accedi
[mail]
view_it_on=Visualizza su %s
@@ -486,16 +508,16 @@ release.downloads=Scaricamenti:
release.download.zip=Codice Sorgente (Zip)
release.download.targz=Codice Sorgente (Tar.Gz)
-repo.transfer.subject_to=%s vorrebbe trasferire "%s" a %s
-repo.transfer.subject_to_you=%s vorrebbe trasferire "%s" a te
+repo.transfer.subject_to=%s vorrebbe trasferire il progetto "%s" presso %s
+repo.transfer.subject_to_you=%s vorrebbe trasferire il progetto "%s" a te
repo.transfer.to_you=tu
repo.transfer.body=Per accettare o respingerla visita %s o semplicemente ignorarla.
-repo.collaborator.added.subject=%s ti ha aggiunto a %s
-repo.collaborator.added.text=Sei stato aggiunto come collaboratore del repository:
+repo.collaborator.added.subject=%s ti ha aggiunto a %s come collaboratorə
+repo.collaborator.added.text=Sei statə aggiuntə come collaboratorə al progetto:
reply = o rispondi direttamente a questa email
admin.new_user.subject = Il nuovo utente %s si è appena registrato
-admin.new_user.user_info = Informazioni Utente
+admin.new_user.user_info = Informazioni utente
team_invite.text_2 = Fai click sul seguente link per far parte del team:
team_invite.subject = %[1]s ti ha invitato a far parte dell'organizzazione %[2]s
activate_email.title = %s, verifica il tuo indirizzo email
@@ -516,7 +538,7 @@ UserName=Nome utente
RepoName=Nome Repository
Email=Indirizzo E-mail
Password=Password
-Retype=Conferma Password
+Retype=Conferma password
SSHTitle=Nome chiave SSH
HttpsUrl=URL HTTPS
PayloadUrl=URL Payload
@@ -603,6 +625,8 @@ must_use_public_key = La chiave che hai fornito è una chiave privata. Non caric
still_own_repo = Il tuo account è ancora proprietario di una o più repository, devi prima eliminarle o trasferirle.
duplicate_invite_to_team = L'utente è già stato invitato ad essere un membro del team.
still_has_org = Il tuo account è ancora membro di una o più organizzazioni, devi prima abbandonarle.
+unsupported_login_type = Il tipo di accesso non è supportato per cancellare il profilo.
+unset_password = L'utente non ha impostato la password.
[user]
@@ -610,8 +634,8 @@ change_avatar=Modifica il tuo avatar…
repositories=Repository
activity=Attività pubblica
followers=Seguaci
-starred=Repositories votate
-watched=Repository Osservate
+starred=Repository preferite
+watched=Repository osservate
projects=Progetti
overview=Riepilogo
following=Seguiti
@@ -620,7 +644,7 @@ unfollow=Non seguire più
user_bio=Biografia
disabled_public_activity=L'utente ha disabilitato la vista pubblica dell'attività.
joined_on = Membro dal %s
-block_user = Blocca Utente
+block_user = Blocca utente
block_user.detail_1 = Questo utente non ti seguirà più.
block_user.detail_2 = Questo utente non potrà interagire con le tue repository, con i problemi che hai creato o con i tuoi commenti.
block_user.detail_3 = Questo utente non ti potrà aggiungere come un collaboratore, né potrai tu aggiungerlo come un collaboratore.
@@ -630,7 +654,7 @@ unblock = Sblocca
email_visibility.limited = Il tuo indirizzo email è visibile a tutti gli utenti autenticati
email_visibility.private = Il tuo indirizzo email è visibile solo a te e agli amministratori
show_on_map = Mostra questo posto su una mappa
-settings = Impostazioni Utente
+settings = Impostazioni utente
form.name_reserved = Il nome utente "%s" è riservato.
form.name_chars_not_allowed = Il nome utente "%s" contiene caratteri non validi.
block_user.detail = Tieni presente che se blocchi questo utente, verranno eseguite altre azioni. Per esempio:
@@ -654,16 +678,16 @@ delete=Elimina account
twofa=Verifica in due passaggi
account_link=Account collegati
organization=Organizzazioni
-webauthn=Chiavi Di Sicurezza
+webauthn=Autenticazione a due passaggi (Chiavi di sicurezza)
public_profile=Profilo pubblico
password_username_disabled=Gli utenti non locali non hanno il permesso di cambiare il proprio nome utente. per maggiori dettagli si prega di contattare l'amministratore del sito.
-full_name=Nome Completo
+full_name=Nome completo
website=Sito web
location=Posizione
-update_theme=Aggiorna tema
-update_profile=Aggiorna Profilo
-update_language=Aggiorna Lingua
+update_theme=Cambia tema
+update_profile=Aggiorna profilo
+update_language=Cambia lingua
update_language_success=La lingua è stata aggiornata.
update_profile_success=Il tuo profilo è stato aggiornato.
change_username=Il tuo nome utente è stato modificato.
@@ -678,36 +702,36 @@ comment_type_group_milestone=Traguardo
comment_type_group_assignee=Assegnatario
comment_type_group_title=Titolo
comment_type_group_branch=Ramo
-comment_type_group_time_tracking=Cronografo
+comment_type_group_time_tracking=Tracciamento del tempo
comment_type_group_deadline=Scadenza
comment_type_group_dependency=Dipendenza
-comment_type_group_lock=Stato Blocco
+comment_type_group_lock=Stato blocco
comment_type_group_review_request=Richiesta di revisione
comment_type_group_pull_request_push=Aggiunti commit
comment_type_group_project=Progetto
comment_type_group_issue_ref=Riferimento del problema
saved_successfully=Le impostazioni sono state salvate correttamente.
privacy=Privacy
-keep_activity_private_popup=Rendi l'attività visibile solo da te e dagli amministratori
+keep_activity_private_popup=La tua attività sarà visibile solo a te e agli amministratori dell'istanza
-lookup_avatar_by_mail=Cerca Avatar per indirizzo Email
-federated_avatar_lookup=Ricerca per avatar federata
+lookup_avatar_by_mail=Cerca avatar per indirizzo email
+federated_avatar_lookup=Ricerca federata dell'avatar
enable_custom_avatar=Abilita avatar personalizzato
choose_new_avatar=Scegli un nuovo avatar
-update_avatar=Aggiorna Avatar
-delete_current_avatar=Elimina Avatar attuale
+update_avatar=Aggiorna avatar
+delete_current_avatar=Elimina avatar attuale
uploaded_avatar_not_a_image=Il file caricato non è un'immagine.
update_avatar_success=Il tuo avatar è stato aggiornato.
update_user_avatar_success=L'avatar dell'utente è stato aggiornato.
-update_password=Aggiorna Password
+update_password=Aggiorna password
old_password=Password attuale
new_password=Nuova password
password_incorrect=La password attuale non è corretta.
change_password_success=La password è stata aggiornata. Utilizza la nuova password la prossima volta che effettui il login.
password_change_disabled=Gli utenti non locali non possono cambiare la loro password attraverso l'interfaccia web.
-emails=Indirizzi e-mail
+emails=Indirizzi email
manage_emails=Gestisci indirizzi email
manage_themes=Seleziona il tema predefinito
manage_openid=Gestisci gli indirizzi OpenID
@@ -740,16 +764,16 @@ openid_desc=OpenID consente di delegare l'autenticazione ad un provider esterno.
manage_ssh_keys=Gestisci chiavi SSH
manage_ssh_principals=Gestisci i Certificati SSH
manage_gpg_keys=Gestisci chiavi GPG
-add_key=Aggiungi Chiave
+add_key=Aggiungi chiave
ssh_desc=Queste chiavi SSH pubbliche sono associate con il tuo account. Le corrispondenti chiavi private consentono l'accesso completo alle tue repositories. Le chiavi SSH che sono state verificate possono essere usate per verificare commit Git firmati tramite SSH.
principal_desc=Questi certificati SSH principali sono associati al tuo account e permettono l'accesso completo alle tue repository.
-gpg_desc=Queste chiavi GPG pubbliche sono associate con il tuo account. Proteggi le tue chiavi private perché permettono di verificare i commits.
+gpg_desc=Queste chiavi GPG pubbliche sono associate con il tuo account e sono usate per verificare i tuoi commit. Proteggi le tue chiavi private perché permettono di firmare i commit con la tue identità.
ssh_helper= Hai bisogno di aiuto? Dai un'occhiata alla guida di GitHub percrea le tue chiavi SSH o risolvere problemi comuni che potresti trovare utilizzando SSH.
gpg_helper=Hai bisogno di aiuto? Dai un'occhiata alla guida di GitHub riguardo il GPG.
-add_new_key=Aggiungi Chiave SSH
-add_new_gpg_key=Aggiungi Chiave GPG
-key_content_ssh_placeholder=Inizia con 'ssh-ed25519', 'ssh-rsa', 'ecdsa-sha2-nistp256', 'ecdsa-sha2-nistp384', 'ecdsa-sha2-nistp521', 'sk-ecdsa-sha2-nistp256@openssh.com', o 'sk-ssh-ed25519@openssh.com'
-key_content_gpg_placeholder=Comincia con '-----BEGIN PGP PUBLIC KEY BLOCK-----'
+add_new_key=Aggiungi chiave SSH
+add_new_gpg_key=Aggiungi chiave GPG
+key_content_ssh_placeholder=Inizia con "ssh-ed25519", "ssh-rsa", "ecdsa-sha2-nistp256", "ecdsa-sha2-nistp384", "ecdsa-sha2-nistp521", "sk-ecdsa-sha2-nistp256@openssh.com", o "sk-ssh-ed25519@openssh.com"
+key_content_gpg_placeholder=Inizia con "-----BEGIN PGP PUBLIC KEY BLOCK-----"
add_new_principal=Aggiungi Principal
ssh_key_been_used=Questa chiave SSH è già stata aggiunta al server.
ssh_key_name_used=Una chiave SSH con lo stesso nome esiste già sul tuo account.
@@ -758,7 +782,7 @@ gpg_key_id_used=Esiste già una chiave GPG pubblica con lo stesso ID.
gpg_no_key_email_found=Questa chiave GPG non corrisponde a nessun indirizzo email attivato associato al tuo account. Potrebbe essere ancora aggiunto se firmi il token fornito.
gpg_key_matched_identities=Identità Corrispondenti:
gpg_key_matched_identities_long=Le identità incorporate in questa chiave corrispondono ai seguenti indirizzi email attivati per questo utente. I commit che corrispondono a questi indirizzi email possono essere verificati con questa chiave.
-gpg_key_verified=Chiave Verificata
+gpg_key_verified=Chiave verificata
gpg_key_verified_long=La chiave è stata verificata con un token e può essere utilizzata per verificare che i commit corrispondano a tutti gli indirizzi email attivati per questo utente oltre a qualsiasi identità corrispondente per questa chiave.
gpg_key_verify=Verifica
gpg_invalid_token_signature=La chiave GPG fornita, la firma e il token non corrispondono o il token è obsoleto.
@@ -767,8 +791,8 @@ gpg_token=Token
gpg_token_help=È possibile generare una firma utilizzando:
gpg_token_code=echo "%s" | gpg -a --default-key %s --detach-sig
gpg_token_signature=Firma GPG corazzata
-key_signature_gpg_placeholder=Comincia con '-----BEGIN PGP SIGNATURE-----'
-ssh_key_verified=Chiave Verificata
+key_signature_gpg_placeholder=Inizia con "-----BEGIN PGP SIGNATURE-----"
+ssh_key_verified=Chiave verificata
ssh_key_verified_long=La chiave è stata verificata con un token e può essere utilizzata per verificare che i commit corrispondano a tutti gli indirizzi email attivati per questo utente.
ssh_key_verify=Verifica
ssh_invalid_token_signature=La chiave SSH fornita, la firma o il token non corrispondono o il token è obsoleto.
@@ -776,10 +800,10 @@ ssh_token_required=Devi fornire una firma per il token sottostante
ssh_token=Token
ssh_token_help=È possibile generare una firma utilizzando:
ssh_token_signature=Firma SSH corazzata
-key_signature_ssh_placeholder=Comincia con '-----BEGIN SSH SIGNATURE-----'
+key_signature_ssh_placeholder=Inizia con "-----BEGIN SSH SIGNATURE-----"
subkeys=Sottochiavi
key_id=ID chiave
-key_name=Nome della Chiave
+key_name=Nome della chiave
key_content=Contenuto
principal_content=Contenuto
delete_key=Rimuovi
@@ -807,11 +831,11 @@ ssh_externally_managed=Questa chiave SSH è gestita esternamente per questo uten
manage_social=Gestisci gli Account Sociali Associati
unbind=Rimuovi il collegamento
-manage_access_token=Gestisci i tokens di accesso
-generate_new_token=Genera Nuovo Token
+manage_access_token=Gestisci i token di accesso
+generate_new_token=Genera nuovo token
tokens_desc=Questi tokens garantiscono l'accesso al tuo account utilizzando l'API di Forgejo.
-token_name=Nome Token
-generate_token=Genera Token
+token_name=Nome token
+generate_token=Genera token
generate_token_success=Il nuovo token è stato generato. Copia ora in quanto non verrà mostrato nuovamente.
generate_token_name_duplicate=%s è già stato utilizzato come nome dell'applicazione. Si prega di usarne uno nuovo.
delete_token=Elimina
@@ -849,7 +873,7 @@ twofa_desc=L'autenticazione a due fattori migliora la sicurezza del tuo account.
twofa_is_enrolled=La verifica in due passaggi è attualmente abilitata sul tuo account.
twofa_not_enrolled=La verifica in due passaggi al momento non è abilitata sul tuo account.
twofa_disable=Disattiva la verifica in due passaggi
-twofa_scratch_token_regenerate=Rigenera il token di sicurezza
+twofa_scratch_token_regenerate=Rigenera la chiave di recupero monouso
twofa_enroll=Iscriviti alla verifica in due passaggi
twofa_disable_note=Se necessario, è possibile disattivare la verifica in due passaggi.
twofa_disable_desc=Disattivare la verifica in due passaggi renderà il tuo account meno sicuro. Continuare?
@@ -863,9 +887,9 @@ twofa_enrolled=Il tuo account è stato registrato alla verifica in due passaggi.
twofa_failed_get_secret=Impossibile ottenere il segreto.
webauthn_desc=Le chiavi di sicurezza sono dispositivi hardware contenenti chiavi crittografiche. Possono essere utilizzate per l'autenticazione a due fattori. Le chiavi di sicurezza devono supportare lo standard WebAuthenticator di WebAuthn.
-webauthn_register_key=Aggiungi Chiave Di Sicurezza
+webauthn_register_key=Aggiungi chiave di sicurezza
webauthn_nickname=Soprannome
-webauthn_delete_key=Rimuovi Chiave Di Sicurezza
+webauthn_delete_key=Rimuovi chiave di sicurezza
webauthn_delete_key_desc=Se si rimuove una chiave di sicurezza non è più possibile accedere con esso. Continuare?
manage_account_links=Gestisci gli account collegati
@@ -879,18 +903,18 @@ remove_account_link_success=L'account collegato è stato rimosso.
orgs_none=Non sei membro di alcuna organizzazione.
-delete_account=Elimina Account
+delete_account=Elimina account
delete_prompt=Questa operazione eliminerà permanentemente il tuo account utente. NON PUÒ essere annullata.
delete_with_all_comments=Il tuo account è più recente di %s giorni. Per evitare commenti fantasma, tutti i commenti relativi a issue/PR verranno eliminati con esso.
-confirm_delete_account=Conferma Eliminazione
+confirm_delete_account=Conferma eliminazione
delete_account_title=Elimina account utente
delete_account_desc=Sei sicuro di voler rimuovere questo account utente permanentemente?
-email_notifications.enable=Abilita Notifiche Email
-email_notifications.onmention=Solo email su Menzione
+email_notifications.enable=Abilita notifiche email
+email_notifications.onmention=Solo email su menzione
email_notifications.disable=Disabilita notifiche email
-email_notifications.submit=Imposta Preferenze Email
-email_notifications.andyourown=E Le Tue Notifiche
+email_notifications.submit=Imposta preferenze email
+email_notifications.andyourown=E le tue notifiche
visibility=Visibilità utente
visibility.public=Pubblico
@@ -902,10 +926,10 @@ biography_placeholder = Parlaci un po' di te! (Puoi usare Markdown)
location_placeholder = Condividi la tua posizione approssimativa con gli altri
update_language_not_found = Il linguaggio "%s" non è disponibile.
change_username_prompt = Nota: Il cambiamento del tuo nome utente cambierà anche l'URL del tuo account.
-keep_activity_private = Nascondi Attività dalla pagina del profilo
+keep_activity_private = Nascondi attività dalla pagina del profilo
retype_new_password = Conferma nuova password
can_not_add_email_activations_pending = C'è una verifica attualmente in corso, riprova tra qualche minuto se vuoi aggiungere una nuova email.
-blocked_users = Utenti Bloccati
+blocked_users = Utenti bloccati
change_password = Modifica password
uploaded_avatar_is_too_big = La dimensione del file caricato (%d KiB) supera il limite massimo (%d KiB).
uid = UID
@@ -914,11 +938,52 @@ permissions_public_only = Solo pubblico
profile_desc = Controlla come il tuo profilo viene mostrato agli altri utenti. Il tuo indirizzo email principale sarà usato per inviarti notifiche, ripristino di password e per le operazioni Git effettuate da web.
email_desc = Il tuo indirizzo email principale sarà usato per inviarti notifiche, ripristino di password e, se non è stato nascosto, per le operazioni Git effettuate da web.
add_email_confirmation_sent = Una email di conferma è stata inviata a "%s". Verifica la posta in arrivo entro %s per confermare il tuo indirizzo email.
+hidden_comment_types_description = I tipi di commenti spuntati qui non saranno mostrati nelle pagine delle segnalazioni. Per esempio, spuntare "Etichetta" rimuove tutti i commenti " ha aggiunto/rimosso ".
+unbind_success = Il profilo social è stato rimosso con successo.
+hidden_comment_types.ref_tooltip = Commenti in cui questa issue è stata citata da un altra issue/commit/…
+verify_ssh_key_success = La chiave SSH "%s" è stata verificata.
+valid_until_date = Valido fino a %s
+ssh_signonly = SSH è attualmente disabilitato quindi queste chiavi sono usate solo per la firma di verifica dei commit.
+social_desc = Questi account social possono essere usati per accedere al tuo account. Assicurati di riconoscerli tutti.
+permission_write = Leggi e scrivi
+access_token_desc = I permessi token selezionati limitano l'autorizzazione solo alle corrispondenti vie API. Leggi la documentazione per ulteriori informazioni.
+create_oauth2_application_success = Hai correttamente creato una nuova applicazione OAuth2.
+update_oauth2_application_success = Hai correttamente aggiornato l'applicazione OAuth2.
+oauth2_redirect_uris = URI per la reindirizzazione. Usa una nuova riga per ogni URI.
+authorized_oauth2_applications_description = Hai consentito l'accesso al tuo account personale Forgejo a queste applicazioni di terze parti. Per favore, revoca l'accesso alle applicazioni che non sono più in uso.
+revoke_oauth2_grant_success = Accesso revocato correttamente.
+twofa_recovery_tip = Se perdi il tuo dispositivo potrai usare una chiave di recupero monouso per riottenere l'accesso al tuo account.
+twofa_scratch_token_regenerated = La tua chiave di recupero monouso è ora %s. Conservala in un posto sicuro dato che non verrà mostrata nuovamente.
+webauthn_key_loss_warning = Se perdi la tua chiave di sicurezza perderai accesso al tuo account.
+webauthn_alternative_tip = Potresti voler configurare un metodo di autenticazione aggiuntivo.
+visibility.public_tooltip = Visibile a tutti
+visibility.limited_tooltip = Visibile solo agli utenti autenticati
+visibility.private_tooltip = Visibile solo a membri di organizzazioni di cui fai parte
+blocked_since = Bloccato da %s
+user_unblock_success = L'utente è stato bloccato correttamente.
+user_block_success = L'utente è stato bloccato correttamente.
+at_least_one_permission = Devi selezionare almeno un permesso per creare un token
+oauth2_confidential_client = Client confidenziale. Seleziona per applicazioni che tengono il segreto confidenziale, come le applicazioni web. Non selezionare per applicazioni native incluse quelle desktop e mobile.
+hidden_comment_types.issue_ref_tooltip = Commenti in cui l'utente ha cambiato la branch/tag associata con l'issue
+add_key_success = La chiave SSH "%s" è stata aggiunta.
+add_gpg_key_success = La chiave GPG "%s" è stata aggiunta.
+add_principal_success = Il certificato principale SSH "%s" è stato aggiunto.
+repo_and_org_access = Accesso al progetto e all'organizzazione
+permissions_access_all = Tutto (publico, privato e limitato)
+oauth2_client_secret_hint = Il segreto non verrà mostrato nuovamente dopo che lasci o ricarichi questa pagina. Assicurati di averlo salvato.
+oauth2_application_remove_description = Rimuovere un applicazione OAuth2 gli impedirà di accedere ad account utenti autorizzati su questa istanza. Continuare?
+oauth2_application_locked = Forgejo preregistra alcune applicazioni OAuth2 all'avvio, se abilitato nella configurazione. Per prevenire comportamenti imprevisti, queste non possono essere né modificate né rimosse. Fai riferimento alla documentazione di OAuth2 per ulteriori informazioni.
+hooks.desc = Aggiungi richiami HTTP che saranno innescati per tutti i progetti che possiedi.
+repos_none = Non possiedi alcun progetto.
+blocked_users_none = Non ci sono utenti bloccati.
+keep_email_private_popup = Questo nasconderà il tuo indirizzo email nel tuo profilo, nelle pull request e quando modifichi un file usando l'interfaccia web. I commit inoltrati non saranno modificati. Usa %s nei commit per associarli al tuo account.
+verify_gpg_key_success = La chiave GPG "%s" è stata verificata.
+added_on = Aggiunto su %s
[repo]
owner=Proprietario
owner_helper=Alcune organizzazioni potrebbero non essere visualizzate nel menu a discesa a causa di un limite massimo al numero di repository.
-repo_name=Nome Repository
+repo_name=Nome progetto
repo_name_helper=Un buon nome per un repository è costituito da parole chiave corte, facili da ricordare e uniche.
repo_size=Dimensione repository
template=Modello
@@ -928,10 +993,10 @@ template_description=I modelli di repository consentono agli utenti di generare
visibility=Visibilità
visibility_description=Solo il proprietario o i membri dell'organizzazione se hanno diritti, saranno in grado di vederlo.
visibility_helper_forced=L'amministratore del sito impone che le nuove repository siano private.
-visibility_fork_helper=(Questa modifica avrà effetto su tutti i fork)
+visibility_fork_helper=(Questa modifica influenzerà la visibilità di tutti i fork.)
clone_helper=Hai bisogno di aiuto per la clonazione? Visita Help.
-fork_repo=Forka Repository
-fork_from=Forka da
+fork_repo=Deriva progetto
+fork_from=Deriva da
already_forked=Hai già fatto il fork di %s
fork_to_different_account=Fai Fork a un account diverso
fork_visibility_helper=La visibilità di un repository forkato non può essere modificata.
@@ -940,14 +1005,14 @@ clone_in_vsc=Clona nel codice VS
download_zip=Scarica ZIP
download_tar=Scarica TAR.GZ
download_bundle=Scarica BUNDLE
-generate_repo=Genera repository
+generate_repo=Genera progetto
generate_from=Genera da
repo_desc=Descrizione
repo_desc_helper=Inserisci una breve descrizione (opzionale)
repo_lang=Lingua
repo_gitignore_helper=Seleziona i template di .gitignore.
repo_gitignore_helper_desc=Scegli di quali file non tenere traccia da un elenco di modelli per le lingue comuni. Gli artefatti tipici generati dagli strumenti di build di ogni lingua sono inclusi su .gitignore per impostazione predefinita.
-issue_labels=Etichette Issue
+issue_labels=Etichette segnalazioni
issue_labels_helper=Seleziona un set di etichette per problemi.
license=Licenza
license_helper=Seleziona un file di licenza.
@@ -955,18 +1020,18 @@ license_helper_desc=Una licenza governa ciò che gli altri possono e non possono
readme=LEGGIMI
readme_helper=Seleziona un template per il file LEGGIMI.
readme_helper_desc=Qui puoi scrivere una descrizione completa del progetto.
-auto_init=Inizializza Repository (Aggiungi .gitignore, Licenza e LEGGIMI)
+auto_init=Inizializza progetto (Aggiunge .gitignore, Licenza e LEGGIMI)
trust_model_helper=Seleziona il modello di fiducia per la verifica della firma. Le opzioni possibili sono:
trust_model_helper_collaborator=Collaboratore: Fidati delle firme da parte dei collaboratori
trust_model_helper_committer=Committer: Fidati delle Firme che corrispondono ai committenti
trust_model_helper_collaborator_committer=Collaboratore+Committer: Fidati delle firme da parte dei collaboratori che corrispondono al committer
trust_model_helper_default=Predefinito: utilizzare il modello di trust predefinito per questa installazione
-create_repo=Crea Repository
-default_branch=Ramo (Branch) predefinito
+create_repo=Crea progetto
+default_branch=Ramo predefinito
default_branch_helper=Il ramo predefinito è il ramo base per le richieste di pull e i commit di codice.
mirror_prune=Rimuovi
mirror_prune_desc=Rimuovi i riferimenti di puntamento-remoto obsoleti
-mirror_interval=Intervallo di specchio (le unità di tempo valide sono 'h', 'm', 's'). 0 per disabilitare la sincronizzazione periodica. (Intervallo minimo: %s)
+mirror_interval=Intervallo di specchio (le unità di tempo valide sono "h", "m", "s"). 0 per disabilitare la sincronizzazione periodica. (Intervallo minimo: %s)
mirror_interval_invalid=L'intervallo di aggiornamento dei mirror non è valido.
mirror_sync_on_commit=Sincronizzazione quando i commit vengono premuti
mirror_address=Clona da URL
@@ -986,7 +1051,7 @@ reactions_more=e %d più
unit_disabled=L'amministratore ha disabilitato questa sezione del repository.
language_other=Altro
adopt_search=Inserisci il nome utente per cercare i repository non adottati... (lascia vuoto per trovare tutti)
-adopt_preexisting_label=Adotta File
+adopt_preexisting_label=Adotta file
adopt_preexisting=Adottare file preesistenti
adopt_preexisting_content=Crea repository da %s
adopt_preexisting_success=File adottati e repository creati da %s
@@ -1009,13 +1074,13 @@ desc.internal=Interno
desc.archived=Archiviato
template.items=Elementi del modello
-template.git_content=Contenuto di Git (Ramo predefinito)
+template.git_content=Contenuto di git (Ramo predefinito)
template.git_hooks=Git Hooks
-template.git_hooks_tooltip=Al momento non sei in grado di modificare o rimuovere Git Hooks una volta aggiunto. Selezionare questa opzione solo se ti fidi del template repository.
+template.git_hooks_tooltip=Al momento non sei in grado di modificare o rimuovere Git hook una volta aggiunti. Selezionare questa opzione solo se ti fidi del progetto modello.
template.webhooks=Webhooks
template.topics=Argomenti
template.avatar=Avatar
-template.issue_labels=Etichette Issue
+template.issue_labels=Etichette segnalazioni
template.one_item=Deve selezionare almeno un elemento del modello
template.invalid=Devi selezionare un modello di repository
@@ -1038,26 +1103,26 @@ migrate_items_wiki=Wiki
migrate_items_milestones=Milestone
migrate_items_labels=Etichette
migrate_items_issues=Issues
-migrate_items_pullrequests=Pull request
-migrate_items_merge_requests=Richieste di Merge
+migrate_items_pullrequests=Richieste di modifica
+migrate_items_merge_requests=Richieste di fusione
migrate_items_releases=Rilasci
-migrate_repo=Migra Repository
+migrate_repo=Migra progetto
migrate.clone_address=Migra / Clona da URL
-migrate.clone_address_desc=URL HTTP (S) o Git 'clone' di un repository esistente
+migrate.clone_address_desc=URL HTTP(S) o Git "clone" di un progetto esistente
migrate.github_token_desc=È possibile mettere uno o più token con virgola separati qui per rendere la migrazione più veloce a causa del limite di velocità API GitHub. ATTENZIONE: L'abuso di questa funzione potrebbe violare la politica del fornitore di servizi e portare al blocco dell'account.
migrate.clone_local_path=o un percorso del server locale
migrate.permission_denied=Non è consentito importare repository locali.
migrate.permission_denied_blocked=Non è possibile importare da host non consentiti, si prega di chiedere all'amministratore di controllare ALLOWED_DOMAINS/ALLOW_LOCALNETWORKS/BLOCKED_DOMAINS impostazioni.
migrate.invalid_lfs_endpoint=Il punto d'accesso LFS non è valido.
migrate.failed=Migrazione non riuscita: %v
-migrate.migrate_items_options=Il Token di accesso è richiesto per migrare elementi aggiuntivi
+migrate.migrate_items_options=Il token di accesso è richiesto per migrare elementi aggiuntivi
migrated_from=Migrato da %[2]s
migrated_from_fake=Migrato da %[1]s
migrate.migrate=Migra da %s
migrate.migrating=Migrazione da %s...
migrate.migrating_failed=Migrazione da %s fallita.
migrate.migrating_failed_no_addr=Migrazione non riuscita.
-migrate.github.description=Migrare i dati da github.com o da altre istanze di GitHub.
+migrate.github.description=Migrare i dati da github.com o da server GitHub Enterprise.
migrate.git.description=Migra un repository solo da qualsiasi servizio Git.
migrate.gitlab.description=Migrare i dati da gitlab.com o da altre istanze di GitLab.
migrate.gitea.description=Migrare i dati da gitea.com o altre istanze di Gitea/Forgejo.
@@ -1065,13 +1130,13 @@ migrate.gogs.description=Migrare i dati da notabug.org o da altre istanze Gogs.
migrate.onedev.description=Migrare i dati da code.onedev.io o da altre istanze OneDev.
migrate.codebase.description=Migrare i dati da codebasehq.com.
migrate.gitbucket.description=Migra i dati dalle istanze di GitBucket.
-migrate.migrating_git=Migrazione dei Dati Git
-migrate.migrating_topics=Migrazione dei topic
-migrate.migrating_milestones=Migrazione dei traguardi
+migrate.migrating_git=Migrazione dei dati Git
+migrate.migrating_topics=Migrazione degli argomenti
+migrate.migrating_milestones=Migrazione delle pietre miliari
migrate.migrating_labels=Migrazione delle etichette
-migrate.migrating_releases=Migrazione delle uscite
-migrate.migrating_issues=Migrazione dei problemi
-migrate.migrating_pulls=Migrazione delle Pull Request
+migrate.migrating_releases=Migrazione dei rilasci
+migrate.migrating_issues=Migrazione delle segnalazioni
+migrate.migrating_pulls=Migrazione delle richieste di modifica
mirror_from=mirror da
forked_from=forkato da
@@ -1085,7 +1150,7 @@ watch=Segui
unstar=Togli il voto
star=Vota
fork=Forka
-download_archive=Scarica Repository
+download_archive=Scarica progetto
no_desc=Nessuna descrizione
quick_guide=Guida rapida
@@ -1105,7 +1170,7 @@ find_tag=Trova etichetta
branches=Rami (Branch)
tags=Tag
issues=Problemi
-pulls=Pull Requests
+pulls=Richieste di modifica
project_board=Progetti
packages=Pacchetti
labels=Etichette
@@ -1133,15 +1198,15 @@ ambiguous_character=`%[1]c [U+%04[1]X] è confondibile con %[2]c [U+%04[2]X]`
escape_control_characters=Fuga
unescape_control_characters=Unescape
-file_copy_permalink=Copia Permalink
-view_git_blame=Visualizza Git Blame
-video_not_supported_in_browser=Il tuo browser non supporta i tag "video" di HTML5.
-audio_not_supported_in_browser=Il tuo browser non supporta il tag "video" di HTML5.
+file_copy_permalink=Copia collegamento permanente
+view_git_blame=Visualizza git incolpa
+video_not_supported_in_browser=Il tuo browser non supporta le etichette "video" di HTML5.
+audio_not_supported_in_browser=Il tuo browser non supporta le etichette "audio" di HTML5.
stored_lfs=Memorizzati con Git LFS
symbolic_link=Link Simbolico
commit_graph=Grafico dei commit
commit_graph.select=Seleziona rami
-commit_graph.hide_pr_refs=Nascondi Pull Requests
+commit_graph.hide_pr_refs=Nascondi richieste di modifica
commit_graph.monochrome=Mono
commit_graph.color=Colore
blame=Blame
@@ -1152,8 +1217,8 @@ lines=righe
editor.add_file=Aggiungi file
editor.new_file=Nuovo file
-editor.upload_file=Carica File
-editor.edit_file=Modifica File
+editor.upload_file=Carica file
+editor.edit_file=Modifica file
editor.preview_changes=Anteprima modifiche
editor.cannot_edit_lfs_files=I file LFS non possono essere modificati nell'interfaccia web.
editor.cannot_edit_non_text_files=I file binari non possono essere modificati tramite interfaccia web.
@@ -1169,7 +1234,7 @@ editor.or=o
editor.cancel_lower=Annulla
editor.commit_signed_changes=Conferma modifiche firmate
editor.commit_changes=Apporta le modifiche
-editor.add_tmpl=Aggiungi ''
+editor.add_tmpl=Aggiungi ""
editor.patch=Applica Patch
editor.patching=Patching:
editor.new_patch=Nuova Patch
@@ -1187,8 +1252,8 @@ editor.commit_empty_file_header=Commit di un file vuoto
editor.commit_empty_file_text=Il file che stai per effettuare il commit è vuoto. Procedere?
editor.no_changes_to_show=Non ci sono cambiamenti da mostrare.
editor.fail_to_update_file_summary=Messaggio d'errore:
-editor.push_rejected_no_message=La modifica è stata rifiutata dal server senza un messaggio. Controlla Git Hooks.
-editor.push_rejected=La modifica è stata rifiutata dal server. Controlla Git Hooks.
+editor.push_rejected_no_message=La modifica è stata rifiutata dal server senza un messaggio. Controlla Git hooks.
+editor.push_rejected=La modifica è stata rifiutata dal server. Controlla Git hooks.
editor.push_rejected_summary=Messaggio Di Rifiuto Completo:
editor.add_subdir=Aggiungi una directory…
editor.no_commit_to_branch=Impossibile effettuare il commit direttamente sul branch perché:
@@ -1211,8 +1276,8 @@ commits.newer=Più recente
commits.signed_by=Firmato da
commits.signed_by_untrusted_user=Firmato da un utente non attendibile
commits.signed_by_untrusted_user_unmatched=Firmato da un utente non attendibile che non corrisponde al committer
-commits.gpg_key_id=ID Chiave GPG
-commits.ssh_key_fingerprint=Impronta Digitale Chiave SSH
+commits.gpg_key_id=ID chiave GPG
+commits.ssh_key_fingerprint=Impronta chiave SSH
commit.revert=Ripristina
commit.revert-header=Ripristina: %s
@@ -1224,14 +1289,14 @@ commit.cherry-pick-content=Seleziona il ramo su cui scegliere:
commitstatus.error=Errore
commitstatus.pending=In sospeso
-ext_issues=Accesso ai Problemi Esterni
+ext_issues=Accesso a segnalazioni esterne
ext_issues.desc=Collegamento al puntatore di una issue esterna.
projects=Progetti
projects.desc=Gestisci problemi e pull nelle schede di progetto.
projects.description=Descrizione (opzionale)
projects.description_placeholder=Descrizione
-projects.create=Crea un progetto
+projects.create=Crea progetto
projects.title=Titolo
projects.new=Nuovo progetto
projects.new_subheader=Coordina, traccia e aggiorna il tuo lavoro in un unico posto, quindi i progetti rimangono trasparenti e in programma.
@@ -1242,9 +1307,9 @@ projects.edit=Modifica progetto
projects.edit_subheader=I progetti organizzano i problemi e monitorano i progressi.
projects.modify=Aggiorna progetto
projects.type.none=Nessuno
-projects.type.basic_kanban=Basic Kanban
+projects.type.basic_kanban=Kanban semplice
projects.type.bug_triage=Bug Triage
-projects.template.desc=Template di progetto
+projects.template.desc=Modello
projects.template.desc_helper=Seleziona un modello di progetto per iniziare
projects.type.uncategorized=Senza categoria
projects.column.edit_title=Nome
@@ -1259,7 +1324,7 @@ issues.filter_milestones=Filtra traguardo
issues.filter_projects=Filtra Progetti
issues.filter_labels=Filtra etichetta
issues.filter_reviewers=Filtra revisore
-issues.new=Nuovo Problema
+issues.new=Nuova segnalazione
issues.new.title_empty=L'intestazione non può essere vuota
issues.new.labels=Etichette
issues.new.no_label=Nessuna etichetta
@@ -1267,32 +1332,32 @@ issues.new.clear_labels=Pulisci le etichette
issues.new.projects=Progetti
issues.new.clear_projects=Cancella progetti
issues.new.no_projects=Nessun progetto
-issues.new.open_projects=Apri Progetti
+issues.new.open_projects=Apri progetti
issues.new.closed_projects=Progetti chiusi
issues.new.no_items=Nessun elemento
issues.new.milestone=Traguardo
-issues.new.no_milestone=Nessuna milestone
+issues.new.no_milestone=Nessuna pietra miliare
issues.new.clear_milestone=Milestone pulita
-issues.new.open_milestone=Apri Milestone
-issues.new.closed_milestone=Milestone chiuse
+issues.new.open_milestone=Apri pietra miliare
+issues.new.closed_milestone=Pietre miliari chiuse
issues.new.assignees=Assegnatari
issues.new.clear_assignees=Cancella assegnatari
-issues.new.no_assignees=Nessuna assegnatario
+issues.new.no_assignees=Nessun assegnatario
issues.new.no_reviewers=Nessun revisore
issues.choose.get_started=Inizia
issues.choose.open_external_link=Apri
issues.choose.blank=Default
issues.choose.blank_about=Crea un problema dal modello predefinito.
-issues.no_ref=Nessun Branch/Tag specificato
-issues.create=Crea Problema
+issues.no_ref=Nessun ramo/etichetta specificato
+issues.create=Crea segnalazione
issues.new_label=Nuova etichetta
issues.new_label_placeholder=Nome etichetta
issues.new_label_desc_placeholder=Descrizione
-issues.create_label=Crea Etichetta
-issues.label_templates.title=Carica un set predefinito di etichette
-issues.label_templates.info=Non esistono etichette. Crea una etichetta con 'Nuova Etichetta' o usa un set predefinito di etichette:
-issues.label_templates.helper=Scegli un set di etichette
-issues.label_templates.use=Usa Set Etichette
+issues.create_label=Crea etichetta
+issues.label_templates.title=Carica un'etichetta predefinita
+issues.label_templates.info=Non esistono etichette. Crea una etichetta con "Nuova etichetta" o usa un'etichetta predefinita:
+issues.label_templates.helper=Seleziona un'etichetta predefinita
+issues.label_templates.use=Usa etichetta predefinita
issues.add_label=ha aggiunto l'etichetta %s %s
issues.add_labels=ha aggiunto le %s etichette %s
issues.remove_label=rimosso l'etichetta %s %s
@@ -1366,14 +1431,14 @@ issues.draft_title=Bozza
issues.num_comments=%d commenti
issues.commented_at=`%s ha commentato`
issues.delete_comment_confirm=Sei sicuro/a di voler eliminare questo commento?
-issues.context.copy_link=Copia link
-issues.context.quote_reply=Quota risposta
-issues.context.reference_issue=Fai riferimento in un nuovo problema
+issues.context.copy_link=Copia collegamento
+issues.context.quote_reply=Cita risposta
+issues.context.reference_issue=Crea riferimento in una nuova segnalazione
issues.context.edit=Modifica
issues.context.delete=Elimina
-issues.close_comment_issue=Commenta e Chiudi
+issues.close_comment_issue=Commenta e chiudi
issues.reopen_issue=Riapri
-issues.reopen_comment_issue=Commenta e Riapri
+issues.reopen_comment_issue=Commenta e riapri
issues.create_comment=Commento
issues.closed_at=`chiuso questo probleam %[2]s`
issues.reopened_at=`riaperto questo problema %[2]s`
@@ -1405,15 +1470,15 @@ issues.label_count=%d etichette
issues.label_open_issues=%d problemi aperti
issues.label_edit=Modifica
issues.label_delete=Elimina
-issues.label_modify=Modifica Etichetta
-issues.label_deletion=Elimina Etichetta
+issues.label_modify=Modifica etichetta
+issues.label_deletion=Elimina etichetta
issues.label_deletion_desc=Eliminare un'etichetta la rimuove da tutte le issue. Continuare?
issues.label_deletion_success=L'etichetta è stata eliminata.
issues.label.filter_sort.alphabetically=In ordine alfabetico
issues.label.filter_sort.reverse_alphabetically=In ordine alfabetico inverso
issues.label.filter_sort.by_size=Dimensione più piccola
issues.label.filter_sort.reverse_by_size=Dimensione più grande
-issues.num_participants=%d Partecipanti
+issues.num_participants=%d partecipanti
issues.attachment.open_tab=`Clicca per vedere "%s" in una nuova scheda`
issues.attachment.download=`Clicca qui per scaricare "%s"`
issues.subscribe=Iscriviti
@@ -1428,7 +1493,7 @@ issues.lock_no_reason=ha bloccato e limitato la conversazione ai collaboratori %
issues.unlock_comment=ha sbloccato questa conversazione %s
issues.lock_confirm=Blocca
issues.unlock_confirm=Sblocca
-issues.lock.notice_1=- Altri utenti non possono aggiungere nuovi commenti a questo problema.
+issues.lock.notice_1=- Altri utenti non possono aggiungere nuovi commenti a questa segnalazione.
issues.lock.notice_2=- Tu e altri collaboratori con accesso a questo repository potete ancora lasciare commenti che altri possono vedere.
issues.lock.notice_3=- Puoi sempre sbloccare questo problema in futuro.
issues.unlock.notice_1=- Tutti potranno commentare nuovamente questo problema.
@@ -1449,7 +1514,7 @@ issues.tracking_already_started=`Hai già avviato il monitoraggio del tempo su <
issues.stop_tracking=Ferma timer
issues.stop_tracking_history=`ha smesso di funzionare %s`
issues.cancel_tracking=Scarta
-issues.add_time=Aggiungi Tempo manualmente
+issues.add_time=Aggiungi tempo manualmente
issues.del_time=Elimina questo registro di tempo
issues.add_time_short=Aggiungi tempo
issues.add_time_cancel=Annulla
@@ -1460,24 +1525,24 @@ issues.add_time_minutes=Minuti
issues.add_time_sum_to_small=Non è stato inserito alcun tempo.
issues.time_spent_total=Tempo totale trascorso
issues.time_spent_from_all_authors=`Totale tempo trascorso: %s`
-issues.due_date=Data di scadenza
-issues.invalid_due_date_format=Il formato della data di scadenza deve essere 'yyyy-mm-dd'.
-issues.error_modifying_due_date=Impossibile modificare la data di scadenza.
-issues.error_removing_due_date=Impossibile rimuovere la data di scadenza.
+issues.due_date=Scadenza
+issues.invalid_due_date_format=Il formato della scadenza deve essere "aaaa-mm-dd".
+issues.error_modifying_due_date=Impossibile modificare la scadenza.
+issues.error_removing_due_date=Impossibile rimuovere la scadenza.
issues.push_commit_1=aggiunto %d commit %s
issues.push_commits_n=aggiunto %d commit %s
issues.force_push_codes=`force-pushed %[1]s from %[2]s
to %[4]s
%[6]s`
issues.force_push_compare=Confronta
-issues.due_date_form=yyyy-mm-dd
-issues.due_date_form_add=Aggiungi data di scadenza
+issues.due_date_form=aaaa-mm-dd
+issues.due_date_form_add=Aggiungi scadenza
issues.due_date_form_edit=Modifica
issues.due_date_form_remove=Rimuovi
-issues.due_date_not_set=Nessuna data di scadenza impostata.
-issues.due_date_added=la data di scadenza %s è stata aggiunta %s
-issues.due_date_modified=ha modificato la data di scadenza da %[2]s a %[1]s %[3]s s
-issues.due_date_remove=rimossa la data di scadenza %s %s
+issues.due_date_not_set=Nessuna scadenza impostata.
+issues.due_date_added=la scadenza %s è stata aggiunta %s
+issues.due_date_modified=ha modificato la scadenza da %[2]s a %[1]s %[3]s s
+issues.due_date_remove=rimossa la scadenza %s %s
issues.due_date_overdue=Scaduto
-issues.due_date_invalid=La data di scadenza non è valida o fuori intervallo. Si prega di utilizzare il formato 'aaaa-mm-dd'.
+issues.due_date_invalid=La scadenza non è valida o fuori intervallo. Si prega di utilizzare il formato "aaaa-mm-dd".
issues.dependency.title=Dipendenze
issues.dependency.issue_no_dependencies=Nessuna dipendenza impostata.
issues.dependency.pr_no_dependencies=Nessuna dipendenza impostata.
@@ -1498,7 +1563,7 @@ issues.dependency.blocked_by_short=Dipende da
issues.dependency.remove_header=Rimuovi Dipendenza
issues.dependency.issue_remove_text=Questo rimuoverà la dipendenza da questa issue. Continuare?
issues.dependency.pr_remove_text=Questo rimuoverà la dipendenza da questa pull request. Continuare?
-issues.dependency.setting=Abilita le dipendenze per problemi e Pull Requests
+issues.dependency.setting=Abilita le dipendenze per segnalazioni e richieste di modifica
issues.dependency.add_error_same_issue=Non si può fare dipendere un problema da se stesso.
issues.dependency.add_error_dep_issue_not_exist=Il problema dipendente non esiste.
issues.dependency.add_error_dep_not_exist=La dipendenza non esiste.
@@ -1509,15 +1574,15 @@ issues.review.self.approval=Non puoi approvare la tua pull request.
issues.review.self.rejection=Non puoi richiedere modifiche sulla tua pull request.
issues.review.approve=hanno approvato queste modifiche %s
issues.review.comment=revisionato %s
-issues.review.dismissed=recensione %s di %s respinta
+issues.review.dismissed=revisione %s di %s respinta
issues.review.dismissed_label=Respinta
issues.review.left_comment=lascia un commento
issues.review.content.empty=Devi lasciare un commento che indichi la modifica richiesta.
-issues.review.reject=richieste modifiche %s
+issues.review.reject=ha richiesto modifiche %s
issues.review.wait=è stato richiesto per la revisione %s
-issues.review.add_review_request=recensione richiesta da %s %s
+issues.review.add_review_request=revisione richiesta da %s %s
issues.review.remove_review_request=ha rimosso la richiesta di revisione per %s %s
-issues.review.remove_review_request_self=ha rifiutato di rivedere %s
+issues.review.remove_review_request_self=ha rifiutato di revisionare %s
issues.review.pending=In sospeso
issues.review.review=Revisiona
issues.review.reviewers=Revisori
@@ -1543,9 +1608,9 @@ compare.compare_base=base
compare.compare_head=confronta
pulls.desc=Attiva pull request e revisioni di codice.
-pulls.new=Nuova Pull Request
-pulls.view=Visualizza Pull Request
-pulls.compare_changes=Nuova Pull Request
+pulls.new=Nuova richiesta di modifica
+pulls.view=Visualizza richiesta di modifica
+pulls.compare_changes=Nuova richiesta di modifica
pulls.allow_edits_from_maintainers=Consenti modifiche dai manutentori
pulls.allow_edits_from_maintainers_desc=Gli utenti con accesso in scrittura al ramo base possono anche inviare a questo ramo
pulls.allow_edits_from_maintainers_err=Aggiornamento non riuscito
@@ -1562,9 +1627,9 @@ pulls.no_results=Nessun risultato trovato.
pulls.nothing_to_compare=Questi rami sono uguali. Non c'è alcuna necessità di creare una pull request.
pulls.nothing_to_compare_and_allow_empty_pr=Questi rami sono uguali. Questa PR sarà vuota.
pulls.has_pull_request=`Una pull request tra questi rami esiste già: %[2]s#%[3]d`
-pulls.create=Crea Pull Request
-pulls.title_desc=vorrebbe unire %[1]d commit da %[2]s
a %[3]s
-pulls.merged_title_desc=ha unito %[1]d commit da %[2]s
a %[3]s
%[4]s
+pulls.create=Crea richiesta di modifica
+pulls.title_desc_few=vorrebbe unire %[1]d commit da %[2]s
a %[3]s
+pulls.merged_title_desc_few=ha unito %[1]d commit da %[2]s
a %[3]s
%[4]s
pulls.change_target_branch_at=`cambiato il branch di destinazione da %s a %s %s`
pulls.tab_conversation=Conversazione
pulls.tab_commits=Commit
@@ -1581,8 +1646,8 @@ pulls.add_prefix=Aggiungi prefisso %s
pulls.remove_prefix=Rimuovi il prefisso %s
pulls.data_broken=Questa pull request è rovinata a causa di informazioni mancanti del fork.
pulls.files_conflicted=Questa pull request ha modifiche in conflitto con il branch di destinazione.
-pulls.is_checking=Verifica dei conflitti di merge in corso. Riprova tra qualche istante.
-pulls.is_ancestor=Questo ramo è già incluso nel ramo di destinazione. Non c'è nulla da unire.
+pulls.is_checking=Verifica dei conflitti di fusione in corso. Riprova tra qualche istante.
+pulls.is_ancestor=Questo ramo è già incluso nel ramo di destinazione. Non c'è nulla da fondere.
pulls.is_empty=Le modifiche di questo ramo sono già nel ramo di destinazione. Questo sarà un commit vuoto.
pulls.required_status_check_failed=Alcuni controlli richiesti non hanno avuto successo.
pulls.required_status_check_missing=Mancano alcuni controlli richiesti.
@@ -1591,14 +1656,14 @@ pulls.can_auto_merge_desc=La pull request può essere unita automaticamente.
pulls.cannot_auto_merge_desc=Questa pull request non può essere unita automaticamente a causa di conflitti.
pulls.cannot_auto_merge_helper=Unire manualmente per risolvere i conflitti.
pulls.num_conflicting_files_1=%d file in conflitto
-pulls.num_conflicting_files_n=%d files in conflitto
+pulls.num_conflicting_files_n=%d file in conflitto
pulls.approve_count_1=%d approvazione
pulls.approve_count_n=%d approvazioni
pulls.reject_count_1=%d richiesta di cambiamento
pulls.reject_count_n=%d richieste di cambiamento
pulls.waiting_count_1=%d in attesa di revisione
pulls.waiting_count_n=%d in attesa di revisione
-pulls.wrong_commit_id=l'id del commit deve essere un id del commit nel branch di destinazione
+pulls.wrong_commit_id=l'id del commit deve essere un id del commit nel ramo di destinazione
pulls.no_merge_desc=Questa pull request non può essere unita perché tutte le opzioni di merge del repository sono disattivate.
pulls.no_merge_helper=Attiva le opzioni di merge nelle impostazioni del repository o unisci la pull request manualmente.
@@ -1621,9 +1686,9 @@ pulls.rebase_conflict_summary=Messaggio d'Errore
pulls.unrelated_histories=Unione fallita: gli Head del ramo da unire e la base non condividono una storia cronologica in comune. Suggerimento: prova una strategia diversa
pulls.merge_out_of_date=Unione fallita: Durante la generazione del merge, la base è stata aggiornata. Suggerimento: Riprova.
pulls.head_out_of_date=Unione non riuscita: durante la generazione della fusione, la testa è stata aggiornata. Suggerimento: Riprova.
-pulls.push_rejected=Unisci non riuscito: il push è stato rifiutato. Rivedi gli Hooks Git per questo repository.
+pulls.push_rejected=Immissione respinta. Rivedi gli hooks Git per questo progetto.
pulls.push_rejected_summary=Messaggio Di Rifiuto Completo
-pulls.push_rejected_no_message=Unione non riuscita: il push è stato rifiutato ma non c'è stato un messaggio remoto.
Controlla gli Hooks di Git per questo repository
+pulls.push_rejected_no_message=Immissione respinta: nessun messaggio remoto. Controlla gli hooks di Git per questo progetto
pulls.open_unmerged_pull_exists=`Non è possibile riaprire questa pull request perché ne esiste un'altra (#%d) con proprietà identiche.`
pulls.status_checking=Alcuni controlli sono in sospeso
pulls.status_checks_success=Tutti i controlli sono stati effettuati con successo
@@ -1657,19 +1722,19 @@ pulls.delete.text=Vuoi davvero eliminare questo problema? (Questo rimuoverà per
-milestones.new=Nuova Milestone
+milestones.new=Nuova pietra miliare
milestones.closed=Chiuso %s
milestones.no_due_date=Nessuna data di scadenza
milestones.open=Apri
milestones.close=Chiudi
milestones.completeness=%d%% Completato
-milestones.create=Crea Milestone
+milestones.create=Crea pietra miliare
milestones.title=Titolo
milestones.desc=Descrizione
-milestones.due_date=Data di scadenza (opzionale)
+milestones.due_date=Scadenza (opzionale)
milestones.clear=Pulisci
-milestones.invalid_due_date_format=Il formato della data di scadenza deve essere 'yyyy-mm-dd'.
-milestones.edit=Modifica Milestone
+milestones.invalid_due_date_format=Il formato della scadenza deve essere 'aaaa-mm-dd'.
+milestones.edit=Modifica pietra miliare
milestones.edit_subheader=Le pietre miliari organizzano le issue e tengono conto del progresso.
milestones.cancel=Annulla
milestones.modify=Aggiorna pietra miliare
@@ -1705,7 +1770,7 @@ wiki.delete_page_button=Cancella Pagina
wiki.page_already_exists=Esiste già una pagina Wiki con questo stesso nome.
wiki.pages=Pagine
wiki.last_updated=Ultimo aggiornamento: %s
-wiki.page_name_desc=Inserisci un nome per questa pagina Wiki. Alcuni nomi speciali sono: 'Home', '_Sidebar' e '_Footer'.
+wiki.page_name_desc=Inserisci un nome per questa pagina wiki. Alcuni nomi speciali sono: "Home", "_Sidebar" e "_Footer".
activity=Attività
activity.period.filter_label=Periodo:
@@ -1717,38 +1782,38 @@ activity.period.quarterly=3 mesi
activity.period.semiyearly=6 mesi
activity.period.yearly=1 anno
activity.overview=Riepilogo
-activity.active_prs_count_1=%d Pull Request attiva
-activity.active_prs_count_n=%d Pull Request attive
-activity.merged_prs_count_1=Pull Request Unita
-activity.merged_prs_count_n=Pull request unite
-activity.opened_prs_count_1=Pull Request proposta
-activity.opened_prs_count_n=Pull Request proposte
+activity.active_prs_count_1=%d richiesta di modifica attiva
+activity.active_prs_count_n=%d richieste di modifiche attive
+activity.merged_prs_count_1=Richiesta di modifica fusa
+activity.merged_prs_count_n=Richieste di modifica fuse
+activity.opened_prs_count_1=Richiesta di modifica proposta
+activity.opened_prs_count_n=Richieste di modifica proposte
activity.title.user_1=%d utente
activity.title.user_n=%d utenti
-activity.title.prs_1=%d Pull request
-activity.title.prs_n=%d Pull request
+activity.title.prs_1=%d richiesta di modifica
+activity.title.prs_n=%d richieste di modifica
activity.title.prs_merged_by=%s unita da %s
activity.title.prs_opened_by=%s proposta da %s
activity.merged_prs_label=Unite
activity.opened_prs_label=Proposta
-activity.active_issues_count_1=%d Issue attiva
-activity.active_issues_count_n=%d Issue attive
-activity.closed_issues_count_1=Issue chiusa
-activity.closed_issues_count_n=Issue chiuse
-activity.title.issues_1=%d Issue
-activity.title.issues_n=%d Issue
+activity.active_issues_count_1=%d segnalazione attiva
+activity.active_issues_count_n=%d segnalazioni attive
+activity.closed_issues_count_1=Segnalazione chiusa
+activity.closed_issues_count_n=Segnalazioni chiuse
+activity.title.issues_1=%d segnalazione
+activity.title.issues_n=%d segnalazioni
activity.title.issues_closed_from=%s chiusa da %s
activity.title.issues_created_by=%s creata da %s
activity.closed_issue_label=Chiusa
-activity.new_issues_count_1=Nuova issue
-activity.new_issues_count_n=Nuove issue
+activity.new_issues_count_1=Nuova segnalazione
+activity.new_issues_count_n=Nuove segnalazioni
activity.new_issue_label=Aperta
-activity.title.unresolved_conv_1=%d Conversazione non risolta
-activity.title.unresolved_conv_n=%d Conversazioni non risolte
+activity.title.unresolved_conv_1=%d conversazione non risolta
+activity.title.unresolved_conv_n=%d conversazioni non risolte
activity.unresolved_conv_desc=Queste issue e pull request cambiate di recente non sono ancora state risolte.
activity.unresolved_conv_label=Aperta
-activity.title.releases_1=%d Release
-activity.title.releases_n=%d Release
+activity.title.releases_1=%d rilascio
+activity.title.releases_n=%d rilasci
activity.title.releases_published_by=%s pubblicata da %s
activity.published_release_label=Pubblicata
activity.no_git_activity=In questo periodo non c'è stata alcuna attività di commit.
@@ -1793,38 +1858,38 @@ settings.collaboration.read=Lettura
settings.collaboration.owner=Proprietario
settings.collaboration.undefined=Non definito
settings.hooks=Webhooks
-settings.githooks=Git Hooks
-settings.basic_settings=Impostazioni di Base
-settings.mirror_settings=Impostazioni di mirror
+settings.githooks=Hook git
+settings.basic_settings=Impostazioni di base
+settings.mirror_settings=Impostazioni dello specchio
settings.mirror_settings.mirrored_repository=Repository replicata
settings.mirror_settings.direction=Direzione
settings.mirror_settings.direction.pull=Tira
settings.mirror_settings.direction.push=Push
settings.mirror_settings.last_update=Ultimo aggiornamento
settings.mirror_settings.push_mirror.none=Nessun mirror push configurato
-settings.mirror_settings.push_mirror.remote_url=Url Del Repository Remoto Git
-settings.mirror_settings.push_mirror.add=Aggiungi Push Mirror
+settings.mirror_settings.push_mirror.remote_url=URL del progetto git remoto
+settings.mirror_settings.push_mirror.add=Aggiungi specchio di immissione
settings.sync_mirror=Sincronizza ora
settings.site=Sito web
-settings.update_settings=Aggiorna Impostazioni
-settings.branches.update_default_branch=Aggiorna Ramo Predefinito
+settings.update_settings=Aggiorna impostazioni
+settings.branches.update_default_branch=Aggiorna ramo predefinito
settings.advanced_settings=Opzioni avanzate
-settings.wiki_desc=Abilita Wiki Repository
+settings.wiki_desc=Abilita wiki del progetto
settings.use_internal_wiki=Utilizza la wiki incorporata
-settings.use_external_wiki=Usa Wiki esterna
-settings.external_wiki_url=URL Wiki esterno
+settings.use_external_wiki=Usa wiki esterna
+settings.external_wiki_url=URL wiki esterno
settings.external_wiki_url_error=L'URL della wiki esterna non è un URL valido.
settings.external_wiki_url_desc=I visitatori verranno reindirizzati all'URL della wiki esterna cliccando sulla scheda di wiki.
-settings.issues_desc=Abilità il tracciatore delle issue del repository
-settings.use_internal_issue_tracker=Usa il tracciatore di issue incorporato
-settings.use_external_issue_tracker=Usa un tracciatore di issue esterno
-settings.external_tracker_url=URL del tracciatore di issue esterno
+settings.issues_desc=Abilità il tracciatore delle segnalazioni del progetto
+settings.use_internal_issue_tracker=Usa il tracciatore di segnalazioni incorporato
+settings.use_external_issue_tracker=Usa un tracciatore di segnalazioni esterno
+settings.external_tracker_url=URL del tracciatore di segnalazioni esterno
settings.external_tracker_url_error=L'URL del tracciatore di issue esterno non è un URL valido.
settings.external_tracker_url_desc=I visitatori verranno reindirizzati all'URL del tracciatore di issue esterno cliccando sulla scheda delle issue.
-settings.tracker_url_format=Formato URL Gestore Problemi Esterno
+settings.tracker_url_format=Formato URL del gestore segnalazioni esterno
settings.tracker_url_format_error=L'URL del tracker di problemi esterno non è un URL valido.
-settings.tracker_issue_style=Formato numerico del tracciatore di issue esterno
+settings.tracker_issue_style=Formato numerico del tracciatore di segnalazioni esterno
settings.tracker_issue_style.numeric=Numerico
settings.tracker_issue_style.alphanumeric=Alfanumerico
settings.tracker_issue_style.regexp=Espressione Regolare
@@ -1833,33 +1898,33 @@ settings.tracker_issue_style.regexp_pattern_desc=Il primo gruppo catturato verr
settings.tracker_url_format_desc=Usa i segnaposto {user}
, {repo}
e {index}
per il nome utente, il nome del repository e l'indice delle issue.
settings.enable_timetracker=Abilita il cronografo
settings.allow_only_contributors_to_track_time=Consenti soltanto ai contributori di utilizzare il cronografo
-settings.pulls_desc=Abilita le pull request del repository
+settings.pulls_desc=Abilita le richieste di modifica del progetto
settings.pulls.ignore_whitespace=Ignora gli spazi bianchi per evitare conflitti
settings.pulls.enable_autodetect_manual_merge=Abilita il rilevamento automatico della fusione manuale (Nota: in alcuni casi speciali possono verificarsi errori)
settings.pulls.allow_rebase_update=Abilita l'aggiornamento del ramo pull request per rebase
settings.pulls.default_delete_branch_after_merge=Elimina il ramo pull request dopo la fusione per impostazione predefinita
-settings.packages_desc=Abilita Il Registro Dei Pacchetti Repository
-settings.projects_desc=Abilita Progetti Repository
+settings.packages_desc=Abilita registro dei pacchetti del progetto
+settings.projects_desc=Abilita progetti del progetto
settings.admin_settings=Impostazioni amministratore
-settings.admin_enable_health_check=Abilita verifica dell'integrità del repository (git fsck)
+settings.admin_enable_health_check=Abilita verifica dell'integrità del progetto (git fsck)
settings.admin_code_indexer=Indicizzatore del codice
settings.admin_stats_indexer=Indicizzatore di statistiche del codice
-settings.admin_indexer_commit_sha=Hash SHA dell'ultimo commit indicizzato
+settings.admin_indexer_commit_sha=Ultimo SHA indicizzato
settings.admin_indexer_unindexed=Non indicizzato
settings.reindex_button=Aggiungi alla coda di re-indicizzazione
settings.reindex_requested=Re-indicizzazione richiesta
settings.admin_enable_close_issues_via_commit_in_any_branch=Chiudi un issue tramite un commit eseguito in un branch non predefinito
-settings.danger_zone=Zona Pericolosa
+settings.danger_zone=Zona pericolosa
settings.new_owner_has_same_repo=Il nuovo proprietario ha già un repository con lo stesso nome. Per favore scegli un altro nome.
-settings.convert=Converti in un repository regolare
+settings.convert=Converti in un progetto regolare
settings.convert_desc=È possibile convertire questo mirror in un repository regolare. Questa operazione non può essere annullata.
settings.convert_notices_1=- Questa operazione convertirà questo mirror in una repository regolare e non potrà essere annullata.
-settings.convert_confirm=Converti Repository
+settings.convert_confirm=Converti progetto
settings.convert_succeed=Il mirror è stato convertito in un repository regolare.
-settings.convert_fork=Converti in un repository regolare
+settings.convert_fork=Converti in un progetto regolare
settings.convert_fork_desc=Puoi convertire questo fork in un normale repository. Questo non può essere annullato.
settings.convert_fork_notices_1=Questa operazione convertirà il fork in un normale repository e non può essere annullata.
-settings.convert_fork_confirm=Converti Repository
+settings.convert_fork_confirm=Converti progetto
settings.convert_fork_succeed=Il fork è stato convertito in un repository regolare.
settings.transfer=Trasferisci proprietà
settings.transfer.rejected=Il trasferimento del repository è stato rifiutato.
@@ -1872,13 +1937,13 @@ settings.transfer_in_progress=Al momento c'è un trasferimento in corso. Si preg
settings.transfer_notices_1=-Si perderà l'accesso al repository se lo si trasferisce ad un utente singolo.
settings.transfer_notices_2=-Si manterrà l'accesso al repository se si trasferisce in un'organizzazione che possiedi (o condividi con qualcun'altro).
settings.transfer_notices_3=- Se il repository è privato e viene trasferito a un singolo utente, questa azione si assicura che l'utente abbia almeno i permessi di lettura (e le modifiche se necessario).
-settings.transfer_owner=Nuovo Proprietario
+settings.transfer_owner=Nuovo proprietario
settings.transfer_perform=Esegui trasferimento
settings.transfer_started=`Questo repository è stato contrassegnato per il trasferimento e attende conferma da "%s"`
settings.transfer_succeed=Il repository è stato trasferito.
-settings.signing_settings=Impostazioni Verifica Firma
-settings.trust_model=Modello di Fiducia per la Firma
-settings.trust_model.default=Modello Di Fiducia Predefinito
+settings.signing_settings=Impostazioni verifica firma
+settings.trust_model=Modello di fiducia per la firma
+settings.trust_model.default=Modello di fiducia predefinito
settings.trust_model.default.desc=Usa il modello di trust del repository predefinito per questa installazione.
settings.trust_model.collaborator=Collaboratore
settings.trust_model.collaborator.long=Collaboratore: Firme di fiducia da parte dei collaboratori
@@ -1888,19 +1953,19 @@ settings.trust_model.committer.long=Committer: firme affidabili che corrispondon
settings.trust_model.collaboratorcommitter=Collaboratore+Committer
settings.trust_model.collaboratorcommitter.long=Collaboratore+Committer: Firme di fiducia da parte dei collaboratori che corrispondono al committer
settings.trust_model.collaboratorcommitter.desc=Le firme valide da parte dei collaboratori di questa repository saranno contrassegnate "fidate" se corrispondono al committer. Altrimenti le firme saranno contrassegnate con "untrusted" se la firma corrisponde al committer non corrisponde. Questo costringerà Forgejo a essere contrassegnato come committer su impegni firmati con l'effettivo committer contrassegnato come Co-Authored-By: e Co-Committed-By: nel commit. La chiave Forgejo predefinita deve corrispondere a un utente nel database.
-settings.wiki_delete=Elimina dati Wiki
+settings.wiki_delete=Elimina dati wiki
settings.wiki_delete_desc=L'eliminazione dei dati della wiki del repository è permanente e non può essere annullata.
settings.wiki_delete_notices_1=-Questa operazione eliminerà permanentemente e disabiliterà la wiki repository per %s.
-settings.confirm_wiki_delete=Elimina dati Wiki
+settings.confirm_wiki_delete=Elimina dati wiki
settings.wiki_deletion_success=I dati della repository wiki sono stati eliminati.
-settings.delete=Elimina questo repository
+settings.delete=Elimina questo progetto
settings.delete_desc=L'eliminazione di un repository è un'operazione permanente e non può essere annullata.
settings.delete_notices_1=-Questa operazione NON PUÒ essere annullata.
settings.delete_notices_2=-Questa operazione eliminerà definitivamente il repository %s inclusi codice, issue, commenti, dati wiki e impostazioni collaboratore.
settings.delete_notices_fork_1=-I fork di questo repository diventeranno indipendenti dopo la cancellazione.
settings.deletion_success=Il repository è stato eliminato.
settings.update_settings_success=Le impostazioni del repository sono state aggiornate.
-settings.confirm_delete=Elimina repository
+settings.confirm_delete=Elimina progetto
settings.add_collaborator=Aggiungi collaboratore
settings.add_collaborator_success=Il collaboratore è stato aggiunto.
settings.add_collaborator_inactive_user=Non posso aggiungere un utente inattivo come collaboratore.
@@ -1914,17 +1979,17 @@ settings.org_not_allowed_to_be_collaborator=Le organizzazioni non possono essere
settings.change_team_access_not_allowed=La modifica dell'accesso al team per il repository è stato limitato al solo proprietario dell'organizzazione
settings.team_not_in_organization=Il team non è nella stessa organizzazione del repository
settings.teams=Gruppi
-settings.add_team=Aggiungi Squadra
+settings.add_team=Aggiungi squadra
settings.add_team_duplicate=Il team ha già il repository
settings.add_team_success=Il team ha ora accesso al repository.
-settings.search_team=Cerca Squadra…
+settings.search_team=Cerca squadra…
settings.change_team_permission_tip=Il permesso del team è impostato sulla pagina delle impostazioni del team e non può essere modificato per repository
settings.delete_team_tip=Questo team ha accesso a tutte le repository e non può essere rimosso
settings.remove_team_success=L'accesso del team al repository è stato rimosso.
-settings.add_webhook=Aggiungi Webhook
+settings.add_webhook=Aggiungi richiamo HTTP
settings.add_webhook.invalid_channel_name=Il canale Webhook non può essere vuoto e contenere solo un # carattere.
settings.hooks_desc=I Webhook effettuano automaticamente richieste HTTP POST ad un server quando si verificano determinati eventi Forgejo. Per saperne di più leggi la guida ai webhooks.
-settings.webhook_deletion=Rimuovi Webhook
+settings.webhook_deletion=Rimuovi richiamo HTTP
settings.webhook_deletion_desc=Rimuovere un webhook rimuove le sue impostazioni e la sua cronologia di consegna. Continuare?
settings.webhook_deletion_success=Il webhook è stato rimosso.
settings.webhook.test_delivery=Test di consegna
@@ -1936,12 +2001,12 @@ settings.webhook.payload=Contenuto
settings.webhook.body=Corpo
settings.webhook.replay.description=Riproduci questo webhook.
settings.webhook.delivery.success=Un evento è stato aggiunto alla coda di consegna. Potrebbe volerci qualche secondo prima che venga visualizzato nella cronologia delle consegne.
-settings.githooks_desc=Git Hooks è alimentato da Git stesso. È possibile modificare i file hook qui sotto per impostare operazioni personalizzate.
+settings.githooks_desc=I Git hook sono alimentati da Git stesso. È possibile modificare i file hook qui sotto per impostare operazioni personalizzate.
settings.githook_edit_desc=Se l'hook è inattivo, sarà presentato un contenuto esempio. Lasciando il contenuto vuoto disattiverai questo hook.
settings.githook_name=Nome hook
settings.githook_content=Contenuto hook
-settings.update_githook=Aggiorna Hook
-settings.add_webhook_desc=Forgejo invierà richieste POST
con un tipo di contenuto specifico all'URL di destinazione. Per saperne di più leggi la guida ai webhook.
+settings.update_githook=Aggiorna hook
+settings.add_webhook_desc=Forgejo invierà richieste POST
con un tipo di contenuto specifico all'URL di destinazione. Per saperne di più leggi la guida ai richiami HTTP.
settings.payload_url=URL di destinazione
settings.http_method=Metodo HTTP
settings.content_type=Tipo di contenuto POST
@@ -1951,11 +2016,11 @@ settings.slack_icon_url=URL icona
settings.slack_color=Colore
settings.discord_username=Nome utente
settings.discord_icon_url=URL icona
-settings.event_desc=Attivato su:
-settings.event_push_only=Pusha eventi
+settings.event_desc=Innesco su:
+settings.event_push_only=Immetti eventi
settings.event_send_everything=Tutti gli eventi
settings.event_choose=Eventi personalizzati…
-settings.event_header_repository=Eventi del repository
+settings.event_header_repository=Eventi del progetto
settings.event_create=Crea
settings.event_create_desc=Branch o tag creato.
settings.event_delete=Elimina
@@ -1969,31 +2034,31 @@ settings.event_push=Push
settings.event_push_desc=Git push in un repository.
settings.event_repository=Repository
settings.event_repository_desc=Repository creato o eliminato.
-settings.event_header_issue=Eventi dei Problemi
+settings.event_header_issue=Eventi delle segnalazioni
settings.event_issues=Issues
settings.event_issues_desc=Issue aperto, chiuso, riaperto o modificato.
-settings.event_issue_assign=Issue Assegnato
+settings.event_issue_assign=Segnalazione assegnata
settings.event_issue_assign_desc=Issue assegnata o non assegnata.
-settings.event_issue_label=Issue etichettato
+settings.event_issue_label=Segnalazione etichettata
settings.event_issue_label_desc=Etichette dei Problemi aggiornate o cancellate.
-settings.event_issue_milestone=Obiettivo Raggiunto
+settings.event_issue_milestone=Segnalazione risolta
settings.event_issue_milestone_desc=Obiettivo raggiunto o abbandonato.
-settings.event_issue_comment=Commento Issue
+settings.event_issue_comment=Commento segnalazione
settings.event_issue_comment_desc=Commento issue creato, modificato o rimosso.
-settings.event_header_pull_request=Eventi di Pull Request
-settings.event_pull_request=Pull Request
+settings.event_header_pull_request=Eventi di richieste di modifiche
+settings.event_pull_request=Richiesta di modifica
settings.event_pull_request_desc=Pull request aperta, chiusa, riaperta o modificata.
-settings.event_pull_request_assign=Pull Request assegnata
+settings.event_pull_request_assign=Richiesta di modifica assegnata
settings.event_pull_request_assign_desc=Pull request assegnata o non assegnata.
-settings.event_pull_request_label=Pull Request etichettata
+settings.event_pull_request_label=Richiesta di modifica etichettata
settings.event_pull_request_label_desc=Etichette Pull request aggiornate o cancellate.
-settings.event_pull_request_milestone=Pull Request raggiunta
+settings.event_pull_request_milestone=Richiesta di modifica risolta
settings.event_pull_request_milestone_desc=Pull request raggiunto o abbandonato.
-settings.event_pull_request_comment=Commento su questa richiesta di pull
+settings.event_pull_request_comment=Commento su richiesta di modifica
settings.event_pull_request_comment_desc=Commento della Pull request creato, modificato o cancellato.
-settings.event_pull_request_review=Pull Request Revisionata
+settings.event_pull_request_review=Richiesta di modifica revisionata
settings.event_pull_request_review_desc=Pull request approvata, respinta o recensione commento.
-settings.event_pull_request_sync=Richiesta Pull Sincronizzata
+settings.event_pull_request_sync=Richiesta di modifica sincronizzata
settings.event_pull_request_sync_desc=Pull request sincronizzata.
settings.event_package=Pacchetto
settings.event_package_desc=Pacchetto creato o eliminato in un repository.
@@ -2094,21 +2159,21 @@ settings.no_protected_branch=Non ci sono branch protetti.
settings.edit_protected_branch=Modifica
settings.protected_branch_required_approvals_min=Le autorizzazioni richieste non possono essere negative.
settings.tags=Etichette
-settings.tags.protection=Protezione Etichetta
-settings.tags.protection.pattern=Sequenza Etichetta
+settings.tags.protection=Protezione dell'etichetta
+settings.tags.protection.pattern=Sequenza etichetta
settings.tags.protection.allowed=Consentito
settings.tags.protection.allowed.users=Utenti ammessi
settings.tags.protection.allowed.teams=Squadre ammesse
settings.tags.protection.allowed.noone=Nessuno
-settings.tags.protection.create=Proteggi Etichetta
+settings.tags.protection.create=Proteggi etichetta
settings.tags.protection.none=Non ci sono etichette protette.
-settings.bot_token=Token del Bot
+settings.bot_token=Token del bot
settings.chat_id=ID chat
settings.matrix.homeserver_url=URL Homeserver
settings.matrix.room_id=ID della stanza
settings.matrix.message_type=Tipo di messaggio
-settings.archive.button=Archivia Repo
-settings.archive.header=Archivia questo Repo
+settings.archive.button=Archivia progetto
+settings.archive.header=Archivia questo progetto
settings.archive.success=Il repo è stato archiviato con successo.
settings.archive.error=Si è verificato un errore durante il tentativo di archiviare il repo. Vedi il log per maggiori dettagli.
settings.archive.error_ismirror=Non puoi archiviare un mirror repo.
@@ -2122,7 +2187,7 @@ settings.lfs_findcommits=Cerca commit
settings.lfs_lfs_file_no_commits=Nessun commit trovato per questo file LFS
settings.lfs_noattribute=Questo percorso non ha l'attributo bloccabile nel ramo predefinito
settings.lfs_delete=Elimina file LFS con OID %s
-settings.lfs_delete_warning=Eliminare un file LFS può causare errori tipo 'oggetto non esiste' al checkout. Sei sicuro?
+settings.lfs_delete_warning=Eliminare un file LFS può causare errori tipo "oggetto non esiste" al passaggio. Sei sicuro?
settings.lfs_findpointerfiles=Trova files puntatori
settings.lfs_locks=Blocca
settings.lfs_invalid_locking_path=Percorso non valido: %s
@@ -2151,11 +2216,11 @@ diff.browse_source=Sfoglia il codice sorgente
diff.parent=parent
diff.commit=commit
diff.git-notes=Note
-diff.data_not_available=Dati Diff non disponibili
-diff.options_button=Opzioni Diff
+diff.data_not_available=Differenze non disponibili
+diff.options_button=Opzioni differenze
diff.show_diff_stats=Mostra statistiche
-diff.download_patch=Scarica il file Patch
-diff.download_diff=Scarica il file Diff
+diff.download_patch=Scarica il file toppa
+diff.download_diff=Scarica il file differenza
diff.show_split_view=Visualizzazione separata
diff.show_unified_view=Visualizzazione unificata
diff.whitespace_button=Spazi bianchi
@@ -2167,7 +2232,7 @@ diff.stats_desc=%d ha cambiato i file con %d aggiunte
diff.stats_desc_file=%d modifiche: %d aggiunte e %d cancellazioni
diff.bin=BIN
diff.bin_not_shown=File binario non mostrato.
-diff.view_file=Vedi File
+diff.view_file=Vedi file
diff.file_before=Prima
diff.file_after=Dopo
diff.file_image_width=Larghezza
@@ -2176,8 +2241,8 @@ diff.file_byte_size=Dimensione
diff.file_suppressed=File diff soppresso perché troppo grande
diff.file_suppressed_line_too_long=File diff soppresso perché una o più righe sono troppo lunghe
diff.too_many_files=Alcuni file non sono stati mostrati perché troppi file sono cambiati in questo diff
-diff.show_more=Mostra Altro
-diff.load=Carica Diff
+diff.show_more=Mostra altro
+diff.load=Carica differenze
diff.generated=generato
diff.vendored=esterno
diff.comment.placeholder=Lascia un commento
@@ -2240,9 +2305,9 @@ release.download_count=Scarica: %s
release.add_tag_msg=Utilizzare il titolo e il contenuto del rilascio come messaggio di tag.
release.add_tag=Crea Solo Branch
-branch.name=Nome branch
+branch.name=Nome ramo
branch.delete_head=Elimina
-branch.delete_html=Elimina branch
+branch.delete_html=Elimina ramo
branch.create_branch=Crea branch %s
branch.deleted_by=Eliminato da %s
branch.included_desc=Questo ramo fa parte del ramo predefinito
@@ -2274,12 +2339,12 @@ pulls.cmd_instruction_merge_title = Merge
pulls.cmd_instruction_checkout_desc = Dalla tua repository del progetto, accedi ad un nuovo ramo e prova le modifiche.
milestones.new_subheader = I traguardi possono aiutarti ad organizzare i problemi e a tracciare i loro progressi.
activity.navbar.contributors = Contributori
-migrate.cancel_migrating_title = Annulla Migrazione
-more_operations = Più Operazioni
+migrate.cancel_migrating_title = Annulla migrazione
+more_operations = Ulteriori operazioni
actions = Azioni
commit.operations = Operazioni
issues.action_check = Seleziona/Deseleziona
-issues.close = Chiudi Problema
+issues.close = Chiudi segnalazione
issues.role.collaborator = Collaboratore
desc.sha256 = SHA256
editor.add = Aggiungi %s
@@ -2291,9 +2356,9 @@ contributors.contribution_type.deletions = Rimozioni
settings.protect_patterns = Sequenze
milestones.update_ago = Aggiornato %s
mirror_sync = sincronizzato
-object_format = Formato Oggetti
+object_format = Formato oggetti
from_comment = (commento)
-executable_file = File Eseguibile
+executable_file = File eseguibile
commits.browse_further = Esplora di più
commitstatus.success = Successo
projects.column.edit = Modifica Colonna
@@ -2323,37 +2388,305 @@ settings.units.overview = Panoramica
all_branches = Tutti i rami
projects.column.assigned_to = Assegnato a
pulls.cmd_instruction_hint = `Visualizza istruzioni per la riga di comando.`
+settings.add_collaborator_blocked_them = Non si può aggiungere il collaboratore perché ha bloccato il proprietario del progetto.
+branch.protected_deletion_failed = Il ramo "%s" è protetto. Non può essere eliminato.
+branch.default_deletion_failed = Il ramo "%s" è il ramo predefinito. Non può essere eliminato.
+branch.tag_collision = Il ramo "%s" non può essere creato perché un'etichetta con lo stesso nome esiste già nel progetto.
+topic.format_prompt = Gli argomenti devono iniziare con una lettera o un numero, possono includere trattini ("-") e punti ("."), possono arrivare fino a 35 caratteri di lunghezza. Le lettere devono essere minuscole.
+error.broken_git_hook = Le hook Git di questo progetto sembrano rotte. Segui la documentazione per ripararli, poi immetti alcuni commit per aggiornare lo stato.
+wiki.reserved_page = La nome della pagina della wiki "%s" è riservato.
+wiki.delete_page_notice_1 = La rimozione della pagina della wiki "%s" non può essere annullata. Continuare?
+settings.webhook.test_delivery_desc_disabled = Per testare questo richiamo HTTP con un evento finto, attivalo.
+settings.protected_branch_duplicate_rule_name = Esiste già una regola per questo insieme di rami
+rss.must_be_on_branch = Devi essere su ramo per avere un feed RSS.
+admin.manage_flags = Gestisci flag
+admin.enabled_flags = Flag abilitate per il progetto:
+admin.update_flags = Aggiorna flag
+admin.failed_to_replace_flags = Impossibile sostituire flag del progetto
+admin.flags_replaced = Flag del progetto sostituite
+fork_branch = Ramo da clonare sulla derivazione
+fork_no_valid_owners = Questo progetto non può essere derivato perché non ci sono validi proprietari.
+mirror_address_url_invalid = L'URL fornito è invalido. Devi eseguire l'escape di tutti i componenti dell'URL correttamente.
+mirror_address_protocol_invalid = L'URL fornito è invalido. Solo posizioni http(s):// o git:// possono essere usate come specchio.
+stars_remove_warning = Questo rimuoverà tutte le stelle da questo progetto.
+blame.ignore_revs = Le revisioni in .git-blame-ignore-revs sono ignorate. Clicca qui per bypassare e vedere la vista incolpa normale.
+archive.title = Questo progetto è archiviato. Puoi vedere i file e clonarlo, ma non puoi immettere o aprire segnalazioni o richieste di modifica.
+archive.title_date = Questo progetto è stato archiviato il %s. Puoi vedere i file e clonarlo, ma non puoi immettere o aprire segnalazioni o richieste di modifica.
+form.name_pattern_not_allowed = La sequenza "%s" non è ammessa nel nome di un progetto.
+migrate.invalid_local_path = Il percorso locale è invalido. Non esiste o non è una cartella.
+migrate.migrating_failed.error = Impossibile migrare: %s
+migrate.forgejo.description = Migra dati da codeberg.org o da altre istanze Forgejo.
+cite_this_repo = Cita questo progetto
+file_follow = Segui Symlink
+invisible_runes_header = `Questo file contiene caratteri Unicode invisibili`
+ambiguous_runes_header = `Questo file contiene caratteri Unicode ambigui`
+ambiguous_runes_description = `Questo file contiene caratteri Unicode che potrebbero essere confusi con altri caratteri. Se pensi che questo sia intenzionale puoi tranquillamente ignorare questo avviso. Usa il tasto Escape per rivelarli.`
+vendored = Vendored
+generated = Generato
+commit.contained_in = Questo commit è contenuto in:
+commit.contained_in_default_branch = Questo commit è parte del ramo predefinito
+commit.load_referencing_branches_and_tags = Carica rami ed etichette che fanno riferimento a questo commit
+editor.fail_to_apply_patch = Impossibile applicare toppa "%s"
+editor.new_branch_name = Dai un nome al nuovo ramo per questo commit
+editor.branch_already_exists = Il ramo "%s" esiste già nel progetto.
+editor.directory_is_a_file = Il nome cartella "%s" è già usato come nome file in questo progetto.
+editor.file_is_a_symlink = `"%s" è un collegamento simbolico. I collegamenti simbolici non possono essere modificati nell'editor web`
+editor.filename_is_a_directory = Il nome file "%s" è già usato come nome cartella in questo progetto.
+editor.file_editing_no_longer_exists = Il file in modifica, "%s", non esiste più in questo progetto.
+editor.file_deleting_no_longer_exists = Il file in eliminazione, "%s", non esiste più in questo progetto.
+editor.file_already_exists = Un file chiamato "%s" esiste già in questo progetto.
+editor.fail_to_update_file = Impossibile aggiornare/creare il file "%s".
+editor.upload_file_is_locked = Il file "%s" è bloccato da %s.
+editor.cannot_commit_to_protected_branch = Non si può fare commit sul ramo protetto "%s".
+commits.search.tooltip = Puoi prefissare parole chiave con "autore:", "committer:", "dopo:", o "prima:", esempio "ripristino autore:Alice prima:2019-01-13".
+issues.filter_project_all = Tutti i progetti
+issues.label_exclusive_desc = Dai all'etichetta il nome ambito/oggetto
per renderla mutualmente esclusiva con altre etichette in ambito/
.
+issues.pin_comment = ha fissato questo %s
+issues.max_pinned = Non puoi fissare ulteriori segnalazioni
+issues.unpin_comment = ha sbloccato questo %s
+issues.cancel_tracking_history = `disabilitato tracciamento del tempo %s`
+issues.due_date_not_writer = Ti serve il permesso di scrittura a questo progetto per poter aggiornare la scadenza di una segnalazione.
+issues.dependency.no_permission_1 = Non hai il permesso per leggere %s dipendenza
+issues.dependency.issue_batch_close_blocked = Non puoi chiudere segnalazioni in gruppo perché la segnalazione #%d ha ancora dipendenze aperte
+issues.review.option.show_outdated_comments = Mostra commenti vecchi
+issues.review.option.hide_outdated_comments = Nascondi commenti vecchi
+issues.comment.blocked_by_user = Non puoi creare un commento su questa segnalazione perché sei bloccato dal proprietario del progetto o dall'autore della segnalazione.
+pulls.expand_files = Espandi tutti i file
+pulls.collapse_files = Collassa tutti i file
+pulls.show_all_commits = Mostra tutti i commit
+pulls.showing_only_single_commit = Mostrando solo cambiamenti del commit %[1]s
+pulls.showing_specified_commit_range = Mostrando solo cambiamenti tra %[1]s..%[2]s
+pulls.select_commit_hold_shift_for_range = Seleziona commit. Premi maiusc + click per selezionare un intervallo
+pulls.filter_changes_by_commit = Filtra per commit
+pulls.nothing_to_compare_have_tag = I rami/etichette selezionati sono uguali.
+pulls.merged_success = Richiesta di modifica fusa correttamente e chiusa
+pulls.closed = Richiesta di modifica chiusa
+pulls.merged_info_text = Il ramo %s può essere eliminato ora.
+pulls.blocked_by_user = Non puoi creare una richiesta di modifica in questo progetto perché sei bloccato dal proprietario.
+pulls.status_checks_hide_all = Nascondi tutti i controlli
+pulls.status_checks_show_all = Mostra tutti i controlli
+pulls.clear_merge_message_hint = Cancellare il messaggio di fusione rimuoverà solo il messaggio di commit e terrà le sequenze generate da git come "Co-Authored-By ..".
+pulls.close = Chiudi la richiesta di modifica
+pulls.reopen_failed.head_branch = La richiesta di modifica non può essere riaperta perché il ramo genitore non esiste più.
+pulls.clear_merge_message = Cancella messaggio di fusione
+pulls.reopen_failed.base_branch = La richiesta di modifica non può essere riaperta perché il ramo di base non esiste più.
+pulls.agit_explanation = Creata usando flusso di lavoro AGit. AGit permette ai contributori di proporre modifiche usando "git push" senza creare una derivazione o un nuovo ramo.
+pulls.recently_pushed_new_branches = Hai immesso sul ramo %[1]s %[2]s
+milestones.filter_sort.earliest_due_data = Scadenza più vicina
+signing.wont_sign.twofa = Devi avere la verifica a due fattori abilitata per firmare i commit.
+signing.wont_sign.parentsigned = Il commit non verrà firmato dato che il commit genitore non è firmato.
+signing.wont_sign.basesigned = La fusione non verrà firmata dato che il commit base non è firmato.
+signing.wont_sign.headsigned = La fusione non verrà firmata dato che il commit genitore non è firmato.
+signing.wont_sign.not_signed_in = Non hai effettuato l'accesso.
+wiki.original_git_entry_tooltip = Visualizza file Git originali invece di usare collegamenti amichevoli.
+activity.navbar.pulse = Battito
+activity.navbar.code_frequency = Frequenza del codice
+activity.navbar.recent_commits = Commit recenti
+contributors.contribution_type.filter_label = Tipi di contributo:
+search.type.tooltip = Cerca tipo
+search.match.tooltip = Includi solo risultati che corrispondono esattamente ai termini di ricerca
+settings.mirror_settings.docs.disabled_push_mirror.instructions = Imposta il tuo progetto in modo che prelevi commit, etichette e rami da un altro progetto.
+settings.mirror_settings.docs.no_new_mirrors = Il tuo progetto sta specchiando i cambiamenti a/da un altro progetto. Tieni a mente che non puoi creare nuovi specchi al momento.
+settings.mirror_settings.docs.can_still_use = Nonostante tu non possa modificare specchi esistenti o crearne di nuovi puoi comunque il tuo specchio esistente.
+settings.mirror_settings.docs.pull_mirror_instructions = Per impostare uno specchio di prelievo consulta:
+settings.mirror_settings.docs.doc_link_title = Come specchio progetti?
+settings.mirror_settings.docs.doc_link_pull_section = la sezione "Prelievo da un progetto remoto" della documentazione.
+settings.mirror_settings.docs.pulling_remote_title = Prelievo da un progetto remote
+settings.transfer_abort_success = Il trasferimento del progetto a %s è stato correttamente cancellato.
+settings.enter_repo_name = Inserisci il proprietario e il nome del progetto esattamente come mostrato:
+settings.confirmation_string = Stringa di conferma
+settings.wiki_rename_branch_main = Normalizza il nome del ramo della wiki
+settings.wiki_rename_branch_main_desc = Rinomina il ramo usato internamente dalla wiki come "%s". Questo è permanente è non può essere annullato.
+settings.wiki_rename_branch_main_notices_1 = Questa operazione NON PUÒ essere annullata.
+settings.wiki_branch_rename_success = Il nome del ramo della wiki del progetto è stato normalizzato correttamente.
+settings.wiki_branch_rename_failure = Impossibile normalizzare il nome del ramo della wiki del progetto.
+settings.confirm_wiki_branch_rename = Rinomina ramo della wiki
+settings.wiki_rename_branch_main_notices_2 = Questo rinominerà permanentemente il ramo interno della wiki del progetto di %s. Passaggi esistenti dovranno essere aggiornati.
+settings.add_collaborator_blocked_our = Non si può aggiungere il collaboratore perché il proprietario del progetto lo ha bloccato.
+settings.webhook.replay.description_disabled = Per riprodurre questo richiamo HTTP, attivalo.
+settings.event_wiki_desc = Pagina wiki creata, rinominata, modificata o rimossa.
+settings.event_pull_request_review_request = Richiesta di modifica revisionata
+branch.branch_already_exists = Il ramo "%s" esiste già nel progetto.
+branch.branch_name_conflict = Il nome del ramo "%s" è in conflitto con il ramo già esiste "%s".
+branch.restore_success = Il ramo "%s" è stato ripristinato.
+branch.restore_failed = Impossibile ripristinare il ramo "%s".
+branch.warning_rename_default_branch = Stai rinominando il ramo predefinito.
+branch.rename_branch_to = Rinomina "%s" come:
+branch.new_branch_from = Crea nuovo ramo da "%s"
+tag.create_tag_from = Crea nuova etichetta da "%s"
+tag.create_success = Etichetta "%s" creata.
+settings.unarchive.button = Disarchivia progetto
+release.tags_for = Etichette per %s
+branch.delete = Elimina ramo "%s"
+issues.role.first_time_contributor_helper = Questa non è il primo contributo di questo utente al progetto.
+issues.role.contributor_helper = Questo utente ha precedentemente fatto commit al progetto.
+pulls.blocked_by_official_review_requests = Questa richiesta di modifica è bloccata perché manca l'approvazione di uno o più revisori ufficiali.
+pulls.blocked_by_changed_protected_files_1 = Questa richiesta di modifica è bloccata perché modifica un file protetto:
+pulls.blocked_by_changed_protected_files_n = Questa richiesta di modifica è bloccata perché modifica file protetti:
+pulls.has_merged = Respinto: la richiesta di modifica è stata fusa, non puoi fonderla di nuovo o cambiare il ramo di destinazione.
+milestones.filter_sort.latest_due_date = Scadenza più lontana
+settings.mirror_settings.docs = Imposta il tuo progetto in modo che sincronizzi automaticamente commit, etichette e rami con un altro progetto.
+settings.mirror_settings.docs.disabled_pull_mirror.instructions = Imposta il tuo progetto in modo che immetta commit, etichette e rami in un altro progetto automaticamente. Gli specchi di prelievo sono stati disabilitati dall'amministratore del sito.
+settings.mirror_settings.docs.disabled_push_mirror.info = Gli specchi di immissione sono stati disabilitati dall'amministratore del sito.
+settings.mirror_settings.docs.more_information_if_disabled = Puoi scoprire di più riguardo specchi di prelievo e di immissione qui:
+commits.view_path = Vista a questo punto nella cronologia
+issues.action_check_all = Seleziona/deseleziona tutti gli elementi
+issues.num_comments_1 = %d commento
+issues.no_content = Descrizione non fornita.
+issues.unpin_issue = Sblocca segnalazione
+new_repo_helper = Un progetto contiene tutti i file, inclusa la storia delle revisioni. Ne ospiti già una altrove? Migra il progetto.
+projects.card_type.images_and_text = Immagini e testo
+object_format_helper = Formato oggetti del progetto. Non può essere cambiato in seguito. SHA1 è il più compatibile.
+editor.file_delete_success = Il file "%s" è stato eliminato.
+editor.upload_files_to_dir = Cari file su "%s"
+commits.no_commits = Nessun commit in comune. "%s" e "%s" hanno cronologie completamente diverse.
+commits.renamed_from = Rinomina da %s
+invisible_runes_description = `Questo file contiene caratteri Unicode invisibili che sono indistinguibili agli umani ma potrebbero essere processati diversamente da un computer. Se pensi che questo sia intenzionale puoi tranquillamente ignorare questo avviso. Usa il tasto Escape per rivelarli.`
+issues.filter_type.reviewed_by_you = Revisionati da te
+projects.edit_success = Il progetto "%s" è stato aggiornato.
+issues.keyword_search_unavailable = La ricerca per parola chiave non è attualmente disponibile. Contatta l'amministratore del sito.
+issues.role.collaborator_helper = Questo utente è stato invitato a collaborare sul progetto.
+pulls.commit_ref_at = `ha fatto riferimento a questa richiesta di modifica da un commit %[2]s`
+settings.thread_id = ID della discussione
+release.title = Titolo del rilascio
+visibility_helper = Rendi progetto privato
+clone_in_vscodium = Clona in VSCodium
+blame.ignore_revs.failed = Impossibile ignorare le revisioni in .git-blame-ignore-revs.
+author_search_tooltip = Mostra un massimo di 30 utenti
+tree_path_not_found_commit = Il percorso %[1]s non esiste nel commit %[2]s
+tree_path_not_found_branch = Il percorso %[1]s non esiste nel ramo %[2]s
+tree_path_not_found_tag = Il percorso %[1]s non esiste nell'etichetta %[2]s
+transfer.no_permission_to_accept = Non hai i permessi per accettare questo trasferimento.
+transfer.no_permission_to_reject = Non hai i permessi per rifiutare questo trasferimento.
+migrate_options_lfs_endpoint.placeholder = Se lasciato vuoto il punto di accesso sarà derivato dall'URL usato per clonare
+migrate.cancel_migrating_confirm = Vuoi cancellare questa migrazione?
+editor.filename_is_invalid = Nome file invalido: "%s".
+editor.unable_to_upload_files = Impossibile caricare i file su "%s" con errore: %v
+projects.create_success = Il progetto "%s" è stato creato.
+projects.column.set_default_desc = Imposta questa colonna come predefinita per segnalazioni e richieste di modifica non categorizzate
+projects.column.unset_default_desc = Disattiva questa colonna come predefinita
+projects.column.deletion_desc = Eliminare la colonna di un progetto sposta tutte le relative segnalazioni in "Non categorizzate". Continuare?
+issues.choose.ignore_invalid_templates = I modelli non validi sono stati ignorati
+issues.choose.invalid_templates = trovati %v modello/i non valido/i
+issues.choose.invalid_config = La configurazione della segnalazione contiene errori:
+issues.label_templates.fail_to_load_file = Impossibile caricare file di modello etichetta "%s": %v
+issues.role.member_helper = questo utente è un membro dell'organizzazione che possiede questo progetto.
+issues.review.pending.tooltip = Questo commento non è attualmente visibile ad altri utenti. Per inviare il tuo commento in attesa selezione "%s" -> "%s/%s/%s" in cima alla pagina.
+pulls.blocked_by_approvals = Questa richiesta di modifica non ha ancora sufficienti approvazioni. %d di %d approvazioni concesse.
+pulls.blocked_by_rejection = Questa richiesta di modifica ha modifiche richieste da un revisore ufficiale.
+pulls.blocked_by_outdated_branch = Questa richiesta di modifica è bloccata perché è obsoleta.
+pulls.fast_forward_only_merge_pull_request = Solo fast-forward
+signing.will_sign = Questo commit verrà firmato con la chiave "%s".
+signing.wont_sign.error = C'è stato un errore durante il controllo per la firma del commit.
+signing.wont_sign.nokey = Non c'è una chiave disponibile per firmare questo commit.
+signing.wont_sign.never = I commit non sono mai firmati.
+signing.wont_sign.always = I commit sono sempre firmati.
+signing.wont_sign.approved = La fusione non sarà firmata dato che la RM non è approvata.
+wiki.page_title = Titolo della pagina
+wiki.page_content = Contenuto della pagina
+settings.mirror_settings.pushed_repository = Progetto immesso
+settings.mirror_settings.push_mirror.edit_sync_time = Modifica intervallo di sincronizzazione degli specchi
+settings.units.units = Unità del progetto
+settings.units.add_more = Aggiungi ancora...
+settings.wiki_globally_editable = Consenti a tutti di modificare la wiki
+settings.pull_mirror_sync_in_progress = Prelevando cambiamenti dal progetto remoto %s.
+settings.push_mirror_sync_in_progress = Immettendo cambiamenti al progetto remoto %s.
+settings.update_mirror_settings = Aggiorna impostazioni dello specchio
+settings.branches.switch_default_branch = Passa al ramo predefinito
+settings.branches.add_new_rule = Aggiungi nuova regola
+settings.actions_desc = Abilita azioni del progetto
+settings.new_owner_blocked_doer = Il nuovo proprietario ti ha bloccato.
+settings.update_settings_no_unit = Ili progetto dovrebbe consentire almeno qualche tipo di interazione.
+settings.add_collaborator_owner = Non si può aggiungere un proprietario come collaboratore.
+branch.delete_desc = Eliminare un ramo è permanente. Nonostante il ramo eliminato potrebbe continuare ad esistere per un breve periodo di tempo prima di essere realmente eliminato, l'eliminazione NON PUÒ essere annullata in molti casi. Continuare?
+editor.invalid_commit_mail = Email invalida per creare un commit.
+editor.branch_does_not_exist = Il ramo "%s" non esiste nel progetto.
+issues.label_archive = Archivia etichetta
+issues.label_archived_filter = Mostra etichette archiviate
+issues.dependency.no_permission_n = Non hai il permesso di lettura per leggere %s dipendenze
+branch.restore = Ripristina il ramo "%s"
+issues.dependency.no_permission.can_remove = Non ha il permesso per leggere questa dipendenza ma puoi rimuovere questa dipendenza
+issues.review.outdated_description = Il contenuto è cambiato da quando questo commento è stato fatto
+settings.tags.protection.pattern.description = Puoi usare un singolo nome o un glob pattern o un'espressione regolare per selezionare più etichette. Leggi di più nella guide sulle etichette protette.
+issues.author_helper = Questo utente è l'autore.
+issues.comment_pull_merged_at = fondi commit %[1]s in %[2]s %[3]s
+issues.comment_manually_pull_merged_at = fondi commit %[1]s in %[2]s %[3]s manualmente
+pulls.review_only_possible_for_full_diff = La revisione è possibile solo quando visualizzando le differenze complete
+issues.role.first_time_contributor = Contributore per la prima volta
+issues.label_archive_tooltip = Le etichette archiviate sono escluse dai suggerimenti quando si ricerca un'etichetta.
+form.name_reserved = Il nome progetto "%s" è riservato.
+release.message = Descrivi questo rilascio
+branch.deletion_success = Il ramo "%s" è stato eliminato.
+branch.deletion_failed = Impossibile eliminare il ramo "%s".
+branch.delete_branch_has_new_commits = Il ramo "%s" non può essere eliminato perché nuovi commit sono stati aggiunti dopo la fusione.
+branch.create_from = da "%s"
+branch.create_success = Il ramo "%s" non può essere creato.
+branch.download = Scarica il ramo "%s"
+branch.rename = Rinomina il ramo "%s"
+branch.search = Cerca ramo
+issues.blocked_by_user = Non puoi creare una segnalazione su questo progetto perché sei bloccato dal proprietario.
+settings.archive.text = Archiviare il progetto lo renderà unicamente di sola lettura. Sarà nascosto nel pannello di controllo. Nessuno (neanche tu!) potrai fare nuovi commit, o aprire segnalazioni o richieste di modifica.
+settings.unarchive.header = Disarchivia questo progetto
+settings.archive.mirrors_unavailable = Gli specchi non sono disponibile se il progetto è archiviato.
+issues.role.owner_helper = Questo utente è il proprietariə di questo progetto.
+issues.label_exclusive_warning = Ogni etichetta in conflitto in un ambito sarà rimossa durante la modifica di un'etichetta di una segnalazione o di una richiesta di modifica.
+pulls.show_changes_since_your_last_review = Mostra cambiamenti dalla tua ultima revisione
+signing.wont_sign.commitssigned = La fusione non verrà firmata dato che tutti i commit associati non sono firmati.
+settings.mirror_settings.docs.disabled_push_mirror.pull_mirror_warning = Al momento questo può essere fatto solo nel menù "Nuova migrazione". Per ulteriori informazioni consulta:
+settings.pulls.default_allow_edits_from_maintainers = Consenti modifica dai manutentori in modo predefinito
+settings.trust_model.committer.desc = Firme valide saranno etichettate "fidata" se corrispondo all'autore del commit, altrimenti saranno etichettate "non corrisponde". Questo costringe Forgejo ad esse l'autore dei commit firmati, con il vero autore etichettato con le sequenze Co-authored-by: e Co-commited-by: nel commit. La chiave predefinita di Forgejo deve corrispondere ad un utente nella base di dati.
+signing.wont_sign.pubkey = Il commit non verrà firmato perché non hai una chiave pubblica associata al tuo account.
+settings.releases_desc = Abilita rilasci del progetto
+settings.unarchive.text = Disarchiviare il progetto ripristinerà la sua abilità di ricevere commit e immissioni, oltre che nuove segnalazioni e richieste di modifica.
+settings.unarchive.success = Il progetto è stato disarchiviato correttamente.
+settings.unarchive.error = Si è verificato un errore durante la disarchiviazione del progetto. Vedi il log per ulteriori dettagli.
+release.title_empty = Il titolo non può essere vuoto.
+release.releases_for = Rilasci per %s
+diff.comment.add_line_comment = Aggiungi riga commento
+diff.show_file_tree = Mostra albero dei file
+diff.hide_file_tree = Nascondi albero dei file
+tag.ahead.target = a %s da questa etichetta
+release.tag_helper_new = Nuova etichetta. Questa etichetta sarà creata dalla destinazione.
+release.tag_helper_existing = Etichetta esistente.
+release.deletion_desc = La rimozione di un rilascio lo rimuove solo da Forgejo. Non influenza l'etichetta Git, i contenuti del tuo progetto o la sua cronologia. Continuare?
+branch.already_exists = Un ramo chiamato "%s" esiste già.
[graphs]
contributors.what = contribuzioni
+component_loading_failed = Impossibile caricare %s
+component_loading_info = Questo potrebbe richiedere un po'…
+component_loading = Caricando %s...
+code_frequency.what = frequenza del codice
+recent_commits.what = commit recenti
+component_failed_to_load = Si è verificato un errore inaspettato.
[org]
-org_name_holder=Nome dell'Organizzazione
+org_name_holder=Nome dell'organizzazione
org_full_name_holder=Nome completo dell'organizzazione
org_name_helper=I nomi delle organizzazioni devono essere brevi e semplici da ricordare.
-create_org=Crea Organizzazione
+create_org=Crea organizzazione
repo_updated=Aggiornato
members=Membri
teams=Team
lower_members=membri
lower_repositories=repository
-create_new_team=Nuovo Team
-create_team=Crea Team
+create_new_team=Nuovo team
+create_team=Crea squadra
org_desc=Descrizione
-team_name=Nome Team
+team_name=Nome squadra
team_desc=Descrizione
team_name_helper=I nomi dei team devono essere brevi e semplici da ricordare.
team_desc_helper=Descrivi lo scopo o il ruolo del team.
team_access_desc=Accesso al repository
team_permission_desc=Autorizzazione
-team_unit_desc=Consentire l'accesso a sezioni di Repository
+team_unit_desc=Consenti l'accesso a sezioni di progetto
team_unit_disabled=(Disabilitato)
form.create_org_not_allowed=Non disponi dell'autorizzazione per creare un organizzazione.
settings=Impostazioni
settings.options=Organizzazione
-settings.full_name=Nome Completo
+settings.full_name=Nome completo
settings.website=Sito Web
settings.location=Residenza
settings.permission=Autorizzazioni
@@ -2361,17 +2694,17 @@ settings.repoadminchangeteam=L'amministratore del repository può aggiungere e r
settings.visibility=Visibilità
settings.visibility.public=Pubblico
settings.visibility.limited_shortname=Limitato
-settings.visibility.private=Privato (Visibile solo ai membri dell'organizzazione)
+settings.visibility.private=Privato (visibile solo ai membri dell'organizzazione)
settings.visibility.private_shortname=Privato
-settings.update_settings=Aggiorna Impostazioni
+settings.update_settings=Aggiorna impostazioni
settings.update_setting_success=Le impostazioni dell'organizzazione sono state aggiornate.
settings.change_orgname_redirect_prompt=Il vecchio nome reindirizzerà fino a quando non sarà richiesto.
settings.update_avatar_success=L'avatar dell'organizzazione è stato aggiornato.
settings.delete=Elimina organizzazione
settings.delete_account=Elimina questa organizzazione
settings.delete_prompt=L'organizzazione verrà rimossa definitivamente. Questa operazione NON PUÒ essere annullata!
-settings.confirm_delete_account=Conferma Eliminazione
+settings.confirm_delete_account=Conferma eliminazione
settings.delete_org_title=Elimina organizzazione
settings.delete_org_desc=Questa organizzazione verrà eliminata definitivamente. Continuare?
settings.hooks_desc=Aggiungi i webhooks che verranno attivati per tutti i repository sotto questa organizzazione.
@@ -2398,9 +2731,9 @@ teams.leave=Abbandona
teams.leave.detail=Lasciare %s?
teams.can_create_org_repo=Crea repository
teams.can_create_org_repo_helper=I membri possono creare nuovi repository nell'organizzazione. Il creatore otterrà l'accesso di amministratore alla nuova repository.
-teams.none_access=Nessun Accesso
+teams.none_access=Nessun accesso
teams.none_access_helper=I membri non possono visualizzare o fare altre azioni su questa unità.
-teams.general_access=Accesso Generale
+teams.general_access=Accesso generale
teams.general_access_helper=I permessi dei membri saranno decisi dalla seguente tabella dei permessi.
teams.read_access=Lettura
teams.read_access_helper=I membri possono visualizzare e clonare i repository del team.
@@ -2411,18 +2744,18 @@ teams.admin_access_helper=I membri possono pullare e pushare sulle repository de
teams.no_desc=Questo team non ha alcuna descrizione
teams.settings=Impostazioni
teams.owners_permission_desc=I proprietari hanno pieno accesso a tutti i repository e hanno diritti di amministratore nell'organizzazione.
-teams.members=Membri del Team
-teams.update_settings=Aggiorna Impostazioni
-teams.delete_team=Elimina team
-teams.add_team_member=Aggiungi un Membro al Team
-teams.delete_team_title=Elimina team
+teams.members=Membri della squadra
+teams.update_settings=Aggiorna impostazioni
+teams.delete_team=Elimina squadra
+teams.add_team_member=Aggiungi un membro alla squadra
+teams.delete_team_title=Elimina squadra
teams.delete_team_desc=Eliminare un team revocherà l'accesso al repository da parte dei suoi membri. Continuare?
teams.delete_team_success=Il team è stato eliminato.
teams.read_permission_desc=Questo team concede l'accesso di lettura: i membri possono visualizzare e clonare i repository del team.
teams.write_permission_desc=Questo team concede l'accesso di Scrittura: i membri possono leggere da e pushare sui repository del team.
teams.admin_permission_desc=Questo team concede l'accesso di Amministratore: i membri possono leggere da, pushare su e aggiungere collaboratori ai repository del team.
teams.create_repo_permission_desc=Inoltre, questo team concede il permesso di Creare repository: i membri possono creare nuove repository nell'organizzazione.
-teams.repositories=Repository di Squadra
+teams.repositories=Progetti della squadra
teams.search_repo_placeholder=Ricerca repository…
teams.remove_all_repos_title=Rimuovi tutti i repository del team
teams.remove_all_repos_desc=Questo rimuoverà tutte le repository dal team.
@@ -2439,15 +2772,27 @@ teams.all_repositories_read_permission_desc=Questo team concede permessi
teams.all_repositories_write_permission_desc=Questo team concede permessi di scrittura accesso a tutte le repository: i membri possono leggere e pushare le repository.
teams.all_repositories_admin_permission_desc=Questo team concede a Amministratore l'accesso a tutte le repository: i membri possono leggere, pushare e aggiungere collaboratori alle repository.
code = Codice
+form.name_pattern_not_allowed = La sequenza "%s" non è consentita nel nome di un'organizzazione.
+settings.change_orgname_prompt = Nota: cambiare il nome dell'organizzazione cambierà anche l'URL dell'organizzazione e libererà il vecchio nome.
+teams.invite_team_member = Invita in %s
+teams.invite_team_member.list = Inviti in sospeso
+teams.add_nonexistent_repo = Il progetto che stai cercando di aggiungere non esiste, crealo prima.
+teams.invite.title = Sei stato invitato ad unirti alla squadra %s nell'organizzazione %s.
+teams.invite.by = Invitato da %s
+teams.invite.description = Clicca il tasto sotto per entrare nella squadra.
+follow_blocked_user = Non puoi seguire questa organizzazione perché ti ha bloccato.
+form.name_reserved = Il nome di organizzazione "%s" è riservato.
+settings.email = Email di contatto
+settings.visibility.limited = Limitato (visibile solo agli utenti autenticati)
[admin]
dashboard=Pannello di Controllo
-users=Account utenti
+users=Profili utenti
organizations=Organizzazioni
repositories=Repository
hooks=Webhooks
authentication=Fonti di autenticazione
-emails=Email Utente
+emails=Email utenti
config=Configurazione
notices=Avvisi di sistema
monitor=Monitoraggio
@@ -2474,63 +2819,63 @@ dashboard.cron.error=Errore in Cron: %s: %[3]s
dashboard.cron.finished=Cron: %[1]s ha finito
dashboard.delete_inactive_accounts=Elimina tutti gli account non attivati
dashboard.delete_inactive_accounts.started=Attività di eliminazione degli account non attivati iniziata.
-dashboard.delete_repo_archives=Elimina tutti gli archivi dei repository (ZIP, TAR.GZ, etc..)
+dashboard.delete_repo_archives=Elimina tutti gli archivi dei progetti (ZIP, TAR.GZ, ecc..)
dashboard.delete_repo_archives.started=Attività di eliminazione degli archivi del repository iniziata.
dashboard.delete_missing_repos=Elimina tutti i repository mancanti dei loro file Git
dashboard.delete_missing_repos.started=Elimina tutti i repository mancanti dei loro file Git.
dashboard.delete_generated_repository_avatars=Elimina gli avatar generati nelle repository
-dashboard.update_mirrors=Aggiorna Mirror
+dashboard.update_mirrors=Aggiorna specchi
dashboard.repo_health_check=Controlla integrità di tutti i repository
dashboard.check_repo_stats=Controlla tutte le statistiche del repository
dashboard.archive_cleanup=Elimina vecchi archivi del repository
dashboard.deleted_branches_cleanup=Pulisci branch eliminati
dashboard.update_migration_poster_id=Aggiorna gli ID del poster di migrazione
dashboard.git_gc_repos=Esegui la garbage collection su tutti i repository
-dashboard.resync_all_sshkeys=Aggiornare il file '.ssh/authorized_keys' con le chiavi SSH Forgejo.
-dashboard.resync_all_sshprincipals=Aggiornare il file '.ssh/authorized_keys' con le chiavi SSH Forgejo.
-dashboard.resync_all_hooks=Sincronizza nuovamente gli hook di pre-ricezione, di aggiornamento e di post-ricezione di tutti i repository.
+dashboard.resync_all_sshkeys=Aggiornare il file ".ssh/authorized_keys" con le chiavi SSH di Forgejo.
+dashboard.resync_all_sshprincipals=Aggiorna il file ".ssh/authorized_keys" con le chiavi principali SSH Forgejo.
+dashboard.resync_all_hooks=Sincronizza nuovamente gli hook di pre-ricezione, di aggiornamento e di post-ricezione di tutti i progetti
dashboard.reinit_missing_repos=Reinizializza tutti i repository Git mancanti per i quali esistono cambiamenti registrati esistenti
dashboard.sync_external_users=Sincronizza dati utente esterno
dashboard.cleanup_hook_task_table=Pulisci tabella hook_task
dashboard.cleanup_packages=Pulizia pacchetti scaduti
-dashboard.server_uptime=Tempo in Attività del Server
-dashboard.current_goroutine=Goroutine Correnti
-dashboard.current_memory_usage=Utilizzo di Memoria Corrente
-dashboard.total_memory_allocated=Memoria Allocata Totale
-dashboard.memory_obtained=Memoria Ottenuta
-dashboard.pointer_lookup_times=Ricerche del Puntatore
+dashboard.server_uptime=Tempo di attività
+dashboard.current_goroutine=Goroutine attuali
+dashboard.current_memory_usage=Utilizzo di memoria attuale
+dashboard.total_memory_allocated=Memoria allocata totale
+dashboard.memory_obtained=Memoria ottenuta
+dashboard.pointer_lookup_times=Tempi di ricerca del puntatore
dashboard.memory_allocate_times=Allocazioni di memoria
dashboard.memory_free_times=Rilasci di memoria
-dashboard.current_heap_usage=Utilizzo Heap Corrente
-dashboard.heap_memory_obtained=Memoria Heap Ottenuta
-dashboard.heap_memory_idle=Memoria Heap Inattiva
-dashboard.heap_memory_in_use=Memoria Heap In Uso
-dashboard.heap_memory_released=Memoria Heap Rilasciata
-dashboard.heap_objects=Oggetti dell'Heap
-dashboard.bootstrap_stack_usage=Utilizzo Pila di Bootstrap
-dashboard.stack_memory_obtained=Memoria Stack Ottenuta
-dashboard.mspan_structures_usage=Utilizzo Strutture MSpan
-dashboard.mspan_structures_obtained=Strutture MSpan Ottenute
-dashboard.mcache_structures_usage=Utilizzo di Strutture MCache
-dashboard.mcache_structures_obtained=Strutture MCache Ottenute
-dashboard.profiling_bucket_hash_table_obtained=Tabella di Hash del Bucket Ottenuta
-dashboard.gc_metadata_obtained=Metadata della GC ottenuta
-dashboard.other_system_allocation_obtained=Altre Allocazioni di Sistema Ottenute
-dashboard.next_gc_recycle=Prossimo Riciclaggio GC
-dashboard.last_gc_time=Dall'Ultimo GC
+dashboard.current_heap_usage=Utilizzo heap attuale
+dashboard.heap_memory_obtained=Memoria heap ottenuta
+dashboard.heap_memory_idle=Memoria heap inattiva
+dashboard.heap_memory_in_use=Memoria heap in uso
+dashboard.heap_memory_released=Memoria heap rilasciata
+dashboard.heap_objects=Oggetti dell'heap
+dashboard.bootstrap_stack_usage=Utilizzo pila iniziale
+dashboard.stack_memory_obtained=Memoria pila ottenuta
+dashboard.mspan_structures_usage=Utilizzo strutture MSpan
+dashboard.mspan_structures_obtained=Strutture MSpan ottenute
+dashboard.mcache_structures_usage=Utilizzo di strutture MCache
+dashboard.mcache_structures_obtained=Strutture MCache ottenute
+dashboard.profiling_bucket_hash_table_obtained=Tabelle hash del secchio di profilazione ottenute
+dashboard.gc_metadata_obtained=Metadata del GC ottenuto
+dashboard.other_system_allocation_obtained=Altre allocazioni di sistema ottenute
+dashboard.next_gc_recycle=Prossimo riciclaggio GC
+dashboard.last_gc_time=Dall'ultimo GC
dashboard.total_gc_time=Pausa Totale della GC
-dashboard.total_gc_pause=Pausa Totale della GC
-dashboard.last_gc_pause=Ultima pausa della GC
+dashboard.total_gc_pause=Pausa totale del GC
+dashboard.last_gc_pause=Ultima pausa del GC
dashboard.gc_times=Esecuzioni GC
dashboard.delete_old_actions=Elimina tutte le vecchie azioni dal database
dashboard.delete_old_actions.started=Elimina tutte le vecchie azioni dal database iniziate.
dashboard.update_checker=Controllore dell'aggiornamento
dashboard.delete_old_system_notices=Elimina tutte le vecchie notifiche di sistema dal database
-users.user_manage_panel=Gestione account utente
+users.user_manage_panel=Gestici account utente
users.new_account=Crea account utente
users.name=Nome utente
-users.full_name=Nome Completo
+users.full_name=Nome completo
users.activated=Attivato
users.admin=Amministratore
users.restricted=Limitato
@@ -2546,24 +2891,24 @@ users.local=Locale
users.auth_login_name=Nome utente per l'autenticazione
users.password_helper=Lascia la password vuota per non modificarla.
users.update_profile_success=L'account utente è stato aggiornato.
-users.edit_account=Modifica account utente
-users.max_repo_creation=Numero massimo di repository
+users.edit_account=Modifica profilo utente
+users.max_repo_creation=Numero massimo di progetti
users.max_repo_creation_desc=(Inserire -1 per utilizzare il limite predefinito globale.)
users.is_activated=Account utente attivato
-users.prohibit_login=Disattiva login
+users.prohibit_login=Disattiva accesso
users.is_admin=È amministratore
users.is_restricted=È limitato
-users.allow_git_hook=Può creare Git Hook
-users.allow_git_hook_tooltip=Git Hooks sono eseguiti come l'utente OS che esegue Forgejo e avrà lo stesso livello di accesso host. Di conseguenza, gli utenti con questo speciale privilegio Git Hook possono accedere e modificare tutti i repository Forgejo e il database utilizzato da Forgejo. Di conseguenza sono anche in grado di ottenere privilegi di amministratore Forgejo.
-users.allow_import_local=Può importare repository locali
+users.allow_git_hook=Può creare hook Git
+users.allow_git_hook_tooltip=Gli hook Git sono eseguiti come l'utente OS che esegue Forgejo e avrà lo stesso livello di accesso host. Di conseguenza, gli utenti con questo speciale privilegio hook Git, possono accedere e modificare tutti i repository Forgejo e il database utilizzato da Forgejo. Di conseguenza sono anche in grado di ottenere privilegi di amministratore Forgejo.
+users.allow_import_local=Può importare progetti locali
users.allow_create_organization=Può creare organizzazioni
-users.update_profile=Aggiorna account utente
-users.delete_account=Elimina account utente
+users.update_profile=Aggiorna profilo utente
+users.delete_account=Elimina profilo utente
users.cannot_delete_self=Non puoi eliminare te stesso
users.still_own_repo=Questo utente possiede ancora una o più repository. Eliminare o trasferire questi repository prima di continuare.
users.still_has_org=Questo utente è membro di un'organizzazione. Rimuovi l'utente da tutte le organizzazioni prima di proseguire.
users.purge=Elimina Utente
-users.purge_help=Eliminare forzatamente l'utente e tutti i depositi, le organizzazioni e i pacchetti di proprietà dell'utente. Tutti i commenti verranno eliminati troppo.
+users.purge_help=Eliminare forzatamente l'utente e tutti i progetti, le organizzazioni e i pacchetti di proprietà dell'utente. Anche tutti i commenti e le segnalazioni verranno eliminati.
users.deletion_success=L'account utente è stato eliminato.
users.reset_2fa=Resetta 2FA
users.list_status_filter.menu_text=Filtro
@@ -2579,26 +2924,26 @@ users.list_status_filter.not_prohibit_login=Consenti Login
users.list_status_filter.is_2fa_enabled=2FA Abilitato
users.list_status_filter.not_2fa_enabled=2FA Disabilitato
-emails.email_manage_panel=Gestione delle Email Utente
+emails.email_manage_panel=Gestisci email dell'utente
emails.primary=Primario
emails.activated=Attivato
emails.filter_sort.email=Email
emails.filter_sort.email_reverse=Email (inverso)
-emails.filter_sort.name=Nome Utente
+emails.filter_sort.name=Nome utente
emails.filter_sort.name_reverse=Nome utente (inverso)
emails.updated=Email aggiornata
emails.not_updated=Impossibile aggiornare l'indirizzo email richiesto: %v
emails.duplicate_active=Questo indirizzo email risulta già attivo per un altro utente.
emails.change_email_header=Aggiorna proprietà email
-orgs.org_manage_panel=Gestione Organizzazione
+orgs.org_manage_panel=Gestisci organizzazioni
orgs.name=Nome
orgs.teams=Team
orgs.members=Membri
-orgs.new_orga=Nuova Organizzazione
+orgs.new_orga=Nuova organizzazione
-repos.repo_manage_panel=Gestione Repository
-repos.unadopted=Depositi Non Adottati
+repos.repo_manage_panel=Gestisci progetti
+repos.unadopted=Progetti non adottati
repos.unadopted.no_more=Nessun repository non adottato trovato
repos.owner=Proprietario
repos.name=Nome
@@ -2609,7 +2954,7 @@ repos.forks=Fork
repos.issues=Problemi
repos.size=Dimensione
-packages.package_manage_panel=Gestione Pacchetti
+packages.package_manage_panel=Gestisci pacchetti
packages.total_size=Dimensione totale: %s
packages.owner=Proprietario
packages.creator=Creatore
@@ -2620,11 +2965,11 @@ packages.repository=Repository
packages.size=Dimensione
packages.published=Pubblicata
-defaulthooks=Webhook predefiniti
+defaulthooks=Richiami HTTP predefiniti
defaulthooks.add_webhook=Aggiungi Webhook predefinito
defaulthooks.update_webhook=Aggiorna Webhook predefinito
-systemhooks=Webhooks di Sistema
+systemhooks=Richiami HTTP di sistema
systemhooks.add_webhook=Aggiungi Webhook di Sistema
systemhooks.update_webhook=Aggiorna Webhook di Sistema
@@ -2642,7 +2987,7 @@ auths.domain=Dominio
auths.host=Host
auths.port=Porta
auths.bind_dn=Binda DN
-auths.bind_password=Binda Password
+auths.bind_password=Associa password
auths.user_base=Base ricerca utente
auths.user_dn=DN dell'utente
auths.attribute_username=Attributo nome utente
@@ -2651,19 +2996,19 @@ auths.attribute_name=Attributo nome
auths.attribute_surname=Attributo cognome
auths.attribute_mail=Attributo email
auths.attribute_ssh_public_key=Attributo chiave SSH pubblica
-auths.attribute_avatar=Attributo Avatar
-auths.attributes_in_bind=Estrai Attributi dal Contesto Bind DN
+auths.attribute_avatar=Attributo avatar
+auths.attributes_in_bind=Estrai attributi dal contesto nind DN
auths.allow_deactivate_all=Consenti un risultato di ricerca vuoto per disattivare tutti gli utenti
auths.use_paged_search=Utilizza ricerca per pagina
auths.search_page_size=Dimensioni pagina
-auths.filter=Fitro utente
-auths.admin_filter=Filtro Amministratore
+auths.filter=Filtro utente
+auths.admin_filter=Filtro amministratore
auths.restricted_filter=Filtro riservato
-auths.restricted_filter_helper=Lasciare vuoto per non impostare alcun utente come limitato. Utilizzare un asterisco ('*') per impostare tutti gli utenti che non corrispondono al filtro amministratore.
+auths.restricted_filter_helper=Lascia vuoto per non impostare alcun utente come limitato. Utilizzare un asterisco ("*") per impostare tutti gli utenti che non corrispondono al filtro amministratore.
auths.verify_group_membership=Verifica l'appartenenza al gruppo in LDAP (lascia vuoto il filtro per saltare)
-auths.group_search_base=Ricerca Gruppo Base DN
-auths.group_attribute_list_users=Gruppo Attributo Contenente Elenco Utenti
-auths.user_attribute_in_group=Attributo Utente Elencato nel Gruppo
+auths.group_search_base=Ricerca gruppo base DN
+auths.group_attribute_list_users=Raggruppa attributo contente lista di utenti
+auths.user_attribute_in_group=Attributo utente elencato nel gruppo
auths.map_group_to_team=Mappa i gruppi LDAP alle squadre dell'organizzazione (lasciare vuoto il campo per saltare)
auths.map_group_to_team_removal=Rimuovi gli utenti dai team sincronizzati se l'utente non appartiene al gruppo LDAP corrispondente
auths.enable_ldap_groups=Abilita gruppi LDAP
@@ -2672,16 +3017,16 @@ auths.smtp_auth=Tipo di autenticazione SMTP
auths.smtphost=Host SMTP
auths.smtpport=Porta SMTP
auths.allowed_domains=Domini consentiti
-auths.allowed_domains_helper=Lasciare vuoto per ammettere tutti i domini. Separare più domini con una virgola (',').
+auths.allowed_domains_helper=Lasciare vuoto per ammettere tutti i domini. Separare più domini con una virgola (",").
auths.skip_tls_verify=Salta verifica TLS
auths.force_smtps=Forza SMTPS
auths.force_smtps_helper=SMTPS è sempre utilizzato sulla porta 465. Impostalo per forzare SMTPS su altre porte. (Otherwise STARTTLS sarà utilizzato su altre porte se è supportato dall'host.)
auths.helo_hostname=HELO nome dell'host
auths.helo_hostname_helper=Nome host inviato con HELO. Lasciare vuoto per inviare il nome host corrente.
auths.disable_helo=Disattiva HELO
-auths.pam_service_name=Nome del Servizio PAM
-auths.pam_email_domain=Dominio Email PAM (opzionale)
-auths.oauth2_provider=OAuth2 Provider
+auths.pam_service_name=Nome del servizio PAM
+auths.pam_email_domain=Dominio email PAM (opzionale)
+auths.oauth2_provider=Fornitore OAuth2
auths.oauth2_icon_url=URL icona
auths.oauth2_clientID=ID Client (Chiave)
auths.oauth2_clientSecret=Segreto del client
@@ -2694,15 +3039,15 @@ auths.oauth2_emailURL=URL email
auths.skip_local_two_fa=Salta 2FA locale
auths.skip_local_two_fa_helper=Lasciare l'azzeramento significa che gli utenti locali con il set 2FA dovranno ancora passare 2FA per accedere
auths.oauth2_tenant=Comproprietà
-auths.oauth2_scopes=Ambiti Aggiuntivi
-auths.oauth2_required_claim_name=Nome Richiesto
+auths.oauth2_scopes=Ambiti aggiuntivi
+auths.oauth2_required_claim_name=Nome richiesto
auths.oauth2_required_claim_name_helper=Imposta questo nome per limitare il login da questa fonte agli utenti con un reclamo con questo nome
-auths.oauth2_required_claim_value=Valore Richiesto
+auths.oauth2_required_claim_value=Valore richiesto
auths.oauth2_required_claim_value_helper=Imposta questo valore per limitare il login da questa fonte agli utenti con un reclamo con questo nome e valore
auths.oauth2_group_claim_name=Riscatta nome che fornisce nomi di gruppo per questa fonte (facoltativo)
auths.oauth2_admin_group=Valore del reclamo di gruppo per gli utenti amministratori. (Opzionale - richiede il nome della richiesta sopra)
auths.oauth2_restricted_group=Valore di reclamo di gruppo per utenti ristretti. (Facoltativo - richiede il nome di reclamo sopra)
-auths.enable_auto_register=Abilitare Registrazione Automatica
+auths.enable_auto_register=Abilita registrazione automatica
auths.sspi_auto_create_users=Crea automaticamente gli utenti
auths.sspi_auto_create_users_helper=Permetti al metodo di autenticazione SSPI di creare automaticamente nuovi account per gli utenti che accedono per la prima volta
auths.sspi_auto_activate_users=Attiva automaticamente gli utenti
@@ -2715,8 +3060,8 @@ auths.sspi_default_language=Lingua predefinita dell'utente
auths.sspi_default_language_helper=Lingua predefinita per gli utenti creati automaticamente dal metodo di autenticazione SSPI. Lascia vuoto se preferisci che la lingua venga rilevata automaticamente.
auths.tips=Consigli
auths.tips.oauth2.general=Autenticazione OAuth2
-auths.tip.oauth2_provider=OAuth2 Provider
-auths.tip.bitbucket=Registra un nuovo cliente OAuth su https://bitbucket.org/account/user//oauth-consumers/new e aggiungi il permesso 'Account' - 'Read'
+auths.tip.oauth2_provider=Fornitore OAuth2
+auths.tip.bitbucket=Registra un nuovo cliente OAuth su https://bitbucket.org/account/user//oauth-consumers/new e aggiungi il permesso "Account" - "Read"
auths.tip.nextcloud=`Registra un nuovo OAuth sulla tua istanza utilizzando il seguente menu "Impostazioni -> Sicurezza -> OAuth 2.0 client"`
auths.tip.dropbox=Crea una nuova applicazione su https://www.dropbox.com/developers/apps
auths.tip.facebook=`Registra una nuova applicazione su https://developers.facebook.com/apps e aggiungi il prodotto "Facebook Login"`
@@ -2739,33 +3084,33 @@ auths.still_in_used=La fonte di autenticazione è ancora in uso. Convertire o el
auths.deletion_success=La fonte d'autenticazione è stata eliminata.
auths.login_source_of_type_exist=Esiste già una fonte di autenticazione di questo tipo.
-config.server_config=Configurazione Server
-config.app_name=Titolo del Sito
+config.server_config=Configurazione server
+config.app_name=Titolo del sito
config.app_ver=Versione Forgejo
config.app_url=URL di base di Forgejo
config.custom_conf=Percorso file di configurazione
-config.custom_file_root_path=Percorso Root File Personalizzato
-config.domain=Dominio Server
+config.custom_file_root_path=Percorso root file personalizzato
+config.domain=Dominio server
config.offline_mode=Modalità locale
-config.disable_router_log=Disattivare Log del Router
-config.run_user=Esegui come Nome utente
-config.run_mode=Modalità Esecuzione
+config.disable_router_log=Disattivare log del router
+config.run_user=Nome utente con cui eseguire
+config.run_mode=Modalità di esecuzione
config.git_version=Versione Git
-config.repo_root_path=Percorso radice del Repository
-config.lfs_root_path=Percorso file LFS
+config.repo_root_path=Percorso radice del progetto
+config.lfs_root_path=Percorso radice LFS
config.log_file_root_path=Percorso dei log
-config.script_type=Tipo di Script
-config.reverse_auth_user=Autenticazione Utente Inversa
+config.script_type=Tipo di script
+config.reverse_auth_user=Autenticazione utente inversa
config.ssh_config=Configurazione SSH
config.ssh_enabled=Attivo
-config.ssh_start_builtin_server=Usa il server integrato
-config.ssh_domain=Dominio Server Ssh
+config.ssh_start_builtin_server=Usa il server incorporato
+config.ssh_domain=Dominio server SSH
config.ssh_port=Porta
config.ssh_listen_port=Porta in ascolto
-config.ssh_root_path=Percorso Root
+config.ssh_root_path=Percorso radice
config.ssh_key_test_path=Percorso chiave di test
-config.ssh_keygen_path=Percorso Keygen ('ssh-keygen')
+config.ssh_keygen_path=Percorso keygen ("ssh-keygen")
config.ssh_minimum_key_size_check=Verifica delle dimensioni minime della chiave
config.ssh_minimum_key_sizes=Dimensioni minime della chiave
@@ -2774,7 +3119,7 @@ config.lfs_enabled=Abilitato
config.lfs_content_path=Percorso del contenuto LFS
config.lfs_http_auth_expiry=Scadenza autenticazione LFS HTTP
-config.db_config=Configurazione Database
+config.db_config=Configurazione base di dati
config.db_type=Tipo
config.db_host=Host
config.db_name=Nome
@@ -2783,31 +3128,31 @@ config.db_schema=Schema
config.db_ssl_mode=SSL
config.db_path=Percorso
-config.service_config=Configurazione Servizio
-config.register_email_confirm=Richiedere la conferma Email per registrarsi
-config.disable_register=Disattiva Self-Registration
+config.service_config=Configurazione servizio
+config.register_email_confirm=Richiedi conferma email per registrarsi
+config.disable_register=Disattiva auto registrazione
config.allow_only_internal_registration=Consenti la registrazione solo tramite Forgejo stessa
config.allow_only_external_registration=Attiva la registrazione solo tramite servizi esterni
-config.enable_openid_signup=Attiva OpenID Self-Registration
+config.enable_openid_signup=Attiva auto registrazione OpenID
config.enable_openid_signin=Attiva l'accesso tramite OpenID
-config.show_registration_button=Mostra Pulsane Registrazione
-config.require_sign_in_view=Richiedi l'accesso per visualizzare le pagine
-config.mail_notify=Attila le notifiche Email
+config.show_registration_button=Mostra tasto per la registrazione
+config.require_sign_in_view=Richiedi l'accesso per visualizzare il contenuto
+config.mail_notify=Attila le notifiche email
config.enable_captcha=Attiva CAPTCHA
-config.active_code_lives=Attiva Vita del Codice
-config.reset_password_code_lives=Recupera il codice di scadenza del tempo del tuo account
-config.default_keep_email_private=Nascondi Indirizzo Email di Default
-config.default_allow_create_organization=Consenti la Creazione di Organizzazioni di Default
+config.active_code_lives=Attiva scadenza del codice
+config.reset_password_code_lives=Tempo di scadenza per il codice di recupero
+config.default_keep_email_private=Nascondi indirizzo email in modo predefinito
+config.default_allow_create_organization=Consenti la creazione di organizzazioni in modo predefinito
config.enable_timetracking=Abilita il cronografo
-config.default_enable_timetracking=Attiva il cronografo di Default
+config.default_enable_timetracking=Attiva il cronografo di default
config.default_allow_only_contributors_to_track_time=Consenti soltanto ai contributori di utilizzare il cronografo
config.no_reply_address=Dominio email nascosto
config.default_visibility_organization=Visibilità predefinita per le nuove organizzazioni
-config.default_enable_dependencies=Abilita i problemi delle dipendenze di default
+config.default_enable_dependencies=Abilita le segnalazioni delle dipendenze in modo predefinito
-config.webhook_config=Configurazione Webhook
+config.webhook_config=Configurazione richiami HTTP
config.queue_length=Lunghezza della coda
-config.deliver_timeout=Tempo Limite di Consegna
+config.deliver_timeout=Tempo limite di consegna
config.skip_tls_verify=Salta autenticazione TLS
config.mailer_config=Configurazione Mailer
@@ -2829,46 +3174,46 @@ config.send_test_mail=Invia email di prova
config.oauth_config=Configurazione OAuth
config.oauth_enabled=Attivo
-config.cache_config=Configurazione Cache
-config.cache_adapter=Adattatore Cache
-config.cache_interval=Intervallo Cache
-config.cache_conn=Connessione Cache
-config.cache_item_ttl=Cache degli elementi TTL
+config.cache_config=Configurazione cache
+config.cache_adapter=Adattatore cache
+config.cache_interval=Intervallo cache
+config.cache_conn=Connessione cache
+config.cache_item_ttl=TTL degli elementi della cache
-config.session_config=Configurazione Sessione
-config.session_provider=Fornitore Sessione
-config.provider_config=Impostazioni Provider
-config.cookie_name=Nome del Cookie
-config.gc_interval_time=Intervallo di tempo della GC
-config.session_life_time=Durata Sessione
+config.session_config=Configurazione sessione
+config.session_provider=Fornitore sessione
+config.provider_config=Impostazioni fornitore
+config.cookie_name=Nome del cookie
+config.gc_interval_time=Intervallo di tempo del GC
+config.session_life_time=Durata sessione
config.https_only=Solo HTTPS
-config.cookie_life_time=Durata Cookie
+config.cookie_life_time=Durata cookie
-config.picture_config=Configurazione Immagine profilo e Avatar
+config.picture_config=Configurazione Immagine profilo e avatar
config.picture_service=Servizio foto
config.disable_gravatar=Disabilita Gravatar
-config.enable_federated_avatar=Attiva i Federated Avatar
+config.enable_federated_avatar=Attiva gli avatar federati
config.git_config=Configurazione Git
-config.git_disable_diff_highlight=Disattiva evidenziatore Diff Syntax
-config.git_max_diff_lines=Numero massimo di righe di diff (per singolo file)
-config.git_max_diff_line_characters=Numero massimo di caratteri di diff (per singola riga)
-config.git_max_diff_files=Numero massimo di file diff mostrati
+config.git_disable_diff_highlight=Disattiva sintassi evidenziate per le differenze
+config.git_max_diff_lines=Numero massimo di righe delle differenze (per singolo file)
+config.git_max_diff_line_characters=Numero massimo di caratteri delle differenze (per singola riga)
+config.git_max_diff_files=Numero massimo di file differenze mostrati
config.git_gc_args=Parametri GC
config.git_migrate_timeout=Timeout per la migrazione
-config.git_mirror_timeout=Timeout per l'aggiornamento del mirror
+config.git_mirror_timeout=Timeout per l'aggiornamento dello specchio
config.git_clone_timeout=Tempo limite operazione di clone
-config.git_pull_timeout=Tempo limite operazione di pull
+config.git_pull_timeout=Tempo limite operazione di prelievo
config.git_gc_timeout=Timeout operazione GC
-config.log_config=Configurazione Log
+config.log_config=Configurazione log
config.disabled_logger=Disabilitato
config.access_log_mode=Modalità log di accesso
config.xorm_log_sql=Log SQL
-monitor.cron=Incarichi Cron
+monitor.cron=Compiti cron
monitor.name=Nome
monitor.schedule=Agenda
monitor.next=La Prossima Volta
@@ -2890,17 +3235,17 @@ monitor.queue=Coda: %s
monitor.queue.name=Nome
monitor.queue.type=Tipo
monitor.queue.exemplar=Tipo di esemplare
-monitor.queue.numberworkers=Numero di workers
-monitor.queue.maxnumberworkers=Massimo numero di Workers
+monitor.queue.numberworkers=Numero di lavoratori
+monitor.queue.maxnumberworkers=Massimo numero di lavoratori
monitor.queue.numberinqueue=Numero in coda
-monitor.queue.settings.title=Impostazioni pool
+monitor.queue.settings.title=Impostazioni piscina
monitor.queue.settings.maxnumberworkers=Massimo numero di workers
monitor.queue.settings.maxnumberworkers.placeholder=Attualmente %[1]d
monitor.queue.settings.maxnumberworkers.error=Il numero massimo di lavoratori deve essere un numero
-monitor.queue.settings.submit=Aggiorna Impostazioni
-monitor.queue.settings.changed=Impostazioni Aggiornate
+monitor.queue.settings.submit=Aggiorna impostazioni
+monitor.queue.settings.changed=Impostazioni aggiornate
-notices.system_notice_list=Avvisi di Sistema
+notices.system_notice_list=Avvisi di sistema
notices.view_detail_header=Visualizza dettagli dell'avviso
notices.select_all=Seleziona tutto
notices.deselect_all=Deseleziona tutto
@@ -2920,6 +3265,62 @@ users.reserved = Riservato
notices.operations = Operazioni
users.bot = Bot
config.send_test_mail_submit = Invia
+dashboard.cron.cancelled = Cron: %[1]s cancellato: %[3]s
+dashboard.new_version_hint = Forgejo %s è ora disponibile, stai eseguendo %s. Controlla il blog per ulteriori dettagli.
+dashboard.sync_repo_branches = Sincronizza rami omessi dai dati Git nella base di dati
+dashboard.gc_lfs = Oggetti meta LFS riciclati
+dashboard.sync_tag.started = Sincronizzazione delle etichette iniziata
+self_check = Auto controllo
+identity_access = Identità e accesso
+assets = Risorse codice
+settings = Impostazioni amministratore
+dashboard.task.cancelled = Compito: %[1]s cancellato: %[3]s
+dashboard.sync_repo_tags = Sincronizza etichette dai dati Git alla base di dati
+users.new_success = Il profilo utente "%s" è stato creato.
+users.still_own_packages = Questo utente possiede ancora uno o più pacchetti, elimina questi pacchetti prima.
+auths.oauth2_map_group_to_team = Associa gruppi reclamati a squadre di organizzazioni. (opzionale - richiede il nome reclamo sopra)
+auths.tip.gitea = Registra una nuova applicazione OAuth2. La guida può essere trovata a https://docs.gitea.com/development/oauth2-provider
+config.test_mail_sent = Una email di prova è stata inviata a "%s".
+monitor.processes_count = %d processi
+monitor.download_diagnosis_report = Scarica relazione diagnostica
+monitor.queue.activeworkers = Lavoratori attivi
+config.app_data_path = Percorso dati dell'applicazione
+packages.cleanup = Pulisci dati scaduti
+dashboard.cleanup_actions = Pulisci log scaduti e artefatti dalle azioni
+dashboard.stop_endless_tasks = Termina compiti senza fine
+dashboard.start_schedule_tasks = Inizia pianificazione compiti
+dashboard.cancel_abandoned_jobs = Cancella lavori abbandonati
+auths.login_source_exist = La fonte di autenticazione "%s" esiste già.
+auths.invalid_openIdConnectAutoDiscoveryURL = URL di auto scoperta invalido (questo deve essere un URL valido che inizia con http:// o con https://)
+config.access_log_template = Modello log di accesso
+config.set_setting_failed = Impossibile impostare il parametro %s
+auths.unable_to_initialize_openid = Impossibile inizializzare OpenID Connect Provider: %s
+dashboard.stop_zombie_tasks = Termina compiti zombie
+dashboard.sync_branch.started = Sincronizzazione dei rami iniziata
+dashboard.rebuild_issue_indexer = Ricostruzione dell'indicizzatore delle segnalazioni
+emails.change_email_text = Sei sicuro di voler aggiornare questo indirizzo email?
+repos.lfs_size = Dimensione LFS
+packages.unreferenced_size = Dimensione senza riferimenti: %s
+packages.cleanup.success = Dati scaduti puliti correttamente
+defaulthooks.desc = I richiami HTTP fanno automaticamente richieste POST al server innescati da alcuni eventi di Forgejo. I richiami HTTP definiti qui sono predefiniti e saranno copiati in tutti i nuovi progetti. Leggi di più nella guida sui richiami HTTP.
+auths.oauth2_map_group_to_team_removal = Rimuovi utenti dalle squadre sincronizzate se l'utente non appartiene al gruppo corrispondente.
+auths.tips.oauth2.general.tip = Quando si registra una nuova autenticazione OAuth2, l'URL di richiamata/reindirizzamento dovrebbe essere:
+config.logger_name_fmt = Logger: %s
+systemhooks.desc = I richiami HTTP fanno automaticamente richieste POST al server innescati da alcuni eventi di Forgejo. I richiami HTTP definiti qui agiranno su tutti i progetti nel sistema, quindi considera li implicazioni sulle prestazioni che questi possono avere. Leggi di più nella guida sui richiami HTTP.
+auths.new_success = L'autenticazione "%s" è stata aggiunta.
+auths.tips.gmail_settings = Impostazioni Gmail:
+config.test_mail_failed = Impossibile inviare email di prova a "%s": %v
+users.details = Dettagli dell'utente
+monitor.queue.review_add = Revisiona / aggiungi lavoratori
+self_check.no_problem_found = Nessun problema trovato.
+self_check.database_inconsistent_collation_columns = La base di dati sta usando la collazione %s ma queste colonne usano una collazione diversa. Potrebbe causare problemi imprevisti.
+monitor.queue.settings.remove_all_items = Rimuovi tutto
+monitor.queue.settings.desc = Le piscine crescono dinamicamente in risposta al blocco dei lavoratori in coda.
+monitor.queue.settings.remove_all_items_done = Tutti gli elementi in coda sono stati rimossi.
+self_check.database_collation_mismatch = Pretendi che la base di dati usi la collazione: %s
+self_check.database_fix_mysql = Per utenti MySQL/MariaDB, potresti usare il comando "gitea doctor convert" per risolvere problemi di collazione, o potresti risolvere il problema manualmente tramite SQL con "ALTER ... COLLATE ...".
+self_check.database_collation_case_insensitive = La base di dati sta usando la collazione %s, che è una collazione insensibile. Nonostante Forgejo potrebbe lavorarci, ci potrebbero essere rari casi che non vanno come previsto.
+self_check.database_fix_mssql = Gli utenti MSSQL possono provare a risolvere il problema tramite SQL con "ALTER ... COLLATE ..." manualmente, per il momento.
[action]
@@ -2952,6 +3353,8 @@ review_dismissed_reason=Motivo:
create_branch=ha creato il ramo %[3]s in %[4]s
starred_repo=ha salvato come preferito %[2]s
watched_repo=ha iniziato a guardare %[2]s
+commit_repo = immesso a %[3]s a %[4]s
+auto_merge_pull_request = `richiesta di modifica %[3]s#%[2]s fusa automaticamente`
[tool]
now=ora
@@ -2990,6 +3393,8 @@ mark_as_read=Segna come letto
mark_as_unread=Segna come non letto
mark_all_as_read=Segna tutti come letti
subscriptions = Sottoscrizioni
+watching = Osservando
+no_subscriptions = Nessuna iscrizione
[gpg]
default_key=Firmato con la chiave predefinita
@@ -2998,7 +3403,7 @@ error.generate_hash=Impossibile generare hash del commit
error.no_committer_account=Nessun account collegato all'indirizzo email del committer
error.no_gpg_keys_found=Non sono state trovate chiavi note per questa firma nel database
error.not_signed_commit=Commit non firmato
-error.failed_retrieval_gpg_keys=Impossibile recuperare le chiavi associate all'account del committer
+error.failed_retrieval_gpg_keys=Impossibile recuperare le chiavi associate al profilo dell'autore del commit
error.probable_bad_signature=ATTENZIONE! Anche se esiste una chiave con questo ID nel database, essa non verifica questo commit! Questo commit è SOSPETTO.
error.probable_bad_default_signature=ATTENZIONE! Anche se la chiave predefinita ha questo ID essa non verifica questo commit! Questo commit è SOSPETTO.
@@ -3026,7 +3431,7 @@ dependencies=Dipendenze
keywords=Parole Chiave
details=Dettagli
details.author=Autore
-details.project_site=Sito Del Progetto
+details.project_site=Sito del progetto
details.license=Licenza
assets=Asset
versions=Versioni
@@ -3103,6 +3508,32 @@ container.digest = Digest:
debian.repository.components = Componenti
alpine.repository.architectures = Architetture
debian.repository.distributions = Distribuzioni
+empty.documentation = Per ulteriori informazioni sul registro dei pacchetti vedi la documentazione.
+registry.documentation = Per ulteriori informazioni sul registro %s vedi la documentazione.
+details.repository_site = Sito del progetto
+details.documentation_site = Sito della documentazione
+alpine.registry = Imposta questo registro aggiungendo l'URL nel tuo file /etc/apk/repositories
:
+alpine.registry.key = Scarica la chiave RSA pubblica del registro nella cartella /etc/apk/keys/
per verificare la firma dell'indice:
+alpine.repository = Informazioni sul progetto
+cargo.registry = Imposta il registro nel file di configurazione di Cargo (per esempio ~/.cargo/config.toml
):
+chef.registry = Imposta questo registro nel tuo file ~/.chef/config.rb
:
+conda.registry = Imposta questo registro come un progetto Conda nel tuo file .condarc
:
+conda.install = Per installare il pacchetto usando conda, esegui il comando seguente:
+debian.registry.info = Scegli $distribuzione e $componente dalla lista sotto.
+debian.repository = Informazioni sul progetto
+go.install = Installa il pacchetto dalla riga di comando:
+rpm.distros.suse = sulle distribuzioni basate su SUSE
+rpm.repository = Informazioni sul progetto
+swift.install = Aggiungi il pacchetto nel tuo file Package.swift
:
+swift.install2 = ed esegui il comando seguente:
+vagrant.install = Per aggiungere una scatola Vagrant esegui il comando seguente:
+owner.settings.cargo.initialize = Inizializza indice
+rpm.distros.redhat = sulle distribuzione basate su RedHat
+alpine.registry.info = scegli $ramo e $progetto dalla lista sotto.
+cargo.install = Per installare il pacchetto usando Cargo esegui il comando seguente:
+cran.registry = Imposta questo registro nel tuo file Rprofile.site
:
+rpm.repository.multiple_groups = Questo pacchetto è disponibile in molteplici gruppi.
+owner.settings.cargo.title = Indice del registro di Cargo
[secrets]
secrets = Segreti
diff --git a/options/locale/locale_ja-JP.ini b/options/locale/locale_ja-JP.ini
index fcccac21cc..1aa00440d9 100644
--- a/options/locale/locale_ja-JP.ini
+++ b/options/locale/locale_ja-JP.ini
@@ -39,12 +39,12 @@ passcode=パスコード
webauthn_insert_key=セキュリティキーを挿入
webauthn_sign_in=セキュリティキーのボタンを押してください。セキュリティキーにボタンが無い場合は、挿入しなおしてください。
-webauthn_press_button=セキュリティキーのボタンを押してください...
+webauthn_press_button=セキュリティキーのボタンを押してください…
webauthn_use_twofa=携帯電話から2要素認証コードを使用する
webauthn_error=セキュリティキーを読み取ることができません。
webauthn_unsupported_browser=お使いのブラウザは現在 WebAuthn をサポートしていません。
webauthn_error_unknown=不明なエラーが発生しました。 もう一度やり直してください。
-webauthn_error_insecure=WebAuthn はセキュアな接続のみをサポートしています。HTTP 経由でテストする場合は、"localhost" または "127.0.0.1" のオリジンが使用できます。
+webauthn_error_insecure=WebAuthn はセキュアな接続のみをサポートしています。HTTP 経由でテストする場合は、"localhost" または "127.0.0.1" のオリジンが使用できます
webauthn_error_unable_to_process=サーバーがリクエストを処理できませんでした。
webauthn_error_duplicated=このリクエストに対しては、許可されていないセキュリティキーです。 キーが未登録であることを確認してください。
webauthn_error_empty=このキーに名前を設定する必要があります。
@@ -88,8 +88,8 @@ rerun_all=すべてのジョブを再実行
save=保存
add=追加
add_all=すべて追加
-remove=除去
-remove_all=すべて除去
+remove=削除
+remove_all=すべて削除
remove_label_str=アイテム「%s」を削除
edit=編集
view=表示
@@ -142,6 +142,19 @@ confirm_delete_selected=選択したすべてのアイテムを削除してよ
name=名称
value=値
+filter.is_archived = アーカイブ
+filter.not_archived = 非アーカイブ
+filter.is_fork = フォーク
+filter.is_mirror = ミラー
+filter.not_mirror = 非ミラー
+filter.is_template = テンプレート
+filter = フィルター
+filter.not_fork = 非フォーク
+filter.clear = フィルタをクリアする
+filter.public = 公開
+filter.private = 非公開
+toggle_menu = トグルメニュー
+filter.not_template = テンプレートではない
[aria]
navbar=ナビゲーションバー
@@ -150,8 +163,8 @@ footer.software=ソフトウェアについて
footer.links=リンク
[heatmap]
-number_of_contributions_in_the_last_12_months=過去 12 か月間で %s 個の貢献
-no_contributions=貢献なし
+number_of_contributions_in_the_last_12_months=過去 12 か月間で %s 件の貢献
+contributions_zero=貢献なし
less=少
more=多
@@ -225,7 +238,7 @@ err_admin_name_pattern_not_allowed=管理者のユーザー名が不正です。
err_admin_name_is_invalid=管理者のユーザー名が不正です
general_title=基本設定
-app_name=サイトタイトル
+app_name=インスタンスの名前
app_name_helper=企業名をここに入れることができます。
repo_path=リポジトリのルートパス
repo_path_helper=リモートGitリポジトリはこのディレクトリに保存されます。
@@ -237,7 +250,7 @@ domain=サーバードメイン
domain_helper=サーバーのドメインまたはホストアドレス。
ssh_port=SSHサーバーのポート
ssh_port_helper=SSHサーバーが使うポート番号。 空の場合はSSHサーバーを無効にします。
-http_port=Forgejo HTTPポート
+http_port=HTTPポート
http_port_helper=ForgejoのWebサーバーが使うポート番号。
app_url=ForgejoのベースURL
app_url_helper=HTTP(S)のクローンURLとメール通知で使うベースアドレス。
@@ -280,7 +293,7 @@ confirm_password=パスワード確認
admin_email=メールアドレス
install_btn_confirm=Forgejoをインストール
test_git_failed="git"コマンドが確認できません: %v
-sqlite3_not_available=ForgejoのこのバージョンはSQLite3をサポートしていません。 公式のバイナリ版を %s からダウンロードしてください。 ("gobuild"版でないもの)
+sqlite3_not_available=ForgejoのこのバージョンはSQLite3をサポートしていません。 公式のバイナリ版を %s からダウンロードしてください ("gobuild"版でないもの)。
invalid_db_setting=データベース設定が無効です: %v
invalid_db_table=データベーステーブルの "%s" が無効です: %v
invalid_repo_path=リポジトリのルートパスが無効です: %v
@@ -307,6 +320,9 @@ enable_update_checker_helper=gitea.ioに接続して定期的に新しいバー
env_config_keys=環境設定
env_config_keys_prompt=以下の環境変数も設定ファイルに適用されます:
allow_dots_in_usernames = ユーザー名にドットを使用できるようにします。既存のアカウントには影響しません。
+smtp_from_invalid = メール送信者のアドレスが無効です
+enable_update_checker_helper_forgejo = Forgejoの最新バージョンを、release.forgejo.orgのDNSのTXTレコードを定期的に参照して取得します。
+config_location_hint = この設定は次に保存されます:
[home]
uname_holder=ユーザー名またはメールアドレス
@@ -398,7 +414,7 @@ twofa_scratch_used=あなたはスクラッチコードを使用しました。
twofa_passcode_incorrect=パスコードが正しくありません。デバイスを紛失した場合は、スクラッチコードを使ってサインインしてください。
twofa_scratch_token_incorrect=スクラッチコードが正しくありません。
login_userpass=サインイン
-login_openid=OpenID
+tab_openid=OpenID
oauth_signup_tab=新規アカウント登録
oauth_signup_title=新規アカウントの仕上げ
oauth_signup_submit=アカウント登録完了
@@ -602,6 +618,8 @@ admin_cannot_delete_self = 管理者である場合、自分自身を削除す
username_error_no_dots = `英数字 (「0-9」、「a-z」、「A-Z」)、ダッシュ (「-」)、およびアンダースコア (「_」) のみを含めることができます。英数字以外の文字で開始または終了することはできず、連続した英数字以外の文字も禁止されています。`
admin_cannot_delete_self=あなたが管理者である場合、自分自身を削除することはできません。最初に管理者権限を削除してください。
+unset_password = ログインしたユーザーにパスワードが設定されていません。
+unsupported_login_type = このログインタイプでは、アカウントの削除はサポートされていません。
[user]
change_avatar=アバターを変更…
@@ -634,6 +652,7 @@ block_user.detail_3 = このユーザーはあなたをコラボレーターと
block_user = ユーザーをブロック
unblock = ブロックを解除
block = ブロック
+block_user.detail = このユーザーをブロックした場合、下記の事などが起こります。例えば:
[settings]
profile=プロフィール
@@ -1199,9 +1218,9 @@ file_view_raw=Rawデータを見る
file_permalink=パーマリンク
file_too_large=このファイルは大きすぎるため、表示できません。
invisible_runes_header=このファイルには不可視のUnicode文字が含まれています
-invisible_runes_description=このファイルには人間が識別できない不可視のUnicode文字が含まれており、コンピューターによって特殊な処理が行われる可能性があります。 それが意図的なものと考えられる場合は、この警告を無視して構いません。 不可視文字を表示するにはエスケープボタンを使用します。
+invisible_runes_description=`このファイルには人間が識別できない不可視のUnicode文字が含まれており、コンピューターによって特殊な処理が行われる可能性があります。 それが意図的なものと考えられる場合は、この警告を無視して構いません。 不可視文字を表示するにはエスケープボタンを使用します。`
ambiguous_runes_header=このファイルには曖昧(ambiguous)なUnicode文字が含まれています
-ambiguous_runes_description=このファイルには、他の文字と見間違える可能性があるUnicode文字が含まれています。 それが意図的なものと考えられる場合は、この警告を無視して構いません。 それらの文字を表示するにはエスケープボタンを使用します。
+ambiguous_runes_description=`このファイルには、他の文字と見間違える可能性があるUnicode文字が含まれています。 それが意図的なものと考えられる場合は、この警告を無視して構いません。 それらの文字を表示するにはエスケープボタンを使用します。`
invisible_runes_line=`この行には不可視のUnicode文字があります`
ambiguous_runes_line=`この行には曖昧(ambiguous)なUnicode文字があります`
ambiguous_character=`%[1]c [U+%04[1]X] は %[2]c [U+%04[2]X] と混同するおそれがあります`
@@ -1534,7 +1553,7 @@ issues.role.member_helper=このユーザーはこのリポジトリを所有し
issues.role.collaborator=共同作業者
issues.role.collaborator_helper=このユーザーはリポジトリ上で共同作業するように招待されています。
issues.role.first_time_contributor=初めての貢献者
-issues.role.first_time_contributor_helper=これは、このユーザーのリポジトリへの最初の貢献です。
+issues.role.first_time_contributor_helper=これは、このユーザーによるリポジトリへの最初の貢献です。
issues.role.contributor=貢献者
issues.role.contributor_helper=このユーザーは以前にリポジトリにコミットしています。
issues.re_request_review=レビューを再依頼
@@ -1741,8 +1760,8 @@ pulls.nothing_to_compare=同じブランチ同士のため、 プルリクエス
pulls.nothing_to_compare_and_allow_empty_pr=これらのブランチは内容が同じです。 空のプルリクエストになります。
pulls.has_pull_request=`同じブランチのプルリクエストはすでに存在します: %[2]s#%[3]d`
pulls.create=プルリクエストを作成
-pulls.title_desc=が %[2]s
から %[3]s
への %[1]d コミットのマージを希望しています
-pulls.merged_title_desc=が %[1]d 個のコミットを %[2]s
から %[3]s
へマージ %[4]s
+pulls.title_desc_few=が %[2]s
から %[3]s
への %[1]d コミットのマージを希望しています
+pulls.merged_title_desc_few=が %[1]d 個のコミットを %[2]s
から %[3]s
へマージ %[4]s
pulls.change_target_branch_at=`がターゲットブランチを %s から %s に変更 %s`
pulls.tab_conversation=会話
pulls.tab_commits=コミット
@@ -2035,7 +2054,8 @@ settings.mirror_settings.docs.more_information_if_disabled=プッシュミラー
settings.mirror_settings.docs.doc_link_title=リポジトリをミラーリングするには?
settings.mirror_settings.docs.doc_link_pull_section=ドキュメントの「リモートリポジトリからのプル」セクション。
settings.mirror_settings.docs.pulling_remote_title=リモートリポジトリからのプル
-settings.mirror_settings.mirrored_repository=同期するリポジトリ
+settings.mirror_settings.mirrored_repository=ミラー元のリポジトリ
+settings.mirror_settings.pushed_repository=プッシュ先のリポジトリ
settings.mirror_settings.direction=方向
settings.mirror_settings.direction.pull=プル
settings.mirror_settings.direction.push=プッシュ
@@ -2471,7 +2491,7 @@ diff.too_many_files=変更されたファイルが多すぎるため、一部の
diff.show_more=さらに表示
diff.load=差分を読み込み
diff.generated=generated
-diff.vendored=vendored
+diff.vendored=vendor済み
diff.comment.add_line_comment=行コメントを追加
diff.comment.placeholder=コメントを残す
diff.comment.markdown_info=Markdownによる書式設定をサポートしています。
@@ -2601,6 +2621,44 @@ error.csv.invalid_field_count=このファイルは %d 行目のフィールド
admin.enabled_flags = このリポジトリで有効になっているフラグたち:
clone_in_vscodium = VSCodiumでcloneする
desc.sha256 = SHA256
+wiki.cancel = キャンセル
+activity.navbar.contributors = 貢献者
+contributors.contribution_type.filter_label = 貢献の種類:
+activity.navbar.recent_commits = 最近の貢献者
+admin.failed_to_replace_flags = リポジトリのフラグを変更するのに失敗しました
+file_follow = シンボリックリンクを辿る
+mirror_sync = 同期済み
+generated = 生成された
+editor.invalid_commit_mail = コミットを作成するためには無効なメールアドレスです。
+issues.blocked_by_user = あなたはこのリポジトリの所有者からブロックされているため、Issueを作成できません。
+pulls.nothing_to_compare_have_tag = 選択されたブランチまたはタグは同一です。
+pulls.blocked_by_user = あなたはこのリポジトリの所有者からブロックされているため、プルリクエストを作成できません。
+rss.must_be_on_branch = RSSフィードを見るためには、ブランチを閲覧する必要があります。
+migrate.forgejo.description = codeberge.orgまたは他のインスタンスからデータを移行する。
+commits.browse_further = もっと見る
+issues.comment.blocked_by_user = あなたはこのリポジトリの所有者か、Issueの投稿者からブロックされているため、このIssueにコメントできません。
+pulls.reopen_failed.head_branch = ブランチがもう存在しないため、このプルリクエストはreopenできません。
+pulls.reopen_failed.base_branch = ベースブランチがもう存在しないため、このプルリクエストは再開できません。
+settings.units.overview = 概要
+settings.new_owner_blocked_doer = 新しい所有者が、あなたをブロックしています。
+settings.enter_repo_name = 所有者とリポジトリ名を、以下のように正確に衆力してください:
+settings.wiki_rename_branch_main = wikiのブランチ名を正規化する
+settings.wiki_rename_branch_main_desc = wikiによって内部的に使われているブランチ名を "%s" に変更します。これは恒久的で元に戻すことはできません。
+contributors.contribution_type.additions = 追加
+vendored = vendor済み
+pulls.commit_ref_at = `このプルリクエストを言及するコミット %[2]s`
+pulls.fast_forward_only_merge_pull_request = Fast-forwardのみ
+admin.manage_flags = フラグ管理
+admin.update_flags = フラグを更新
+admin.flags_replaced = リポジトリのフラグは更新されました
+commits.renamed_from = %sから名前を変更
+pulls.made_using_agit = Agit
+pulls.agit_explanation = Agitによるワークフローを作成します。Agitでは、貢献者は変更をforkしたりブランチを作るのではなく、"git push"して提案します。
+contributors.contribution_type.deletions = 削除
+settings.units.add_more = さらに...
+settings.wiki_globally_editable = 誰にでもWikiの編集を許す
+settings.confirmation_string = 確認
+settings.wiki_rename_branch_main_notices_1 = この操作は 取り消しできません 。
[graphs]
@@ -3574,6 +3632,8 @@ runs.actors_no_select=すべてのアクター
runs.status_no_select=すべてのステータス
runs.no_results=一致する結果はありません。
runs.no_workflows=ワークフローはまだありません。
+runs.no_workflows.quick_start=Gitea Actions の始め方がわからない? ではクイックスタートガイドをご覧ください。
+runs.no_workflows.documentation=Gitea Actions の詳細については、ドキュメントを参照してください。
runs.no_runs=ワークフローはまだ実行されていません。
runs.empty_commit_message=(空のコミットメッセージ)
diff --git a/options/locale/locale_ko-KR.ini b/options/locale/locale_ko-KR.ini
index 89ea2f3335..fa6df2d2a1 100644
--- a/options/locale/locale_ko-KR.ini
+++ b/options/locale/locale_ko-KR.ini
@@ -251,7 +251,7 @@ twofa_scratch_used=스크래치 코드를 사용하셨습니다. 이중인증
twofa_passcode_incorrect=패스코드가 맞지 않습니다. 기기를 잘못 등록 한 경우, 스크래치 코드를 이용해 로그인 하십시오.
twofa_scratch_token_incorrect=스크래치 코드가 올바르지 않습니다.
login_userpass=로그인
-login_openid=OpenID
+tab_openid=OpenID
oauth_signup_tab=새 계정 등록하기
oauth_signup_submit=등록 완료
oauth_signin_tab=기존 계정으로 연결하기
@@ -847,8 +847,8 @@ pulls.compare_compare=다음으로부터 풀
pulls.filter_branch=Filter Branch
pulls.no_results=결과 없음
pulls.create=풀 리퀘스트 생성
-pulls.title_desc="%[2]s
에서 %[3]s
로 %[1]d commits 를 머지하려 합니다"
-pulls.merged_title_desc=%[2]s
에서 %[3]s
로 %[1]d commits 를 머지했습니다 %[4]s
+pulls.title_desc_few="%[2]s
에서 %[3]s
로 %[1]d commits 를 머지하려 합니다"
+pulls.merged_title_desc_few=%[2]s
에서 %[3]s
로 %[1]d commits 를 머지했습니다 %[4]s
pulls.tab_conversation=대화
pulls.tab_commits=커밋
pulls.tab_files=파일 변경됨
diff --git a/options/locale/locale_lv-LV.ini b/options/locale/locale_lv-LV.ini
index 718f3dc9a4..ce8f05e4b5 100644
--- a/options/locale/locale_lv-LV.ini
+++ b/options/locale/locale_lv-LV.ini
@@ -150,7 +150,7 @@ footer.links=Saites
[heatmap]
number_of_contributions_in_the_last_12_months=%s darbības pēdējo 12 mēnešu laikā
-no_contributions=Nav aktivitātes
+contributions_zero=Nav aktivitātes
less=Mazāk
more=Vairāk
@@ -395,7 +395,7 @@ twofa_scratch_used=Vienreizējais kods tika izmantots. Notika pārvirzīšana uz
twofa_passcode_incorrect=Piekļuves kods nav pareizs. Ja esat pazaudējis ierīci, izmantojiet vienreizējo kodu, lai pieteiktos.
twofa_scratch_token_incorrect=Ievadīts nepareizs vienreizējais kods.
login_userpass=Pieteikties
-login_openid=OpenID
+tab_openid=OpenID
oauth_signup_tab=Reģistrēt jaunu kontu
oauth_signup_title=Pabeigt konta veidošanu
oauth_signup_submit=Pabeigt reģistrāciju
@@ -1713,8 +1713,8 @@ pulls.nothing_to_compare=Nav ko salīdzināt, jo bāzes un salīdzināmie atzari
pulls.nothing_to_compare_and_allow_empty_pr=Šie atzari ir vienādi. Izveidotais izmaiņu pieprasījums būs tukšs.
pulls.has_pull_request=`Izmaiņu pieprasījums starp šiem atzariem jau eksistē: %[2]s#%[3]d`
pulls.create=Izveidot izmaiņu pieprasījumu
-pulls.title_desc=vēlas sapludināt %[1]d revīzijas no %[2]s
uz %[3]s
-pulls.merged_title_desc=sapludināja %[1]d revīzijas no %[2]s
uz %[3]s
%[4]s
+pulls.title_desc_few=vēlas sapludināt %[1]d revīzijas no %[2]s
uz %[3]s
+pulls.merged_title_desc_few=sapludināja %[1]d revīzijas no %[2]s
uz %[3]s
%[4]s
pulls.change_target_branch_at=`nomainīja mērķa atzaru no %s uz %s %s`
pulls.tab_conversation=Saruna
pulls.tab_commits=Revīzijas
diff --git a/options/locale/locale_nl-NL.ini b/options/locale/locale_nl-NL.ini
index 4d494a6d8b..95d370661d 100644
--- a/options/locale/locale_nl-NL.ini
+++ b/options/locale/locale_nl-NL.ini
@@ -143,6 +143,18 @@ unpin = Ontpinnen
remove_label_str = Verwijder punt "%s"
confirm_delete_artifact = Weet u zeker dat u het artefact "%s" wilt verwijderen?
toggle_menu = Menu schakelen
+filter.clear = Filter wissen
+filter.is_archived = Gearchiveerd
+filter.is_fork = Geforkt
+filter.not_fork = Niet geforkt
+filter.is_mirror = Gespiegeld
+filter.not_mirror = Niet gespiegeld
+filter.is_template = Sjabloon
+filter.not_template = Geen sjabloon
+filter.public = Publiek
+filter.private = Privé
+filter = Filter
+filter.not_archived = Niet gearchiveerd
[aria]
navbar = Navigatiebalk
@@ -152,7 +164,7 @@ footer.links = Verwijzingen
[heatmap]
number_of_contributions_in_the_last_12_months = %s contributies in de laatste 12 maanden
-no_contributions = Geen contributies
+contributions_zero = Geen contributies
less = Minder
more = Meer
@@ -225,41 +237,41 @@ err_admin_name_is_reserved=Gebruikersnaam van beheerder is ongeldig, gebruikersn
err_admin_name_pattern_not_allowed=Gebruikersnaam van beheerder is ongeldig, de gebruikersnaam is gereserveerd
err_admin_name_is_invalid=Gebruikersnaam van beheerder is ongeldig
-general_title=Algemene Instellingen
-app_name=Naam site
+general_title=Algemene instellingen
+app_name=Instantienaam
app_name_helper=U kan de naam van uw bedrijf hier invullen.
-repo_path=Repositories basis map
+repo_path=Repository hoofdpad
repo_path_helper=Externe git repositories worden opgeslagen in deze map.
lfs_path=Git LFS root pad
lfs_path_helper=Bestanden bijgehouden door Git LFS zullenworden opgeslagen in deze map. Laat leeg om uit te schakelen.
-run_user=Uitvoeren als gebruiker
-domain=Server Domein
+run_user=Gebruiker om als uit te voeren
+domain=Serverdomein
domain_helper=Domein of hostadres voor de server.
ssh_port=SSH server-poort
-ssh_port_helper=Nummer van de poort die uw SSH-server gebruikt. Laat dit veld leeg om de SSH functie uit te schakelen.
-http_port=Forgejo HTTP-poort
-http_port_helper=De poort waar de web server van Forgejo naar gaat luisteren.
-app_url=Forgejo base URL
+ssh_port_helper=Poortnummer dat zal worden gebruikt door de SSH-server. Leeg laten om SSH-server uit te schakelen.
+http_port=HTTP luisterpoort
+http_port_helper=Poortnummer dat zal worden gebruikt door de Forgejo webserver.
+app_url=Basis URL
app_url_helper=Basisadres voor HTTP(S) kloon URL's en e-mailmeldingen.
log_root_path=Log-pad
log_root_path_helper=Logboekbestanden worden geschreven naar deze map.
optional_title=Optionele instellingen
email_title=E-mail instellingen
-smtp_addr=SMTP Host
-smtp_port=SMTP Poort
+smtp_addr=SMTP-host
+smtp_port=SMTP-poort
smtp_from=E-mails versturen als
smtp_from_helper=E-mailadres dat Forgejo gaat gebruiken. Voer een gewoon e-mailadres in of gebruik de "Naam" -indeling.
mailer_user=SMTP gebruikersnaam
mailer_password=SMTP wachtwoord
register_confirm=E-mailbevestiging vereist bij registreren
mail_notify=Activeer e-mailnotificaties
-server_service_title=Server en Third-Party Service-instellingen
+server_service_title=Server en service-instellingen van derden
offline_mode=Lokale modus inschakelen
offline_mode_popup=Schakel third-party content uit en gebruik alleen lokale middelen.
disable_gravatar=Gravatar uitschakelen
disable_gravatar_popup=Gravatar en derden avatar bronnen uitschakelen. Een standaard avatar zal worden gebruikt, tenzij een gebruiker een lokale avatar uploadt.
-federated_avatar_lookup=Federated Avatars toestaan
+federated_avatar_lookup=Federated avatars toestaan
federated_avatar_lookup_popup=Enable federated avatars lookup to use federated open source service based on libravatar.
disable_registration=Schakel zelf registratie uit
disable_registration_popup=Schakel zelfregistratie uit, alleen admins kunnen accounts maken.
@@ -270,7 +282,7 @@ openid_signup=OpenID zelf-registratie inschakelen
openid_signup_popup=OpenID zelfregistratie inschakelen.
enable_captcha=Registratie CAPTCHA inschakelen
enable_captcha_popup=Vereis captcha validatie voor zelf-registratie van gebruiker.
-require_sign_in_view=Vereis inloggen om pagina's te kunnen bekijken
+require_sign_in_view=Aanmelden vereist om inhoud van instantie te bekijken
admin_setting_desc=Het creëren van een administrator-account is optioneel. De eerste geregistreerde gebruiker wordt automatisch de beheerder.
admin_title=Instellingen beheerdersaccount
admin_name=Admin gebruikersnaam
@@ -297,7 +309,7 @@ default_enable_timetracking=Tijdregistratie standaard inschakelen
default_enable_timetracking_popup=Tijdsregistratie voor nieuwe repositories standaard inschakelen.
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
+password_algorithm=Wachtwoord hash-algoritme
env_config_keys = Configuratie Omgeving
env_config_keys_prompt = De volgende omgevingsvariabelen worden ook toegepast op je configuratiebestand:
invalid_db_table = De database tabel "%s" is ongeldig: %v
@@ -307,9 +319,10 @@ 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_popup = Beperk de toegang tot de pagina's tot ingelogde gebruikers. Bezoekers zien alleen de aanmeldings- en registratiepagina's.
-enable_update_checker_helper_forgejo = Controleert periodiek op nieuwe versies van Forgejo door een DNS TXT-record op release.forgejo.org te controleren.
+enable_update_checker_helper_forgejo = Het zal periodiek controleren op nieuwe Forgejo-versies door een TXT DNS-record op release.forgejo.org te controleren.
enable_update_checker_helper = Controleert periodiek op nieuwe versies door verbinding te maken met gitea.io.
smtp_from_invalid = Het adres "E-mails versturen als" is ongeldig
+config_location_hint = Deze configuratieopties worden opgeslagen in:
[home]
uname_holder=Gebruikersnaam of e-mailadres
@@ -395,7 +408,7 @@ twofa_scratch_used=Je hebt je eenmalige code gebruikt. Je wordt omgeleid naar de
twofa_passcode_incorrect=Uw wachtwoord is onjuist. Als u uw apparaat kwijt bent, gebruik dan je eenmalige code om in te loggen.
twofa_scratch_token_incorrect=Je eenmalige code is onjuist.
login_userpass=Inloggen
-login_openid=OpenID
+tab_openid=OpenID
oauth_signup_tab=Registreer nieuw account
oauth_signup_title=Voltooi nieuw account
oauth_signup_submit=Account voltooien
@@ -486,12 +499,12 @@ release.downloads=Downloads:
release.download.zip=Broncode (ZIP)
release.download.targz=Broncode (TAR.GZ)
-repo.transfer.subject_to=%s zou "%s" willen overdragen aan %s
-repo.transfer.subject_to_you=%s wil "%s" aan jou overdragen
+repo.transfer.subject_to=%s wil repository "%s" overdragen aan %s
+repo.transfer.subject_to_you=%s wilt repository "%s" naar u overdragen
repo.transfer.to_you=jij
repo.transfer.body=Om het te accepteren of afwijzen, bezoek %s of negeer het gewoon.
-repo.collaborator.added.subject=%s heeft jou toegevoegd aan %s
+repo.collaborator.added.subject=%s heeft jou toegevoegd aan %s als samenwerker
repo.collaborator.added.text=U bent toegevoegd als een samenwerker van de repository:
reply = of antwoord op deze e-mail
admin.new_user.subject = Nieuwe gebruiker %s heeft zich zojuist geregisteerd
@@ -603,6 +616,8 @@ username_error_no_dots = ` kan alleen alfanumerieke karakters ("0-9","a-z","A-Z"
invalid_group_team_map_error = ` mapping is ongeldig: %s"
org_still_own_repo = Deze organisatie is eigenaar van één of meer repositories, verwijder of draag deze eerst over.
org_still_own_packages = Deze organisatie is eigenaar van één of meer pakketten, verwijder deze eerst.
+unset_password = De inloggebruiker heeft het wachtwoord niet ingesteld.
+unsupported_login_type = Het aanmeldtype wordt niet ondersteund om accounts te verwijderen.
[user]
@@ -1603,8 +1618,8 @@ pulls.nothing_to_compare=Deze branches zijn gelijk. Er is geen pull request nodi
pulls.nothing_to_compare_and_allow_empty_pr=Deze branches zijn gelijk. Deze pull verzoek zal leeg zijn.
pulls.has_pull_request=`Een pull-verzoek tussen deze branches bestaat al: %[2]s#%[3]d`
pulls.create=Pull verzoek aanmaken
-pulls.title_desc=wil %[1]d commits van %[2]s
samenvoegen met %[3]s
-pulls.merged_title_desc=heeft %[1]d commits samengevoegd van %[2]s
naar %[3]s
%[4]s
+pulls.title_desc_few=wil %[1]d commits van %[2]s
samenvoegen met %[3]s
+pulls.merged_title_desc_few=heeft %[1]d commits samengevoegd van %[2]s
naar %[3]s
%[4]s
pulls.change_target_branch_at='doelbranch aangepast van %s naar %s %s'
pulls.tab_conversation=Discussie
pulls.tab_commits=Commits
@@ -1661,9 +1676,9 @@ pulls.rebase_conflict_summary=Foutmelding
pulls.unrelated_histories=Samenvoegen mislukt: de HEAD en base delen geen gemeenschappelijke geschiedenis. Tip: Probeer een andere strategie
pulls.merge_out_of_date=Samenvoegen mislukt: Tijdens het samenvoegen is de basis bijgewerkt. Tip: Probeer het opnieuw.
pulls.head_out_of_date=Samenvoegen mislukt: tijdens het genereren van de samenvoeging is de kop bijgewerkt. Tip: Probeer het opnieuw.
-pulls.push_rejected=Samenvoegen mislukt: De push is geweigerd. Controleer de Git Hooks voor deze repository.
+pulls.push_rejected=Push mislukt: De push is geweigerd. Controleer de Git Hooks voor deze repository.
pulls.push_rejected_summary=Volledig afwijzingsbericht
-pulls.push_rejected_no_message=Samenvoegen mislukt: De push is afgewezen, maar er was geen extern bericht.
Controleer de Git Hooks voor deze repository
+pulls.push_rejected_no_message=Push mislukt: De push is afgewezen maar er was geen remote bericht. Bekijk de Git Hooks voor dit repository
pulls.open_unmerged_pull_exists=`Je kan deze pull request niet opnieuw openen omdat er een andere (#%d) met identieke eigenschappen open staat.`
pulls.status_checking=Sommige controles zijn in behandeling
pulls.status_checks_success=Alle checks waren succesvol
@@ -2089,7 +2104,7 @@ settings.matrix.homeserver_url=Homeserver URL
settings.matrix.room_id=Kamer ID
settings.matrix.message_type=Bericht type
settings.archive.button=Repo archiveren
-settings.archive.header=Deze Repo archiveren
+settings.archive.header=Archiveer deze repo
settings.archive.success=De repo is succesvol gearchiveerd.
settings.archive.error=Er is een fout opgetreden tijdens het archiveren van de repo. Zie het logboek voor meer informatie.
settings.archive.error_ismirror=U kunt geen gespiegelde repo archiveren.
@@ -2423,7 +2438,7 @@ signing.wont_sign.never = Commits worden nooit ondertekend.
signing.wont_sign.error = Er is een fout opgetreden tijdens het controleren of de commit ondertekend kon worden.
signing.will_sign = Deze commit wordt ondertekend met sleutel "%s".
milestones.filter_sort.latest_due_date = Uiterste vervaldatum
-milestones.filter_sort.earliest_due_data = Vroegste vervaldatum
+milestones.filter_sort.earliest_due_data = Dichtstbijzijnde vervaldatum
milestones.edit_success = Mijlpaal "%s" is bijgewerkt.
milestones.create_success = De mijlpaal "%s" is aangemaakt.
signing.wont_sign.not_signed_in = U bent niet ingelogd.
@@ -2651,6 +2666,7 @@ settings.confirmation_string = Confirmatie string
activity.navbar.code_frequency = Code Frequentie
activity.navbar.recent_commits = Recente commits
file_follow = Volg Symlink
+error.broken_git_hook = it hooks van deze repository lijken kapot te zijn. Volg alsjeblieft de documentatie om ze te repareren, push daarna wat commits om de status te vernieuwen.
@@ -2797,7 +2813,7 @@ total=Totaal: %d
dashboard.statistic=Overzicht
dashboard.operations=Onderhoudswerkzaamheden
-dashboard.system_status=Systeemtatus
+dashboard.system_status=Systeemstatus
dashboard.operation_name=Bewerking naam
dashboard.operation_switch=Omschakelen
dashboard.operation_run=Uitvoeren
@@ -2831,17 +2847,17 @@ dashboard.resync_all_hooks=Opnieuw synchroniseren van pre-ontvangst, bewerk en p
dashboard.reinit_missing_repos=Herinitialiseer alle ontbrekende Git repositories waarvoor records bestaan
dashboard.sync_external_users=Externe gebruikersgegevens synchroniseren
dashboard.server_uptime=Uptime server
-dashboard.current_goroutine=Huidige Goroutines
+dashboard.current_goroutine=Huidige goroutines
dashboard.current_memory_usage=Huidig geheugen gebruik
dashboard.total_memory_allocated=Totaal toegewezen geheugen
dashboard.memory_obtained=Geheugen gebruikt
dashboard.pointer_lookup_times=Aanwijzer Lookup keer
dashboard.memory_allocate_times=Geheugentoewijzingen
dashboard.memory_free_times=Geheugen vrjigemaakt
-dashboard.current_heap_usage=Huidige Heap gebruik
+dashboard.current_heap_usage=Huidige heap gebruik
dashboard.heap_memory_obtained=Heap geheugen verkregen
dashboard.heap_memory_idle=Heap geheugen inactief
-dashboard.heap_memory_in_use=Heap geheugen In gebruik
+dashboard.heap_memory_in_use=Heap geheugen in gebruik
dashboard.heap_memory_released=Heap geheugen vrijgegeven
dashboard.heap_objects=Heap-objecten
dashboard.bootstrap_stack_usage=Bootstrap Stack gebruik
@@ -2851,7 +2867,7 @@ dashboard.mspan_structures_obtained=MSpan structuren verkregen
dashboard.mcache_structures_usage=MCache structuren gebruik
dashboard.mcache_structures_obtained=MCache structuren verkregen
dashboard.profiling_bucket_hash_table_obtained=Profilering emmer hashtabel verkregen
-dashboard.gc_metadata_obtained=GC Metadada verkregen
+dashboard.gc_metadata_obtained=GC metadada verkregen
dashboard.other_system_allocation_obtained=Andere systeem toewijzing verkregen
dashboard.next_gc_recycle=Volgende GC recycle
dashboard.last_gc_time=Sinds vorige GC verwerkingstijd
@@ -2977,8 +2993,8 @@ auths.group_search_base=Groep zoekbasis DN
auths.group_attribute_list_users=Groep Attribuut met lijst van gebruikers
auths.user_attribute_in_group=Gebruikerskenmerken vermeld in groep
auths.smtp_auth=SMTP-authenticatietype
-auths.smtphost=SMTP host
-auths.smtpport=SMTP poort
+auths.smtphost=SMTP-host
+auths.smtpport=SMTP-poort
auths.allowed_domains=Toegelaten domeinen
auths.allowed_domains_helper=Laat leeg om alle domeinen toe te staan. Meerdere domeinen scheiden met een komma (",").
auths.skip_tls_verify=TLS-verificatie overslaan
@@ -3023,37 +3039,37 @@ auths.still_in_used=De authenticatiebron is nog in gebruik. Converteer of verwij
auths.deletion_success=De authenticatie-bron is verwijderd.
config.server_config=Serverconfiguratie
-config.app_name=Naam site
+config.app_name=Instantietitel
config.app_ver=Forgejo versie
-config.app_url=Forgejo basis URL
+config.app_url=Basis URL
config.custom_conf=Configuratiebestandspad
config.custom_file_root_path=Hoofdmap voor aangepaste bestanden
config.offline_mode=Lokale modus
config.disable_router_log=Router-log uitschakelen
-config.run_user=Uitvoeren als gebruiker
+config.run_user=Gebruiker om als uit te voeren
config.run_mode=Uitvoer modus
config.git_version=Git versie
config.repo_root_path=Repository basis pad
config.lfs_root_path=LFS rootpad
config.log_file_root_path=Log-pad
-config.script_type=Script type
+config.script_type=Script soort
config.reverse_auth_user=Omgekeerde verificatie gebruiker
config.ssh_config=SSH-configuratie
config.ssh_enabled=Ingeschakeld
config.ssh_start_builtin_server=Gebruik de ingebouwde server
config.ssh_port=Poort
-config.ssh_listen_port=Luister op poort
+config.ssh_listen_port=Luisterpoort
config.ssh_root_path=Root-pad
config.ssh_key_test_path=Pad voor key-tests
config.ssh_keygen_path=Pad van keygen ("ssh-keygen")
config.ssh_minimum_key_size_check=Controleer minimale key-lengte
config.ssh_minimum_key_sizes=Minimale key-lengtes
-config.lfs_config=LFS Configuratie
+config.lfs_config=LFS configuratie
config.lfs_enabled=Ingeschakeld
config.lfs_content_path=LFS inhoudspad
-config.lfs_http_auth_expiry=LFS HTTP Auth Vervaltijd
+config.lfs_http_auth_expiry=LFS HTTP auth vervaltijd
config.db_config=Databaseconfiguratie
config.db_type=Type
@@ -3074,8 +3090,8 @@ config.show_registration_button=Registeren knop weergeven
config.require_sign_in_view=Vereis inloggen om pagina's te kunnen bekijken
config.mail_notify=Activeer e-mailnotificaties
config.enable_captcha=CAPTCHA inschakelen
-config.active_code_lives=Actieve Code leven
-config.reset_password_code_lives=Herstel accountcode vervaltijd
+config.active_code_lives=Vervaltijd activeringscode
+config.reset_password_code_lives=Vervaltijd herstelcode
config.default_keep_email_private=Verberg standaard alle e-mailadressen
config.default_allow_create_organization=Standaard toestaan om organisaties aan te maken
config.enable_timetracking=Tijdregistratie inschakelen
@@ -3113,12 +3129,12 @@ config.cache_item_ttl=Cache-item TTL
config.session_config=Sessieconfiguratie
config.session_provider=Sessieprovider
-config.provider_config=Provider config
+config.provider_config=Configuratie provider
config.cookie_name=Cookie naam
-config.gc_interval_time=GC interval time
+config.gc_interval_time=GC intervaltijd
config.session_life_time=Sessie duur
config.https_only=Alleen HTTPS
-config.cookie_life_time=Cookie duur leeftijd
+config.cookie_life_time=Levensduur cookie
config.picture_config=Foto en avatar configuratie
config.picture_service=Foto service
@@ -3126,12 +3142,12 @@ config.disable_gravatar=Gravatar uitschakelen
config.enable_federated_avatar=Federated avatars toestaan
config.git_config=Git configuratie
-config.git_disable_diff_highlight=Uitschakelen Diff Syntaxis-Highlight
-config.git_max_diff_lines=Maximum Diff Lijnen (voor een enkel bestand)
-config.git_max_diff_files=Max Diff bestanden (om weer te geven)
-config.git_gc_args=GC Parameters
+config.git_disable_diff_highlight=Diff syntax highlighting uitschakelen
+config.git_max_diff_lines=Max diff regels per bestand
+config.git_max_diff_files=Max. getoonde diff-bestanden
+config.git_gc_args=GC-argumenten
config.git_migrate_timeout=Migratie time-out
-config.git_mirror_timeout=Kopie Update Timeout
+config.git_mirror_timeout=Time-out spiegelupdate
config.git_clone_timeout=Kloon operatie timeout
config.git_pull_timeout=Pull operatie timeout
config.git_gc_timeout=GC operatie timeout
@@ -3172,7 +3188,7 @@ monitor.queue.settings.maxnumberworkers.error=Maximaal aantal workers moet een n
monitor.queue.settings.submit=Instellingen bijwerken
monitor.queue.settings.changed=Instellingen bijgewerkt
-notices.system_notice_list=Systeem aankondigingen
+notices.system_notice_list=Systeemmeldingen
notices.view_detail_header=Bekijk notificatie details
notices.select_all=Alles selecteren
notices.deselect_all=Alles deselecteren
@@ -3217,7 +3233,7 @@ packages.version = Versie
packages.published = Gepubliceerd
defaulthooks = Standaard webhooks
defaulthooks.update_webhook = Standaard webhook bijwerken
-auths.auth_manage_panel = Authenticatie Bronbeheer
+auths.auth_manage_panel = Authenticatie bronbeheer
auths.oauth2_required_claim_value = Vereiste claimwaarde
auths.oauth2_group_claim_name = Claimnaam die groepsnamen geeft voor deze bron. (Optioneel)
auths.oauth2_admin_group = Groepsclaimwaarde voor beheerdersgebruikers. (Optioneel - vereist bovenstaande claimnaam)
@@ -3293,7 +3309,7 @@ config.test_mail_sent = Er is een testmail verzonden naar "%s".
config.test_mail_failed = Er is geen testmail verzonden naar "%s": %v
config.access_log_template = Sjabloon voor toegangslogboek
config.logger_name_fmt = Logger: %s
-config.git_max_diff_line_characters = Max Diff tekens (voor een enkele regel)
+config.git_max_diff_line_characters = Max diff tekens per regel
auths.sspi_strip_domain_names_helper = Als deze optie is aangevinkt, worden domeinnamen verwijderd uit inlognamen (bijv. "DOMEIN\gebruiker" en "gebruiker@example.org" worden beide gewoon "gebruiker").
auths.map_group_to_team_removal = Gebruikers verwijderen uit gesynchroniseerde teams als gebruiker niet tot overeenkomstige LDAP-groep behoort
config.send_test_mail_submit = Stuur
diff --git a/options/locale/locale_pl-PL.ini b/options/locale/locale_pl-PL.ini
index 3b2fcd9ec0..a254a912bd 100644
--- a/options/locale/locale_pl-PL.ini
+++ b/options/locale/locale_pl-PL.ini
@@ -334,7 +334,7 @@ twofa_scratch_used=Użyłeś/aś swojego kodu jednorazowego. Przekierowano Cię
twofa_passcode_incorrect=Twój kod autoryzacji jest niepoprawny. Jeśli zapodziałeś(-aś) swoje urządzenie, użyj swojego kodu jednorazowego do zalogowania.
twofa_scratch_token_incorrect=Twój kod jednorazowy jest niepoprawny.
login_userpass=Zaloguj się
-login_openid=OpenID
+tab_openid=OpenID
oauth_signup_tab=Utwórz nowe konto
oauth_signup_title=Ukończ nowe konto
oauth_signup_submit=Utwórz konto
@@ -1302,8 +1302,8 @@ pulls.no_results=Nie znaleziono wyników.
pulls.nothing_to_compare=Te gałęzie są sobie równe. Nie ma potrzeby tworzyć Pull Requesta.
pulls.nothing_to_compare_and_allow_empty_pr=Te gałęzie są równe. Ten PR będzie pusty.
pulls.create=Utwórz Pull Request
-pulls.title_desc=chce scalić %[1]d commity/ów z %[2]s
do %[3]s
-pulls.merged_title_desc=scala %[1]d commity/ów z %[2]s
do %[3]s
%[4]s
+pulls.title_desc_few=chce scalić %[1]d commity/ów z %[2]s
do %[3]s
+pulls.merged_title_desc_few=scala %[1]d commity/ów z %[2]s
do %[3]s
%[4]s
pulls.change_target_branch_at=`zmienia gałąź docelową z %s na %s %s`
pulls.tab_conversation=Dyskusja
pulls.tab_commits=Commity
diff --git a/options/locale/locale_pt-BR.ini b/options/locale/locale_pt-BR.ini
index e6fc0df5ef..ade7c6c704 100644
--- a/options/locale/locale_pt-BR.ini
+++ b/options/locale/locale_pt-BR.ini
@@ -29,7 +29,7 @@ return_to_gitea=Volte para Forgejo
username=Nome de usuário
email=Endereço de e-mail
password=Senha
-access_token=Token de Acesso
+access_token=Token de acesso
re_type=Confirmar senha
captcha=CAPTCHA
twofa=Autenticação de dois fatores
@@ -142,6 +142,12 @@ view = Visualizar
copy_hash = Copiar hash
tracked_time_summary = Resumo do tempo de rastreamento baseado em filtros da lista de issues
confirm_delete_artifact = Tem certeza de que deseja excluir o artefato "%s"?
+filter = Filtro
+filter.clear = Limpar filtro
+filter.is_archived = Arquivado
+filter.public = Público
+filter.is_template = Modelo
+filter.private = Privado
[aria]
navbar=Barra de navegação
@@ -151,7 +157,7 @@ footer.links=Links
[heatmap]
number_of_contributions_in_the_last_12_months=%s contribuições nos últimos 12 meses
-no_contributions=Sem contribuições
+contributions_zero=Sem contribuições
less=Menos
more=Mais
@@ -398,7 +404,7 @@ twofa_scratch_used=Você usou seu código de backup. Você foi redirecionado par
twofa_passcode_incorrect=Seu código de acesso está incorreto. Se você perdeu seu dispositivo, use seu código de backup para acessar.
twofa_scratch_token_incorrect=Seu código de backup está incorreto.
login_userpass=Acessar
-login_openid=OpenID
+tab_openid=OpenID
oauth_signup_tab=Cadastrar nova conta
oauth_signup_title=Completar Nova Conta
oauth_signup_submit=Completar conta
@@ -1718,8 +1724,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: %[2]s#%[3]d`
pulls.create=Criar pull request
-pulls.title_desc=quer aplicar o merge de %[1]d commits de %[2]s
em %[3]s
-pulls.merged_title_desc=aplicou merge dos %[1]d commits de %[2]s
em %[3]s
%[4]s
+pulls.title_desc_few=quer aplicar o merge de %[1]d commits de %[2]s
em %[3]s
+pulls.merged_title_desc_few=aplicou merge dos %[1]d commits de %[2]s
em %[3]s
%[4]s
pulls.change_target_branch_at=`mudou o branch de destino de %s para %s %s`
pulls.tab_conversation=Conversação
pulls.tab_commits=Commits
@@ -3579,4 +3585,4 @@ executable_file = Arquivo executável
component_loading = Carregando %s...
component_loading_failed = Não foi possível carregar o(a) %s
component_loading_info = Pode demorar um pouco…
-contributors.what = contribuições
\ No newline at end of file
+contributors.what = contribuições
diff --git a/options/locale/locale_pt-PT.ini b/options/locale/locale_pt-PT.ini
index 649ddfd819..3538ac9460 100644
--- a/options/locale/locale_pt-PT.ini
+++ b/options/locale/locale_pt-PT.ini
@@ -151,7 +151,7 @@ footer.links=Ligações
[heatmap]
number_of_contributions_in_the_last_12_months=%s contribuições nos últimos 12 meses
-no_contributions=Nenhuma contribuição
+contributions_zero=Nenhuma contribuição
less=Menos
more=Mais
@@ -396,7 +396,7 @@ twofa_scratch_used=Você usou o seu código de recuperação. Foi reencaminhado
twofa_passcode_incorrect=A senha está errada. Se perdeu o seu dispositivo, use o código de recuperação para iniciar a sessão.
twofa_scratch_token_incorrect=O código de recuperação está errado.
login_userpass=Iniciar sessão
-login_openid=OpenID
+tab_openid=OpenID
oauth_signup_tab=Fazer inscrição
oauth_signup_title=Completar a nova conta
oauth_signup_submit=Completar conta
@@ -1722,8 +1722,8 @@ pulls.nothing_to_compare_have_tag=O ramo/etiqueta escolhidos são iguais.
pulls.nothing_to_compare_and_allow_empty_pr=Estes ramos são iguais. Este pedido de integração ficará vazio.
pulls.has_pull_request=`Já existe um pedido de integração entre estes ramos: %[2]s#%[3]d`
pulls.create=Criar um pedido de integração
-pulls.title_desc=quer integrar %[1]d cometimento(s) do ramo %[2]s
no ramo %[3]s
-pulls.merged_title_desc=integrou %[1]d cometimento(s) do ramo %[2]s
no ramo %[3]s
%[4]s
+pulls.title_desc_few=quer integrar %[1]d cometimento(s) do ramo %[2]s
no ramo %[3]s
+pulls.merged_title_desc_few=integrou %[1]d cometimento(s) do ramo %[2]s
no ramo %[3]s
%[4]s
pulls.change_target_branch_at=`mudou o ramo de destino de %s para %s %s`
pulls.tab_conversation=Diálogo
pulls.tab_commits=Cometimentos
diff --git a/options/locale/locale_ru-RU.ini b/options/locale/locale_ru-RU.ini
index 131aa521c1..e355d4c9c9 100644
--- a/options/locale/locale_ru-RU.ini
+++ b/options/locale/locale_ru-RU.ini
@@ -1,6 +1,6 @@
[common]
home=Главная
-dashboard=Панель управления
+dashboard=Главная
explore=Обзор
help=Помощь
logo=Логотип
@@ -56,7 +56,7 @@ mirror=Зеркало
new_repo=Новый репозиторий
new_migrate=Новая миграция
new_mirror=Новое зеркало
-new_fork=Новый форк репозитория
+new_fork=Новое ответвление репозитория
new_org=Новая организация
new_project=Новый проект
new_project_column=Новый столбец
@@ -72,7 +72,7 @@ all=Все
sources=Собственные
mirrors=Зеркала
collaborative=Совместные
-forks=Форки
+forks=Ответвления
activities=Активности
pull_requests=Слияния
@@ -143,6 +143,18 @@ tracked_time_summary = Сводка отслеженного времени на
view = Просмотр
confirm_delete_artifact = Вы точно хотите удалить артефакт «%s»?
toggle_menu = Показать/скрыть меню
+filter.not_archived = Не архивированные
+filter = Фильтры
+filter.clear = Очистить фильтры
+filter.is_fork = Ответвления
+filter.not_fork = Не ответвления
+filter.is_mirror = Зеркала
+filter.is_template = Шаблоны
+filter.not_template = Не шаблоны
+filter.public = Публичные
+filter.private = Приватные
+filter.is_archived = Архивированные
+filter.not_mirror = Не зеркала
[aria]
navbar=Панель навигации
@@ -152,7 +164,10 @@ footer.links=Ссылки
[heatmap]
number_of_contributions_in_the_last_12_months=Принимал(а) участие %s раз за последние 12 месяцев
-no_contributions=Не принимал(а) участия
+contributions_zero=Действий не было
+contributions_format = {contributions} {day} {month} {year}
+contributions_one=действие
+contributions_few=действий
less=Меньше
more=Больше
@@ -226,7 +241,7 @@ err_admin_name_pattern_not_allowed=Неверное имя администра
err_admin_name_is_invalid=Неверное имя администратора
general_title=Основные настройки
-app_name=Название сайта
+app_name=Название сервера
app_name_helper=Здесь вы можете ввести название своей компании.
repo_path=Путь до каталога репозиториев
repo_path_helper=Все удалённые Git репозитории будут сохранены в этом каталоге.
@@ -242,7 +257,7 @@ http_port=Forgejo HTTP порт
http_port_helper=Номер порта, который будет прослушиваться Forgejo веб-сервером.
app_url=Базовый URL Forgejo
app_url_helper=Этот параметр влияет на URL для клонирования по HTTP/HTTPS и на некоторые уведомления по эл. почте.
-log_root_path=Путь к журналу
+log_root_path=Путь журналов
log_root_path_helper=Файлы журнала будут записываться в этот каталог.
optional_title=Расширенные настройки
@@ -254,13 +269,13 @@ smtp_from_helper=Адрес эл. почты, который будет испо
mailer_user=Логин SMTP
mailer_password=Пароль SMTP
register_confirm=Требовать подтверждение по эл. почте для регистрации
-mail_notify=Разрешить почтовые уведомления
-server_service_title=Сервер и настройки внешних служб
-offline_mode=Включить локальный режим
+mail_notify=Уведомления по эл. почте
+server_service_title=Настройки сервера и внешних служб
+offline_mode=Локальный режим
offline_mode_popup=Отключить сторонние сети доставки контента и передавать все ресурсы из их локальных копий.
disable_gravatar=Отключить Gravatar
disable_gravatar_popup=Отключить Gravatar и сторонние источники аватаров. Если пользователь не загрузит аватар локально, то по умолчанию будет использоваться стандартный аватар.
-federated_avatar_lookup=Включить федерированные аватары
+federated_avatar_lookup=Федерированные аватары
federated_avatar_lookup_popup=Включите поиск федеративного аватара для использования службы с открытым исходным кодом на основе libravatar.
disable_registration=Отключить самостоятельную регистрацию
disable_registration_popup=Отключить самостоятельную регистрацию. Только администраторы смогут создавать новые учётные записи пользователей.
@@ -298,18 +313,19 @@ default_allow_create_organization=Разрешить создание орган
default_allow_create_organization_popup=Разрешить новым учётным записям пользователей создавать организации по умолчанию.
default_enable_timetracking=Включить отслеживание времени по умолчанию
default_enable_timetracking_popup=Включить отслеживание времени для новых репозиториев по умолчанию.
-no_reply_address=Скрытый почтовый домен
+no_reply_address=Домен скрытых адресов почты
no_reply_address_helper=Доменное имя для пользователей со скрытым адресом эл. почты. Например, пользователь «joe» будет зарегистрирован в Git как «joe@noreply.example.org», если скрытый домен эл. почты задан как «noreply.example.org».
-password_algorithm=Алгоритм хеширования пароля
+password_algorithm=Алгоритм хеширования паролей
invalid_password_algorithm=Некорректный алгоритм хеширования пароля
password_algorithm_helper=Задайте алгоритм хеширования паролей. Алгоритмы имеют различные требования и стойкость. Алгоритм argon2 довольно безопасен, но он использует много памяти и может не подходить для слабых систем.
-enable_update_checker=Включить проверку обновлений
+enable_update_checker=Проверка обновлений
enable_update_checker_helper=Периодически проверяет наличие новых версий, подключаясь к gitea.io.
env_config_keys=Настройка окружения
env_config_keys_prompt=Следующие переменные окружения также будут применены к вашему конфигурационному файлу:
enable_update_checker_helper_forgejo = Периодически проверять наличие новых версий Forgejo через DNS-запись TXT на release.forgejo.org.
allow_dots_in_usernames = Разрешить точки в логинах пользователей. Это не повлияет на уже созданные учётные записи.
smtp_from_invalid = Адрес для отправки писем некорректен
+config_location_hint = Эти настройки конфигурации будут сохранены в:
[home]
uname_holder=Логин или адрес эл. почты
@@ -374,7 +390,7 @@ forgot_password=Забыли пароль?
sign_up_now=Нужна учётная запись? Зарегистрируйтесь.
sign_up_successful=Учётная запись успешно создана. Добро пожаловать!
confirmation_mail_sent_prompt=Новое письмо для подтверждения направлено на %s. Пожалуйста, проверьте ваш почтовый ящик в течение %s для завершения регистрации.
-must_change_password=Обновить пароль
+must_change_password=Обновите пароль
allow_password_change=Требовать смену пароля пользователем (рекомендуется)
reset_password_mail_sent_prompt=Письмо с подтверждением отправлено на %s. Пожалуйста, проверьте входящую почту в течение %s, чтобы завершить процесс восстановления учётной записи.
active_your_account=Активируйте свою учётную запись
@@ -401,7 +417,9 @@ twofa_scratch_used=Вы использовали scratch-код. Вы были
twofa_passcode_incorrect=Ваш пароль неверен. Если вы потеряли устройство, используйте ваш scratch-код.
twofa_scratch_token_incorrect=Неверный scratch-код.
login_userpass=Вход
-login_openid=OpenID
+tab_signin = Войти
+tab_signup = Зарегистрироваться
+tab_openid=OpenID
oauth_signup_tab=Зарегистрировать новую учётную запись
oauth_signup_title=Полная новая учётная запись
oauth_signup_submit=Полная учётная запись
@@ -453,7 +471,7 @@ activate_email.text=Для подтверждения эл. почты пере
register_notify=Добро пожаловать в Forgejo
register_notify.title=%[1]s, добро пожаловать в %[2]s
register_notify.text_1=это письмо с вашим подтверждением регистрации в %s!
-register_notify.text_2=Теперь вы можете войти в учётную запись, используя логин: %s.
+register_notify.text_2=Теперь вы можете войти в учётную запись, используя логин: %s
register_notify.text_3=Если эта учётная запись создана кем-то для вас, сперва будет необходимо задать пароль.
reset_password=Восстановление учётной записи
@@ -462,21 +480,21 @@ reset_password.text=Если этот запрос ваш, для восстан
register_success=Регистрация прошла успешно
-issue_assigned.pull=@%[1]s вы назначены на запрос слияния %[2]s в репозитории %[3]s.
+issue_assigned.pull=@%[1]s назначил(а) вам запрос на слияние %[2]s в репозитории %[3]s.
issue_assigned.issue=@%[1]s назначил(а) вам задачу %[2]s в репозитории %[3]s.
issue.x_mentioned_you=@%s упомянул(а) вас:
issue.action.force_push=%[1]s форсировал(а) отправку в %[2]s изменений %[4]s вместо %[3]s.
-issue.action.push_1=@%[1]s отправил(а) %[3]d изменение в %[2]s
-issue.action.push_n=@%[1]s отправил(а) %[3]d изменений в %[2]s
+issue.action.push_1=@%[1]s отправлено %[3]d изменение в %[2]s
+issue.action.push_n=@%[1]s отправлены %[3]d изменений в %[2]s
issue.action.close=@%[1]s закрыл(а) #%[2]d.
issue.action.reopen=@%[1]s переоткрыл(а) #%[2]d.
issue.action.merge=@%[1]s слил(а) #%[2]d в %[3]s.
-issue.action.approve=@%[1]s одобрение этого слияния.
-issue.action.reject=@%[1]s запрос изменений в этом запросе на слияние.
-issue.action.review=@%[1]s комментарий для этого запроса на слияние.
-issue.action.review_dismissed=@%[1]s отклонён последний отзыв от %[2]s для этого запроса на слияние.
-issue.action.ready_for_review=@%[1]s запрос на слияние отмечен как готовый к рецензии.
+issue.action.approve=@%[1]s одобрил(а) этот запрос на слияние.
+issue.action.reject=@%[1]s запросил(а) изменения в этом запросе на слияние.
+issue.action.review=@%[1]s прокомментировал(а) этот запрос на слияние.
+issue.action.review_dismissed=@%[1]s отклонил(а) последний отзыв с %[2]s для этого запроса на слияние.
+issue.action.ready_for_review=@%[1]s отметил(а) этот запрос на слияние как готовый к рассмотрению.
issue.action.new=@%[1]s создал(а) #%[2]d.
issue.in_tree_path=В %s:
@@ -488,12 +506,12 @@ release.downloads=Загрузки:
release.download.zip=Исходный код (ZIP)
release.download.targz=Исходный код (TAR.GZ)
-repo.transfer.subject_to=%s хочет передать «%s» в %s
-repo.transfer.subject_to_you=%s хочет передать вам «%s»
+repo.transfer.subject_to=%s хочет передать репозиторий «%s» в %s
+repo.transfer.subject_to_you=%s хочет передать вам репозиторий «%s»
repo.transfer.to_you=вам
repo.transfer.body=Чтобы принять или отклонить передачу, перейдите по ссылке %s или просто проигнорируйте этот запрос.
-repo.collaborator.added.subject=%s вы добавлены в %s
+repo.collaborator.added.subject=%s вы добавлены как соучастник в %s
repo.collaborator.added.text=Вы были добавлены в качестве соучастника репозитория:
team_invite.subject=%[1]s приглашает вас присоединиться к организации %[2]s
@@ -603,6 +621,8 @@ org_still_own_packages=Эта организация всё ещё владее
target_branch_not_exist=Целевая ветка не существует.
admin_cannot_delete_self = Вы не можете удалить свою учётную запись, будучи администратором. Сперва снимите с себя роль администратора.
username_error_no_dots = ` может состоять только из латинских букв («a-z», «A-Z»), цифр («0-9»), знаков минуса («-») и нижнего подчёркивания («_»). Знаки не могут стоять в начале или в конце, а также идти подряд.`
+unsupported_login_type = Удаление аккаунта невозможно с этим типом авторизации.
+unset_password = У пользователя не задан пароль.
[user]
@@ -651,7 +671,7 @@ applications=Приложения
orgs=Управление организациями
repos=Репозитории
delete=Удалить учётную запись
-twofa=Двухфакторная аутентификация
+twofa=Двухфакторная аутентификация (TOTP)
account_link=Привязанные учётные записи
organization=Организации
uid=UID
@@ -662,12 +682,12 @@ biography_placeholder=Расскажите немного о себе! (Можн
location_placeholder=Поделитесь своим приблизительным местоположением с другими
profile_desc=Как ваш профиль будет отображаться для других пользователей. Ваш основной адрес эл. почты будет использоваться для уведомлений, восстановления пароля и веб-операций с Git.
password_username_disabled=Нелокальным пользователям запрещено изменение их имени пользователя. Для получения более подробной информации обратитесь к администратору сайта.
-full_name=Имя и фамилия
+full_name=Полное имя
website=Веб-сайт
location=Местоположение
-update_theme=Обновить тему
+update_theme=Изменить тему
update_profile=Обновить профиль
-update_language=Обновить язык
+update_language=Сменить язык
update_language_not_found=Язык «%s» недоступен.
update_language_success=Язык обновлён.
update_profile_success=Ваш профиль успешно обновлён.
@@ -691,7 +711,7 @@ comment_type_group_branch=Операции с ветками
comment_type_group_time_tracking=Отслеживание времени
comment_type_group_deadline=Модификации сроков выполнения
comment_type_group_dependency=Модификации зависимостей
-comment_type_group_lock=Смена статуса ограничения на обсуждение
+comment_type_group_lock=Статус ограничения
comment_type_group_review_request=Запросы на рецензию
comment_type_group_pull_request_push=Добавленные коммиты
comment_type_group_project=Проект
@@ -723,7 +743,7 @@ password_change_disabled=Нелокальные учётные записи не
emails=Email адреса
manage_emails=Управление адресами эл. почты
manage_themes=Выберите тему по умолчанию
-manage_openid=Управление OpenID
+manage_openid=Управление адресами OpenID
email_desc=Ваш основной адрес эл. почты будет использоваться для уведомлений, восстановления пароля и, если он не скрыт, для действий с Git в веб-интерфейсе.
theme_desc=Это будет темой по умолчанию для всего сайта.
primary=Основной
@@ -744,7 +764,7 @@ openid_deletion_desc=После удаления адреса OpenID вы не
openid_deletion_success=Адрес OpenID удален.
add_new_email=Добавить адрес эл. почты
add_new_openid=Добавить новый OpenID URI
-add_email=Добавить новый адрес
+add_email=Добавить адрес эл. почты
add_openid=Добавить адрес OpenID
add_email_confirmation_sent=Письмо для подтверждения отправлено на «%s». Пожалуйста, проверьте ваш почтовый ящик в течение %s, чтобы завершить процесс подтверждения.
add_email_success=Добавлен новый адрес эл. почты.
@@ -926,11 +946,11 @@ repos_none=Вы не владеете ни одним репозиторием.
delete_account=Удаление учётной записи
delete_prompt=Эта операция навсегда удалит вашу учётную запись. Это НЕВОЗМОЖНО будет отменить.
delete_with_all_comments=Ваша учётная запись младше %s. Чтобы избежать комментариев к плану, все комментарии к ней будут удалены.
-confirm_delete_account=Подтвердите удаление
+confirm_delete_account=Подтвердить удаление
delete_account_title=Удалить эту учётную запись
delete_account_desc=Вы уверены, что хотите навсегда удалить эту учётную запись?
-email_notifications.enable=Включить почтовые уведомления
+email_notifications.enable=Разрешить уведомления по почте
email_notifications.onmention=Посылать письмо на эл. почту только при упоминании
email_notifications.disable=Отключить почтовые уведомления
email_notifications.submit=Установить настройки эл. почты
@@ -970,21 +990,21 @@ visibility=Видимость
visibility_description=Это увидят только владелец организации или участники при наличии прав.
visibility_helper=Сделать репозиторий приватным
visibility_helper_forced=Администратор сайта настроил параметр видимости новых репозиториев. Репозиторий приватный по умолчанию.
-visibility_fork_helper=(Изменение этого повлияет на все форки.)
+visibility_fork_helper=(Это изменит видимость всех ответвлений.)
clone_helper=Нужна помощь в клонировании? Посетите страницу помощи.
-fork_repo=Форкнуть репозиторий
-fork_from=Форк от
-already_forked=Вы уже форкнули %s
+fork_repo=Создать ответвление
+fork_from=Ответвить от
+already_forked=У вас уже есть ответвление %s
fork_to_different_account=Ответвление для другой учётной записи
-fork_visibility_helper=Видимость форкнутого репозитория изменить нельзя.
-fork_branch=Ветка для клонирования в форк
+fork_visibility_helper=Нельзя изменить видимость ответвлённого репозитория.
+fork_branch=Ветка, клонируемая в ответвление
all_branches=Все ветки
use_template=Использовать этот шаблон
clone_in_vsc=Клонировать в VS Code
download_zip=Скачать ZIP
download_tar=Скачать TAR.GZ
download_bundle=Скачать BUNDLE
-generate_repo=Создать репозиторий
+generate_repo=Сгенерировать репозиторий
generate_from=Создать из
repo_desc=Описание
repo_desc_helper=Добавьте краткое описание (необязательно)
@@ -1011,7 +1031,7 @@ default_branch_label=по умолчанию
default_branch_helper=Ветка по умолчанию является базовой веткой для запросов на слияние и коммитов кода.
mirror_prune=Очистить
mirror_prune_desc=Удаление устаревших отслеживаемых ссылок
-mirror_interval=Интервал зеркалирования (допустимы единицы времени 'h', 'm', 's'). Значение 0 отключает периодическую синхронизацию. (Минимальный интервал: %s)
+mirror_interval=Интервал зеркалирования (единицы времени: «h», «m», «s»). Значение 0 отключит периодическую синхронизацию. (Мин. интервал: %s)
mirror_interval_invalid=Недопустимый интервал зеркалирования.
mirror_sync_on_commit=Синхронизировать при отправке коммитов
mirror_address=Клонировать по URL
@@ -1027,7 +1047,7 @@ mirror_password_help=Смените имя пользователя для уд
watchers=Наблюдатели
stargazers=Звездочеты
stars_remove_warning=Данное действие удалит все звёзды из этого репозитория.
-forks=Форки
+forks=Ответвления
reactions_more=и ещё %d
unit_disabled=Администратор сайта отключил этот раздел репозитория.
language_other=Разное
@@ -1046,9 +1066,9 @@ author_search_tooltip=Показывает максимум 30 пользова
tree_path_not_found_commit=Путь %[1]s не существует в коммите %[2]s
tree_path_not_found_branch=Путь %[1]s не существует в ветке %[2]s
-transfer.accept=Принять перенос
+transfer.accept=Принять передачу
transfer.accept_desc=Переместить в «%s»
-transfer.reject=Отказаться от перемещения
+transfer.reject=Отказаться от передачи
transfer.reject_desc=Отменить перемещение в «%s»
desc.private=Приватный
@@ -1077,14 +1097,14 @@ form.name_reserved=Название репозитория «%s» зарезер
form.name_pattern_not_allowed=Шаблон «%s» не допускается в названии репозитория.
need_auth=Авторизация
-migrate_options=Параметры миграции
+migrate_options=Параметры переноса
migrate_service=Сервис миграции
migrate_options_mirror_helper=Этот репозиторий будет зеркалом
migrate_options_lfs=Перенос LFS файлов
migrate_options_lfs_endpoint.label=Конечная точка LFS
-migrate_options_lfs_endpoint.description=Миграция попытается использовать ваш Git удаленно, чтобы определить сервер LFS. Вы также можете указать пользовательскую конечную точку, если данные хранятся в другом месте.
+migrate_options_lfs_endpoint.description=При переносе будет произведена попытка определить сервер LFS автоматически через Git. Если данные LFS хранятся в другом месте, укажите конечную точку самостоятельно.
migrate_options_lfs_endpoint.description.local=Также поддерживается путь на локальном сервере.
-migrate_items=Элементы миграции
+migrate_items=Переносимые элементы
migrate_items_wiki=Вики
migrate_items_milestones=Этапы
migrate_items_labels=Метки
@@ -1101,16 +1121,16 @@ migrate.permission_denied=У вас нет прав на импорт локал
migrate.permission_denied_blocked=Вы не можете импортировать с запрещённых хостов, пожалуйста, попросите администратора проверить настройки ALLOWED_DOMAINS/ALLOW_LOCALNETWORKS/BLOCKED_DOMAINS.
migrate.invalid_local_path=Недопустимый локальный путь. Он не существует или не является каталогом.
migrate.invalid_lfs_endpoint=Конечная точка LFS недействительна.
-migrate.failed=Миграция не удалась: %v
-migrate.migrate_items_options=Токен доступа необходим для миграции дополнительных элементов
+migrate.failed=Перенос не удался: %v
+migrate.migrate_items_options=Токен доступа необходим для переноса дополнительных элементов
migrated_from=Перенесено из %[2]s
migrated_from_fake=Перенесено из %[1]s
-migrate.migrate=Миграция из %s
+migrate.migrate=Перенос из %s
migrate.migrating=Перенос из %s...
migrate.migrating_failed=Перенос из %s не удался.
migrate.migrating_failed.error=Не удалось мигрировать: %s
-migrate.migrating_failed_no_addr=Миграция не удалась.
-migrate.github.description=Переносите данные с github.com или других серверов GitHub.
+migrate.migrating_failed_no_addr=Перенос не удался.
+migrate.github.description=Перенесите данные с github.com или сервера GitHub Enterprise.
migrate.git.description=Перенести только репозиторий из любого Git сервиса.
migrate.gitlab.description=Перенести данные с gitlab.com или других серверов GitLab.
migrate.gitea.description=Перенести данные с gitea.com или других серверов Gitea/Forgejo.
@@ -1118,28 +1138,28 @@ migrate.gogs.description=Перенести данные с notabug.org или
migrate.onedev.description=Перенести данные с code.onedev.io или других серверов OneDev.
migrate.codebase.description=Перенос данных с codebasehq.com.
migrate.gitbucket.description=Перенести данные из экземпляров GitBucket.
-migrate.migrating_git=Перенос Git данных
-migrate.migrating_topics=Миграция тем
+migrate.migrating_git=Перенос данных Git
+migrate.migrating_topics=Перенос тем
migrate.migrating_milestones=Перенос этапов
-migrate.migrating_labels=Миграция меток
-migrate.migrating_releases=Миграция выпусков
-migrate.migrating_issues=Миграция задач
-migrate.migrating_pulls=Миграция запросов на слияние
-migrate.cancel_migrating_title=Отменить миграцию
+migrate.migrating_labels=Перенос меток
+migrate.migrating_releases=Перенос выпусков
+migrate.migrating_issues=Перенос задач
+migrate.migrating_pulls=Перенос запросов на слияние
+migrate.cancel_migrating_title=Отменить перенос
migrate.cancel_migrating_confirm=Вы хотите отменить эту миграцию?
mirror_from=зеркало из
forked_from=ответвлено от
generated_from=создано из
-fork_from_self=Вы не можете форкнуть ваш собственный репозиторий.
-fork_guest_user=Войдите, чтобы форкнуть репозиторий.
+fork_from_self=Вы не можете создать ответвление собственного репозитория.
+fork_guest_user=Войдите, чтобы создать ответвление репозитория.
watch_guest_user=Войдите, чтобы отслеживать этот репозиторий.
star_guest_user=Войдите, чтобы добавить в избранное этот репозиторий.
unwatch=Не отслеживать
watch=Отслеживать
unstar=Убр. из избранного
star=В избранное
-fork=Форкнуть
+fork=Ответвление
download_archive=Скачать репозиторий
more_operations=Ещё действия
@@ -1226,7 +1246,7 @@ editor.cannot_edit_non_text_files=Двоичные файлы нельзя ре
editor.edit_this_file=Редактировать файл
editor.this_file_locked=Файл заблокирован
editor.must_be_on_a_branch=Чтобы внести или предложить изменения этого файла, необходимо выбрать ветку.
-editor.fork_before_edit=Необходимо сделать форк этого репозитория, чтобы внести или предложить изменения этого файла.
+editor.fork_before_edit=Необходимо сделать ответвление этого репозитория, чтобы внести или предложить изменения этого файла.
editor.delete_this_file=Удалить файл
editor.must_have_write_access=Вам необходимо иметь права на запись, чтобы вносить или предлагать изменения этого файла.
editor.file_delete_success=Файл «%s» удалён.
@@ -1449,19 +1469,19 @@ issues.filter_type.created_by_you=Созданные вами
issues.filter_type.mentioning_you=Вы упомянуты
issues.filter_type.review_requested=Проверка запрошена
issues.filter_type.reviewed_by_you=Проверенные вами
-issues.filter_sort=Сортировать
+issues.filter_sort=Сортировка
issues.filter_sort.latest=Новейшие
issues.filter_sort.oldest=Старейшие
issues.filter_sort.recentupdate=Недавно обновленные
issues.filter_sort.leastupdate=Давно обновленные
issues.filter_sort.mostcomment=Больше комментариев
issues.filter_sort.leastcomment=Меньше комментариев
-issues.filter_sort.nearduedate=Ближайшее по дате завершения
-issues.filter_sort.farduedate=Удалённое по дате завершения
+issues.filter_sort.nearduedate=Ближайший срок выполнения
+issues.filter_sort.farduedate=Поздний срок выполнения
issues.filter_sort.moststars=Больше звезд
issues.filter_sort.feweststars=Меньше звезд
-issues.filter_sort.mostforks=Больше форков
-issues.filter_sort.fewestforks=Меньше форков
+issues.filter_sort.mostforks=Больше ответвлений
+issues.filter_sort.fewestforks=Меньше ответвлений
issues.keyword_search_unavailable=В настоящее время поиск по ключевым словам недоступен. Обратитесь к администратору сайта.
issues.action_open=Открыть
issues.action_close=Закрыть
@@ -1485,7 +1505,7 @@ issues.closed_title=Закрыто
issues.draft_title=Черновик
issues.num_comments_1=%d комментарий
issues.num_comments=комментариев: %d
-issues.commented_at=`прокомментировал(а) %s`
+issues.commented_at=`оставлен комментарий в %s`
issues.delete_comment_confirm=Вы уверены, что хотите удалить этот комментарий?
issues.context.copy_link=Копировать ссылку
issues.context.quote_reply=Цитировать ответ
@@ -1494,21 +1514,21 @@ issues.context.edit=Редактировать
issues.context.delete=Удалить
issues.no_content=Описание отсутствует.
issues.close=Закрыть задачу
-issues.comment_pull_merged_at=слил(а) коммит %[1]s в %[2]s %[3]s
-issues.comment_manually_pull_merged_at=вручную слил(а) коммит %[1]s в %[2]s %[3]s
+issues.comment_pull_merged_at=коммит %[1]s был добавлен в %[2]s %[3]s
+issues.comment_manually_pull_merged_at=коммит %[1]s был вручную добавлен в %[2]s %[3]s
issues.close_comment_issue=Прокомментировать и закрыть
issues.reopen_issue=Открыть снова
issues.reopen_comment_issue=Прокомментировать и открыть снова
issues.create_comment=Комментировать
-issues.closed_at=`закрыл(а) эту задачу %[2]s`
-issues.reopened_at=`переоткрыл(а) эту проблему %[2]s`
+issues.closed_at=`задача была закрыта %[2]s`
+issues.reopened_at=`задача была открыта снова %[2]s`
issues.commit_ref_at=`упоминание этой задачи в коммите %[2]s`
issues.ref_issue_from=`упоминание этой задачи %[4]s %[2]s`
issues.ref_pull_from=`упоминание этого запроса слияния %[4]s %[2]s`
issues.ref_closing_from=`упоминание запроса слияния %[4]s, закрывающего эту задачу %[2]s`
issues.ref_reopening_from=`упоминание запроса слияния %[4]s, повторно открывающего эту задачу %[2]s`
issues.ref_closed_from=`закрыл этот запрос %[4]s %[2]s`
-issues.ref_reopened_from=`переоткрыл эту задачу %[4]s %[2]s`
+issues.ref_reopened_from=`задача была открыта снова %[4]s %[2]s`
issues.ref_from=`из %[1]s`
issues.author=Автор
issues.author_helper=Этот пользователь является автором.
@@ -1535,7 +1555,7 @@ issues.label_title=Имя метки
issues.label_description=Описание метки
issues.label_color=Цвет метки
issues.label_exclusive=Эксклюзивный
-issues.label_archive=Метка архива
+issues.label_archive=Архивная метка
issues.label_archived_filter=Показать архивированные метки
issues.label_archive_tooltip=Архивированные метки исключаются по умолчанию из подсказок при поиске по метке.
issues.label_exclusive_desc=Назовите метку область/элемент
, чтобы сделать ее взаимоисключающей с другими метками область/
.
@@ -1550,8 +1570,8 @@ issues.label_deletion_desc=Удаление метки удаляет ее из
issues.label_deletion_success=Метка удалена.
issues.label.filter_sort.alphabetically=По алфавиту
issues.label.filter_sort.reverse_alphabetically=С конца алфавита
-issues.label.filter_sort.by_size=Минимальный размер
-issues.label.filter_sort.reverse_by_size=Максимальный размер
+issues.label.filter_sort.by_size=Меньший размер
+issues.label.filter_sort.reverse_by_size=Больший размер
issues.num_participants=%d участвующих
issues.attachment.open_tab=`Нажмите, чтобы увидеть «%s» в новой вкладке`
issues.attachment.download=`Нажмите, чтобы скачать «%s»`
@@ -1583,17 +1603,17 @@ issues.comment_on_locked=Вы не можете оставить коммент
issues.delete=Удалить
issues.delete.title=Удалить эту задачу?
issues.delete.text=Вы точно хотите удалить эту задачу? (Это навсегда удалит всё её содержимое. Возможно, лучше закрыть её в архивных целях)
-issues.tracker=Отслеживание времени
-issues.start_tracking_short=Запустить таймер
-issues.start_tracking=Начать отслеживание времени
+issues.tracker=Подсчёт времени
+issues.start_tracking_short=Запустить подсчёт
+issues.start_tracking=Начать подсчёт времени
issues.start_tracking_history=`начал(а) работать %s`
issues.tracker_auto_close=Таймер будет остановлен автоматически, когда эта проблема будет закрыта
issues.tracking_already_started=`Вы уже начали отслеживать время для другой задачи!`
-issues.stop_tracking=Остановить таймер
+issues.stop_tracking=Остановить подсчёт
issues.stop_tracking_history=`перестал(а) работать %s`
issues.cancel_tracking=Отмена
issues.cancel_tracking_history=`отменил(а) отслеживание времени %s`
-issues.add_time=Вручную добавить время
+issues.add_time=Добавить время вручную
issues.del_time=Удалить этот журнал времени
issues.add_time_short=Добавить время
issues.add_time_cancel=Отмена
@@ -1602,10 +1622,10 @@ issues.del_time_history=`удалил(а) потраченное время %s`
issues.add_time_hours=Часы
issues.add_time_minutes=Минуты
issues.add_time_sum_to_small=Время не было введено.
-issues.time_spent_total=Общее затраченное время
-issues.time_spent_from_all_authors=`Общее затраченное время: %s`
+issues.time_spent_total=Всего затрачено времени
+issues.time_spent_from_all_authors=`Всего затрачено времени: %s`
issues.due_date=Срок выполнения
-issues.invalid_due_date_format=Дата окончания должна быть в формате «гггг-мм-дд».
+issues.invalid_due_date_format=Срок выполнения должен быть в формате «гггг-мм-дд».
issues.error_modifying_due_date=Не удалось изменить срок выполнения.
issues.error_removing_due_date=Не удалось убрать срок выполнения.
issues.push_commit_1=добавлен %d коммит %s
@@ -1614,12 +1634,12 @@ issues.force_push_codes=`форсировал(а) отправку измене
issues.force_push_compare=Сравнить
issues.due_date_form=гггг-мм-дд
issues.due_date_form_add=Добавить срок выполнения
-issues.due_date_form_edit=Редактировать
+issues.due_date_form_edit=Изменить
issues.due_date_form_remove=Удалить
issues.due_date_not_set=Срок выполнения не установлен.
issues.due_date_added=добавлен срок выполнения %s %s
-issues.due_date_modified=изменил(а) срок выполнения с %[2]s на %[1]s %[3]s
-issues.due_date_remove=убрал(а) срок выполнения %s %s
+issues.due_date_modified=срок выполнения передвинут с %[2]s на %[1]s %[3]s
+issues.due_date_remove=убран срок выполнения %s %s
issues.due_date_overdue=Просроченные
issues.due_date_invalid=Срок выполнения недействителен или находится за пределами допустимого диапазона. Пожалуйста, используйте формат «гггг-мм-дд».
issues.dependency.title=Зависимости
@@ -1721,8 +1741,10 @@ pulls.nothing_to_compare=Нечего сравнивать, родительск
pulls.nothing_to_compare_and_allow_empty_pr=Ветки идентичны. Этот PR будет пустым.
pulls.has_pull_request=`Запрос на слияние этих веток уже существует: %[2]s#%[3]d`
pulls.create=Создать запрос на слияние
-pulls.title_desc=хочет влить %[1]d коммит(ов) из %[2]s
в %[3]s
-pulls.merged_title_desc=слито %[1]d коммит(ов) из %[2]s
в %[3]s
%[4]s
+pulls.title_desc_one=хочет влить %[1]d коммит из %[2]s
в %[3]s
+pulls.title_desc_few=хочет влить %[1]d коммит(ов) из %[2]s
в %[3]s
+pulls.merged_title_desc_one=слит %[1]d коммит из %[2]s
в %[3]s
%[4]s
+pulls.merged_title_desc_few=слито %[1]d коммит(ов) из %[2]s
в %[3]s
%[4]s
pulls.change_target_branch_at=`изменил(а) целевую ветку с %s на %s %s`
pulls.tab_conversation=Обсуждение
pulls.tab_commits=Коммиты
@@ -1740,7 +1762,7 @@ pulls.cannot_merge_work_in_progress=Этот запрос на слияние п
pulls.still_in_progress=Всё ещё в процессе?
pulls.add_prefix=Добавить %s префикс
pulls.remove_prefix=Удалить %s префикс
-pulls.data_broken=Содержимое этого запроса было нарушено вследствие удаления информации форка.
+pulls.data_broken=Содержимое этого слияния нарушено из-за удаления информации об ответвлении.
pulls.files_conflicted=Этот запрос на слияние имеет изменения конфликтующие с целевой веткой.
pulls.is_checking=Продолжается проверка конфликтов. Повторите попытку позже.
pulls.is_ancestor=Эта ветка уже включена в целевую ветку. Объединять нечего.
@@ -1784,9 +1806,9 @@ pulls.rebase_conflict_summary=Сообщение об ошибке
pulls.unrelated_histories=Слияние не удалось: у источника и цели слияния нет общей истории. Совет: попробуйте другую стратегию
pulls.merge_out_of_date=Слияние не удалось: при создании слияния база данных была обновлена. Подсказка: попробуйте ещё раз.
pulls.head_out_of_date=Слияние не удалось: во время слияния головной коммит был обновлён. Попробуйте ещё раз.
-pulls.push_rejected=Слияние не удалось: отправка была отклонена. Проверьте Git-хуки для этого репозитория.
+pulls.push_rejected=Отправка была отклонена. Проверьте Git-хуки этого репозитория.
pulls.push_rejected_summary=Полная ошибка отклонения
-pulls.push_rejected_no_message=Слияние не удалось: отправка была отклонена, но сервер не указал причину.
Проверьте Git-хуки для этого репозитория
+pulls.push_rejected_no_message=Отправка была отклонена и удалённый сервер не указал причину. Проверьте Git-хуки этого репозитория
pulls.open_unmerged_pull_exists=`Вы не можете снова открыть, поскольку уже существует запрос на слияние (#%d) из того же репозитория с той же информацией о слиянии и ожидающий слияния.`
pulls.status_checking=Выполняются некоторые проверки
pulls.status_checks_success=Все проверки выполнены успешно
@@ -1839,9 +1861,9 @@ milestones.completeness=%d%% выполнено
milestones.create=Создать этап
milestones.title=Заголовок
milestones.desc=Описание
-milestones.due_date=Дата окончания (опционально)
+milestones.due_date=Срок выполнения (опционально)
milestones.clear=Очистить
-milestones.invalid_due_date_format=Дата выполнения должна быть в формате «гггг-мм-дд».
+milestones.invalid_due_date_format=Срок выполнения должен быть в формате «гггг-мм-дд».
milestones.create_success=Этап «%s» создан.
milestones.edit=Редактировать этап
milestones.edit_subheader=Используйте лучшее описание контрольной точки, во избежание непонимания со стороны других людей.
@@ -1851,12 +1873,12 @@ milestones.edit_success=Этап «%s» обновлён.
milestones.deletion=Удалить этап
milestones.deletion_desc=Удаление этапа приведет к его удалению из всех связанных задач. Продолжить?
milestones.deletion_success=Этап успешно удалён.
-milestones.filter_sort.earliest_due_data=По возрастанию даты завершения
-milestones.filter_sort.latest_due_date=По убыванию даты завершения
+milestones.filter_sort.earliest_due_data=Ближайший срок выполнения
+milestones.filter_sort.latest_due_date=Поздний срок выполнения
milestones.filter_sort.least_complete=Менее полное
milestones.filter_sort.most_complete=Более полное
-milestones.filter_sort.most_issues=Большинство задач
-milestones.filter_sort.least_issues=Меньшинство задач
+milestones.filter_sort.most_issues=Больше задач
+milestones.filter_sort.least_issues=Меньше задач
signing.will_sign=Этот коммит будет подписан ключом «%s».
signing.wont_sign.never=Коммиты никогда не подписываются.
@@ -2071,24 +2093,24 @@ settings.convert_notices_1=Эта операция преобразует это
settings.convert_confirm=Подтвердите преобразование
settings.convert_succeed=Репозиторий успешно преобразован в обычный.
settings.convert_fork=Преобразовать в обычный репозиторий
-settings.convert_fork_desc=Вы можете преобразовать этот форк в обычный репозиторий. Это не может быть отменено.
-settings.convert_fork_notices_1=Эта операция преобразует этот форк в обычный репозиторий, и не может быть отменена.
-settings.convert_fork_confirm=Преобразовать Репозиторий
-settings.convert_fork_succeed=Форк преобразован в обычный репозиторий.
+settings.convert_fork_desc=Вы можете преобразовать это ответвление в обычный репозиторий. Это не может быть отменено.
+settings.convert_fork_notices_1=Эта операция преобразует этот ответвление в обычный репозиторий, и не может быть отменена.
+settings.convert_fork_confirm=Преобразовать репозиторий
+settings.convert_fork_succeed=Ответвление преобразовано в обычный репозиторий.
settings.transfer=Передать права собственности
-settings.transfer.rejected=Перенос репозитория отменён.
-settings.transfer.success=Перенос репозитория выполнен успешно.
-settings.transfer_abort=Отменить перенос
-settings.transfer_abort_invalid=Невозможно отменить перенос несуществующего репозитория.
+settings.transfer.rejected=Передача репозитория отменена.
+settings.transfer.success=Передача репозитория выполнена успешно.
+settings.transfer_abort=Отменить передачу
+settings.transfer_abort_invalid=Невозможно отменить передачу несуществующего репозитория.
settings.transfer_abort_success=Передача репозитория %s успешно отменена.
settings.transfer_desc=Передать репозиторий другому пользователю или организации где у вас есть права администратора.
settings.transfer_form_title=Введите сопутствующую информацию для подтверждения операции:
-settings.transfer_in_progress=Имеется текущий перенос. Отмените его, если хотите выполнить перенос другому пользователю.
+settings.transfer_in_progress=Имеется текущая передача. Отмените её, если хотите выполнить передачу другому пользователю.
settings.transfer_notices_1=- Вы можете потерять доступ, если новый владелец является отдельным пользователем.
settings.transfer_notices_2=- Вы сохраните доступ, если новым владельцем станет организация, владельцем которой вы являетесь.
settings.transfer_notices_3=- если репозиторий является приватным и передается отдельному пользователю, это действие позволяет убедиться, что пользователь имеет хотя бы права на чтение (и при необходимости изменяет права доступа).
settings.transfer_owner=Новый владелец
-settings.transfer_perform=Выполнить перенос
+settings.transfer_perform=Выполнить передачу
settings.transfer_started=Репозиторий ожидает подтверждения передачи от «%s»
settings.transfer_succeed=Репозиторий перенесён.
settings.signing_settings=Настройки подписи верификации
@@ -2113,7 +2135,7 @@ settings.delete=Удалить этот репозиторий
settings.delete_desc=Будьте внимательны! Как только вы удалите репозиторий — пути назад не будет.
settings.delete_notices_1=- Эта операция НЕ МОЖЕТ быть отменена.
settings.delete_notices_2=- Эта операция навсегда удалит всё из репозитория %s, включая данные Git, связанные с ним задачи, комментарии и права доступа для сотрудников.
-settings.delete_notices_fork_1=- Все форки станут независимыми репозиториями после удаления.
+settings.delete_notices_fork_1=- После удаления все ответвления станут независимыми репозиториями.
settings.deletion_success=Репозиторий удалён.
settings.update_settings_success=Настройки репозитория обновлены.
settings.update_settings_no_unit=Должно быть разрешено хоть какое-то взаимодействие с репозиторием.
@@ -2178,8 +2200,8 @@ settings.event_create=Создать
settings.event_create_desc=Ветка или тэг созданы.
settings.event_delete=Удалить
settings.event_delete_desc=Ветка или тег удалены.
-settings.event_fork=Форкнуть
-settings.event_fork_desc=Репозиторий форкнут.
+settings.event_fork=Ответвление
+settings.event_fork_desc=Ответвление создано.
settings.event_wiki=Вики
settings.event_wiki_desc=Страница вики создана, переименована, изменена или удалена.
settings.event_release=Выпуск
@@ -2235,7 +2257,7 @@ settings.hook_type=Тип хука
settings.slack_token=Slack токен
settings.slack_domain=Домен
settings.slack_channel=Канал
-settings.add_web_hook_desc=Интегрировать %s в ваш репозиторий.
+settings.add_web_hook_desc=Интегрируйте %s с этим репозиторием .
settings.web_hook_name_gitea=Gitea
settings.web_hook_name_forgejo = Forgejo
settings.web_hook_name_gogs=Gogs
@@ -2557,7 +2579,7 @@ error.csv.too_large=Не удается отобразить этот файл,
error.csv.unexpected=Не удается отобразить этот файл, потому что он содержит неожиданный символ в строке %d и столбце %d.
error.csv.invalid_field_count=Не удается отобразить этот файл, потому что он имеет неправильное количество полей в строке %d.
mirror_address_protocol_invalid = Эта ссылка недействительна. Для зеркалирования можно использовать только расположения http(s):// и git:// .
-fork_no_valid_owners = Этот репозиторий не может быть форкнут, т.к. здесь нет действующих владельцев.
+fork_no_valid_owners = Невозможно создать ответвление этого репозитория, т.к. здесь нет действующих владельцев.
new_repo_helper = Репозиторий содержит все файлы проекта и историю изменений. Уже где-то есть репозиторий? Выполните миграцию.
mirror_address_url_invalid = Эта ссылка недействительна. Необходимо правильно указать все части адреса.
issues.comment.blocked_by_user = Вы не можете комментировать под этой задачей, т.к. вы заблокированы владельцем репозитория или автором задачи.
@@ -2591,11 +2613,11 @@ diff.comment.add_line_comment = Добавить комментарий к ст
tree_path_not_found_tag = Путь %[1]s отсутствует в теге %[2]s
migrate_options_lfs_endpoint.placeholder = Если не заполнено, конечная точка будет определена из URL клонирования
invisible_runes_description = `Этот файл содержит невидимые символы Юникода, которые невозможно заметить, но которые потенциально будут влиять на обработку файла. Если так и должно быть, можете спокойно игнорировать это предупреждение. Отобразить символы можно кнопкой Экранирования.`
-transfer.no_permission_to_accept = У вас недостаточно прав для принятия этого переноса.
-transfer.no_permission_to_reject = У вас недостаточно прав для отклонения этого переноса.
+transfer.no_permission_to_accept = У вас недостаточно прав для принятия этой передачи.
+transfer.no_permission_to_reject = У вас недостаточно прав для отклонения этой передачи.
commits.view_path = Просмотреть в этом моменте истории
commits.renamed_from = Переименован с %s
-issues.due_date_not_writer = Для обновления даты выполнения задачи требуются на запись в этом репозитории.
+issues.due_date_not_writer = Для обновления срока выполнения задачи требуется право на запись в этом репозитории.
issues.review.outdated_description = С момента добавления этого комментария содержимое изменилось
pulls.nothing_to_compare_have_tag = Выбранные ветки/теги идентичны.
pulls.select_commit_hold_shift_for_range = Выберите коммит. Зажмите Shift, чтобы выбрать диапазон
@@ -2643,13 +2665,15 @@ activity.navbar.recent_commits = Недавние коммиты
settings.confirmation_string = Подтверждение
settings.archive.text = Архивация репозитория сделает всё его содержимое доступным только для чтения. Он будет скрыт с домашнего экрана. Никто (включая вас!) не сможет добавлять коммиты, открывать задачи и запросы слияний.
release.deletion_desc = Удаление выпуска удаляет его только в Forgejo. Это действие не затронет тег в git, содержимое репозитория и его историю. Продолжить?
-pulls.agit_explanation = Создано через рабочий поток AGit. С ним можно предлагать изменения, используя команду «git push», без необходимости в создании форка или новой ветки.
+pulls.agit_explanation = Создано через рабочий поток AGit. С ним можно предлагать изменения, используя команду «git push», без необходимости в создании ответвления или новой ветки.
settings.webhook.replay.description_disabled = Активируйте веб-хук для повторения отправки.
activity.navbar.pulse = Недавняя активность
settings.tags.protection.pattern.description = Можно указать название тега. Для выбора нескольких тегов можно указать поисковый шаблон или регулярное выражение. Подробнее о защищённых тегах.
file_follow = Пройти по мягкой ссылке
settings.pull_mirror_sync_in_progress = Идёт получение изменений из удалённого репозитория %s.
settings.ignore_stale_approvals_desc = Не учитывать одобрения, оставленные для старых коммитов (устаревшие отзывы), при подсчёте общего числа одобрений у запроса на слияние. Не относится к отклонённым отзывам.
+settings.mirror_settings.docs.doc_link_pull_section = раздел документации «Pulling from a remote repository».
+wiki.original_git_entry_tooltip = Перейти по настоящему пути вместо читабельной ссылки.
[graphs]
@@ -2664,7 +2688,7 @@ teams=Команды
code=Код
lower_members=участники
lower_repositories=репозитории
-create_new_team=Создание команды
+create_new_team=Новая команда
create_team=Создать команду
org_desc=Описание
team_name=Название команды
@@ -2683,17 +2707,17 @@ form.create_org_not_allowed=Этому пользователю не разре
settings=Настройки
settings.options=Организация
settings.full_name=Полное имя
-settings.email=Почта для связи
+settings.email=Эл. почта для связи
settings.website=Сайт
settings.location=Местоположение
settings.permission=Разрешения
settings.repoadminchangeteam=Администратор репозитория может добавлять и удалять права доступа для команд
settings.visibility=Видимость
settings.visibility.public=Публичный
-settings.visibility.limited=Ограниченный (Видимый только выполнившим вход пользователям)
+settings.visibility.limited=Ограниченная (видна только авторизованным пользователям)
settings.visibility.limited_shortname=Ограниченный
-settings.visibility.private=Приватный (Видимый только для участников организации)
-settings.visibility.private_shortname=Приватный
+settings.visibility.private=Частная (видна только участникам организации)
+settings.visibility.private_shortname=Частная
settings.update_settings=Обновить настройки
settings.update_setting_success=Настройки организации обновлены.
@@ -2704,13 +2728,13 @@ settings.delete=Удалить организацию
settings.delete_account=Удалить эту организацию
settings.delete_prompt=Это действие БЕЗВОЗВРАТНО удалит эту организацию навсегда!
settings.confirm_delete_account=Подтвердить удаление
-settings.delete_org_title=Удалить организацию
+settings.delete_org_title=Удаление организации
settings.delete_org_desc=Эта организация будет безвозвратно удалена. Продолжить?
settings.hooks_desc=Добавьте веб-хуки, которые будет вызываться для всех репозиториев под этой организации.
settings.labels_desc=Добавьте метки, которые могут быть использованы в задачах для всех репозиториев этой организации.
-members.membership_visibility=Видимость участника команды:
+members.membership_visibility=Видимость участника:
members.public=Видимый
members.public_helper=скрыть
members.private=Скрыт
@@ -2748,14 +2772,14 @@ teams.delete_team=Удалить команду
teams.add_team_member=Добавить участника
teams.invite_team_member=Пригласить в %s
teams.invite_team_member.list=Приглашения в ожидании
-teams.delete_team_title=Удалить команду
+teams.delete_team_title=Удаление команды
teams.delete_team_desc=Удаление команды отменяет доступ к репозиторию для её членов. Продолжить?
teams.delete_team_success=Команда удалена.
teams.read_permission_desc=Эта команда предоставляет доступ на Чтение: члены могут просматривать и клонировать репозитории команды.
teams.write_permission_desc=Эта команда предоставляет доступ на Запись: члены могут получать и выполнять push команды в репозитории.
teams.admin_permission_desc=Эта команда даёт административный доступ: участники могут читать, отправлять изменения и добавлять соучастников к её репозиториям.
teams.create_repo_permission_desc=Кроме того, эта команда предоставляет право Создание репозитория: участники команды могут создавать новые репозитории в организации.
-teams.repositories=Репозитории группы разработки
+teams.repositories=Репозитории команды
teams.search_repo_placeholder=Поиск репозитория…
teams.remove_all_repos_title=Удалить все репозитории команды
teams.remove_all_repos_desc=Удаляет все репозитории из команды.
@@ -2776,9 +2800,10 @@ teams.invite.title=Вас пригласили присоединиться к
teams.invite.by=Приглашен(а) %s
teams.invite.description=Нажмите на кнопку ниже, чтобы присоединиться к команде.
follow_blocked_user = Вы не можете подписаться на эту организацию, т.к. вы в ней заблокированы.
+teams.general_access = Настраиваемый доступ
[admin]
-dashboard=Панель
+dashboard=Панель управления
identity_access=Идентификация и доступ
users=Пользователи
organizations=Организации
@@ -2796,7 +2821,7 @@ total=Всего: %d
dashboard.new_version_hint=Доступна новая версия Forgejo %s, вы используете %s. Более подробную информацию читайте в блоге.
dashboard.statistic=Статистика
-dashboard.operations=Операции
+dashboard.operations=Обслуживание
dashboard.system_status=Состояние системы
dashboard.operation_name=Имя операции
dashboard.operation_switch=Переключить
@@ -2830,58 +2855,58 @@ dashboard.update_migration_poster_id=Обновить ИД плакатов ми
dashboard.git_gc_repos=Выполнить сборку мусора для всех репозиториев
dashboard.resync_all_sshkeys=Обновить файл '.ssh/authorized_keys' с ключами SSH Forgejo.
dashboard.resync_all_sshprincipals=Обновите файл '.ssh/authorized_principals' SSH данными участника Forgejo.
-dashboard.resync_all_hooks=Пересинхронизировать хуки pre-receive, update и post-receive всех репозиториев.
+dashboard.resync_all_hooks=Пересинхронизировать хуки pre-receive, update и post-receive всех репозиториев
dashboard.reinit_missing_repos=Переинициализировать все отсутствующие Git репозитории, для которых существуют записи
dashboard.sync_external_users=Синхронизировать данные сторонних пользователей
dashboard.cleanup_hook_task_table=Очистить таблицу hook_task
dashboard.cleanup_packages=Очистка устаревших пакетов
-dashboard.server_uptime=Время непрерывной работы сервера
-dashboard.current_goroutine=Текущее количество Goroutines
+dashboard.server_uptime=Время работы
+dashboard.current_goroutine=Количество goroutines
dashboard.current_memory_usage=Текущее использование памяти
-dashboard.total_memory_allocated=Всего памяти выделено
-dashboard.memory_obtained=Памяти использовано
-dashboard.pointer_lookup_times=Запросов указателя
+dashboard.total_memory_allocated=Всего памяти выделялось
+dashboard.memory_obtained=Получено памяти
+dashboard.pointer_lookup_times=Поисков указателя
dashboard.memory_allocate_times=Выделений памяти
-dashboard.memory_free_times=Освобождений памяти
+dashboard.memory_free_times=Высвобождений памяти
dashboard.current_heap_usage=Текущее использование кучи
dashboard.heap_memory_obtained=Получено динамической памяти
-dashboard.heap_memory_idle=Не используется динамической памяти
-dashboard.heap_memory_in_use=Кучи памяти в работе
+dashboard.heap_memory_idle=Простаивающая динамическая память
+dashboard.heap_memory_in_use=Используемая динамическая память
dashboard.heap_memory_released=Освобождено динамической памяти
dashboard.heap_objects=Объектов динамической памяти
dashboard.bootstrap_stack_usage=Использование стека загрузчика
-dashboard.stack_memory_obtained=Память, занятая под стек
+dashboard.stack_memory_obtained=Стековой памяти выделялось
dashboard.mspan_structures_usage=Использование структур MSpan
-dashboard.mspan_structures_obtained=Получено структур MSpan
+dashboard.mspan_structures_obtained=Структур MSpan выделялось
dashboard.mcache_structures_usage=Использование структур MCache
dashboard.mcache_structures_obtained=Получено структур MCache
-dashboard.profiling_bucket_hash_table_obtained=Хеш-таблиц получено при профилировании
-dashboard.gc_metadata_obtained=Полученных метаданных сборщика мусора
-dashboard.other_system_allocation_obtained=Получено прочих выделений системной памяти
-dashboard.next_gc_recycle=Следующая очистка сборщика мусора
+dashboard.profiling_bucket_hash_table_obtained=Хеш-таблиц получено при профайлинге
+dashboard.gc_metadata_obtained=Метаданных сборщика мусора создавалось
+dashboard.other_system_allocation_obtained=Прочие системные выделения памяти
+dashboard.next_gc_recycle=Следующее высвобождение сборщиком мусора
dashboard.last_gc_time=Прошло с последнего сбора мусора
dashboard.total_gc_time=Итоговая задержка GC
-dashboard.total_gc_pause=Итоговая задержка GC
-dashboard.last_gc_pause=Последняя пауза сборщика мусора
-dashboard.gc_times=Количество сборок мусора
-dashboard.delete_old_actions=Удалите все старые действия из базы данных
-dashboard.delete_old_actions.started=Удалите все старые действия из запущенной базы данных.
+dashboard.total_gc_pause=Итоговая задержка сборщика
+dashboard.last_gc_pause=Последняя пауза сборщика
+dashboard.gc_times=Сборок мусора
+dashboard.delete_old_actions=Удалить все старые действия из базы данных
+dashboard.delete_old_actions.started=Запущено удаление всех старых действий из БД.
dashboard.update_checker=Проверка обновлений
dashboard.delete_old_system_notices=Удалить все старые системные уведомления из базы данных
dashboard.gc_lfs=Выполнить сборку мусора метаобъектов LFS
dashboard.stop_zombie_tasks=Остановить задания-зомби
-dashboard.stop_endless_tasks=Остановить бесконечные задания
+dashboard.stop_endless_tasks=Остановить непрекращающиеся задания
dashboard.cancel_abandoned_jobs=Отменить брошенные задания
dashboard.start_schedule_tasks=Запустить запланированные задания
-users.user_manage_panel=Панель управления пользователями
+users.user_manage_panel=Управление пользователями
users.new_account=Создать новую учётную запись
users.name=Имя пользователя
users.full_name=Полное имя
users.activated=Активирован
users.admin=Администратор
users.restricted=Ограничено
-users.reserved=Зарезервировано
+users.reserved=Резерв
users.bot=Бот
users.2fa=Двухфакторная авторизация
users.repos=Репозитории
@@ -2931,13 +2956,13 @@ users.list_status_filter.is_2fa_enabled=2FA включено
users.list_status_filter.not_2fa_enabled=2FA отключено
users.details=О пользователе
-emails.email_manage_panel=Управление эл. почтой пользователя
+emails.email_manage_panel=Управление адресами эл. почты пользователей
emails.primary=Первичный
emails.activated=Активирован
-emails.filter_sort.email=Эл. почта
-emails.filter_sort.email_reverse=Эл. почта (обратный)
-emails.filter_sort.name=Имя пользователя
-emails.filter_sort.name_reverse=Имя пользователя (обратное)
+emails.filter_sort.email=По эл. почте
+emails.filter_sort.email_reverse=По эл. почте (наоборот)
+emails.filter_sort.name=По имени пользователя
+emails.filter_sort.name_reverse=По имени пользователя (наоборот)
emails.updated=Email обновлён
emails.not_updated=Не удалось обновить запрошенный адрес эл. почты: %v
emails.duplicate_active=Этот адрес эл. почты уже активирован для другого пользователя.
@@ -2958,7 +2983,7 @@ repos.name=Название
repos.private=Личный
repos.watches=Следят
repos.stars=Звезды
-repos.forks=Форки
+repos.forks=Ответвления
repos.issues=Задачи
repos.size=Размер
repos.lfs_size=Размер LFS
@@ -2977,7 +3002,7 @@ packages.repository=Репозиторий
packages.size=Размер
packages.published=Опубликовано
-defaulthooks=Стандартные Веб-хуки
+defaulthooks=Стандартные веб-хуки
defaulthooks.add_webhook=Добавить стандартный Веб-хук
defaulthooks.update_webhook=Обновить стандартный Веб-хук
@@ -2985,7 +3010,7 @@ systemhooks=Системные веб-хуки
systemhooks.add_webhook=Добавить системный веб-хук
systemhooks.update_webhook=Обновить системный веб-хук
-auths.auth_manage_panel=Управление аутентификацией
+auths.auth_manage_panel=Управление источниками аутентификации
auths.new=Добавить новый источник
auths.name=Имя
auths.type=Тип
@@ -3030,7 +3055,7 @@ auths.smtphost=Адрес SMTP
auths.smtpport=Порт SMTP
auths.allowed_domains=Разрешенные домены
auths.allowed_domains_helper=Разделяйте домены запятыми («,»). Оставьте пустым, чтобы разрешить все домены.
-auths.skip_tls_verify=Пропустить проверку TLS
+auths.skip_tls_verify=Пропуск проверки TLS
auths.force_smtps=Принудительный SMTPS
auths.force_smtps_helper=SMTPS всегда использует 465 порт. Установите это, что бы принудительно использовать SMTPS на других портах. (Иначе STARTTLS будет использоваться на других портах, если это поддерживается хостом.)
auths.helo_hostname=HELO Hostname
@@ -3103,22 +3128,22 @@ auths.unable_to_initialize_openid=Не удалось инициализиров
auths.invalid_openIdConnectAutoDiscoveryURL=Неверный URL для автоматического обнаружения (это должен быть валидный URL, начинающийся с http:// или https://)
config.server_config=Конфигурация сервера
-config.app_name=Название сайта
+config.app_name=Название сервера
config.app_ver=Версия Forgejo
config.app_url=Базовый URL Forgejo
config.custom_conf=Путь к файлу конфигурации
-config.custom_file_root_path=Пользовательский путь до каталога с файлами
+config.custom_file_root_path=Путь до каталога с файлами для персонализации
config.domain=Домен сервера
config.offline_mode=Локальный режим
config.disable_router_log=Отключение журнала маршрутизатора
config.run_user=Запуск от имени пользователя
-config.run_mode=Режим выполнения
-config.git_version=Версия Git
+config.run_mode=Режим работы
+config.git_version=Версия git
config.app_data_path=Путь к данным приложения
config.repo_root_path=Путь до каталога репозиториев
config.lfs_root_path=Корневой путь LFS
-config.log_file_root_path=Путь к журналу
-config.script_type=Тип скрипта
+config.log_file_root_path=Путь журналов
+config.script_type=Тип сценария
config.reverse_auth_user=Имя пользователя для авторизации на reverse proxy
config.ssh_config=Конфигурация SSH
@@ -3129,14 +3154,14 @@ config.ssh_port=Порт
config.ssh_listen_port=Прослушиваемый порт
config.ssh_root_path=Корневой путь
config.ssh_key_test_path=Путь к тестовому ключу
-config.ssh_keygen_path=Путь к генератору ключей ('ssh-keygen')
+config.ssh_keygen_path=Путь до генератора ключей («ssh-keygen»)
config.ssh_minimum_key_size_check=Минимальный размер ключа проверки
config.ssh_minimum_key_sizes=Минимальные размеры ключа
config.lfs_config=Конфигурация LFS
config.lfs_enabled=Включено
-config.lfs_content_path=Путь к контенту LFS
-config.lfs_http_auth_expiry=Устаревание HTTP-аутентификации LFS
+config.lfs_content_path=Путь к содержимому LFS
+config.lfs_http_auth_expiry=Срок действия HTTP-аутентификации LFS
config.db_config=Конфигурация базы данных
config.db_type=Тип
@@ -3147,34 +3172,34 @@ config.db_schema=Схема
config.db_ssl_mode=SSL
config.db_path=Путь
-config.service_config=Сервисная конфигурация
-config.register_email_confirm=Требуется подтверждение по эл. почте
-config.disable_register=Отключить самостоятельную регистрацию
-config.allow_only_internal_registration=Разрешить регистрацию только через Forgejo
+config.service_config=Конфигурация служб
+config.register_email_confirm=Требовать подтверждение по эл. почте для регистрации
+config.disable_register=Саморегистрация отключена
+config.allow_only_internal_registration=Разрешить регистрацию только напрямую через Forgejo
config.allow_only_external_registration=Разрешить регистрацию только через сторонние сервисы
-config.enable_openid_signup=Включить cамостоятельную регистрацию OpenID
-config.enable_openid_signin=Включение входа через OpenID
-config.show_registration_button=Показать кнопку регистрации
+config.enable_openid_signup=Cаморегистрация через OpenID
+config.enable_openid_signin=Вход через OpenID
+config.show_registration_button=Кнопка регистрации
config.require_sign_in_view=Для просмотра необходима авторизация
-config.mail_notify=Почтовые уведомления
-config.enable_captcha=Включить CAPTCHA
-config.active_code_lives=Время жизни кода для активации
+config.mail_notify=Уведомления по эл. почте
+config.enable_captcha=CAPTCHA
+config.active_code_lives=Срок действия кода активации учётной записи
config.reset_password_code_lives=Срок действия кода восстановления учётной записи
config.default_keep_email_private=Скрывать адреса эл. почты по умолчанию
config.default_allow_create_organization=Разрешить создание организаций по умолчанию
-config.enable_timetracking=Включить отслеживание времени
+config.enable_timetracking=Отслеживание времени
config.default_enable_timetracking=Включить отслеживание времени по умолчанию
config.default_allow_only_contributors_to_track_time=Подсчитывать время могут только соавторы
-config.no_reply_address=No-reply адрес
-config.default_visibility_organization=Видимость по умолчанию для новых организаций
+config.no_reply_address=Домен скрытых адресов почты
+config.default_visibility_organization=Видимость новых организаций по умолчанию
config.default_enable_dependencies=Включение зависимостей для задач по умолчанию
config.webhook_config=Конфигурация веб-хуков
config.queue_length=Длина очереди
config.deliver_timeout=Задержка доставки
-config.skip_tls_verify=Пропустить проверку TLS
+config.skip_tls_verify=Пропуск проверки TLS
-config.mailer_config=Настройки почты
+config.mailer_config=Конфигурация почтового сервера
config.mailer_enabled=Почта включена
config.mailer_enable_helo=Включить HELO
config.mailer_name=Имя
@@ -3185,7 +3210,7 @@ config.mailer_user=Пользователь
config.mailer_use_sendmail=Использовать Sendmail
config.mailer_sendmail_path=Путь к Sendmail
config.mailer_sendmail_args=Дополнительные аргументы для Sendmail
-config.mailer_sendmail_timeout=Тайм-аут Sendmail
+config.mailer_sendmail_timeout=Истечение ожидания Sendmail
config.mailer_use_dummy=Заглушка
config.test_email_placeholder=Эл. почта (например, test@example.com)
config.send_test_mail=Отправить тестовое письмо
@@ -3196,7 +3221,7 @@ config.test_mail_sent=Тестовое письмо было отправлен
config.oauth_config=Конфигурация OAuth
config.oauth_enabled=OAuth включен
-config.cache_config=Настройки кеша
+config.cache_config=Конфигурация кэша
config.cache_adapter=Адаптер кэша
config.cache_interval=Интервал кэширования
config.cache_conn=Подключение кэша
@@ -3211,22 +3236,22 @@ config.session_life_time=Время жизни сессии
config.https_only=Только HTTPS
config.cookie_life_time=Время жизни файла cookie
-config.picture_config=Настройка изображения
-config.picture_service=Сервис изображений
+config.picture_config=Конфигурация аватаров и изображений
+config.picture_service=Служба изображений
config.disable_gravatar=Отключить Gravatar
-config.enable_federated_avatar=Включить федерированные аватары
+config.enable_federated_avatar=Федерированные аватары
config.git_config=Конфигурация Git
config.git_disable_diff_highlight=Отключить подсветку синтаксиса при сравнении
-config.git_max_diff_lines=Макс. количество строк (на файл) при сравнении
-config.git_max_diff_line_characters=Макс. количество символов (в строке) при сравнении
+config.git_max_diff_lines=Макс. количество строк в файле при сравнении
+config.git_max_diff_line_characters=Макс. количество символов в строке при сравнении
config.git_max_diff_files=Макс. отображаемое количество файлов при сравнении
-config.git_gc_args=Аргументы GC
-config.git_migrate_timeout=Лимит времени миграций
-config.git_mirror_timeout=Лимит времени обновления зеркал
-config.git_clone_timeout=Лимит времени операции клонирования
-config.git_pull_timeout=Лимит времени получения изменений
-config.git_gc_timeout=Лимит времени сборки мусора
+config.git_gc_args=Аргументы сборщика мусора
+config.git_migrate_timeout=Ограничение времени миграций
+config.git_mirror_timeout=Ограничение времени на синхронизацию зеркала
+config.git_clone_timeout=Ограничение времени операций клонирования
+config.git_pull_timeout=Ограничение времени на получение изменений
+config.git_gc_timeout=Ограничение времени на сборку мусора
config.log_config=Конфигурация журнала
config.logger_name_fmt=Журнал: %s
@@ -3239,7 +3264,7 @@ config.set_setting_failed=Задать параметр %s не удалось
monitor.stats=Статистика
-monitor.cron=Запланированные задания
+monitor.cron=Плановые задания
monitor.name=Название
monitor.schedule=Расписание
monitor.next=Следующий раз
@@ -3310,15 +3335,16 @@ self_check = Самопроверка
dashboard.rebuild_issue_indexer = Пересобрать индексатор задач
systemhooks.desc = Веб-хуки автоматически совершают POST запросы до указанного HTTP сервера, когда в Forgejo происходят определённые события. Заданные здесь веб-хуки будут срабатывать во всех репозиториях на этом сервере и могут привести к проблемам с производительностью. Подробнее о веб-хуках.
defaulthooks.desc = Веб-хуки автоматически совершают POST запросы до указанного HTTP сервера, когда в Forgejo происходят определённые события. Заданные здесь веб-хуки используются по умолчанию и будут добавлены во все новые репозитории. Подробнее о веб-хуках.
+users.remote = Дистанц
[action]
create_repo=создал(а) репозиторий %s
rename_repo=переименовал(а) репозиторий из %[1]s
на %[3]s
commit_repo=отправил(а) изменения в %[3]s в %[4]s
-create_issue=`открыл(а) задачу %[3]s#%[2]s`
+create_issue=`задача создана %[3]s#%[2]s`
close_issue=`закрыл(а) задачу %[3]s#%[2]s`
-reopen_issue=`переоткрыл(а) задачу %[3]s#%[2]s`
+reopen_issue=`задача снова открыта %[3]s#%[2]s`
create_pull_request=`создал(а) запрос на слияние %[3]s#%[2]s`
close_pull_request=`закрыл(а) запрос на слияние %[3]s#%[2]s`
reopen_pull_request=`переоткрыл(а) запрос на слияние %[3]s#%[2]s`
diff --git a/options/locale/locale_si-LK.ini b/options/locale/locale_si-LK.ini
index 318eb24df8..7cb1768d22 100644
--- a/options/locale/locale_si-LK.ini
+++ b/options/locale/locale_si-LK.ini
@@ -287,7 +287,7 @@ twofa_scratch_used=ඔබ ඔබේ සීරීම් කේතය භාවි
twofa_passcode_incorrect=ඔබගේ මුර කේතය වැරදිය. ඔබ ඔබේ උපාංගය අස්ථානගත කර ඇත්නම්, පුරනය වීමට ඔබේ සීරීම් කේතය භාවිතා කරන්න.
twofa_scratch_token_incorrect=ඔබේ සීරීම් කේතය වැරදියි.
login_userpass=පිවිසෙන්න
-login_openid=විවෘතහැඳු.
+tab_openid=විවෘතහැඳු.
oauth_signup_tab=නව ගිණුමක් ලියාපදිංචි කරන්න
oauth_signup_title=නව ගිණුම සම්පූර්ණ කරන්න
oauth_signup_submit=ගිණුම සම්පූර්ණ කරන්න
@@ -579,7 +579,7 @@ gpg_invalid_token_signature=සපයන ලද GPG යතුර, අත්ස
gpg_token_required=පහත ටෝකනය සඳහා ඔබ අත්සනක් ලබා දිය යුතුය
gpg_token=ටෝකනය
gpg_token_help=ඔබට අත්සනක් ජනනය කළ හැකිය:
-gpg_token_code=දෝංකාරය "%s" | gpg -a -පැහැර හැරීම-යතුර %s —වෙන්ච-සිග්
+gpg_token_code=echo "%s" | gpg -a --default-key %s --detach-sig
gpg_token_signature=සන්නද්ධ GPG අත්සන
key_signature_gpg_placeholder=ආරම්භ වන්නේ '—ආරම්භ කරන්න PGP සිග්නේටුර්—'
ssh_key_verified=සත්යාපිත යතුර
@@ -1269,8 +1269,8 @@ pulls.nothing_to_compare=මෙම ශාඛා සමාන වේ. අදි
pulls.nothing_to_compare_and_allow_empty_pr=මෙම ශාඛා සමාන වේ. මෙම මහජන සම්බන්ධතා හිස් වනු ඇත.
pulls.has_pull_request=`මෙම ශාඛා අතර අදින්න ඉල්ලීම දැනටමත් පවතී: %[2]s #%[3]d`
pulls.create=අදින්න ඉල්ලීම නිර්මාණය
-pulls.title_desc=%[1]d සිට %[2]s
දක්වා %[3]s
-pulls.merged_title_desc=මර්ජ්%[1]d සිට %[2]s
දක්වා %[3]s
%[4]s
+pulls.title_desc_few=%[1]d සිට %[2]s
දක්වා %[3]s
+pulls.merged_title_desc_few=මර්ජ්%[1]d සිට %[2]s
දක්වා %[3]s
%[4]s
pulls.change_target_branch_at=`ඉලක්කගත ශාඛාව %s සිට %s %sදක්වා වෙනස් කර ඇත`
pulls.tab_conversation=සංවාදය
pulls.tab_commits=විවරයන්
diff --git a/options/locale/locale_sk-SK.ini b/options/locale/locale_sk-SK.ini
index 758b01573d..549e3a7a1f 100644
--- a/options/locale/locale_sk-SK.ini
+++ b/options/locale/locale_sk-SK.ini
@@ -149,7 +149,7 @@ footer.links=Odkazy
[heatmap]
number_of_contributions_in_the_last_12_months=%s príspevkov za posledných 12 mesiacov
-no_contributions=Žiadne príspevky
+contributions_zero=Žiadne príspevky
less=Menej
more=Viac
@@ -384,7 +384,7 @@ twofa_scratch_used=Použili ste pomocný kód. Boli ste presmerovaní na stránk
twofa_passcode_incorrect=Váš prístupový kód je nesprávny. Ak ste vaše zariadenie umiestnili nesprávne, použite pomocný kód na prihlásenie.
twofa_scratch_token_incorrect=Váš pomocný kód je nesprávny.
login_userpass=Prihlásiť sa
-login_openid=OpenID
+tab_openid=OpenID
oauth_signup_tab=Zaregistrovať nový účet
oauth_signup_title=Dokončiť nový účet
oauth_signup_submit=Dokončiť účet
diff --git a/options/locale/locale_sl.ini b/options/locale/locale_sl.ini
index d117230aa2..01404dd0b4 100644
--- a/options/locale/locale_sl.ini
+++ b/options/locale/locale_sl.ini
@@ -122,6 +122,14 @@ confirm_delete_artifact = Ste prepričani, da želite izbrisati artefakt "%s"?
concept_code_repository = Repozitorij
error404 = Stran, ki jo poskušate doseči, ne obstaja ali niste pooblaščeni za njen ogled.
toggle_menu = Toggle Meni
+filter.is_fork = Vtičnica
+filter.not_fork = Ni vstavljena vilica
+filter.is_mirror = Zrcalni
+filter.not_mirror = Ni zrcaljen
+filter.public = Javni
+filter.private = Zasebno
+filter.not_archived = Ni arhivirano
+pull_requests = Zahteve za umik
[install]
reinstall_confirm_check_3 = Potrjujete, da ste popolnoma prepričani, da se ta program Forgejo izvaja s pravilno lokacijo app.ini, in da ste prepričani, da ga morate znova namestiti. Potrjujete, da se zavedate zgoraj navedenih tveganj.
@@ -131,8 +139,8 @@ reinstall_confirm_message = Ponovna namestitev z obstoječo zbirko podatkov Forg
err_admin_name_is_reserved = Administrator Uporabniško ime je neveljavno, uporabniško ime je rezervirano
disable_gravatar_popup = Onemogočite vire avatarjev Gravatar in avatarje tretjih oseb. Uporabi se privzeti avatar, razen če uporabnik lokalno naloži avatar.
install = Namestitev
-title = Začetna konfiguracija
-db_title = Nastavitve zbirke podatkov
+title = Začetna nastavitev
+db_title = Nastavitve podatkovne zbirke
db_type = Vrsta zbirke podatkov
host = Gostitelj
db_schema_helper = Pustite prazno za privzeto zbirko podatkov ("public").
@@ -230,6 +238,8 @@ enable_update_checker = Omogočite preverjanje posodobitev
enable_update_checker_helper = Redno preverja izdaje novih različic tako, da se poveže s spletnim mestom gitea.io.
env_config_keys = Konfiguracija okolja
env_config_keys_prompt = V konfiguracijski datoteki bodo uporabljene tudi naslednje okoljske spremenljivke:
+smtp_from_invalid = Naslov "Pošlji e-pošto kot" je neveljaven
+smtp_from_helper = e-poštni naslov, ki ga bo uporabljal Forgejo. Vnesite navaden e-poštni naslov ali uporabite obliko "Ime" .
[admin]
users.allow_git_hook_tooltip = Kljuke Git se izvajajo kot uporabnik operacijskega sistema, v katerem je nameščen program Forgejo, in imajo enako raven dostopa do gostitelja. Uporabniki s tem posebnim privilegijem Git Hook lahko dostopajo do vseh skladišč Forgejo in spreminjajo vse zbirke Forgejo ter podatkovno bazo, ki jo uporablja Forgejo. Posledično lahko pridobijo tudi skrbniške privilegije Forgejo.
@@ -239,6 +249,24 @@ users.purge_help = Prisilno izbrišite uporabnika in vsa skladišča, organizaci
auths.sspi_default_language_helper = Privzet jezik za uporabnike, samodejno ustvarjene z metodo avtentikacije SSPI. Pustite prazno, če želite, da se jezik zazna samodejno.
auths.restricted_filter_helper = Pustite prazno, če ne želite nastaviti nobenega uporabnika kot omejenega. Uporabite zvezdico ("*"), če želite vse uporabnike, ki se ne ujemajo z administratorskim filtrom, nastaviti kot omejene.
auths.tip.twitter = Pojdite na https://dev.twitter.com/apps, ustvarite aplikacijo in preverite, ali je omogočena možnost "Allow this application to be used to Sign in with Twitter"
+auths.tip.yandex = Ustvarite novo aplikacijo na spletnem mestu https://oauth.yandex.com/client/new. V razdelku "Yandex.Passport API" izberite naslednja dovoljenja: "Dostop do e-poštnega naslova", "Dostop do avatarja uporabnika" in "Dostop do uporabniškega imena, imena in priimka, spola"
+config.git_migrate_timeout = Časovna omejitev migracije
+config.git_gc_args = Argumenti GC
+config.git_max_diff_files = Prikazane največje razlike v datotekah
+notices.system_notice_list = Sistemska obvestila
+monitor.cron = Opravila Cron
+config.access_log_template = Predloga dnevnika dostopa
+config.access_log_mode = Način beleženja dostopa
+config.git_gc_timeout = GC Časovni rok delovanja
+config.git_pull_timeout = Potegnite Časovni rok delovanja
+config.git_clone_timeout = Časovni limit operacije kloniranja
+config.git_mirror_timeout = Časovna omejitev posodobitve zrcala
+config.git_max_diff_lines = Največ razlikovalnih vrstic na datoteko
+config.git_disable_diff_highlight = Onemogočite razlikovanje sintakse
+config.git_config = Konfiguracija Git
+config.git_max_diff_line_characters = Največ različnih znakov na vrstico
+notices.view_detail_header = Podrobnosti obvestila
+config.log_config = Konfiguracija dnevnika
[repo]
migrate.github_token_desc = Tu lahko vstavite enega ali več žetonov, ločenih z vejico, da bo selitev hitrejša zaradi omejitve hitrosti GitHub API. OPOZORILO: Zloraba te funkcije lahko krši pravila ponudnika storitev in povzroči blokado računa.
@@ -250,6 +278,10 @@ settings.githook_edit_desc = Če kavelj ni aktiven, se prikaže vzorčna vsebina
editor.file_changed_while_editing = Vsebina datoteke se je od začetka urejanja spremenila. Klikni tukaj, da si jih ogledaš, ali Sprejemi spremembe znova, da jih prepišeš.
settings.webhook.delivery.success = Dogodek je bil dodan v čakalno vrsto za dostavo. Lahko traja nekaj sekund, preden se prikaže v zgodovini dostave.
editor.filename_help = Dodajte imenik tako, da vnesete njegovo ime, ki mu sledi poševnica ("/"). Imenik odstranite tako, da na začetku vnosnega polja vtipkate backspace.
+settings.transfer_notices_3 = - Če je skladišče zasebno in je preneseno na posameznega uporabnika, to dejanje zagotovi, da ima uporabnik vsaj dovoljenje za branje (in po potrebi spremeni dovoljenja).
+settings.protect_status_check_patterns_desc = Vnesite vzorce, s katerimi določite, kateri pregledi stanja morajo biti uspešno opravljeni, preden se veje lahko združijo v vejo, ki ustreza temu pravilu. Vsaka vrstica določa vzorec. Vzorci ne smejo biti prazni.
+settings.unarchive.button = Odprava arhiviranja repozitorija
+settings.archive.header = Arhiviranje tega repozitorija
[editor]
buttons.list.ordered.tooltip = Dodajte oštevilčen seznam
@@ -340,11 +372,12 @@ webauthn = Dvofaktorsko preverjanje pristnosti (varnostni ključi)
change_username_redirect_prompt = Staro uporabniško ime bo preusmerjeno, dokler ga nekdo ne prevzame.
orgs = Upravljanje organizacij
public_profile = Javni profil
+gpg_key_verified_long = Ključ je bil preverjen z žetonom in ga je mogoče uporabiti za preverjanje zavez, ki ustrezajo vsem aktiviranim e-poštnim naslovom tega uporabnika, poleg vseh ujemajočih se identitet za ta ključ.
[heatmap]
less = Manj
number_of_contributions_in_the_last_12_months = %s prispevkov v zadnjih 12 mesecih
-no_contributions = Ni prispevkov
+contributions_zero = Ni prispevkov
more = Več
[filter]
@@ -461,7 +494,7 @@ email_domain_blacklisted = S svojim e-poštnim naslovom se ne morete registrirat
authorize_application = Odobritev vloge
authorize_application_description = Če mu dovolite dostop, bo lahko dostopal do vseh informacij o vašem računu, vključno z zasebnimi skladišči in organizacijami, in pisal vanje.
remember_me = Ne pozabite na to napravo
-login_openid = Odprta identiteta
+tab_openid = Odprta identiteta
[home]
show_both_archived_unarchived = Prikazovanje arhiviranih in nearhiviranih
@@ -536,6 +569,13 @@ release.new.text = @%[1]s izdal %[2]s v %[3]s
repo.transfer.subject_to = %s želi prenesti "%s" na %s
repo.transfer.subject_to_you = %s želi prenesti "%s" na vas
repo.collaborator.added.text = Dodani ste kot sodelavec repozitorija:
+issue.action.merge = @%[1]s je združil #%[2]d v %[3]s.
+issue.action.push_1 = @%[1]s potisnil %[3]d commit v %[2]s
+issue.action.push_n = @%[1]s potisnil %[3]d zavez v %[2]s
+issue.action.review = @%[1]s je komentiral/a to zahtevo.
+issue.action.review_dismissed = @%[1]s je zavrnil zadnji pregled %[2]s za to zahtevo.
+issue.action.ready_for_review = @%[1]s je to zahtevo označil kot pripravljeno za pregled.
+issue.in_tree_path = V %s:
[modal]
confirm = Potrdite
@@ -613,6 +653,15 @@ regex_pattern_error = ` regex vzorec je neveljaven: %s.`
url_error = `"%s" ni veljaven naslov URL.`
TreeName = Pot do datoteke
username_error_no_dots = ` lahko vsebuje samo alfanumerične znake ("0-9", "a-z", "A-Z"), pomišljaj ("-") in podčrtaj ("_"). Ne sme se začeti ali končati z nealfanumeričnimi znaki, prepovedani pa so tudi zaporedni nealfanumerični znaki.`
+AdminEmail = E-pošta upravitelja
+CommitSummary = Povzetek obveznosti
+CommitMessage = Sporočilo o zavezanosti
+CommitChoice = Izbira obveznosti
+invalid_ssh_key = Ni mogoče preveriti vašega ključa SSH: %s
+invalid_gpg_key = Ni mogoče preveriti ključa GPG: %s
+unable_verify_ssh_key = Ključa SSH ni mogoče preveriti, zato ga dvakrat preverite, ali v njem ni napak.
+last_org_owner = Zadnjega uporabnika ne morete odstraniti iz skupine lastnikov. V organizaciji mora biti vsaj en lastnik.
+cannot_add_org_to_team = Organizacije ni mogoče dodati kot člana skupine.
[user]
form.name_chars_not_allowed = Uporabniško ime "%s" vsebuje neveljavne znake.
@@ -639,4 +688,7 @@ follow_blocked_user = Temu uporabniku ne morete slediti, ker ste ga blokirali al
code = Koda
[packages]
-owner.settings.chef.keypair.description = Za preverjanje pristnosti v registru Chef je potreben par ključev. Če ste par ključev ustvarili že prej, se pri ustvarjanju novega para ključev stari par ključev zavrže.
\ No newline at end of file
+owner.settings.chef.keypair.description = Za preverjanje pristnosti v registru Chef je potreben par ključev. Če ste par ključev ustvarili že prej, se pri ustvarjanju novega para ključev stari par ključev zavrže.
+
+[actions]
+runners.runner_manage_panel = Upravljanje tekačev
diff --git a/options/locale/locale_sv-SE.ini b/options/locale/locale_sv-SE.ini
index 5c5736013c..38382a6f66 100644
--- a/options/locale/locale_sv-SE.ini
+++ b/options/locale/locale_sv-SE.ini
@@ -274,7 +274,7 @@ twofa_scratch_used=Du har använt din skrapkod. Du har blivit omdirigerad till t
twofa_passcode_incorrect=Din kod är inte giltig. Om du har tappat bort din enhet, använd din skrapkod för att logga in.
twofa_scratch_token_incorrect=Din skrapkod är ogiltlig.
login_userpass=Logga in
-login_openid=OpenID
+tab_openid=OpenID
oauth_signup_tab=Skapa nytt konto
oauth_signup_title=Slutför nytt konto
oauth_signup_submit=Slutför kontot
@@ -1088,8 +1088,8 @@ pulls.filter_branch=Filtrera gren
pulls.no_results=Inga resultat hittades.
pulls.nothing_to_compare=Dessa brancher är ekvivalenta. Det finns ingen anledning att skapa en pull-request.
pulls.create=Skapa Pullförfrågan
-pulls.title_desc=vill sammanfoga %[1]d incheckningar från s[2]s
in i %[3]s
-pulls.merged_title_desc=sammanfogade %[1]d incheckningar från %[2]s
in i %[3]s
%[4]s
+pulls.title_desc_few=vill sammanfoga %[1]d incheckningar från s[2]s
in i %[3]s
+pulls.merged_title_desc_few=sammanfogade %[1]d incheckningar från %[2]s
in i %[3]s
%[4]s
pulls.change_target_branch_at=`ändrade mål-branch från %s till %s%s`
pulls.tab_conversation=Konversation
pulls.tab_commits=Incheckningar
diff --git a/options/locale/locale_tr-TR.ini b/options/locale/locale_tr-TR.ini
index 0702262f9c..74ef77eb19 100644
--- a/options/locale/locale_tr-TR.ini
+++ b/options/locale/locale_tr-TR.ini
@@ -150,7 +150,7 @@ footer.links=Bağlantılar
[heatmap]
number_of_contributions_in_the_last_12_months=son 12 ayda %s katkı
-no_contributions=Katkı yapılmamış
+contributions_zero=Katkı yapılmamış
less=Daha az
more=Daha Fazla
@@ -395,7 +395,7 @@ twofa_scratch_used=Geçici kodunuzu kullandınız. İki aşamalı ayarlar sayfas
twofa_passcode_incorrect=Şifreniz yanlış. Aygıtınızı yanlış yerleştirdiyseniz, oturum açmak için çizgi kodunuzu kullanın.
twofa_scratch_token_incorrect=Çizgi kodunuz doğru değildir.
login_userpass=Oturum Aç
-login_openid=Açık Kimlik
+tab_openid=Açık Kimlik
oauth_signup_tab=Yeni Hesap Oluştur
oauth_signup_title=Yeni Hesabı Tamamla
oauth_signup_submit=Hesabı Tamamla
@@ -1712,8 +1712,8 @@ pulls.nothing_to_compare=Bu dallar eşit. Değişiklik isteği oluşturmaya gere
pulls.nothing_to_compare_and_allow_empty_pr=Bu dallar eşittir. Bu Dİ boş olacak.
pulls.has_pull_request=`Bu dallar arasında zaten bir değişiklik isteği var: %[2]s#%[3]d`
pulls.create=Değişiklik İsteği Oluştur
-pulls.title_desc=%[2]s
içindeki %[1]d işlemeyi %[3]s
ile birleştirmek istiyor
-pulls.merged_title_desc=%[4]s %[2]s
içindeki %[1]d işlemeyi %[3]s
ile birleştirdi
+pulls.title_desc_few=%[2]s
içindeki %[1]d işlemeyi %[3]s
ile birleştirmek istiyor
+pulls.merged_title_desc_few=%[4]s %[2]s
içindeki %[1]d işlemeyi %[3]s
ile birleştirdi
pulls.change_target_branch_at='hedef dal %s adresinden %s%s adresine değiştirildi'
pulls.tab_conversation=Sohbet
pulls.tab_commits=İşleme
diff --git a/options/locale/locale_uk-UA.ini b/options/locale/locale_uk-UA.ini
index a5a2050577..0a79e54010 100644
--- a/options/locale/locale_uk-UA.ini
+++ b/options/locale/locale_uk-UA.ini
@@ -353,7 +353,7 @@ twofa_scratch_used=Ви використовували одноразовий п
twofa_passcode_incorrect=Ваш пароль є невірним. Якщо ви втратили пристрій, використовуйте ваш одноразовий пароль.
twofa_scratch_token_incorrect=Невірний одноразовий пароль.
login_userpass=Увійти
-login_openid=OpenID
+tab_openid=OpenID
oauth_signup_tab=Зареєструвати обліковий запис
oauth_signup_title=Повний новий обліковий запис
oauth_signup_submit=Повний обліковий запис
@@ -1385,8 +1385,8 @@ pulls.nothing_to_compare=Ці гілки однакові. Немає необх
pulls.nothing_to_compare_and_allow_empty_pr=Одинакові гілки. Цей PR буде порожнім.
pulls.has_pull_request=`Запит злиття для цих гілок вже існує: %[2]s#%[3]d`
pulls.create=Створити запит на злиття
-pulls.title_desc=хоче злити %[1]d комітів з %[2]s
в %[3]s
-pulls.merged_title_desc=злито %[1]d комітів з %[2]s
до %[3]s
%[4]s
+pulls.title_desc_few=хоче злити %[1]d комітів з %[2]s
в %[3]s
+pulls.merged_title_desc_few=злито %[1]d комітів з %[2]s
до %[3]s
%[4]s
pulls.change_target_branch_at=`змінена цільова гілка з %s на %s %s`
pulls.tab_conversation=Обговорення
pulls.tab_commits=Коміти
diff --git a/options/locale/locale_zh-CN.ini b/options/locale/locale_zh-CN.ini
index 8e2dee8ec2..bc768afc6f 100644
--- a/options/locale/locale_zh-CN.ini
+++ b/options/locale/locale_zh-CN.ini
@@ -124,7 +124,7 @@ pin=固定
unpin=取消置顶
artifacts=制品
-confirm_delete_artifact=您确定要删除制品'%s'吗?
+confirm_delete_artifact=您确定要删除制品“%s”吗?
archived=已归档
@@ -142,6 +142,19 @@ confirm_delete_selected=确认删除所有选中项目?
name=名称
value=值
+filter = 筛选
+filter.clear = 清除筛选条件
+filter.is_archived = 已归档
+filter.not_archived = 未归档
+filter.is_fork = 已派生
+filter.not_fork = 未派生
+filter.is_mirror = 已镜像
+filter.not_mirror = 未镜像
+filter.is_template = 模板
+filter.not_template = 非模板
+filter.public = 公开
+filter.private = 私有
+toggle_menu = 菜单
[aria]
navbar=导航栏
@@ -151,9 +164,10 @@ footer.links=链接
[heatmap]
number_of_contributions_in_the_last_12_months=一年内 %s 次贡献
-no_contributions=目前还没有贡献。
+contributions_zero=目前还没有贡献。
less=更少的
more=更多的
+contributions_format = {contributions} 于 {month} {day}, {year}
[editor]
buttons.heading.tooltip=添加标题
@@ -182,6 +196,7 @@ missing_csrf=错误的请求:没有 CSRF 令牌
invalid_csrf=错误的请求:无效的 CSRF 令牌
not_found=找不到目标。
network_error=网络错误
+server_internal = 服务器内部错误
[startpage]
app_desc=一款极易搭建的自助 Git 服务
@@ -234,7 +249,7 @@ run_user=以用户名运行
run_user_helper=输入 Forgejo 运行的操作系统用户名。请注意,此用户必须具有对仓库根路径的访问权限。
domain=服务器域名
domain_helper=服务器的域名或主机地址。
-ssh_port=SSH 服务端口
+ssh_port=SSH 服务器端口
ssh_port_helper=SSH 服务器的端口号,为空则禁用它。
http_port=HTTP 服务端口
http_port_helper=Forgejos web 服务器将侦听的端口号。
@@ -278,8 +293,8 @@ admin_password=管理员密码
confirm_password=确认密码
admin_email=电子邮件地址
install_btn_confirm=立即安装
-test_git_failed=无法识别 'git' 命令:%v
-sqlite3_not_available=您所使用的发行版不支持 SQLite3,请从 %s 下载官方构建版,而不是 gobuild 版本。
+test_git_failed=无法识别 “git” 命令:%v
+sqlite3_not_available=当前 Forgejo 版本不支持 SQLite3。请从 %s 下载官方构建版(注:请勿下载标有 “gobuild” 的版本)。
invalid_db_setting=数据库设置无效: %v
invalid_db_table=数据库表 '%s' 无效: %v
invalid_repo_path=仓库根目录设置无效:%v
@@ -297,7 +312,7 @@ default_allow_create_organization_popup=默认情况下, 允许新用户帐户
default_enable_timetracking=默认情况下启用时间跟踪
default_enable_timetracking_popup=默认情况下启用新仓库的时间跟踪。
no_reply_address=隐藏电子邮件
-no_reply_address_helper=具有隐藏电子邮件地址的用户的域名。例如, 用户名 "joe" 将以 "joe@noreply.example.org" 的身份登录到 Git 中. 如果隐藏的电子邮件域设置为 "noreply.example.org"。
+no_reply_address_helper=用于设置隐藏电子邮件地址的用户使用的电子邮件域名。例如,如果用于隐藏电子邮件地址的域名设为“noreply.example.org”,则用户名 “joe” 在 Git 中将以 “joe@noreply.example.org” 表示。
password_algorithm=密码哈希算法
invalid_password_algorithm=无效的密码哈希算法
password_algorithm_helper=设置密码散列算法。算法有不同的要求和强度。 argon2 算法相当安全,但使用大量内存,因此可能不适合小型系统。
@@ -307,6 +322,8 @@ env_config_keys=环境配置
env_config_keys_prompt=以下环境变量也将应用于您的配置文件:
allow_dots_in_usernames = 允许用户在用户名中使用英文句号。不影响已有的帐户。
enable_update_checker_helper_forgejo = 通过检查 release.forgejo.org 上的 DNS TXT 记录,定期检查 Forgejo 的新版本。
+smtp_from_invalid = 电子邮件发件人地址无效
+config_location_hint = 这些配置项将被保存在:
[home]
uname_holder=用户名或邮箱
@@ -356,6 +373,10 @@ code_search_results=“%s” 的搜索结果是
code_last_indexed_at=最后索引于 %s
relevant_repositories_tooltip=派生的仓库,以及缺少主题、图标和描述的仓库将被隐藏。
relevant_repositories=只显示相关的仓库, 显示未过滤结果。
+stars_one = %d 点赞
+stars_few = %d 点赞
+forks_one = %d 派生
+forks_few = %d 派生
[auth]
create_new_account=注册帐号
@@ -398,7 +419,7 @@ twofa_scratch_used=你已经使用了你的验证口令。你将会转到两步
twofa_passcode_incorrect=你的验证码不正确。如果你丢失了你的设备,请使用你的验证口令。
twofa_scratch_token_incorrect=你的验证口令不正确。
login_userpass=登录
-login_openid=OpenID
+tab_openid=OpenID
oauth_signup_tab=注册帐号
oauth_signup_title=完成新帐户
oauth_signup_submit=完成账号
@@ -428,11 +449,16 @@ sspi_auth_failed=SSPI 认证失败
password_pwned=此密码出现在 被盗密码 列表上并且曾经被公开。 请使用另一个密码再试一次。
password_pwned_err=无法完成对 HaveIBeenPwned 的请求
last_admin=您不能删除最后一个管理员。必须至少保留一个管理员。
+change_unconfirmed_email = 如果您在注册时提供了错误的邮箱地址,您可以在下方修改,激活邮件会发送到修改后的邮箱地址。
+change_unconfirmed_email_summary = 修改用来接收激活邮件的邮箱地址。
+change_unconfirmed_email_error = 无法修改邮箱地址: %v
+tab_signin = 登录
+tab_signup = 注册
[mail]
view_it_on=在 %s 上查看
reply=或直接回复此邮件
-link_not_working_do_paste=不起作用?尝试复制并粘贴到您的浏览器。
+link_not_working_do_paste=链接点不了?尝试复制并粘贴到您的浏览器。
hi_user_x=%s 您好,
activate_account=请激活您的帐户
@@ -447,12 +473,12 @@ activate_email.text=请在 %s 时间内,点击以下链接,以验证
register_notify=欢迎来到 Forgejo
register_notify.title=%[1]s,欢迎来到 %[2]s
register_notify.text_1=这是您的 %s 注册确认电子邮件 !
-register_notify.text_2=您现在可以以用户名 %s 登录。
-register_notify.text_3=如果此账户已为您创建,请先 设置您的密码。
+register_notify.text_2=您现在可以以用户名 %s 登录
+register_notify.text_3=如果此账户是别人为您创建的,请先 设置您的密码。
reset_password=恢复您的账户
-reset_password.title=%s,您已请求恢复您的帐户
-reset_password.text=请在 %s 时间内,点击以下链接,恢复你的账户:
+reset_password.title=%s,我们收到了恢复您的帐户的请求
+reset_password.text=如果此请求是您本人作出的,则请在 %s 时间内,点击以下链接,恢复你的账户:
register_success=注册成功
@@ -482,12 +508,12 @@ release.downloads=下载:
release.download.zip=源代码 (ZIP)
release.download.targz=源代码 (TAR.GZ)
-repo.transfer.subject_to=%s 想要将 "%s" 转让给 %s
-repo.transfer.subject_to_you=%s 想要将 "%s" 转让给你
+repo.transfer.subject_to=%s 想要将 "%s" 仓库转让给 %s
+repo.transfer.subject_to_you=%s 想要将 "%s" 仓库转让给你
repo.transfer.to_you=你
repo.transfer.body=访问 %s 以接受或拒绝转移,亦可忽略此邮件。
-repo.collaborator.added.subject=%s 把你添加到了 %s
+repo.collaborator.added.subject=%s 已将你作为协作者添加到 %s
repo.collaborator.added.text=您已被添加为代码库的协作者:
team_invite.subject=%[1]s 邀请您加入组织 %[2]s
@@ -529,8 +555,8 @@ SSPISeparatorReplacement=分隔符
SSPIDefaultLanguage=默认语言
require_error=不能为空。
-alpha_dash_error=应该只包含字母数字、破折号 ('-') 和下划线 ('_') 字符。
-alpha_dash_dot_error=` 应该只包含字母数字, 破折号 ('-'), 下划线 ('_') 和点 ('. ') 。`
+alpha_dash_error=` 只允许包含字母数字、破折号(“-”)和下划线(“_”)字符。
+alpha_dash_dot_error=` 应该只包含半角字母、数字、破折号(“-”)、下划线(“_”)和半角句号(“.”) 。`
git_ref_name_error=` 必须是格式良好的 git 引用名称。`
size_error=长度必须为 %s。
min_size_error=长度最小为 %s 个字符。
@@ -540,7 +566,7 @@ url_error=`'%s' 不是一个有效的 URL。`
include_error=`必须包含子字符串 "%s"。`
glob_pattern_error=`匹配模式无效:%s.`
regex_pattern_error=`正则表达式无效:%s.`
-username_error=` 只能包含字母数字字符('0-9','a-z','A-Z'), 破折号 ('-'), 下划线 ('_') 和点 ('.'). 不能以非字母数字字符开头或结尾,并且不允许连续的非字母数字字符。`
+username_error=` 只允许包含字母数字字符(“0-9”、“a-z”、“A-Z”)、破折号(“-”)、下划线(“_”)和点(“.”)。不能以非字母数字字符开头或结尾,并且不允许连续的非字母数字字符。`
invalid_group_team_map_error=`映射无效: %s`
unknown_error=未知错误:
captcha_incorrect=验证码不正确。
@@ -576,7 +602,7 @@ enterred_invalid_owner_name=新的所有者名称无效。
enterred_invalid_password=输入的密码不正确
user_not_exist=该用户不存在
team_not_exist=团队不存在
-last_org_owner=您不能从 "所有者" 团队中删除最后一个用户。组织中必须至少有一个所有者。
+last_org_owner=您不能从“所有者”团队中删除最后一个用户。组织中必须至少有一个所有者。
cannot_add_org_to_team=组织不能被加入到团队中。
duplicate_invite_to_team=此用户已被邀请为团队成员。
organization_leave_success=您已成功离开组织 %s。
@@ -589,16 +615,18 @@ unable_verify_ssh_key=无法验证 SSH 密钥,请仔细检查是否有错误
auth_failed=授权验证失败:%v
still_own_repo=此帐户仍拥有至少一个仓库,您需要先删除或转移它们。
-still_has_org=此帐户隶属于一个或多个组织,请先退出这些组织。
+still_has_org=此帐户目前是一个或多个组织的成员,请先退出这些组织。
still_own_packages=您的账户拥有一个或多个软件包,请先删除它们。
-org_still_own_repo=该组织仍然是某些仓库的拥有者,请先删除或转移它们!
-org_still_own_packages=该组织仍然是一个或多个软件包的拥有者,请先删除它们。
+org_still_own_repo=该组织下仍有仓库,请先删除或转移它们。
+org_still_own_packages=该组织下仍有软件包,请先删除它们。
target_branch_not_exist=目标分支不存在。
-username_error_no_dots = ` 只能包含英文字母与数字 ('0-9','a-z','A-Z'), 连字符 ('-') 与下划线 ('_')。 开头与结尾的字符只能使用英文字母或数字,且不能包含连续的非字母非数字字符。`
+username_error_no_dots = ` 只能包含英文字母与数字(“0-9”、“a-z”、“A-Z”)、横杠(“-”) 与下划线(“_”)。 开头与结尾的字符只能使用英文字母或数字,且不能包含连续的非字母非数字字符。`
admin_cannot_delete_self = 您无法以管理员的身份删除自己。请先移除您的管理员权限。
admin_cannot_delete_self=当您是管理员时,您不能删除自己。请先移除您的管理员权限
+unsupported_login_type = 该账号使用的登录方式不支持删除此账户。
+unset_password = 当前登录用户尚未设置密码。
[user]
change_avatar=修改头像
@@ -657,12 +685,12 @@ biography_placeholder=告诉我们一点您自己! (您可以使用Markdown)
location_placeholder=与他人分享你的大概位置
profile_desc=控制您的个人资料对其他用户的显示方式。您的主要电子邮件地址将用于通知、密码恢复和基于网页界面的 Git 操作。
password_username_disabled=不允许非本地用户更改他们的用户名。更多详情请联系您的系统管理员。
-full_name=自定义名称
+full_name=全名
website=个人网站
location=所在地区
-update_theme=更新主题
-update_profile=更新信息
-update_language=更新语言
+update_theme=更换主题
+update_profile=更新个人资料
+update_language=更改语言
update_language_not_found=语言 %s 不可用。
update_language_success=语言已更新。
update_profile_success=您的资料信息已经更新
@@ -696,7 +724,7 @@ privacy=隐私设置
keep_activity_private=隐藏个人资料页面中的活动
keep_activity_private_popup=使活动仅对您和管理员可见
-lookup_avatar_by_mail=从电子邮箱地址查找头像
+lookup_avatar_by_mail=使用电子邮箱地址查找头像
federated_avatar_lookup=Federated Avatar 查找
enable_custom_avatar=启动自定义头像
choose_new_avatar=选择新的头像
@@ -737,7 +765,7 @@ theme_update_error=所选主题不存在。
openid_deletion=移除 OpenID 地址
openid_deletion_desc=删除此 OpenID 地址将会阻止你使用它进行登录。你确定要继续吗?
openid_deletion_success=OpenID地址已被移除。
-add_new_email=添加新的邮箱地址
+add_new_email=添加邮箱地址
add_new_openid=添加新的 OpenID URI
add_email=增加电子邮件地址
add_openid=添加 OpenID URI
@@ -745,7 +773,7 @@ add_email_confirmation_sent=一封确认邮件已经被发送至 %s,请检查
add_email_success=新的电子邮件地址已添加。
email_preference_set_success=电子邮件首选项已成功设置。
add_openid_success=新的 OpenID 地址已添加。
-keep_email_private=隐藏电子邮件地址
+keep_email_private=隐藏邮箱地址
keep_email_private_popup=这将会隐藏您的电子邮件地址,不仅在您的个人资料中,还在您使用Web界面创建拉取请求或编辑文件时。已推送的提交将不会被修改。
openid_desc=OpenID 让你可以将认证转发到外部服务。
@@ -753,15 +781,15 @@ manage_ssh_keys=管理 SSH 密钥
manage_ssh_principals=管理SSH证书规则
manage_gpg_keys=管理 GPG 密钥
add_key=增加密钥
-ssh_desc=这些 SSH 公钥已经关联到你的账号。相应的私钥拥有完全操作你的仓库的权限。
+ssh_desc=这些 SSH 公钥已经关联到你的账号。相应的私钥拥有完全操作你的仓库的权限,且已验证的 SSH 密钥可以用于验证 SSH 签名的 Git 提交。
principal_desc=这些SSH证书规则已关联到你的账号将允许完全访问你的所有仓库。
-gpg_desc=这些 GPG 公钥已经关联到你的账号。请妥善保管你的私钥因为他们将被用于认证提交。
+gpg_desc=这些 GPG 公钥已经关联到你的账号,并用于验证您的提交。请妥善保管你的私钥,因为这些私钥可以用于以你的身份签名提交。
ssh_helper=需要帮助? 请查看有关 如何生成 SSH 密钥 或 常见 SSH 问题 寻找答案。
gpg_helper=需要帮助吗?看一看 GitHub 关于GPG 的指导。
add_new_key=增加 SSH 密钥
add_new_gpg_key=添加的 GPG 密钥
-key_content_ssh_placeholder=以 'ssh-ed25519'、 'ssh-rsa'、 'ecdsa-sha2-nistp256'、'ecdsa-sha2-nistp384'、'ecdsa-sha2-nistp521'、 'sk-ecdsa-sha2-nistp256@openssh.com' 或 'sk-ssh-ed25519@openssh.com' 开头
-key_content_gpg_placeholder=以 '-----BEGIN PGP PUBLIC KEY BLOCK-----' 开头
+key_content_ssh_placeholder=以“ssh-ed25519”、“ssh-rsa”、“ecdsa-sha2-nistp256”、“ecdsa-sha2-nistp384”、“ecdsa-sha2-nistp521”、“sk-ecdsa-sha2-nistp256@openssh.com” 或 “sk-ssh-ed25519@openssh.com” 开头
+key_content_gpg_placeholder=以 “-----BEGIN PGP PUBLIC KEY BLOCK-----” 开头
add_new_principal=添加规则
ssh_key_been_used=此 SSH 密钥已添加到服务器。
ssh_key_name_used=使用相同名称的SSH公钥已经存在!
@@ -779,7 +807,7 @@ gpg_token=令牌
gpg_token_help=您可以使用以下方式生成签名:
gpg_token_code=echo "%s" | gpg -a --default-key %s --detach-sig
gpg_token_signature=GPG 增强签名
-key_signature_gpg_placeholder=以 '-----BEGIN PGP PUBLIC KEY BLOCK-----' 开头
+key_signature_gpg_placeholder=以 “-----BEGIN PGP SIGNATURE-----” 开头
verify_gpg_key_success=GPG 密钥 %s 已被验证。
ssh_key_verified=已验证的密钥
ssh_key_verified_long=密钥已经用令牌进行了验证,并且可以用来验证匹配此用户任何已激活电子邮件地址的提交。
@@ -789,7 +817,7 @@ ssh_token_required=您必须为下面的令牌提供签名
ssh_token=令牌
ssh_token_help=您可以使用以下方式生成签名:
ssh_token_signature=增强 SSH 签名
-key_signature_ssh_placeholder=以 '-----BEGIN SSH SIGNATURE -----' 开头
+key_signature_ssh_placeholder=以 “-----BEGIN SSH SIGNATURE -----” 开头
verify_ssh_key_success=SSH 密钥 %s 已被验证。
subkeys=子项
key_id=键ID
@@ -829,7 +857,7 @@ social_desc=这些社交账户可以用来登录您的账户。确保您认识
unbind=取消链接
unbind_success=社交账户已成功移除。
-manage_access_token=管理 Access Token
+manage_access_token=管理访问令牌
generate_new_token=生成新的令牌
tokens_desc=这些令牌拥有通过 Forgejo API 对您的帐户的访问权限。
token_name=令牌名称
@@ -837,7 +865,7 @@ generate_token=生成令牌
generate_token_success=新令牌生成成功。请拷贝因为令牌将只会显示一次。
generate_token_name_duplicate=%s 已被用作应用程序名称。请使用一个新的名称。
delete_token=删除令牌
-access_token_deletion=删除 Access Token
+access_token_deletion=删除访问令牌
access_token_deletion_cancel_action=取消
access_token_deletion_confirm_action=刪除
access_token_deletion_desc=删除令牌将撤销程序对您账户的访问权限。此操作无法撤消。是否继续?
@@ -878,7 +906,7 @@ oauth2_application_remove_description=移除一个OAuth2应用将会阻止它访
oauth2_application_locked=如果配置启用,Forgejo预注册一些OAuth2应用程序。 为了防止意外的行为, 这些应用既不能编辑也不能删除。请参阅OAuth2文档以获取更多信息。
authorized_oauth2_applications=已授权的 OAuth2 应用
-authorized_oauth2_applications_description=您已授予这些第三方应用程序访问您的个人 Forgejo 账户的权限。请撤销那些您不再需要的应用程序的访问权限。
+authorized_oauth2_applications_description=您已授予这些第三方应用程序访问您的个人 Forgejo 账户的权限。请撤销那些您不再使用的应用程序的访问权限。
revoke_key=撤销
revoke_oauth2_grant=撤回权限
revoke_oauth2_grant_description=确定撤销此三方应用程序的授权,并阻止此应用程序访问您的数据?
@@ -889,7 +917,7 @@ twofa_recovery_tip=如果您丢失了您的设备,您将能够使用一次性
twofa_is_enrolled=你的账号已启用了两步验证。
twofa_not_enrolled=你的账号未开启两步验证。
twofa_disable=禁用两步认证
-twofa_scratch_token_regenerate=重新生成初始令牌
+twofa_scratch_token_regenerate=重新生成一次性恢复令牌
twofa_scratch_token_regenerated=您的临时令牌现在是 %s。将其存放在安全的地方,它将不会再次显示。
twofa_enroll=启用两步验证
twofa_disable_note=如果需要, 可以禁用双因素身份验证。
@@ -945,10 +973,11 @@ visibility.limited_tooltip=仅对已认证的用户可见
visibility.private=私有
visibility.private_tooltip=仅对您已加入的组织的成员可见。
blocked_users = 已屏蔽的用户
-blocked_users_none = 您未屏蔽任何用户。
+blocked_users_none = 黑名单中没有用户。
blocked_since = 自 %s 起被屏蔽
user_unblock_success = 已成功取消对该用户的屏蔽。
user_block_success = 已成功屏蔽该用户。
+change_password = 更改密码
[repo]
new_repo_helper=代码仓库包含了所有的项目文件,包括版本历史记录。已经在其他地方托管了?迁移仓库。
@@ -1009,7 +1038,7 @@ default_branch_label=默认
default_branch_helper=默认分支是用于合并请求和代码提交的基础分支。
mirror_prune=修剪
mirror_prune_desc=删除过时的远程跟踪引用
-mirror_interval=镜像间隔 (有效的时间单位是 'h', 'm', 's')。0 禁用自动定期同步 (最短间隔: %s)
+mirror_interval=镜像间隔(有效的时间单位是 “h"、“m”、“s”)。填 0 禁用自动定期同步。(最短间隔:%s)
mirror_interval_invalid=镜像间隔无效。
mirror_sync=已同步
mirror_sync_on_commit=推送提交时同步
@@ -1104,12 +1133,12 @@ migrate_items_merge_requests=合并请求
migrate_items_releases=版本发布
migrate_repo=迁移仓库
migrate.clone_address=从 URL 迁移/克隆
-migrate.clone_address_desc=现有仓库的 HTTP(s) 或 Git "clone" URL
+migrate.clone_address_desc=现有仓库的 HTTP(s) 或 Git “clone” URL
migrate.github_token_desc=由于 GitHub API 速率限制,您可以在此处放置一个或多个以逗号分隔的令牌,以加快迁移速度。 警告:滥用此功能可能会违反服务提供商的政策并导致帐户被封。
migrate.clone_local_path=或服务器本地路径
migrate.permission_denied=您没有获得导入本地仓库的权限。
migrate.permission_denied_blocked=您不能从不允许的主机导入,请询问管理员以检查 ALLOWED_DOMAINS/ALLOW_LOCALNETWORKS/BLOCKED_DOMAINS 设置。
-migrate.invalid_local_path=本地路径无效。它不存在或不是一个目录。
+migrate.invalid_local_path=本地路径不存在或不是一个目录。
migrate.invalid_lfs_endpoint=LFS 网址无效。
migrate.failed=迁移失败:%v
migrate.migrate_items_options=需要访问令牌来迁移额外的内容
@@ -1129,12 +1158,12 @@ migrate.onedev.description=从 code.onedev.io 或其他 OneDev 实例迁移数
migrate.codebase.description=从 codebasehq.com 迁移数据
migrate.gitbucket.description=从 GitBucket 实例迁移数据
migrate.migrating_git=迁移Git数据
-migrate.migrating_topics=迁移主题
-migrate.migrating_milestones=迁移里程碑
-migrate.migrating_labels=迁移标签
-migrate.migrating_releases=迁移发布
-migrate.migrating_issues=迁移工单
-migrate.migrating_pulls=迁移合并请求
+migrate.migrating_topics=正在迁移主题
+migrate.migrating_milestones=正在迁移里程碑
+migrate.migrating_labels=正在迁移标签
+migrate.migrating_releases=正在迁移发布
+migrate.migrating_issues=正在迁移工单
+migrate.migrating_pulls=正在迁移合并请求
migrate.cancel_migrating_title=取消迁移
migrate.cancel_migrating_confirm=您想要取消此次迁移吗?
@@ -1206,10 +1235,10 @@ ambiguous_character=`%[1]c [U+%04[1]X] 容易和 %[2]c [U+%04[2]X] 混淆`
escape_control_characters=Escape
unescape_control_characters=Unescape
-file_copy_permalink=复制永久链接
+file_copy_permalink=复制固定链接
view_git_blame=查看 Git Blame
-video_not_supported_in_browser=您的浏览器不支持使用 HTML5 'video' 标签。
-audio_not_supported_in_browser=您的浏览器不支持使用 HTML5 'video' 标签。
+video_not_supported_in_browser=您的浏览器不支持 HTML5 “video” 标签。
+audio_not_supported_in_browser=您的浏览器不支持 HTML5 “audio” 标签。
stored_lfs=存储到Git LFS
symbolic_link=符号链接
executable_file=可执行文件
@@ -1245,12 +1274,12 @@ editor.delete_this_file=删除文件
editor.must_have_write_access=您必须具有写权限才能对此文件进行修改操作。
editor.file_delete_success=文件 %s 已被删除。
editor.name_your_file=命名文件...
-editor.filename_help=通过键入名称后跟斜线 ("/") 来添加目录。通过在输入框的开头键入 "退格" 来删除目录。
+editor.filename_help=通过键入名称后跟半角斜杠(“/”)来添加目录。在输入框的开头退格来删除目录。
editor.or=或
editor.cancel_lower=取消
editor.commit_signed_changes=提交已签名的更改
editor.commit_changes=提交变更
-editor.add_tmpl=添加 ''
+editor.add_tmpl=添加 “”
editor.add=添加 %s
editor.update=更新 %s
editor.delete=删除 %s
@@ -1361,12 +1390,12 @@ projects.column.new_title=名称
projects.column.new_submit=创建列
projects.column.new=创建列
projects.column.set_default=设为默认
-projects.column.set_default_desc=设置此列为未分类问题和合并请求的默认值
+projects.column.set_default_desc=设置此列为未分类工单和合并请求的默认值
projects.column.unset_default=取消设为默认
projects.column.unset_default_desc=取消此列为默认值
projects.column.delete=删除列
-projects.column.deletion_desc=删除项目列会将所有相关问题移到“未分类”。是否继续?
-projects.column.color=彩色
+projects.column.deletion_desc=删除项目列会将所有相关工单移到“未分类”。是否继续?
+projects.column.color=颜色
projects.open=开启
projects.close=关闭
projects.column.assigned_to=指派给
@@ -1407,14 +1436,14 @@ issues.choose.blank_about=从默认模板创建一个工单。
issues.choose.ignore_invalid_templates=已忽略无效模板
issues.choose.invalid_templates=发现了 %v 个无效模板
issues.choose.invalid_config=问题配置包含错误:
-issues.no_ref=分支/标记未指定
+issues.no_ref=未指定分支或标签
issues.create=创建工单
issues.new_label=创建标签
issues.new_label_placeholder=标签名称
issues.new_label_desc_placeholder=描述
issues.create_label=创建标签
issues.label_templates.title=加载预定义的标签模板
-issues.label_templates.info=还没有任何标签。您可以使用'创建标签'按钮或者加载预定义的标签集创建标签
+issues.label_templates.info=还没有任何标签。您可以使用“创建标签”按钮或者加载预定义的标签集创建标签:
issues.label_templates.helper=选择标签模板
issues.label_templates.use=使用标签集
issues.label_templates.fail_to_load_file=加载标签模板文件 %s 时发生错误:%v
@@ -1575,19 +1604,19 @@ issues.subscribe=订阅
issues.unsubscribe=取消订阅
issues.unpin_issue=取消置顶
issues.max_pinned=您不能置顶更多工单
-issues.pin_comment=于 %s 被置顶
-issues.unpin_comment=于 %s 取消置顶
+issues.pin_comment=于 %s 置顶本工单
+issues.unpin_comment=于 %s 取消置顶本工单
issues.lock=锁定对话
issues.unlock=解锁对话
issues.lock.unknown_reason=由于未知原因无法锁定。
issues.lock_duplicate=一个工单不能被锁定两次。
issues.unlock_error=无法解锁一个未锁定的工单。
-issues.lock_with_reason=因为 %s 而锁定,并将对话限制为协作者 %s
-issues.lock_no_reason=锁定并限制仅协作者 %s
-issues.unlock_comment=解锁此对话 %s
+issues.lock_with_reason=于 %[2]s 以 %[1]s 锁定本工单,并限制仅限协作者发言
+issues.lock_no_reason=于 %s 锁定本议题并限制仅协作者可发言
+issues.unlock_comment=于 %s 解锁此议题
issues.lock_confirm=锁定
issues.unlock_confirm=解锁
-issues.lock.notice_1=- 其他用户不能对这个工单添加新的评论。
+issues.lock.notice_1=- 其他用户不能评论此工单。
issues.lock.notice_2=- 您和仓库其他协作者仍可评论并可见。
issues.lock.notice_3=- 您可以在未来再次解锁这个工单。
issues.unlock.notice_1=- 每个人都可以再次就这一工单发表评论。
@@ -1609,7 +1638,7 @@ issues.stop_tracking=停止计时器
issues.stop_tracking_history=`停止工作 %s`
issues.cancel_tracking=放弃
issues.cancel_tracking_history=`取消时间跟踪 %s`
-issues.add_time=手动添加时间
+issues.add_time=手动记录时间
issues.del_time=删除此时间跟踪日志
issues.add_time_short=添加时间
issues.add_time_cancel=取消
@@ -1621,24 +1650,24 @@ issues.add_time_sum_to_small=没有输入时间。
issues.time_spent_total=总用时
issues.time_spent_from_all_authors=`总花费时间:%s`
issues.due_date=到期时间
-issues.invalid_due_date_format=到期时间的格式必须是 'yyyy-mm-dd' 的形式。
+issues.invalid_due_date_format=到期时间的格式必须是“yyyy-mm-dd”。
issues.error_modifying_due_date=修改到期时间失败。
issues.error_removing_due_date=删除到期时间失败。
issues.push_commit_1=于 %[2]s 推送了 %[1]d 个提交
issues.push_commits_n=于 %[2]s 推送了 %[1]d 个提交
issues.force_push_codes=`于 %[6]s 强制推送 %[1]s,从 %[2]s
,至 %[4]s
`
issues.force_push_compare=比较
-issues.due_date_form=yyyy年mm月dd日
+issues.due_date_form=yyyy-mm-dd
issues.due_date_form_add=设置到期时间
issues.due_date_form_edit=编辑
issues.due_date_form_remove=删除
issues.due_date_not_writer=您需要该仓库的写权限才能更新工单的到期日期。
issues.due_date_not_set=未设置到期时间。
issues.due_date_added=于 %[2]s 设置到期时间为 %[1]s
-issues.due_date_modified=将到期日从 %[2]s 修改为 %[1]s %[3]s
+issues.due_date_modified=于 %[3]s 将到期日从 %[2]s 修改为 %[1]s
issues.due_date_remove=于 %[2]s 删除了到期时间 %[1]s
-issues.due_date_overdue=过期
-issues.due_date_invalid=到期日期无效或超出范围。请使用 'yyyy-mm-dd' 格式。
+issues.due_date_overdue=超期
+issues.due_date_invalid=到期日期无效或超出范围。请使用“yyyy-mm-dd”格式。
issues.dependency.title=依赖工单
issues.dependency.issue_no_dependencies=没有设置依赖项。
issues.dependency.pr_no_dependencies=没有设置依赖项。
@@ -1678,11 +1707,11 @@ issues.review.dismissed=于 %[2]s 取消了 %[1]s 的评审
issues.review.dismissed_label=已取消
issues.review.left_comment=留下了一条评论
issues.review.content.empty=您需要留下一个注释,表明需要的更改。
-issues.review.reject=请求变更 %s
-issues.review.wait=已请求 %s 审核
+issues.review.reject=于 %s 请求变更
+issues.review.wait=于 %s 请求审核
issues.review.add_review_request=于 %[2]s 请求 %[1]s 评审
-issues.review.remove_review_request=取消对 %s 的评审请求 %s
-issues.review.remove_review_request_self=拒绝审核 %s
+issues.review.remove_review_request=于 %[2]s 取消对 %[1]s 的评审请求
+issues.review.remove_review_request_self=于 %s 拒绝审核
issues.review.pending=待定
issues.review.pending.tooltip=此评论目前对其他用户不可见。 若要提交您的待定评论,请在页面顶部选择 %s -> %s/%s/%s。
issues.review.review=评审
@@ -1713,7 +1742,7 @@ compare.compare_head=比较
pulls.desc=启用合并请求和代码评审。
pulls.new=创建合并请求
-pulls.view=查看拉取请求
+pulls.view=审阅合并请求
pulls.compare_changes=创建合并请求
pulls.allow_edits_from_maintainers=允许维护者编辑
pulls.allow_edits_from_maintainers_desc=对基础分支有写入权限的用户也可以推送到此分支
@@ -1742,8 +1771,8 @@ pulls.nothing_to_compare_have_tag=所选分支/标签相同。
pulls.nothing_to_compare_and_allow_empty_pr=这些分支是相等的,此合并请求将为空。
pulls.has_pull_request=这些分支之间的合并请求已存在: %[2]s#%[3]d
pulls.create=创建合并请求
-pulls.title_desc=请求将 %[1]d 次代码提交从 %[2]s
合并至 %[3]s
-pulls.merged_title_desc=于 %[4]s 将 %[1]d 次代码提交从 %[2]s
合并至 %[3]s
+pulls.title_desc_few=请求将 %[1]d 次代码提交从 %[2]s
合并至 %[3]s
+pulls.merged_title_desc_few=于 %[4]s 将 %[1]d 次代码提交从 %[2]s
合并至 %[3]s
pulls.change_target_branch_at=将目标分支从 %s 更改为 %s %s
pulls.tab_conversation=对话内容
pulls.tab_commits=代码提交
@@ -1764,29 +1793,29 @@ pulls.remove_prefix=删除 %s 前缀
pulls.data_broken=此合并请求因为派生仓库信息缺失而中断。
pulls.files_conflicted=此合并请求有变更与目标分支冲突。
pulls.is_checking=正在进行合并冲突检测,请稍后再试。
-pulls.is_ancestor=此分支已经包含在目标分支中,没有什么可以合并。
+pulls.is_ancestor=此分支已经包含在目标分支中,没有更改可以合并。
pulls.is_empty=此分支上的更改已经在目标分支上。这将是一个空提交。
pulls.required_status_check_failed=一些必要的检查没有成功
pulls.required_status_check_missing=缺少一些必要的检查。
pulls.required_status_check_administrator=作为管理员,您仍可合并此合并请求
-pulls.blocked_by_approvals=此合并请求没有通过审批。已获取审批数%d个,共需要审批数%d个。
+pulls.blocked_by_approvals=此合并请求当前还没有通过审批。已获取审批数%d个,共需要审批数%d个。
pulls.blocked_by_rejection=此合并请求有官方审核员请求的更改。
-pulls.blocked_by_official_review_requests=此合并请求已被阻止,需要一名或多名审核员审阅批准。
+pulls.blocked_by_official_review_requests=此合并请求需要一名或多名审核员审阅批准。
pulls.blocked_by_outdated_branch=此合并请求因过期而被阻止。
-pulls.blocked_by_changed_protected_files_1=此合并请求被阻止是因为修改了被保护的文件:
-pulls.blocked_by_changed_protected_files_n=此合并请求被阻止是因为修改了被保护的文件:
+pulls.blocked_by_changed_protected_files_1=此合并请求因修改了下列被保护的文件而被阻止:
+pulls.blocked_by_changed_protected_files_n=此合并请求因修改了下列被保护的文件而被阻止:
pulls.can_auto_merge_desc=该合并请求可以进行自动合并操作。
pulls.cannot_auto_merge_desc=该合并请求存在冲突,无法进行自动合并操作。
pulls.cannot_auto_merge_helper=手动合并解决此冲突
pulls.num_conflicting_files_1=%d 个冲突文件
pulls.num_conflicting_files_n=%d 个冲突文件
pulls.approve_count_1=%d 项批准
-pulls.approve_count_n=%d 批准的
+pulls.approve_count_n=%d 项批准
pulls.reject_count_1=%d 变更请求
pulls.reject_count_n=%d 变更请求
pulls.waiting_count_1=%d 个正在等待审核
pulls.waiting_count_n=%d 个正在等待审核
-pulls.wrong_commit_id=提交 id 必须在目标分支 上
+pulls.wrong_commit_id=提交 ID 必须是目标分支上的提交的 ID
pulls.no_merge_desc=由于未启用合并选项,此合并请求无法被合并。
pulls.no_merge_helper=在仓库设置中启用合并选项或者手工合并请求。
@@ -1810,9 +1839,9 @@ pulls.unrelated_histories=合并失败:两个分支没有共同历史。提示
pulls.merge_out_of_date=合并失败:在生成合并时,主分支已更新。提示:再试一次。
pulls.head_out_of_date=合并失败:在生成合并时,head 已更新。提示:再试一次。
pulls.has_merged=失败:合并请求已经被合并,您不能再次合并或更改目标分支。
-pulls.push_rejected=合并失败:推送被拒绝。审查此仓库的 Git 钩子。
+pulls.push_rejected=合并失败:推送被拒绝。请查看此仓库的 Git 钩子。
pulls.push_rejected_summary=详细拒绝信息
-pulls.push_rejected_no_message=合并失败:此推送被拒绝但未提供其他信息。
请检查此仓库的 Git Hook。
+pulls.push_rejected_no_message=推送失败:此推送被拒绝但未提供其他信息。请检查此仓库的 Git Hook
pulls.open_unmerged_pull_exists=`您不能执行重新打开操作, 因为已经存在相同的合并请求 (#%d)。`
pulls.status_checking=一些检测仍在等待运行
pulls.status_checks_success=所有检测均成功
@@ -1871,7 +1900,7 @@ milestones.title=标题
milestones.desc=描述
milestones.due_date=截止日期(可选)
milestones.clear=清除
-milestones.invalid_due_date_format=到期时间的格式必须是 'yyyy-mm-dd' 的形式。
+milestones.invalid_due_date_format=到期时间的格式必须是“yyyy-mm-dd”。
milestones.create_success=里程碑 %s 创建成功。
milestones.edit=编辑里程碑
milestones.edit_subheader=里程碑组织工单,合并请求和跟踪进度。
@@ -1929,7 +1958,7 @@ wiki.page_already_exists=相同名称的 Wiki 页面已经存在。
wiki.reserved_page=百科页面名称 %s 是被保留的。
wiki.pages=所有页面
wiki.last_updated=最后更新于 %s
-wiki.page_name_desc=输入此 Wiki 页面的名称。特殊名称有:'Home', '_Sidebar' 和 '_Footer'。
+wiki.page_name_desc=输入此 Wiki 页面的名称。特殊名称包括“Home”、“_Sidebar”和“_Footer”。
wiki.original_git_entry_tooltip=查看原始的 Git 文件而不是使用友好链接。
activity=动态
@@ -1945,14 +1974,14 @@ activity.period.yearly=1年
activity.overview=概览
activity.active_prs_count_1=%d 合并请求
activity.active_prs_count_n=%d 合并请求
-activity.merged_prs_count_1=合并请求
-activity.merged_prs_count_n=合并请求
+activity.merged_prs_count_1=已合并的合并请求
+activity.merged_prs_count_n=已合并的合并请求
activity.opened_prs_count_1=新合并请求
activity.opened_prs_count_n=新合并请求
activity.title.user_1=%d 用户
activity.title.user_n=%d 用户
-activity.title.prs_1=%d 合并请求
-activity.title.prs_n=%d 合并请求
+activity.title.prs_1=%d 个合并请求
+activity.title.prs_n=%d 个合并请求
activity.title.prs_merged_by=%[2]s 由 %[1]s 合并
activity.title.prs_opened_by=%[2]s 创建了 %[1]s
activity.merged_prs_label=已合并
@@ -2051,7 +2080,7 @@ settings.mirror_settings.push_mirror.remote_url=Git 远程仓库链接
settings.mirror_settings.push_mirror.add=添加推送镜像
settings.mirror_settings.push_mirror.edit_sync_time=编辑镜像同步间隔
-settings.sync_mirror=同步
+settings.sync_mirror=立即同步
settings.pull_mirror_sync_in_progress=正在从远程 %s 拉取更改。
settings.push_mirror_sync_in_progress=正在推送变更到远程 %s 。
settings.site=网站
@@ -2316,7 +2345,7 @@ settings.protected_branch.delete_rule=删除规则
settings.protected_branch_can_push=允许推吗?
settings.protected_branch_can_push_yes=你可以推
settings.protected_branch_can_push_no=你不能推
-settings.branch_protection=分支 '%s' 的分支保护
+settings.branch_protection=分支 “%s” 的保护规则
settings.protect_this_branch=启用分支保护
settings.protect_this_branch_desc=阻止删除并限制Git推送和合并到分支。
settings.protect_disable_push=禁用推送
@@ -2359,10 +2388,10 @@ settings.require_signed_commits_desc=拒绝推送未签名或无法验证的提
settings.protect_branch_name_pattern=受保护的分支名称模式
settings.protect_branch_name_pattern_desc=分支保护的名称匹配规则。语法请参阅 文档 。如:main, release/**
settings.protect_patterns=规则
-settings.protect_protected_file_patterns=受保护的文件模式(使用分号 ';' 分隔):
-settings.protect_protected_file_patterns_desc=即使用户有权添加、编辑或删除此分支中的文件,也不允许直接更改受保护的文件。 可以使用分号 (';') 分隔多个模式。 见github.com/gobwas/glob文档了解模式语法。例如: .drone.yml
, /docs/**/*.txt
-settings.protect_unprotected_file_patterns=不受保护的文件模式(使用分号 ';' 分隔):
-settings.protect_unprotected_file_patterns_desc=如果用户有写权限,则允许直接更改的不受保护的文件,以绕过推送限制。可以使用分号分隔多个模式 (';')。 见 github.com/gobwas/glob 文档了解模式语法。例如: .drone.yml
, /docs/**/*.txt
+settings.protect_protected_file_patterns=受保护的文件模式(使用半角分号“;”分隔):
+settings.protect_protected_file_patterns_desc=即使用户有权添加、编辑或删除此分支中的文件,也不允许直接更改受保护的文件。 可以使用半角分号(“;”)分隔多个模式。 见github.com/gobwas/glob文档了解模式语法。例如: .drone.yml
, /docs/**/*.txt
。
+settings.protect_unprotected_file_patterns=不受保护的文件模式(使用半角分号“;”分隔):
+settings.protect_unprotected_file_patterns_desc=在用户有写权限的情况下允许绕过限制,直接修改设为不保护的文件。如有多个匹配模式,则可用半角分号(“;”)分隔开。见 github.com/gobwas/glob 的文档以了解匹配模式的格式。例子: .drone.yml
、/docs/**/*.txt
。
settings.add_protected_branch=启用保护
settings.delete_protected_branch=禁用保护
settings.update_protect_branch_success=分支保护规则 %s 更新成功。
@@ -2383,7 +2412,7 @@ settings.choose_branch=选择一个分支...
settings.no_protected_branch=没有受保护的分支
settings.edit_protected_branch=编辑
settings.protected_branch_required_rule_name=必须填写规则名称
-settings.protected_branch_duplicate_rule_name=规则名称已存在
+settings.protected_branch_duplicate_rule_name=这些分支已设有规则
settings.protected_branch_required_approvals_min=所需的审批数不能为负数。
settings.tags=标签
settings.tags.protection=Git标签保护
@@ -2423,7 +2452,7 @@ settings.lfs_findcommits=查找提交
settings.lfs_lfs_file_no_commits=没有找到关于此 LFS 文件的提交
settings.lfs_noattribute=此路径在默认分支中没有可锁定的属性
settings.lfs_delete=删除 OID 为 %s 的 LFS 文件
-settings.lfs_delete_warning=删除一个 LFS 文件可能导致检出时显示'对象不存在'的错误。确定继续吗?
+settings.lfs_delete_warning=删除一个 LFS 文件可能导致检出时出现“对象不存在”的错误。确定继续吗?
settings.lfs_findpointerfiles=查找指针文件
settings.lfs_locks=锁定
settings.lfs_invalid_locking_path=无效路径:%s
@@ -2599,7 +2628,7 @@ tag.create_success=标签"%s"已存在
topic.manage_topics=管理主题
topic.done=保存
topic.count_prompt=您最多选择25个主题
-topic.format_prompt=主题必须以字母或数字开头,可以包含连字符 ('-') 和句点 ('.'),长度不得超过35个字符。字符必须为小写。
+topic.format_prompt=主题必须以字母或数字开头,可以包含半角连字符(“-”)和句点(“.”),长度不得超过35个字符。字符必须为小写。
find_file.go_to_file=转到文件
find_file.no_matching=没有找到匹配的文件
@@ -2631,25 +2660,34 @@ pulls.nothing_to_compare_have_tag = 所选分支/标签相同。
wiki.cancel = 取消
settings.wiki_globally_editable = 允许任何人编辑百科
settings.mirror_settings.pushed_repository = 已推送的仓库
-settings.new_owner_blocked_doer = 新所有者屏蔽了你。
-settings.enter_repo_name = 输入仓库名称以确认:
+settings.new_owner_blocked_doer = 新所有者已将你拉黑。
+settings.enter_repo_name = 输入所有者和仓库的名称:
settings.wiki_rename_branch_main = 标准化 Wiki 分支名称
settings.wiki_rename_branch_main_notices_1 = 此操作无法撤消。
settings.wiki_branch_rename_success = wiki 仓库的分支名称已成功规范化。
settings.confirm_wiki_branch_rename = 重命名 wiki 分支
-pulls.commit_ref_at = `提交 %[2]s 引用了此合并请求`
+pulls.commit_ref_at = `在提交 %[2]s 中引用了此合并请求`
desc.sha256 = SHA256
settings.ignore_stale_approvals = 忽略过时的批准
-settings.ignore_stale_approvals_desc = 不对旧的提交(过时的审查)计入已批准的合并请求数量。
+settings.ignore_stale_approvals_desc = 不对旧的提交(过时的审查)计入已批准的合并请求数量。注:如过期的审核已被取消,则无需设置。
settings.archive.mirrors_unavailable = 如果仓库已存档,则仓库镜像不再可用。
settings.wiki_rename_branch_main_notices_2 = 这将预先重命名 %s 的存储库 wiki 的内部分支。 现存的检出方式需要更新。
settings.wiki_branch_rename_failure = 无法标准化存储库 wiki 的分支名称。
-settings.add_collaborator_blocked_our = 无法添加协作者,因为仓库所有者已屏蔽他们。
-settings.add_collaborator_blocked_them = 无法添加协作者,因为已屏蔽仓库所有者。
+settings.add_collaborator_blocked_our = 因仓库所有者已将其拉黑,不能添加该用户为协作者。
+settings.add_collaborator_blocked_them = 因该用户已将仓库所有者拉黑,不能添加该用户为协作者。
settings.units.units = 仓库单元
pulls.fast_forward_only_merge_pull_request = 仅快速向前
settings.units.overview = 概览
settings.units.add_more = 添加更多
+file_follow = 跟随符号链接
+pulls.reopen_failed.head_branch = 因头部分支不再存在,该合并请求不能再被重新打开。
+pulls.reopen_failed.base_branch = 因基础分支不再存在,该合并请求不能再被重新打开。
+pulls.made_using_agit = AGit
+activity.navbar.pulse = 动态
+activity.navbar.code_frequency = 代码频率
+activity.navbar.recent_commits = 近期提交
+pulls.agit_explanation = 该合并请求是用 AGit 创建的。AGit 是一种可以让贡献者直接通过 “git push” 提出更改代码而不需要派生或建立新分支。
+error.broken_git_hook = 该仓库的 Git 钩子似乎已经损坏,请按照 此文档来修复这些问题,然后推送一些提交来刷新状态。
[graphs]
component_loading=正在加载 %s...
@@ -2657,6 +2695,8 @@ component_loading_failed=无法加载 %s
component_loading_info=这可能需要一点…
component_failed_to_load=意外的错误发生了。
contributors.what=贡献
+recent_commits.what = 近期提交
+code_frequency.what = 代码频率
[org]
org_name_holder=组织名称
@@ -2825,12 +2865,12 @@ dashboard.cron.error=任务中的错误: %s: %[3]s
dashboard.cron.finished=任务:%[1]s 已经完成
dashboard.delete_inactive_accounts=删除所有未激活的帐户
dashboard.delete_inactive_accounts.started=删除所有未激活的账户任务已启动。
-dashboard.delete_repo_archives=删除所有代码库的存档 (ZIP、 TAR、GZ, 等...)
+dashboard.delete_repo_archives=删除所有仓库的存档(ZIP、 TAR.GZ 等…)
dashboard.delete_repo_archives.started=删除所有仓库存档任务已启动。
dashboard.delete_missing_repos=删除所有丢失 Git 文件的仓库
dashboard.delete_missing_repos.started=删除所有丢失 Git 文件的仓库任务已启动。
dashboard.delete_generated_repository_avatars=删除生成的仓库头像
-dashboard.sync_repo_branches=将缺少的分支从 git 数据同步到数据库
+dashboard.sync_repo_branches=将缺少的分支从 Git 数据同步到数据库
dashboard.sync_repo_tags=从 git 数据同步标签到数据库
dashboard.update_mirrors=更新镜像仓库
dashboard.repo_health_check=健康检查所有仓库
@@ -2839,8 +2879,8 @@ dashboard.archive_cleanup=删除旧的仓库存档
dashboard.deleted_branches_cleanup=清理已删除的分支
dashboard.update_migration_poster_id=更新迁移的发表者ID
dashboard.git_gc_repos=对仓库进行垃圾回收
-dashboard.resync_all_sshkeys=使用 Forgejo 的 SSH 密钥更新「.ssh/authorized_keys」文件。
-dashboard.resync_all_sshprincipals=使用 Forgejo 的 SSH 规则更新「.ssh/authorized_principals」文件。
+dashboard.resync_all_sshkeys=使用 Forgejo 的 SSH 密钥更新“.ssh/authorized_keys”文件。
+dashboard.resync_all_sshprincipals=使用 Forgejo 的 SSH 规则更新“.ssh/authorized_principals”文件。
dashboard.resync_all_hooks=重新同步所有仓库的 pre-receive、update 和 post-receive 钩子
dashboard.reinit_missing_repos=重新初始化所有丢失的 Git 仓库存在的记录
dashboard.sync_external_users=同步外部用户数据
@@ -2918,7 +2958,7 @@ users.max_repo_creation_desc=(设置为 -1 表示使用全局默认值)
users.is_activated=该用户已被激活
users.prohibit_login=禁用登录
users.is_admin=是管理员
-users.is_restricted=受限
+users.is_restricted=受限制的
users.allow_git_hook=允许创建 Git 钩子
users.allow_git_hook_tooltip=Git 钩子将会被以操作系统用户运行,将会拥有同样的主机访问权限。因此,拥有此特殊的Git 钩子权限将能够访问合修改所有的 Forgejo 仓库或者Forgejo的数据库。同时也能获得Forgejo的管理员权限。
users.allow_import_local=允许导入本地仓库
@@ -2947,7 +2987,7 @@ users.list_status_filter.is_2fa_enabled=已启用 2FA
users.list_status_filter.not_2fa_enabled=未启用 2FA
users.details=用户详细信息
-emails.email_manage_panel=邮件管理
+emails.email_manage_panel=管理用户邮件地址
emails.primary=主要的
emails.activated=已激活
emails.filter_sort.email=电子邮件
@@ -3047,7 +3087,7 @@ auths.smtp_auth=SMTP 认证类型
auths.smtphost=SMTP 主机地址
auths.smtpport=SMTP 主机端口
auths.allowed_domains=域名白名单
-auths.allowed_domains_helper=置空将允许所有域名,每个域名用逗号分隔。
+auths.allowed_domains_helper=每个域名用逗号分隔,如要允许任意域名则留空。
auths.skip_tls_verify=忽略 TLS 验证
auths.force_smtps=强制 SMTPS
auths.force_smtps_helper=SMTPS 始终用于 465 端口。设置此项会强制其他端口也使用 SMTPS。(否则,如果主机支持,将在其他端口上使用 STARTTLS。)
@@ -3094,7 +3134,7 @@ auths.tips=帮助提示
auths.tips.oauth2.general=OAuth2 认证
auths.tips.oauth2.general.tip=当注册新的 OAuth2 身份验证时,回调/重定向 URL 应该是:
auths.tip.oauth2_provider=OAuth2 提供程序
-auths.tip.bitbucket=`在 https://bitbucket.org/account/user//oauth-consumers/new 注册新的 OAuth 消费者同时添加权限"帐户"-"读"`
+auths.tip.bitbucket=`在 https://bitbucket.org/account/user//oauth-consumers/new 注册新的 OAuth consumer 并添加权限“Account” 和 “Read”`
auths.tip.nextcloud=使用下面的菜单“设置(Settings) -> 安全(Security) -> OAuth 2.0 client”在您的实例上注册一个新的 OAuth 客户端。
auths.tip.dropbox=在 https://www.dropbox.com/developers/apps 上创建一个新的应用程序
auths.tip.facebook=`在 https://developers.facebook.com/apps 注册一个新的应用,并添加产品"Facebook 登录"`
@@ -3149,7 +3189,7 @@ config.ssh_port=端口
config.ssh_listen_port=监听端口
config.ssh_root_path=根目录
config.ssh_key_test_path=密钥测试路径
-config.ssh_keygen_path=密钥生成器('ssh-keygen')路径
+config.ssh_keygen_path=密钥生成器(“ssh-keygen”)路径
config.ssh_minimum_key_size_check=密钥最小长度检查
config.ssh_minimum_key_sizes=密钥最小长度限制
@@ -3328,6 +3368,7 @@ self_check.database_collation_case_insensitive=数据库正在使用一个校验
self_check.database_inconsistent_collation_columns=数据库正在使用%s的排序规则,但是这些列使用了不匹配的排序规则。这可能会造成一些意外问题。
self_check.database_fix_mysql=对于MySQL/MariaDB用户,您可以使用“gitea doctor convert”命令来解决校验问题。 或者您也可以通过 "ALTER ... COLLATE ..." 这样的SQL 来手动解决这个问题。
self_check.database_fix_mssql=对于MSSQL用户,您现在只能通过"ALTER ... COLLATE ..."SQLs手动解决这个问题。
+auths.tips.gmail_settings = Gmail 设置:
[action]
create_repo=创建了仓库 %s
@@ -3408,10 +3449,10 @@ error.extract_sign=无法提取签名
error.generate_hash=无法生成提交的哈希
error.no_committer_account=没有帐户链接到提交者的电子邮件
error.no_gpg_keys_found=找不到此签名对应的密钥
-error.not_signed_commit=未签名的提交
+error.not_signed_commit=提交未签名
error.failed_retrieval_gpg_keys=找不到任何与该提交者账号相关的密钥
-error.probable_bad_signature=警告!虽然数据库中有一个此ID的密钥,但它没有验证此提交!此提交是有疑问的。
-error.probable_bad_default_signature=警告!虽然默认密钥拥有此ID,但它没有验证此提交!此提交是有疑问的。
+error.probable_bad_signature=警告!虽然数据库中有一个此ID对应的密钥,但这个密钥不能验证此提交!该提交可疑。
+error.probable_bad_default_signature=警告!虽然默认密钥拥有此ID,但不能验证此提交!该提交可疑。
[units]
unit=单元
@@ -3572,6 +3613,7 @@ owner.settings.chef.keypair.description=需要密钥对才能向 Chef 注册中
rpm.repository = 仓库信息
rpm.repository.architectures = 架构
rpm.repository.multiple_groups = 该软件包可在多个组中使用。
+owner.settings.cargo.rebuild.no_index = 无法重建,未初始化任何索引。
[secrets]
secrets=密钥
@@ -3679,6 +3721,7 @@ variables.creation.failed=添加变量失败。
variables.creation.success=变量 “%s” 添加成功。
variables.update.failed=编辑变量失败。
variables.update.success=该变量已被编辑。
+runs.workflow = 工作流
[projects]
type-1.display_name=个人项目
diff --git a/options/locale/locale_zh-HK.ini b/options/locale/locale_zh-HK.ini
index 289a3e7b5d..5c1e234392 100644
--- a/options/locale/locale_zh-HK.ini
+++ b/options/locale/locale_zh-HK.ini
@@ -484,7 +484,7 @@ pulls.compare_changes=建立合併請求
pulls.filter_branch=過濾分支
pulls.no_results=未找到結果
pulls.create=建立合併請求
-pulls.merged_title_desc=於 %[4]s 將 %[1]d 次代碼提交從 %[2]s
合併至 %[3]s
+pulls.merged_title_desc_few=於 %[4]s 將 %[1]d 次代碼提交從 %[2]s
合併至 %[3]s
pulls.tab_conversation=對話內容
pulls.tab_commits=程式碼提交
pulls.reopen_to_merge=請重新開啟合併請求來完成合併操作。
diff --git a/options/locale/locale_zh-TW.ini b/options/locale/locale_zh-TW.ini
index e49be30691..5bfff77fd2 100644
--- a/options/locale/locale_zh-TW.ini
+++ b/options/locale/locale_zh-TW.ini
@@ -28,7 +28,7 @@ return_to_gitea=返回 Forgejo
username=帳號
email=電子信箱
password=密碼
-access_token=Access Token
+access_token=訪問令牌(Access Token)
re_type=確認密碼
captcha=驗證碼
twofa=兩步驟驗證
@@ -54,7 +54,7 @@ organization=組織
mirror=鏡像
new_repo=新增儲存庫
new_migrate=遷移外部儲存庫
-new_mirror=新鏡像
+new_mirror=建立新的鏡像
new_fork=新增儲存庫 Fork
new_org=新增組織
new_project=新增專案
@@ -125,6 +125,36 @@ concept_user_organization=組織
name=名稱
value=值
+go_back = 返回
+sign_in_with_provider = 使用 %s 登入
+tracked_time_summary = 基於 issue 清單篩選器的追蹤時間摘要
+locked = 已鎖定
+rerun = 重新執行
+rerun_all = 重新執行所有作業
+copy_hash = 複製哈希值
+toggle_menu = 切換選單
+concept_system_global = 全局
+view = 查看
+filter = 篩選
+filter.clear = 清除篩選條件
+filter.is_archived = 已歸檔
+filter.not_archived = 未歸檔
+filter.is_fork = 已派生
+filter.not_fork = 未派生
+filter.is_mirror = 已鏡像
+filter.not_mirror = 未鏡像
+filter.is_template = 模板
+filter.not_template = 非模版
+filter.public = 公開
+filter.private = 私有
+artifacts = 製品
+concept_user_individual = 個人
+show_timestamps = 顯示時間戳
+show_log_seconds = 顯示秒數
+show_full_screen = 全屏顯示
+download_logs = 下載日誌
+confirm_delete_selected = 確認刪除所有選中專案?
+confirm_delete_artifact = 您確定要刪除製品“%s”嗎?
[aria]
navbar=導航列
@@ -134,7 +164,7 @@ footer.links=連結
[heatmap]
number_of_contributions_in_the_last_12_months=過去十二個月內有 %s 個貢獻
-no_contributions=沒有貢獻
+contributions_zero=沒有貢獻
less=少
more=多
@@ -152,6 +182,7 @@ buttons.mention.tooltip=提及使用者或團隊
buttons.ref.tooltip=參考問題或合併請求
buttons.enable_monospace_font=啟用等寬字型
buttons.disable_monospace_font=停用等寬字型
+buttons.switch_to_legacy.tooltip = 使用舊版編輯器
[filter]
string.asc=A - Z
@@ -163,6 +194,8 @@ missing_csrf=錯誤的請求:未提供 CSRF token
invalid_csrf=錯誤的請求:無效的 CSRF token
not_found=找不到目標。
network_error=網路錯誤
+report_message = 如果您確定這是一個 Forgejo bug,請在 Codeberg 上搜索問題,或在必要時建立一個新工單。
+server_internal = 伺服器內部錯誤
[startpage]
app_desc=一套極易架設的 Git 服務
@@ -282,6 +315,7 @@ invalid_password_algorithm=無效的密碼雜湊演算法
password_algorithm_helper=設定密碼雜湊演算法。演算法有不同的需求與強度。argon2 演算法雖然較安全但會使用大量記憶體,可能不適用於小型系統。
enable_update_checker=啟用更新檢查器
enable_update_checker_helper=定期連線到 gitea.io 檢查更新。
+run_user_helper = 輸入 Forgejo 執行的作業系統使用者名稱。請注意,此使用者必須具有對儲存庫根路徑的訪問許可權。
[home]
uname_holder=帳號或電子信箱
@@ -367,7 +401,7 @@ twofa_scratch_used=您已經用掉了備用驗證碼。您已被重新導向到
twofa_passcode_incorrect=您的驗證碼不正確。如果您遺失設備,請使用您的備用驗證碼登入。
twofa_scratch_token_incorrect=您的備用驗證碼不正確
login_userpass=登入
-login_openid=OpenID
+tab_openid=OpenID
oauth_signup_tab=註冊新帳戶
oauth_signup_title=完成新帳戶
oauth_signup_submit=完成帳戶
@@ -1558,8 +1592,8 @@ pulls.nothing_to_compare=這些分支的內容相同,無需建立合併請求
pulls.nothing_to_compare_and_allow_empty_pr=這些分支的內容相同,此合併請求將會是空白的。
pulls.has_pull_request=`已有介於這些分支間的合併請求:%[2]s#%[3]d`
pulls.create=建立合併請求
-pulls.title_desc=請求將 %[1]d 次程式碼提交從 %[2]s
合併至 %[3]s
-pulls.merged_title_desc=將 %[1]d 次提交從 %[2]s
合併至 %[3]s
%[4]s
+pulls.title_desc_few=請求將 %[1]d 次程式碼提交從 %[2]s
合併至 %[3]s
+pulls.merged_title_desc_few=將 %[1]d 次提交從 %[2]s
合併至 %[3]s
%[4]s
pulls.change_target_branch_at=`將目標分支從 %s 更改為 %s %s`
pulls.tab_conversation=對話內容
pulls.tab_commits=程式碼提交
diff --git a/package-lock.json b/package-lock.json
index 6d1d2850c1..37f620f6ef 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -5,9 +5,9 @@
"packages": {
"": {
"dependencies": {
- "@citation-js/core": "0.7.6",
- "@citation-js/plugin-bibtex": "0.7.8",
- "@citation-js/plugin-csl": "0.7.6",
+ "@citation-js/core": "0.7.9",
+ "@citation-js/plugin-bibtex": "0.7.9",
+ "@citation-js/plugin-csl": "0.7.9",
"@citation-js/plugin-software-formats": "0.6.1",
"@claviska/jquery-minicolors": "2.3.6",
"@github/markdown-toolbar-element": "2.2.3",
@@ -15,7 +15,6 @@
"@github/text-expander-element": "2.6.1",
"@mcaptcha/vanilla-glue": "0.1.0-alpha-3",
"@primer/octicons": "19.8.0",
- "@webcomponents/custom-elements": "1.6.0",
"add-asset-webpack-plugin": "2.0.1",
"ansi_up": "6.0.2",
"asciinema-player": "3.7.0",
@@ -24,30 +23,31 @@
"chartjs-plugin-zoom": "2.0.1",
"clippie": "4.0.7",
"css-loader": "6.10.0",
- "css-variables-parser": "1.0.1",
"dayjs": "1.11.10",
"dropzone": "6.0.0-beta.2",
"easymde": "2.18.0",
- "esbuild-loader": "4.0.3",
+ "esbuild-loader": "4.1.0",
"escape-goat": "4.0.0",
"fast-glob": "3.3.2",
- "htmx.org": "1.9.10",
+ "htmx.org": "1.9.11",
"idiomorph": "0.3.0",
"jquery": "3.7.1",
"katex": "0.16.9",
"license-checker-webpack-plugin": "0.2.1",
- "mermaid": "10.8.0",
+ "mermaid": "10.9.0",
"mini-css-extract-plugin": "2.8.1",
"minimatch": "9.0.3",
- "monaco-editor": "0.46.0",
+ "monaco-editor": "0.47.0",
"monaco-editor-webpack-plugin": "7.1.0",
"pdfobject": "2.3.0",
"postcss": "8.4.35",
"postcss-loader": "8.1.1",
+ "postcss-nesting": "12.1.0",
"pretty-ms": "9.0.0",
"sortablejs": "1.15.2",
- "swagger-ui-dist": "5.11.8",
+ "swagger-ui-dist": "5.12.0",
"tailwindcss": "3.4.1",
+ "temporal-polyfill": "0.2.3",
"throttle-debounce": "5.0.0",
"tinycolor2": "1.6.0",
"tippy.js": "6.3.7",
@@ -67,7 +67,7 @@
"@eslint-community/eslint-plugin-eslint-comments": "4.1.0",
"@playwright/test": "1.42.1",
"@stoplight/spectral-cli": "6.11.0",
- "@stylistic/eslint-plugin-js": "1.6.3",
+ "@stylistic/eslint-plugin-js": "1.7.0",
"@stylistic/stylelint-plugin": "2.1.0",
"@vitejs/plugin-vue": "5.0.4",
"eslint": "8.57.0",
@@ -77,12 +77,12 @@
"eslint-plugin-jquery": "1.5.1",
"eslint-plugin-no-jquery": "2.7.0",
"eslint-plugin-no-use-extend-native": "0.5.0",
- "eslint-plugin-regexp": "2.2.0",
+ "eslint-plugin-regexp": "2.3.0",
"eslint-plugin-sonarjs": "0.24.0",
"eslint-plugin-unicorn": "51.0.1",
- "eslint-plugin-vitest": "0.3.22",
+ "eslint-plugin-vitest": "0.3.26",
"eslint-plugin-vitest-globals": "1.4.0",
- "eslint-plugin-vue": "9.22.0",
+ "eslint-plugin-vue": "9.23.0",
"eslint-plugin-vue-scoped-css": "2.7.2",
"eslint-plugin-wc": "2.0.4",
"jsdom": "24.0.0",
@@ -92,7 +92,7 @@
"stylelint-declaration-block-no-ignored-properties": "2.8.0",
"stylelint-declaration-strict-value": "1.10.4",
"svgo": "3.2.0",
- "updates": "15.1.2",
+ "updates": "15.3.1",
"vite-string-plugin": "1.1.5",
"vitest": "1.3.1"
},
@@ -323,9 +323,9 @@
"integrity": "sha512-s3jaWicZd0pkP0jf5ysyHUI/RE7MHos6qlToFcGWXVp+ykHOy77OUMrfbgJ9it2C5bow7OIQwYYaHjk9XlBQ2A=="
},
"node_modules/@citation-js/core": {
- "version": "0.7.6",
- "resolved": "https://registry.npmjs.org/@citation-js/core/-/core-0.7.6.tgz",
- "integrity": "sha512-qbB6RjwSsx/AjlCSAqoWKN05VxpjADYe8GmnPJnRB7QeNiVmqaRc8NSQDdvQ+4qhCkQOtMH15Sa2Nde4cvlXhw==",
+ "version": "0.7.9",
+ "resolved": "https://registry.npmjs.org/@citation-js/core/-/core-0.7.9.tgz",
+ "integrity": "sha512-fSbkB32JayDChZnAYC/kB+sWHRvxxL7ibVetyBOyzOc+5aCnjb6UVsbcfhnkOIEyAMoRRvWDyFmakEoTtA5ttQ==",
"dependencies": {
"@citation-js/date": "^0.5.0",
"@citation-js/name": "^0.4.2",
@@ -353,9 +353,9 @@
}
},
"node_modules/@citation-js/plugin-bibtex": {
- "version": "0.7.8",
- "resolved": "https://registry.npmjs.org/@citation-js/plugin-bibtex/-/plugin-bibtex-0.7.8.tgz",
- "integrity": "sha512-20fUXe1zm1oCONFflGj3mgIk6DHspPjWrBirGfsyHmVSR/4xqnSbrqtztLiV15zt3tbKLepTaHm3ZTrcLOK0MA==",
+ "version": "0.7.9",
+ "resolved": "https://registry.npmjs.org/@citation-js/plugin-bibtex/-/plugin-bibtex-0.7.9.tgz",
+ "integrity": "sha512-gIJpCd6vmmTOcRfDrSOjtoNhw2Mi94UwFxmgJ7GwkXyTYcNheW5VlMMo1tlqjakJGARQ0eOsKcI57gSPqJSS2g==",
"dependencies": {
"@citation-js/date": "^0.5.0",
"@citation-js/name": "^0.4.2",
@@ -381,9 +381,9 @@
}
},
"node_modules/@citation-js/plugin-csl": {
- "version": "0.7.6",
- "resolved": "https://registry.npmjs.org/@citation-js/plugin-csl/-/plugin-csl-0.7.6.tgz",
- "integrity": "sha512-H/dhzU56+D71Hzjto1x9PDtvsWaiI+Dx6Jj1vjiFtCCnbU/Zvqo5xFZNPstee+hFE6AsJ2xYlI8QujrGH+V1pQ==",
+ "version": "0.7.9",
+ "resolved": "https://registry.npmjs.org/@citation-js/plugin-csl/-/plugin-csl-0.7.9.tgz",
+ "integrity": "sha512-mbD7CnUiPOuVnjeJwo+d0RGUcY0PE8n01gHyjq0qpTeS42EGmQ9+LzqfsTUVWWBndTwc6zLRuIF1qFAUHKE4oA==",
"dependencies": {
"@citation-js/date": "^0.5.0",
"citeproc": "^2.4.6"
@@ -466,9 +466,9 @@
}
},
"node_modules/@csstools/css-parser-algorithms": {
- "version": "2.6.0",
- "resolved": "https://registry.npmjs.org/@csstools/css-parser-algorithms/-/css-parser-algorithms-2.6.0.tgz",
- "integrity": "sha512-YfEHq0eRH98ffb5/EsrrDspVWAuph6gDggAE74ZtjecsmyyWpW768hOyiONa8zwWGbIWYfa2Xp4tRTrpQQ00CQ==",
+ "version": "2.6.1",
+ "resolved": "https://registry.npmjs.org/@csstools/css-parser-algorithms/-/css-parser-algorithms-2.6.1.tgz",
+ "integrity": "sha512-ubEkAaTfVZa+WwGhs5jbo5Xfqpeaybr/RvWzvFxRs4jfq16wH8l8Ty/QEEpINxll4xhuGfdMbipRyz5QZh9+FA==",
"dev": true,
"funding": [
{
@@ -484,13 +484,13 @@
"node": "^14 || ^16 || >=18"
},
"peerDependencies": {
- "@csstools/css-tokenizer": "^2.2.3"
+ "@csstools/css-tokenizer": "^2.2.4"
}
},
"node_modules/@csstools/css-tokenizer": {
- "version": "2.2.3",
- "resolved": "https://registry.npmjs.org/@csstools/css-tokenizer/-/css-tokenizer-2.2.3.tgz",
- "integrity": "sha512-pp//EvZ9dUmGuGtG1p+n17gTHEOqu9jO+FiCUjNN3BDmyhdA2Jq9QsVeR7K8/2QCK17HSsioPlTW9ZkzoWb3Lg==",
+ "version": "2.2.4",
+ "resolved": "https://registry.npmjs.org/@csstools/css-tokenizer/-/css-tokenizer-2.2.4.tgz",
+ "integrity": "sha512-PuWRAewQLbDhGeTvFuq2oClaSCKPIBmHyIobCV39JHRYN0byDcUWJl5baPeNUcqrjtdMNqFooE0FGl31I3JOqw==",
"dev": true,
"funding": [
{
@@ -507,9 +507,9 @@
}
},
"node_modules/@csstools/media-query-list-parser": {
- "version": "2.1.8",
- "resolved": "https://registry.npmjs.org/@csstools/media-query-list-parser/-/media-query-list-parser-2.1.8.tgz",
- "integrity": "sha512-DiD3vG5ciNzeuTEoh74S+JMjQDs50R3zlxHnBnfd04YYfA/kh2KiBCGhzqLxlJcNq+7yNQ3stuZZYLX6wK/U2g==",
+ "version": "2.1.9",
+ "resolved": "https://registry.npmjs.org/@csstools/media-query-list-parser/-/media-query-list-parser-2.1.9.tgz",
+ "integrity": "sha512-qqGuFfbn4rUmyOB0u8CVISIp5FfJ5GAR3mBrZ9/TKndHakdnm6pY0L/fbLcpPnrzwCyyTEZl1nUcXAYHEWneTA==",
"dev": true,
"funding": [
{
@@ -525,15 +525,35 @@
"node": "^14 || ^16 || >=18"
},
"peerDependencies": {
- "@csstools/css-parser-algorithms": "^2.6.0",
- "@csstools/css-tokenizer": "^2.2.3"
+ "@csstools/css-parser-algorithms": "^2.6.1",
+ "@csstools/css-tokenizer": "^2.2.4"
+ }
+ },
+ "node_modules/@csstools/selector-resolve-nested": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@csstools/selector-resolve-nested/-/selector-resolve-nested-1.1.0.tgz",
+ "integrity": "sha512-uWvSaeRcHyeNenKg8tp17EVDRkpflmdyvbE0DHo6D/GdBb6PDnCYYU6gRpXhtICMGMcahQmj2zGxwFM/WC8hCg==",
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/csstools"
+ },
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/csstools"
+ }
+ ],
+ "engines": {
+ "node": "^14 || ^16 || >=18"
+ },
+ "peerDependencies": {
+ "postcss-selector-parser": "^6.0.13"
}
},
"node_modules/@csstools/selector-specificity": {
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/@csstools/selector-specificity/-/selector-specificity-3.0.2.tgz",
"integrity": "sha512-RpHaZ1h9LE7aALeQXmXrJkRG84ZxIsctEN2biEUmFyKpzFM3zZ35eUMcIzZFsw/2olQE6v69+esEqU2f1MKycg==",
- "dev": true,
"funding": [
{
"type": "github",
@@ -560,9 +580,9 @@
}
},
"node_modules/@esbuild/aix-ppc64": {
- "version": "0.19.12",
- "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.19.12.tgz",
- "integrity": "sha512-bmoCYyWdEL3wDQIVbcyzRyeKLgk2WtWLTWz1ZIAZF/EGbNOwSA6ew3PftJ1PqMiOOGu0OyFMzG53L0zqIpPeNA==",
+ "version": "0.20.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.20.2.tgz",
+ "integrity": "sha512-D+EBOJHXdNZcLJRBkhENNG8Wji2kgc9AZ9KiPr1JuZjsNtyHzrsfLRrY0tk2H2aoFu6RANO1y1iPPUCDYWkb5g==",
"cpu": [
"ppc64"
],
@@ -575,9 +595,9 @@
}
},
"node_modules/@esbuild/android-arm": {
- "version": "0.19.12",
- "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.19.12.tgz",
- "integrity": "sha512-qg/Lj1mu3CdQlDEEiWrlC4eaPZ1KztwGJ9B6J+/6G+/4ewxJg7gqj8eVYWvao1bXrqGiW2rsBZFSX3q2lcW05w==",
+ "version": "0.20.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.20.2.tgz",
+ "integrity": "sha512-t98Ra6pw2VaDhqNWO2Oph2LXbz/EJcnLmKLGBJwEwXX/JAN83Fym1rU8l0JUWK6HkIbWONCSSatf4sf2NBRx/w==",
"cpu": [
"arm"
],
@@ -590,9 +610,9 @@
}
},
"node_modules/@esbuild/android-arm64": {
- "version": "0.19.12",
- "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.19.12.tgz",
- "integrity": "sha512-P0UVNGIienjZv3f5zq0DP3Nt2IE/3plFzuaS96vihvD0Hd6H/q4WXUGpCxD/E8YrSXfNyRPbpTq+T8ZQioSuPA==",
+ "version": "0.20.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.20.2.tgz",
+ "integrity": "sha512-mRzjLacRtl/tWU0SvD8lUEwb61yP9cqQo6noDZP/O8VkwafSYwZ4yWy24kan8jE/IMERpYncRt2dw438LP3Xmg==",
"cpu": [
"arm64"
],
@@ -605,9 +625,9 @@
}
},
"node_modules/@esbuild/android-x64": {
- "version": "0.19.12",
- "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.19.12.tgz",
- "integrity": "sha512-3k7ZoUW6Q6YqhdhIaq/WZ7HwBpnFBlW905Fa4s4qWJyiNOgT1dOqDiVAQFwBH7gBRZr17gLrlFCRzF6jFh7Kew==",
+ "version": "0.20.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.20.2.tgz",
+ "integrity": "sha512-btzExgV+/lMGDDa194CcUQm53ncxzeBrWJcncOBxuC6ndBkKxnHdFJn86mCIgTELsooUmwUm9FkhSp5HYu00Rg==",
"cpu": [
"x64"
],
@@ -620,9 +640,9 @@
}
},
"node_modules/@esbuild/darwin-arm64": {
- "version": "0.19.12",
- "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.19.12.tgz",
- "integrity": "sha512-B6IeSgZgtEzGC42jsI+YYu9Z3HKRxp8ZT3cqhvliEHovq8HSX2YX8lNocDn79gCKJXOSaEot9MVYky7AKjCs8g==",
+ "version": "0.20.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.20.2.tgz",
+ "integrity": "sha512-4J6IRT+10J3aJH3l1yzEg9y3wkTDgDk7TSDFX+wKFiWjqWp/iCfLIYzGyasx9l0SAFPT1HwSCR+0w/h1ES/MjA==",
"cpu": [
"arm64"
],
@@ -635,9 +655,9 @@
}
},
"node_modules/@esbuild/darwin-x64": {
- "version": "0.19.12",
- "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.19.12.tgz",
- "integrity": "sha512-hKoVkKzFiToTgn+41qGhsUJXFlIjxI/jSYeZf3ugemDYZldIXIxhvwN6erJGlX4t5h417iFuheZ7l+YVn05N3A==",
+ "version": "0.20.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.20.2.tgz",
+ "integrity": "sha512-tBcXp9KNphnNH0dfhv8KYkZhjc+H3XBkF5DKtswJblV7KlT9EI2+jeA8DgBjp908WEuYll6pF+UStUCfEpdysA==",
"cpu": [
"x64"
],
@@ -650,9 +670,9 @@
}
},
"node_modules/@esbuild/freebsd-arm64": {
- "version": "0.19.12",
- "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.19.12.tgz",
- "integrity": "sha512-4aRvFIXmwAcDBw9AueDQ2YnGmz5L6obe5kmPT8Vd+/+x/JMVKCgdcRwH6APrbpNXsPz+K653Qg8HB/oXvXVukA==",
+ "version": "0.20.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.20.2.tgz",
+ "integrity": "sha512-d3qI41G4SuLiCGCFGUrKsSeTXyWG6yem1KcGZVS+3FYlYhtNoNgYrWcvkOoaqMhwXSMrZRl69ArHsGJ9mYdbbw==",
"cpu": [
"arm64"
],
@@ -665,9 +685,9 @@
}
},
"node_modules/@esbuild/freebsd-x64": {
- "version": "0.19.12",
- "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.19.12.tgz",
- "integrity": "sha512-EYoXZ4d8xtBoVN7CEwWY2IN4ho76xjYXqSXMNccFSx2lgqOG/1TBPW0yPx1bJZk94qu3tX0fycJeeQsKovA8gg==",
+ "version": "0.20.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.20.2.tgz",
+ "integrity": "sha512-d+DipyvHRuqEeM5zDivKV1KuXn9WeRX6vqSqIDgwIfPQtwMP4jaDsQsDncjTDDsExT4lR/91OLjRo8bmC1e+Cw==",
"cpu": [
"x64"
],
@@ -680,9 +700,9 @@
}
},
"node_modules/@esbuild/linux-arm": {
- "version": "0.19.12",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.19.12.tgz",
- "integrity": "sha512-J5jPms//KhSNv+LO1S1TX1UWp1ucM6N6XuL6ITdKWElCu8wXP72l9MM0zDTzzeikVyqFE6U8YAV9/tFyj0ti+w==",
+ "version": "0.20.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.20.2.tgz",
+ "integrity": "sha512-VhLPeR8HTMPccbuWWcEUD1Az68TqaTYyj6nfE4QByZIQEQVWBB8vup8PpR7y1QHL3CpcF6xd5WVBU/+SBEvGTg==",
"cpu": [
"arm"
],
@@ -695,9 +715,9 @@
}
},
"node_modules/@esbuild/linux-arm64": {
- "version": "0.19.12",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.19.12.tgz",
- "integrity": "sha512-EoTjyYyLuVPfdPLsGVVVC8a0p1BFFvtpQDB/YLEhaXyf/5bczaGeN15QkR+O4S5LeJ92Tqotve7i1jn35qwvdA==",
+ "version": "0.20.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.20.2.tgz",
+ "integrity": "sha512-9pb6rBjGvTFNira2FLIWqDk/uaf42sSyLE8j1rnUpuzsODBq7FvpwHYZxQ/It/8b+QOS1RYfqgGFNLRI+qlq2A==",
"cpu": [
"arm64"
],
@@ -710,9 +730,9 @@
}
},
"node_modules/@esbuild/linux-ia32": {
- "version": "0.19.12",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.19.12.tgz",
- "integrity": "sha512-Thsa42rrP1+UIGaWz47uydHSBOgTUnwBwNq59khgIwktK6x60Hivfbux9iNR0eHCHzOLjLMLfUMLCypBkZXMHA==",
+ "version": "0.20.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.20.2.tgz",
+ "integrity": "sha512-o10utieEkNPFDZFQm9CoP7Tvb33UutoJqg3qKf1PWVeeJhJw0Q347PxMvBgVVFgouYLGIhFYG0UGdBumROyiig==",
"cpu": [
"ia32"
],
@@ -725,9 +745,9 @@
}
},
"node_modules/@esbuild/linux-loong64": {
- "version": "0.19.12",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.19.12.tgz",
- "integrity": "sha512-LiXdXA0s3IqRRjm6rV6XaWATScKAXjI4R4LoDlvO7+yQqFdlr1Bax62sRwkVvRIrwXxvtYEHHI4dm50jAXkuAA==",
+ "version": "0.20.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.20.2.tgz",
+ "integrity": "sha512-PR7sp6R/UC4CFVomVINKJ80pMFlfDfMQMYynX7t1tNTeivQ6XdX5r2XovMmha/VjR1YN/HgHWsVcTRIMkymrgQ==",
"cpu": [
"loong64"
],
@@ -740,9 +760,9 @@
}
},
"node_modules/@esbuild/linux-mips64el": {
- "version": "0.19.12",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.19.12.tgz",
- "integrity": "sha512-fEnAuj5VGTanfJ07ff0gOA6IPsvrVHLVb6Lyd1g2/ed67oU1eFzL0r9WL7ZzscD+/N6i3dWumGE1Un4f7Amf+w==",
+ "version": "0.20.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.20.2.tgz",
+ "integrity": "sha512-4BlTqeutE/KnOiTG5Y6Sb/Hw6hsBOZapOVF6njAESHInhlQAghVVZL1ZpIctBOoTFbQyGW+LsVYZ8lSSB3wkjA==",
"cpu": [
"mips64el"
],
@@ -755,9 +775,9 @@
}
},
"node_modules/@esbuild/linux-ppc64": {
- "version": "0.19.12",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.19.12.tgz",
- "integrity": "sha512-nYJA2/QPimDQOh1rKWedNOe3Gfc8PabU7HT3iXWtNUbRzXS9+vgB0Fjaqr//XNbd82mCxHzik2qotuI89cfixg==",
+ "version": "0.20.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.20.2.tgz",
+ "integrity": "sha512-rD3KsaDprDcfajSKdn25ooz5J5/fWBylaaXkuotBDGnMnDP1Uv5DLAN/45qfnf3JDYyJv/ytGHQaziHUdyzaAg==",
"cpu": [
"ppc64"
],
@@ -770,9 +790,9 @@
}
},
"node_modules/@esbuild/linux-riscv64": {
- "version": "0.19.12",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.19.12.tgz",
- "integrity": "sha512-2MueBrlPQCw5dVJJpQdUYgeqIzDQgw3QtiAHUC4RBz9FXPrskyyU3VI1hw7C0BSKB9OduwSJ79FTCqtGMWqJHg==",
+ "version": "0.20.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.20.2.tgz",
+ "integrity": "sha512-snwmBKacKmwTMmhLlz/3aH1Q9T8v45bKYGE3j26TsaOVtjIag4wLfWSiZykXzXuE1kbCE+zJRmwp+ZbIHinnVg==",
"cpu": [
"riscv64"
],
@@ -785,9 +805,9 @@
}
},
"node_modules/@esbuild/linux-s390x": {
- "version": "0.19.12",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.19.12.tgz",
- "integrity": "sha512-+Pil1Nv3Umes4m3AZKqA2anfhJiVmNCYkPchwFJNEJN5QxmTs1uzyy4TvmDrCRNT2ApwSari7ZIgrPeUx4UZDg==",
+ "version": "0.20.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.20.2.tgz",
+ "integrity": "sha512-wcWISOobRWNm3cezm5HOZcYz1sKoHLd8VL1dl309DiixxVFoFe/o8HnwuIwn6sXre88Nwj+VwZUvJf4AFxkyrQ==",
"cpu": [
"s390x"
],
@@ -800,9 +820,9 @@
}
},
"node_modules/@esbuild/linux-x64": {
- "version": "0.19.12",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.19.12.tgz",
- "integrity": "sha512-B71g1QpxfwBvNrfyJdVDexenDIt1CiDN1TIXLbhOw0KhJzE78KIFGX6OJ9MrtC0oOqMWf+0xop4qEU8JrJTwCg==",
+ "version": "0.20.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.20.2.tgz",
+ "integrity": "sha512-1MdwI6OOTsfQfek8sLwgyjOXAu+wKhLEoaOLTjbijk6E2WONYpH9ZU2mNtR+lZ2B4uwr+usqGuVfFT9tMtGvGw==",
"cpu": [
"x64"
],
@@ -815,9 +835,9 @@
}
},
"node_modules/@esbuild/netbsd-x64": {
- "version": "0.19.12",
- "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.19.12.tgz",
- "integrity": "sha512-3ltjQ7n1owJgFbuC61Oj++XhtzmymoCihNFgT84UAmJnxJfm4sYCiSLTXZtE00VWYpPMYc+ZQmB6xbSdVh0JWA==",
+ "version": "0.20.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.20.2.tgz",
+ "integrity": "sha512-K8/DhBxcVQkzYc43yJXDSyjlFeHQJBiowJ0uVL6Tor3jGQfSGHNNJcWxNbOI8v5k82prYqzPuwkzHt3J1T1iZQ==",
"cpu": [
"x64"
],
@@ -830,9 +850,9 @@
}
},
"node_modules/@esbuild/openbsd-x64": {
- "version": "0.19.12",
- "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.19.12.tgz",
- "integrity": "sha512-RbrfTB9SWsr0kWmb9srfF+L933uMDdu9BIzdA7os2t0TXhCRjrQyCeOt6wVxr79CKD4c+p+YhCj31HBkYcXebw==",
+ "version": "0.20.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.20.2.tgz",
+ "integrity": "sha512-eMpKlV0SThJmmJgiVyN9jTPJ2VBPquf6Kt/nAoo6DgHAoN57K15ZghiHaMvqjCye/uU4X5u3YSMgVBI1h3vKrQ==",
"cpu": [
"x64"
],
@@ -845,9 +865,9 @@
}
},
"node_modules/@esbuild/sunos-x64": {
- "version": "0.19.12",
- "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.19.12.tgz",
- "integrity": "sha512-HKjJwRrW8uWtCQnQOz9qcU3mUZhTUQvi56Q8DPTLLB+DawoiQdjsYq+j+D3s9I8VFtDr+F9CjgXKKC4ss89IeA==",
+ "version": "0.20.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.20.2.tgz",
+ "integrity": "sha512-2UyFtRC6cXLyejf/YEld4Hajo7UHILetzE1vsRcGL3earZEW77JxrFjH4Ez2qaTiEfMgAXxfAZCm1fvM/G/o8w==",
"cpu": [
"x64"
],
@@ -860,9 +880,9 @@
}
},
"node_modules/@esbuild/win32-arm64": {
- "version": "0.19.12",
- "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.19.12.tgz",
- "integrity": "sha512-URgtR1dJnmGvX864pn1B2YUYNzjmXkuJOIqG2HdU62MVS4EHpU2946OZoTMnRUHklGtJdJZ33QfzdjGACXhn1A==",
+ "version": "0.20.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.20.2.tgz",
+ "integrity": "sha512-GRibxoawM9ZCnDxnP3usoUDO9vUkpAxIIZ6GQI+IlVmr5kP3zUq+l17xELTHMWTWzjxa2guPNyrpq1GWmPvcGQ==",
"cpu": [
"arm64"
],
@@ -875,9 +895,9 @@
}
},
"node_modules/@esbuild/win32-ia32": {
- "version": "0.19.12",
- "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.19.12.tgz",
- "integrity": "sha512-+ZOE6pUkMOJfmxmBZElNOx72NKpIa/HFOMGzu8fqzQJ5kgf6aTGrcJaFsNiVMH4JKpMipyK+7k0n2UXN7a8YKQ==",
+ "version": "0.20.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.20.2.tgz",
+ "integrity": "sha512-HfLOfn9YWmkSKRQqovpnITazdtquEW8/SoHW7pWpuEeguaZI4QnCRW6b+oZTztdBnZOS2hqJ6im/D5cPzBTTlQ==",
"cpu": [
"ia32"
],
@@ -890,9 +910,9 @@
}
},
"node_modules/@esbuild/win32-x64": {
- "version": "0.19.12",
- "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.19.12.tgz",
- "integrity": "sha512-T1QyPSDCyMXaO3pzBkF96E8xMkiRYbUEZADd29SyPGabqxMViNoii+NcK7eWJAEoU6RZyEm5lVSIjTmcdoB9HA==",
+ "version": "0.20.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.20.2.tgz",
+ "integrity": "sha512-N49X4lJX27+l9jbLKSqZ6bKNjzQvHaT8IIFUy+YIqmXQdjYCToGWwOItDrfby14c78aDd5NHQl29xingXfCdLQ==",
"cpu": [
"x64"
],
@@ -1230,12 +1250,12 @@
}
},
"node_modules/@jridgewell/source-map": {
- "version": "0.3.5",
- "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.5.tgz",
- "integrity": "sha512-UTYAUj/wviwdsMfzoSJspJxbkH5o1snzwX0//0ENX1u/55kkZZkcTZP6u9bwKGkv+dkk9at4m1Cpt0uY80kcpQ==",
+ "version": "0.3.6",
+ "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.6.tgz",
+ "integrity": "sha512-1ZJTZebgqllO79ue2bm3rIGud/bOe0pP5BjSRCRxxYkEZS8STV7zN84UBbiYu7jy+eCKSnVIUgoWWE/tt+shMQ==",
"dependencies": {
- "@jridgewell/gen-mapping": "^0.3.0",
- "@jridgewell/trace-mapping": "^0.3.9"
+ "@jridgewell/gen-mapping": "^0.3.5",
+ "@jridgewell/trace-mapping": "^0.3.25"
}
},
"node_modules/@jridgewell/sourcemap-codec": {
@@ -1460,9 +1480,9 @@
"dev": true
},
"node_modules/@rollup/rollup-android-arm-eabi": {
- "version": "4.12.0",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.12.0.tgz",
- "integrity": "sha512-+ac02NL/2TCKRrJu2wffk1kZ+RyqxVUlbjSagNgPm94frxtr+XDL12E5Ll1enWskLrtrZ2r8L3wED1orIibV/w==",
+ "version": "4.13.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.13.0.tgz",
+ "integrity": "sha512-5ZYPOuaAqEH/W3gYsRkxQATBW3Ii1MfaT4EQstTnLKViLi2gLSQmlmtTpGucNP3sXEpOiI5tdGhjdE111ekyEg==",
"cpu": [
"arm"
],
@@ -1473,9 +1493,9 @@
]
},
"node_modules/@rollup/rollup-android-arm64": {
- "version": "4.12.0",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.12.0.tgz",
- "integrity": "sha512-OBqcX2BMe6nvjQ0Nyp7cC90cnumt8PXmO7Dp3gfAju/6YwG0Tj74z1vKrfRz7qAv23nBcYM8BCbhrsWqO7PzQQ==",
+ "version": "4.13.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.13.0.tgz",
+ "integrity": "sha512-BSbaCmn8ZadK3UAQdlauSvtaJjhlDEjS5hEVVIN3A4bbl3X+otyf/kOJV08bYiRxfejP3DXFzO2jz3G20107+Q==",
"cpu": [
"arm64"
],
@@ -1486,9 +1506,9 @@
]
},
"node_modules/@rollup/rollup-darwin-arm64": {
- "version": "4.12.0",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.12.0.tgz",
- "integrity": "sha512-X64tZd8dRE/QTrBIEs63kaOBG0b5GVEd3ccoLtyf6IdXtHdh8h+I56C2yC3PtC9Ucnv0CpNFJLqKFVgCYe0lOQ==",
+ "version": "4.13.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.13.0.tgz",
+ "integrity": "sha512-Ovf2evVaP6sW5Ut0GHyUSOqA6tVKfrTHddtmxGQc1CTQa1Cw3/KMCDEEICZBbyppcwnhMwcDce9ZRxdWRpVd6g==",
"cpu": [
"arm64"
],
@@ -1499,9 +1519,9 @@
]
},
"node_modules/@rollup/rollup-darwin-x64": {
- "version": "4.12.0",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.12.0.tgz",
- "integrity": "sha512-cc71KUZoVbUJmGP2cOuiZ9HSOP14AzBAThn3OU+9LcA1+IUqswJyR1cAJj3Mg55HbjZP6OLAIscbQsQLrpgTOg==",
+ "version": "4.13.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.13.0.tgz",
+ "integrity": "sha512-U+Jcxm89UTK592vZ2J9st9ajRv/hrwHdnvyuJpa5A2ngGSVHypigidkQJP+YiGL6JODiUeMzkqQzbCG3At81Gg==",
"cpu": [
"x64"
],
@@ -1512,9 +1532,9 @@
]
},
"node_modules/@rollup/rollup-linux-arm-gnueabihf": {
- "version": "4.12.0",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.12.0.tgz",
- "integrity": "sha512-a6w/Y3hyyO6GlpKL2xJ4IOh/7d+APaqLYdMf86xnczU3nurFTaVN9s9jOXQg97BE4nYm/7Ga51rjec5nfRdrvA==",
+ "version": "4.13.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.13.0.tgz",
+ "integrity": "sha512-8wZidaUJUTIR5T4vRS22VkSMOVooG0F4N+JSwQXWSRiC6yfEsFMLTYRFHvby5mFFuExHa/yAp9juSphQQJAijQ==",
"cpu": [
"arm"
],
@@ -1525,9 +1545,9 @@
]
},
"node_modules/@rollup/rollup-linux-arm64-gnu": {
- "version": "4.12.0",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.12.0.tgz",
- "integrity": "sha512-0fZBq27b+D7Ar5CQMofVN8sggOVhEtzFUwOwPppQt0k+VR+7UHMZZY4y+64WJ06XOhBTKXtQB/Sv0NwQMXyNAA==",
+ "version": "4.13.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.13.0.tgz",
+ "integrity": "sha512-Iu0Kno1vrD7zHQDxOmvweqLkAzjxEVqNhUIXBsZ8hu8Oak7/5VTPrxOEZXYC1nmrBVJp0ZcL2E7lSuuOVaE3+w==",
"cpu": [
"arm64"
],
@@ -1538,9 +1558,9 @@
]
},
"node_modules/@rollup/rollup-linux-arm64-musl": {
- "version": "4.12.0",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.12.0.tgz",
- "integrity": "sha512-eTvzUS3hhhlgeAv6bfigekzWZjaEX9xP9HhxB0Dvrdbkk5w/b+1Sxct2ZuDxNJKzsRStSq1EaEkVSEe7A7ipgQ==",
+ "version": "4.13.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.13.0.tgz",
+ "integrity": "sha512-C31QrW47llgVyrRjIwiOwsHFcaIwmkKi3PCroQY5aVq4H0A5v/vVVAtFsI1nfBngtoRpeREvZOkIhmRwUKkAdw==",
"cpu": [
"arm64"
],
@@ -1551,9 +1571,9 @@
]
},
"node_modules/@rollup/rollup-linux-riscv64-gnu": {
- "version": "4.12.0",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.12.0.tgz",
- "integrity": "sha512-ix+qAB9qmrCRiaO71VFfY8rkiAZJL8zQRXveS27HS+pKdjwUfEhqo2+YF2oI+H/22Xsiski+qqwIBxVewLK7sw==",
+ "version": "4.13.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.13.0.tgz",
+ "integrity": "sha512-Oq90dtMHvthFOPMl7pt7KmxzX7E71AfyIhh+cPhLY9oko97Zf2C9tt/XJD4RgxhaGeAraAXDtqxvKE1y/j35lA==",
"cpu": [
"riscv64"
],
@@ -1564,9 +1584,9 @@
]
},
"node_modules/@rollup/rollup-linux-x64-gnu": {
- "version": "4.12.0",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.12.0.tgz",
- "integrity": "sha512-TenQhZVOtw/3qKOPa7d+QgkeM6xY0LtwzR8OplmyL5LrgTWIXpTQg2Q2ycBf8jm+SFW2Wt/DTn1gf7nFp3ssVA==",
+ "version": "4.13.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.13.0.tgz",
+ "integrity": "sha512-yUD/8wMffnTKuiIsl6xU+4IA8UNhQ/f1sAnQebmE/lyQ8abjsVyDkyRkWop0kdMhKMprpNIhPmYlCxgHrPoXoA==",
"cpu": [
"x64"
],
@@ -1577,9 +1597,9 @@
]
},
"node_modules/@rollup/rollup-linux-x64-musl": {
- "version": "4.12.0",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.12.0.tgz",
- "integrity": "sha512-LfFdRhNnW0zdMvdCb5FNuWlls2WbbSridJvxOvYWgSBOYZtgBfW9UGNJG//rwMqTX1xQE9BAodvMH9tAusKDUw==",
+ "version": "4.13.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.13.0.tgz",
+ "integrity": "sha512-9RyNqoFNdF0vu/qqX63fKotBh43fJQeYC98hCaf89DYQpv+xu0D8QFSOS0biA7cGuqJFOc1bJ+m2rhhsKcw1hw==",
"cpu": [
"x64"
],
@@ -1590,9 +1610,9 @@
]
},
"node_modules/@rollup/rollup-win32-arm64-msvc": {
- "version": "4.12.0",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.12.0.tgz",
- "integrity": "sha512-JPDxovheWNp6d7AHCgsUlkuCKvtu3RB55iNEkaQcf0ttsDU/JZF+iQnYcQJSk/7PtT4mjjVG8N1kpwnI9SLYaw==",
+ "version": "4.13.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.13.0.tgz",
+ "integrity": "sha512-46ue8ymtm/5PUU6pCvjlic0z82qWkxv54GTJZgHrQUuZnVH+tvvSP0LsozIDsCBFO4VjJ13N68wqrKSeScUKdA==",
"cpu": [
"arm64"
],
@@ -1603,9 +1623,9 @@
]
},
"node_modules/@rollup/rollup-win32-ia32-msvc": {
- "version": "4.12.0",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.12.0.tgz",
- "integrity": "sha512-fjtuvMWRGJn1oZacG8IPnzIV6GF2/XG+h71FKn76OYFqySXInJtseAqdprVTDTyqPxQOG9Exak5/E9Z3+EJ8ZA==",
+ "version": "4.13.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.13.0.tgz",
+ "integrity": "sha512-P5/MqLdLSlqxbeuJ3YDeX37srC8mCflSyTrUsgbU1c/U9j6l2g2GiIdYaGD9QjdMQPMSgYm7hgg0551wHyIluw==",
"cpu": [
"ia32"
],
@@ -1616,9 +1636,9 @@
]
},
"node_modules/@rollup/rollup-win32-x64-msvc": {
- "version": "4.12.0",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.12.0.tgz",
- "integrity": "sha512-ZYmr5mS2wd4Dew/JjT0Fqi2NPB/ZhZ2VvPp7SmvPZb4Y1CG/LRcS6tcRo2cYU7zLK5A7cdbhWnnWmUjoI4qapg==",
+ "version": "4.13.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.13.0.tgz",
+ "integrity": "sha512-UKXUQNbO3DOhzLRwHSpa0HnhhCgNODvfoPWv2FCXme8N/ANFfhIPMGuOT+QuKd16+B5yxZ0HdpNlqPvTMS1qfw==",
"cpu": [
"x64"
],
@@ -2086,9 +2106,9 @@
"dev": true
},
"node_modules/@stylistic/eslint-plugin-js": {
- "version": "1.6.3",
- "resolved": "https://registry.npmjs.org/@stylistic/eslint-plugin-js/-/eslint-plugin-js-1.6.3.tgz",
- "integrity": "sha512-ckdz51oHxD2FaxgY2piJWJVJiwgp8Uu96s+as2yB3RMwavn3nHBrpliVukXY9S/DmMicPRB2+H8nBk23GDG+qA==",
+ "version": "1.7.0",
+ "resolved": "https://registry.npmjs.org/@stylistic/eslint-plugin-js/-/eslint-plugin-js-1.7.0.tgz",
+ "integrity": "sha512-PN6On/+or63FGnhhMKSQfYcWutRlzOiYlVdLM6yN7lquoBTqUJHYnl4TA4MHwiAt46X5gRxDr1+xPZ1lOLcL+Q==",
"dev": true,
"dependencies": {
"@types/eslint": "^8.56.2",
@@ -2236,9 +2256,9 @@
"integrity": "sha512-nG96G3Wp6acyAgJqGasjODb+acrI7KltPiRxzHPXnP3NgI28bpQDRv53olbqGXbfcgF5aiiHmO3xpwEpS5Ld9g=="
},
"node_modules/@types/node": {
- "version": "20.11.24",
- "resolved": "https://registry.npmjs.org/@types/node/-/node-20.11.24.tgz",
- "integrity": "sha512-Kza43ewS3xoLgCEpQrsT+xRo/EJej1y0kVYGiLFE1NEODXGzTfwiC6tXTLMQskn1X4/Rjlh0MQUvx9W+L9long==",
+ "version": "20.11.27",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-20.11.27.tgz",
+ "integrity": "sha512-qyUZfMnCg1KEz57r7pzFtSGt49f6RPkPBis3Vo4PbS7roQEDn22hiHzl/Lo1q4i4hDEgBJmBF/NTNg2XR0HbFg==",
"dependencies": {
"undici-types": "~5.26.4"
}
@@ -2281,16 +2301,16 @@
"dev": true
},
"node_modules/@typescript-eslint/eslint-plugin": {
- "version": "7.1.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.1.0.tgz",
- "integrity": "sha512-j6vT/kCulhG5wBmGtstKeiVr1rdXE4nk+DT1k6trYkwlrvW9eOF5ZbgKnd/YR6PcM4uTEXa0h6Fcvf6X7Dxl0w==",
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.2.0.tgz",
+ "integrity": "sha512-mdekAHOqS9UjlmyF/LSs6AIEvfceV749GFxoBAjwAv0nkevfKHWQFDMcBZWUiIC5ft6ePWivXoS36aKQ0Cy3sw==",
"dev": true,
"dependencies": {
"@eslint-community/regexpp": "^4.5.1",
- "@typescript-eslint/scope-manager": "7.1.0",
- "@typescript-eslint/type-utils": "7.1.0",
- "@typescript-eslint/utils": "7.1.0",
- "@typescript-eslint/visitor-keys": "7.1.0",
+ "@typescript-eslint/scope-manager": "7.2.0",
+ "@typescript-eslint/type-utils": "7.2.0",
+ "@typescript-eslint/utils": "7.2.0",
+ "@typescript-eslint/visitor-keys": "7.2.0",
"debug": "^4.3.4",
"graphemer": "^1.4.0",
"ignore": "^5.2.4",
@@ -2316,15 +2336,15 @@
}
},
"node_modules/@typescript-eslint/parser": {
- "version": "7.1.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-7.1.0.tgz",
- "integrity": "sha512-V1EknKUubZ1gWFjiOZhDSNToOjs63/9O0puCgGS8aDOgpZY326fzFu15QAUjwaXzRZjf/qdsdBrckYdv9YxB8w==",
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-7.2.0.tgz",
+ "integrity": "sha512-5FKsVcHTk6TafQKQbuIVkXq58Fnbkd2wDL4LB7AURN7RUOu1utVP+G8+6u3ZhEroW3DF6hyo3ZEXxgKgp4KeCg==",
"dev": true,
"dependencies": {
- "@typescript-eslint/scope-manager": "7.1.0",
- "@typescript-eslint/types": "7.1.0",
- "@typescript-eslint/typescript-estree": "7.1.0",
- "@typescript-eslint/visitor-keys": "7.1.0",
+ "@typescript-eslint/scope-manager": "7.2.0",
+ "@typescript-eslint/types": "7.2.0",
+ "@typescript-eslint/typescript-estree": "7.2.0",
+ "@typescript-eslint/visitor-keys": "7.2.0",
"debug": "^4.3.4"
},
"engines": {
@@ -2344,13 +2364,13 @@
}
},
"node_modules/@typescript-eslint/scope-manager": {
- "version": "7.1.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.1.0.tgz",
- "integrity": "sha512-6TmN4OJiohHfoOdGZ3huuLhpiUgOGTpgXNUPJgeZOZR3DnIpdSgtt83RS35OYNNXxM4TScVlpVKC9jyQSETR1A==",
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.2.0.tgz",
+ "integrity": "sha512-Qh976RbQM/fYtjx9hs4XkayYujB/aPwglw2choHmf3zBjB4qOywWSdt9+KLRdHubGcoSwBnXUH2sR3hkyaERRg==",
"dev": true,
"dependencies": {
- "@typescript-eslint/types": "7.1.0",
- "@typescript-eslint/visitor-keys": "7.1.0"
+ "@typescript-eslint/types": "7.2.0",
+ "@typescript-eslint/visitor-keys": "7.2.0"
},
"engines": {
"node": "^16.0.0 || >=18.0.0"
@@ -2361,13 +2381,13 @@
}
},
"node_modules/@typescript-eslint/type-utils": {
- "version": "7.1.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-7.1.0.tgz",
- "integrity": "sha512-UZIhv8G+5b5skkcuhgvxYWHjk7FW7/JP5lPASMEUoliAPwIH/rxoUSQPia2cuOj9AmDZmwUl1usKm85t5VUMew==",
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-7.2.0.tgz",
+ "integrity": "sha512-xHi51adBHo9O9330J8GQYQwrKBqbIPJGZZVQTHHmy200hvkLZFWJIFtAG/7IYTWUyun6DE6w5InDReePJYJlJA==",
"dev": true,
"dependencies": {
- "@typescript-eslint/typescript-estree": "7.1.0",
- "@typescript-eslint/utils": "7.1.0",
+ "@typescript-eslint/typescript-estree": "7.2.0",
+ "@typescript-eslint/utils": "7.2.0",
"debug": "^4.3.4",
"ts-api-utils": "^1.0.1"
},
@@ -2388,9 +2408,9 @@
}
},
"node_modules/@typescript-eslint/types": {
- "version": "7.1.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.1.0.tgz",
- "integrity": "sha512-qTWjWieJ1tRJkxgZYXx6WUYtWlBc48YRxgY2JN1aGeVpkhmnopq+SUC8UEVGNXIvWH7XyuTjwALfG6bFEgCkQA==",
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.2.0.tgz",
+ "integrity": "sha512-XFtUHPI/abFhm4cbCDc5Ykc8npOKBSJePY3a3s+lwumt7XWJuzP5cZcfZ610MIPHjQjNsOLlYK8ASPaNG8UiyA==",
"dev": true,
"engines": {
"node": "^16.0.0 || >=18.0.0"
@@ -2401,13 +2421,13 @@
}
},
"node_modules/@typescript-eslint/typescript-estree": {
- "version": "7.1.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.1.0.tgz",
- "integrity": "sha512-k7MyrbD6E463CBbSpcOnwa8oXRdHzH1WiVzOipK3L5KSML92ZKgUBrTlehdi7PEIMT8k0bQixHUGXggPAlKnOQ==",
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.2.0.tgz",
+ "integrity": "sha512-cyxS5WQQCoBwSakpMrvMXuMDEbhOo9bNHHrNcEWis6XHx6KF518tkF1wBvKIn/tpq5ZpUYK7Bdklu8qY0MsFIA==",
"dev": true,
"dependencies": {
- "@typescript-eslint/types": "7.1.0",
- "@typescript-eslint/visitor-keys": "7.1.0",
+ "@typescript-eslint/types": "7.2.0",
+ "@typescript-eslint/visitor-keys": "7.2.0",
"debug": "^4.3.4",
"globby": "^11.1.0",
"is-glob": "^4.0.3",
@@ -2429,17 +2449,17 @@
}
},
"node_modules/@typescript-eslint/utils": {
- "version": "7.1.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.1.0.tgz",
- "integrity": "sha512-WUFba6PZC5OCGEmbweGpnNJytJiLG7ZvDBJJoUcX4qZYf1mGZ97mO2Mps6O2efxJcJdRNpqweCistDbZMwIVHw==",
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.2.0.tgz",
+ "integrity": "sha512-YfHpnMAGb1Eekpm3XRK8hcMwGLGsnT6L+7b2XyRv6ouDuJU1tZir1GS2i0+VXRatMwSI1/UfcyPe53ADkU+IuA==",
"dev": true,
"dependencies": {
"@eslint-community/eslint-utils": "^4.4.0",
"@types/json-schema": "^7.0.12",
"@types/semver": "^7.5.0",
- "@typescript-eslint/scope-manager": "7.1.0",
- "@typescript-eslint/types": "7.1.0",
- "@typescript-eslint/typescript-estree": "7.1.0",
+ "@typescript-eslint/scope-manager": "7.2.0",
+ "@typescript-eslint/types": "7.2.0",
+ "@typescript-eslint/typescript-estree": "7.2.0",
"semver": "^7.5.4"
},
"engines": {
@@ -2454,12 +2474,12 @@
}
},
"node_modules/@typescript-eslint/visitor-keys": {
- "version": "7.1.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.1.0.tgz",
- "integrity": "sha512-FhUqNWluiGNzlvnDZiXad4mZRhtghdoKW6e98GoEOYSu5cND+E39rG5KwJMUzeENwm1ztYBRqof8wMLP+wNPIA==",
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.2.0.tgz",
+ "integrity": "sha512-c6EIQRHhcpl6+tO8EMR+kjkkV+ugUNXOmeASA1rlzkd8EPIriavpWoiEz1HR/VLhbVIdhqnV6E7JZm00cBDx2A==",
"dev": true,
"dependencies": {
- "@typescript-eslint/types": "7.1.0",
+ "@typescript-eslint/types": "7.2.0",
"eslint-visitor-keys": "^3.4.1"
},
"engines": {
@@ -2559,9 +2579,9 @@
}
},
"node_modules/@vitest/snapshot/node_modules/magic-string": {
- "version": "0.30.7",
- "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.7.tgz",
- "integrity": "sha512-8vBuFF/I/+OSLRmdf2wwFCJCz+nSn0m6DPvGH1fS/KiQoSaR+sETbov0eIk9KhEKy8CYqIkIAnbohxT/4H0kuA==",
+ "version": "0.30.8",
+ "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.8.tgz",
+ "integrity": "sha512-ISQTe55T2ao7XtlAStud6qwYPZjE4GK1S/BeVPus4jrq6JuOnQ00YKQC581RWhR122W7msZV263KzVeLoqidyQ==",
"dev": true,
"dependencies": {
"@jridgewell/sourcemap-codec": "^1.4.15"
@@ -2650,9 +2670,9 @@
}
},
"node_modules/@vue/compiler-sfc/node_modules/magic-string": {
- "version": "0.30.7",
- "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.7.tgz",
- "integrity": "sha512-8vBuFF/I/+OSLRmdf2wwFCJCz+nSn0m6DPvGH1fS/KiQoSaR+sETbov0eIk9KhEKy8CYqIkIAnbohxT/4H0kuA==",
+ "version": "0.30.8",
+ "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.8.tgz",
+ "integrity": "sha512-ISQTe55T2ao7XtlAStud6qwYPZjE4GK1S/BeVPus4jrq6JuOnQ00YKQC581RWhR122W7msZV263KzVeLoqidyQ==",
"dependencies": {
"@jridgewell/sourcemap-codec": "^1.4.15"
},
@@ -2714,9 +2734,9 @@
"integrity": "sha512-PuJe7vDIi6VYSinuEbUIQgMIRZGgM8e4R+G+/dQTk0X1NEdvgvvgv7m+rfmDH1gZzyA1OjjoWskvHlfRNfQf3g=="
},
"node_modules/@webassemblyjs/ast": {
- "version": "1.11.6",
- "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.11.6.tgz",
- "integrity": "sha512-IN1xI7PwOvLPgjcf180gC1bqn3q/QaOCwYUahIOhbYUu8KA/3tw2RT/T0Gidi1l7Hhj5D/INhJxiICObqpMu4Q==",
+ "version": "1.12.1",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.12.1.tgz",
+ "integrity": "sha512-EKfMUOPRRUTy5UII4qJDGPpqfwjOmZ5jeGFwid9mnoqIFK+e0vqoi1qH56JpmZSzEL53jKnNzScdmftJyG5xWg==",
"dependencies": {
"@webassemblyjs/helper-numbers": "1.11.6",
"@webassemblyjs/helper-wasm-bytecode": "1.11.6"
@@ -2733,9 +2753,9 @@
"integrity": "sha512-o0YkoP4pVu4rN8aTJgAyj9hC2Sv5UlkzCHhxqWj8butaLvnpdc2jOwh4ewE6CX0txSfLn/UYaV/pheS2Txg//Q=="
},
"node_modules/@webassemblyjs/helper-buffer": {
- "version": "1.11.6",
- "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.11.6.tgz",
- "integrity": "sha512-z3nFzdcp1mb8nEOFFk8DrYLpHvhKC3grJD2ardfKOzmbmJvEf/tPIqCY+sNcwZIY8ZD7IkB2l7/pqhUhqm7hLA=="
+ "version": "1.12.1",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.12.1.tgz",
+ "integrity": "sha512-nzJwQw99DNDKr9BVCOZcLuJJUlqkJh+kVzVl6Fmq/tI5ZtEyWT1KZMyOXltXLZJmDtvLCDgwsyrkohEtopTXCw=="
},
"node_modules/@webassemblyjs/helper-numbers": {
"version": "1.11.6",
@@ -2753,14 +2773,14 @@
"integrity": "sha512-sFFHKwcmBprO9e7Icf0+gddyWYDViL8bpPjJJl0WHxCdETktXdmtWLGVzoHbqUcY4Be1LkNfwTmXOJUFZYSJdA=="
},
"node_modules/@webassemblyjs/helper-wasm-section": {
- "version": "1.11.6",
- "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.11.6.tgz",
- "integrity": "sha512-LPpZbSOwTpEC2cgn4hTydySy1Ke+XEu+ETXuoyvuyezHO3Kjdu90KK95Sh9xTbmjrCsUwvWwCOQQNta37VrS9g==",
+ "version": "1.12.1",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.12.1.tgz",
+ "integrity": "sha512-Jif4vfB6FJlUlSbgEMHUyk1j234GTNG9dBJ4XJdOySoj518Xj0oGsNi59cUQF4RRMS9ouBUxDDdyBVfPTypa5g==",
"dependencies": {
- "@webassemblyjs/ast": "1.11.6",
- "@webassemblyjs/helper-buffer": "1.11.6",
+ "@webassemblyjs/ast": "1.12.1",
+ "@webassemblyjs/helper-buffer": "1.12.1",
"@webassemblyjs/helper-wasm-bytecode": "1.11.6",
- "@webassemblyjs/wasm-gen": "1.11.6"
+ "@webassemblyjs/wasm-gen": "1.12.1"
}
},
"node_modules/@webassemblyjs/ieee754": {
@@ -2785,26 +2805,26 @@
"integrity": "sha512-vtXf2wTQ3+up9Zsg8sa2yWiQpzSsMyXj0qViVP6xKGCUT8p8YJ6HqI7l5eCnWx1T/FYdsv07HQs2wTFbbof/RA=="
},
"node_modules/@webassemblyjs/wasm-edit": {
- "version": "1.11.6",
- "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.11.6.tgz",
- "integrity": "sha512-Ybn2I6fnfIGuCR+Faaz7YcvtBKxvoLV3Lebn1tM4o/IAJzmi9AWYIPWpyBfU8cC+JxAO57bk4+zdsTjJR+VTOw==",
+ "version": "1.12.1",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.12.1.tgz",
+ "integrity": "sha512-1DuwbVvADvS5mGnXbE+c9NfA8QRcZ6iKquqjjmR10k6o+zzsRVesil54DKexiowcFCPdr/Q0qaMgB01+SQ1u6g==",
"dependencies": {
- "@webassemblyjs/ast": "1.11.6",
- "@webassemblyjs/helper-buffer": "1.11.6",
+ "@webassemblyjs/ast": "1.12.1",
+ "@webassemblyjs/helper-buffer": "1.12.1",
"@webassemblyjs/helper-wasm-bytecode": "1.11.6",
- "@webassemblyjs/helper-wasm-section": "1.11.6",
- "@webassemblyjs/wasm-gen": "1.11.6",
- "@webassemblyjs/wasm-opt": "1.11.6",
- "@webassemblyjs/wasm-parser": "1.11.6",
- "@webassemblyjs/wast-printer": "1.11.6"
+ "@webassemblyjs/helper-wasm-section": "1.12.1",
+ "@webassemblyjs/wasm-gen": "1.12.1",
+ "@webassemblyjs/wasm-opt": "1.12.1",
+ "@webassemblyjs/wasm-parser": "1.12.1",
+ "@webassemblyjs/wast-printer": "1.12.1"
}
},
"node_modules/@webassemblyjs/wasm-gen": {
- "version": "1.11.6",
- "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.11.6.tgz",
- "integrity": "sha512-3XOqkZP/y6B4F0PBAXvI1/bky7GryoogUtfwExeP/v7Nzwo1QLcq5oQmpKlftZLbT+ERUOAZVQjuNVak6UXjPA==",
+ "version": "1.12.1",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.12.1.tgz",
+ "integrity": "sha512-TDq4Ojh9fcohAw6OIMXqiIcTq5KUXTGRkVxbSo1hQnSy6lAM5GSdfwWeSxpAo0YzgsgF182E/U0mDNhuA0tW7w==",
"dependencies": {
- "@webassemblyjs/ast": "1.11.6",
+ "@webassemblyjs/ast": "1.12.1",
"@webassemblyjs/helper-wasm-bytecode": "1.11.6",
"@webassemblyjs/ieee754": "1.11.6",
"@webassemblyjs/leb128": "1.11.6",
@@ -2812,22 +2832,22 @@
}
},
"node_modules/@webassemblyjs/wasm-opt": {
- "version": "1.11.6",
- "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.11.6.tgz",
- "integrity": "sha512-cOrKuLRE7PCe6AsOVl7WasYf3wbSo4CeOk6PkrjS7g57MFfVUF9u6ysQBBODX0LdgSvQqRiGz3CXvIDKcPNy4g==",
+ "version": "1.12.1",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.12.1.tgz",
+ "integrity": "sha512-Jg99j/2gG2iaz3hijw857AVYekZe2SAskcqlWIZXjji5WStnOpVoat3gQfT/Q5tb2djnCjBtMocY/Su1GfxPBg==",
"dependencies": {
- "@webassemblyjs/ast": "1.11.6",
- "@webassemblyjs/helper-buffer": "1.11.6",
- "@webassemblyjs/wasm-gen": "1.11.6",
- "@webassemblyjs/wasm-parser": "1.11.6"
+ "@webassemblyjs/ast": "1.12.1",
+ "@webassemblyjs/helper-buffer": "1.12.1",
+ "@webassemblyjs/wasm-gen": "1.12.1",
+ "@webassemblyjs/wasm-parser": "1.12.1"
}
},
"node_modules/@webassemblyjs/wasm-parser": {
- "version": "1.11.6",
- "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.11.6.tgz",
- "integrity": "sha512-6ZwPeGzMJM3Dqp3hCsLgESxBGtT/OeCvCZ4TA1JUPYgmhAx38tTPR9JaKy0S5H3evQpO/h2uWs2j6Yc/fjkpTQ==",
+ "version": "1.12.1",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.12.1.tgz",
+ "integrity": "sha512-xikIi7c2FHXysxXe3COrVUPSheuBtpcfhbpFj4gmu7KRLYOzANztwUU0IbsqvMqzuNK2+glRGWCEqZo1WCLyAQ==",
"dependencies": {
- "@webassemblyjs/ast": "1.11.6",
+ "@webassemblyjs/ast": "1.12.1",
"@webassemblyjs/helper-api-error": "1.11.6",
"@webassemblyjs/helper-wasm-bytecode": "1.11.6",
"@webassemblyjs/ieee754": "1.11.6",
@@ -2836,19 +2856,14 @@
}
},
"node_modules/@webassemblyjs/wast-printer": {
- "version": "1.11.6",
- "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.11.6.tgz",
- "integrity": "sha512-JM7AhRcE+yW2GWYaKeHL5vt4xqee5N2WcezptmgyhNS+ScggqcT1OtXykhAb13Sn5Yas0j2uv9tHgrjwvzAP4A==",
+ "version": "1.12.1",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.12.1.tgz",
+ "integrity": "sha512-+X4WAlOisVWQMikjbcvY2e0rwPsKQ9F688lksZhBcPycBBuii3O7m8FACbDMWDojpAqvjIncrG8J0XHKyQfVeA==",
"dependencies": {
- "@webassemblyjs/ast": "1.11.6",
+ "@webassemblyjs/ast": "1.12.1",
"@xtuc/long": "4.2.2"
}
},
- "node_modules/@webcomponents/custom-elements": {
- "version": "1.6.0",
- "resolved": "https://registry.npmjs.org/@webcomponents/custom-elements/-/custom-elements-1.6.0.tgz",
- "integrity": "sha512-CqTpxOlUCPWRNUPZDxT5v2NnHXA4oox612iUGnmTUGQFhZ1Gkj8kirtl/2wcF6MqX7+PqqicZzOCBKKfIn0dww=="
- },
"node_modules/@webpack-cli/configtest": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/@webpack-cli/configtest/-/configtest-2.1.1.tgz",
@@ -3410,11 +3425,14 @@
}
},
"node_modules/binary-extensions": {
- "version": "2.2.0",
- "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz",
- "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==",
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz",
+ "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==",
"engines": {
"node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/boolbase": {
@@ -3564,9 +3582,9 @@
}
},
"node_modules/caniuse-lite": {
- "version": "1.0.30001591",
- "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001591.tgz",
- "integrity": "sha512-PCzRMei/vXjJyL5mJtzNiUCKP59dm8Apqc3PH8gJkMnMXZGox93RbE76jHsmLwmIo6/3nsYIpJtx0O7u5PqFuQ==",
+ "version": "1.0.30001597",
+ "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001597.tgz",
+ "integrity": "sha512-7LjJvmQU6Sj7bL0j5b5WY/3n7utXUJvAe1lxhsHDbLmwX9mdL86Yjtr+5SRCyf8qME4M7pU2hswj0FpyBVCv9w==",
"funding": [
{
"type": "opencollective",
@@ -4032,35 +4050,6 @@
"node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0"
}
},
- "node_modules/css-variables-parser": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/css-variables-parser/-/css-variables-parser-1.0.1.tgz",
- "integrity": "sha512-GWaqrwGtAWVr/yjjE17iyvbcy+W3voe0vko1/xLCwFeYd3kTLstzUdVH+g5TTXejrtlsb1FS4L9rP6PmeTa8wQ==",
- "dependencies": {
- "postcss": "^7.0.36"
- }
- },
- "node_modules/css-variables-parser/node_modules/picocolors": {
- "version": "0.2.1",
- "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz",
- "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA=="
- },
- "node_modules/css-variables-parser/node_modules/postcss": {
- "version": "7.0.39",
- "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz",
- "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==",
- "dependencies": {
- "picocolors": "^0.2.1",
- "source-map": "^0.6.1"
- },
- "engines": {
- "node": ">=6.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/postcss/"
- }
- },
"node_modules/css-what": {
"version": "6.1.0",
"resolved": "https://registry.npmjs.org/css-what/-/css-what-6.1.0.tgz",
@@ -4158,9 +4147,9 @@
}
},
"node_modules/d3": {
- "version": "7.8.5",
- "resolved": "https://registry.npmjs.org/d3/-/d3-7.8.5.tgz",
- "integrity": "sha512-JgoahDG51ncUfJu6wX/1vWQEqOflgXyl4MaHqlcSruTez7yhaRKR9i8VjjcQGeS2en/jnFivXuaIMnseMMt0XA==",
+ "version": "7.9.0",
+ "resolved": "https://registry.npmjs.org/d3/-/d3-7.9.0.tgz",
+ "integrity": "sha512-e1U46jVP+w7Iut8Jt8ri1YsPOvFpg46k+K8TpCb0P+zjCkjkPnV7WzfDJzMHy1LnA+wj5pLT1wjO901gLXeEhA==",
"dependencies": {
"d3-array": "3",
"d3-axis": "3",
@@ -4365,9 +4354,9 @@
}
},
"node_modules/d3-geo": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/d3-geo/-/d3-geo-3.1.0.tgz",
- "integrity": "sha512-JEo5HxXDdDYXCaWdwLRt79y7giK8SbhZJbFWXqbRTolCHFI5jRqteLzCsq51NKbUoX0PjBVSohxrx+NoOUujYA==",
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/d3-geo/-/d3-geo-3.1.1.tgz",
+ "integrity": "sha512-637ln3gXKXOwhalDzinUgY83KzNWZRKbYubaG+fGVuc/dxO64RRljtCTnf5ecMyE1RIdtqpkVcq0IbtU2S8j2Q==",
"dependencies": {
"d3-array": "2.5.0 - 3"
},
@@ -4477,9 +4466,9 @@
}
},
"node_modules/d3-scale-chromatic": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/d3-scale-chromatic/-/d3-scale-chromatic-3.0.0.tgz",
- "integrity": "sha512-Lx9thtxAKrO2Pq6OO2Ua474opeziKr279P/TKZsMAhYyNDD3EnCffdbgeSYN5O7m2ByQsxtuP2CSDczNUIZ22g==",
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/d3-scale-chromatic/-/d3-scale-chromatic-3.1.0.tgz",
+ "integrity": "sha512-A3s5PWiZ9YCXFye1o246KoscMWqf8BsD9eRiJ3He7C9OBaxKhAd5TFCdEx/7VbKtxxTsu//1mMJFrEt572cEyQ==",
"dependencies": {
"d3-color": "1 - 3",
"d3-interpolate": "1 - 3"
@@ -4885,9 +4874,9 @@
}
},
"node_modules/electron-to-chromium": {
- "version": "1.4.690",
- "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.690.tgz",
- "integrity": "sha512-+2OAGjUx68xElQhydpcbqH50hE8Vs2K6TkAeLhICYfndb67CVH0UsZaijmRUE3rHlIxU1u0jxwhgVe6fK3YANA=="
+ "version": "1.4.706",
+ "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.706.tgz",
+ "integrity": "sha512-fO01fufoGd6jKK3HR8ofBapF3ZPfgxNJ/ua9xQAhFu93TwWIs4d+weDn3kje3GB4S7aGUTfk5nvdU5F7z5mF9Q=="
},
"node_modules/elkjs": {
"version": "0.9.2",
@@ -4908,9 +4897,9 @@
}
},
"node_modules/enhanced-resolve": {
- "version": "5.15.1",
- "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.15.1.tgz",
- "integrity": "sha512-3d3JRbwsCLJsYgvb6NuWEG44jjPSOMuS73L/6+7BZuoKm3W+qXnSoIYVHi8dG7Qcg4inAY4jbzkZ7MnskePeDg==",
+ "version": "5.16.0",
+ "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.16.0.tgz",
+ "integrity": "sha512-O+QWCviPNSSLAD9Ucn8Awv+poAkqn3T1XY5/N7kR7rQO9yfSGWkYZDwpJ+iKF7B8rxaQKWngSqACpgzeapSyoA==",
"dependencies": {
"graceful-fs": "^4.2.4",
"tapable": "^2.2.0"
@@ -5133,9 +5122,9 @@
}
},
"node_modules/esbuild": {
- "version": "0.19.12",
- "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.19.12.tgz",
- "integrity": "sha512-aARqgq8roFBj054KvQr5f1sFu0D65G+miZRCuJyJ0G13Zwx7vRar5Zhn2tkQNzIXcBrNVsv/8stehpj+GAjgbg==",
+ "version": "0.20.2",
+ "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.20.2.tgz",
+ "integrity": "sha512-WdOOppmUNU+IbZ0PaDiTst80zjnrOkyJNHoKupIcVyU8Lvla3Ugx94VzkQ32Ijqd7UhHJy75gNWDMUekcrSJ6g==",
"hasInstallScript": true,
"bin": {
"esbuild": "bin/esbuild"
@@ -5144,37 +5133,37 @@
"node": ">=12"
},
"optionalDependencies": {
- "@esbuild/aix-ppc64": "0.19.12",
- "@esbuild/android-arm": "0.19.12",
- "@esbuild/android-arm64": "0.19.12",
- "@esbuild/android-x64": "0.19.12",
- "@esbuild/darwin-arm64": "0.19.12",
- "@esbuild/darwin-x64": "0.19.12",
- "@esbuild/freebsd-arm64": "0.19.12",
- "@esbuild/freebsd-x64": "0.19.12",
- "@esbuild/linux-arm": "0.19.12",
- "@esbuild/linux-arm64": "0.19.12",
- "@esbuild/linux-ia32": "0.19.12",
- "@esbuild/linux-loong64": "0.19.12",
- "@esbuild/linux-mips64el": "0.19.12",
- "@esbuild/linux-ppc64": "0.19.12",
- "@esbuild/linux-riscv64": "0.19.12",
- "@esbuild/linux-s390x": "0.19.12",
- "@esbuild/linux-x64": "0.19.12",
- "@esbuild/netbsd-x64": "0.19.12",
- "@esbuild/openbsd-x64": "0.19.12",
- "@esbuild/sunos-x64": "0.19.12",
- "@esbuild/win32-arm64": "0.19.12",
- "@esbuild/win32-ia32": "0.19.12",
- "@esbuild/win32-x64": "0.19.12"
+ "@esbuild/aix-ppc64": "0.20.2",
+ "@esbuild/android-arm": "0.20.2",
+ "@esbuild/android-arm64": "0.20.2",
+ "@esbuild/android-x64": "0.20.2",
+ "@esbuild/darwin-arm64": "0.20.2",
+ "@esbuild/darwin-x64": "0.20.2",
+ "@esbuild/freebsd-arm64": "0.20.2",
+ "@esbuild/freebsd-x64": "0.20.2",
+ "@esbuild/linux-arm": "0.20.2",
+ "@esbuild/linux-arm64": "0.20.2",
+ "@esbuild/linux-ia32": "0.20.2",
+ "@esbuild/linux-loong64": "0.20.2",
+ "@esbuild/linux-mips64el": "0.20.2",
+ "@esbuild/linux-ppc64": "0.20.2",
+ "@esbuild/linux-riscv64": "0.20.2",
+ "@esbuild/linux-s390x": "0.20.2",
+ "@esbuild/linux-x64": "0.20.2",
+ "@esbuild/netbsd-x64": "0.20.2",
+ "@esbuild/openbsd-x64": "0.20.2",
+ "@esbuild/sunos-x64": "0.20.2",
+ "@esbuild/win32-arm64": "0.20.2",
+ "@esbuild/win32-ia32": "0.20.2",
+ "@esbuild/win32-x64": "0.20.2"
}
},
"node_modules/esbuild-loader": {
- "version": "4.0.3",
- "resolved": "https://registry.npmjs.org/esbuild-loader/-/esbuild-loader-4.0.3.tgz",
- "integrity": "sha512-YpaSRisj7TSg6maKKKG9OJGGm0BZ7EXeov8J8cXEYdugjlAJ0wL7aj2JactoQvPJ113v2Ar204pdJWrZsAQc8Q==",
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/esbuild-loader/-/esbuild-loader-4.1.0.tgz",
+ "integrity": "sha512-543TtIvqbqouEMlOHg4xKoDQkmdImlwIpyAIgpUtDPvMuklU/c2k+Qt2O3VeDBgAwozxmlEbjOzV+F8CZ0g+Bw==",
"dependencies": {
- "esbuild": "^0.19.0",
+ "esbuild": "^0.20.0",
"get-tsconfig": "^4.7.0",
"loader-utils": "^2.0.4",
"webpack-sources": "^1.4.3"
@@ -5707,9 +5696,9 @@
}
},
"node_modules/eslint-plugin-regexp": {
- "version": "2.2.0",
- "resolved": "https://registry.npmjs.org/eslint-plugin-regexp/-/eslint-plugin-regexp-2.2.0.tgz",
- "integrity": "sha512-0kwpiWiLRVBkVr3oIRQLl196sXP/NF6DQFefv9jtR4ZOgQR+6WID2pIZ0I+wIt54qgBPwBB7Gm2a+ueh8/WsFQ==",
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/eslint-plugin-regexp/-/eslint-plugin-regexp-2.3.0.tgz",
+ "integrity": "sha512-T8JUs7ssRGbuXb+CGfdUJbcxTBMCNOpNqNBLuC8JUKAEIez72J37RaOi5/4dAUsGz92GbWVtqTLPSJZGyP/sQA==",
"dev": true,
"dependencies": {
"@eslint-community/eslint-utils": "^4.2.0",
@@ -5773,12 +5762,12 @@
}
},
"node_modules/eslint-plugin-vitest": {
- "version": "0.3.22",
- "resolved": "https://registry.npmjs.org/eslint-plugin-vitest/-/eslint-plugin-vitest-0.3.22.tgz",
- "integrity": "sha512-atkFGQ7aVgcuSeSMDqnyevIyUpfBPMnosksgEPrKE7Y8xQlqG/5z2IQ6UDau05zXaaFv7Iz8uzqvIuKshjZ0Zw==",
+ "version": "0.3.26",
+ "resolved": "https://registry.npmjs.org/eslint-plugin-vitest/-/eslint-plugin-vitest-0.3.26.tgz",
+ "integrity": "sha512-oxe5JSPgRjco8caVLTh7Ti8PxpwJdhSV0hTQAmkFcNcmy/9DnqLB/oNVRA11RmVRP//2+jIIT6JuBEcpW3obYg==",
"dev": true,
"dependencies": {
- "@typescript-eslint/utils": "^6.21.0"
+ "@typescript-eslint/utils": "^7.1.1"
},
"engines": {
"node": "^18.0.0 || >= 20.0.0"
@@ -5802,110 +5791,10 @@
"integrity": "sha512-WE+YlK9X9s4vf5EaYRU0Scw7WItDZStm+PapFSYlg2ABNtaQ4zIG7wEqpoUB3SlfM+SgkhgmzR0TeJOO5k3/Nw==",
"dev": true
},
- "node_modules/eslint-plugin-vitest/node_modules/@typescript-eslint/scope-manager": {
- "version": "6.21.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.21.0.tgz",
- "integrity": "sha512-OwLUIWZJry80O99zvqXVEioyniJMa+d2GrqpUTqi5/v5D5rOrppJVBPa0yKCblcigC0/aYAzxxqQ1B+DS2RYsg==",
- "dev": true,
- "dependencies": {
- "@typescript-eslint/types": "6.21.0",
- "@typescript-eslint/visitor-keys": "6.21.0"
- },
- "engines": {
- "node": "^16.0.0 || >=18.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/typescript-eslint"
- }
- },
- "node_modules/eslint-plugin-vitest/node_modules/@typescript-eslint/types": {
- "version": "6.21.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.21.0.tgz",
- "integrity": "sha512-1kFmZ1rOm5epu9NZEZm1kckCDGj5UJEf7P1kliH4LKu/RkwpsfqqGmY2OOcUs18lSlQBKLDYBOGxRVtrMN5lpg==",
- "dev": true,
- "engines": {
- "node": "^16.0.0 || >=18.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/typescript-eslint"
- }
- },
- "node_modules/eslint-plugin-vitest/node_modules/@typescript-eslint/typescript-estree": {
- "version": "6.21.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.21.0.tgz",
- "integrity": "sha512-6npJTkZcO+y2/kr+z0hc4HwNfrrP4kNYh57ek7yCNlrBjWQ1Y0OS7jiZTkgumrvkX5HkEKXFZkkdFNkaW2wmUQ==",
- "dev": true,
- "dependencies": {
- "@typescript-eslint/types": "6.21.0",
- "@typescript-eslint/visitor-keys": "6.21.0",
- "debug": "^4.3.4",
- "globby": "^11.1.0",
- "is-glob": "^4.0.3",
- "minimatch": "9.0.3",
- "semver": "^7.5.4",
- "ts-api-utils": "^1.0.1"
- },
- "engines": {
- "node": "^16.0.0 || >=18.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/typescript-eslint"
- },
- "peerDependenciesMeta": {
- "typescript": {
- "optional": true
- }
- }
- },
- "node_modules/eslint-plugin-vitest/node_modules/@typescript-eslint/utils": {
- "version": "6.21.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.21.0.tgz",
- "integrity": "sha512-NfWVaC8HP9T8cbKQxHcsJBY5YE1O33+jpMwN45qzWWaPDZgLIbo12toGMWnmhvCpd3sIxkpDw3Wv1B3dYrbDQQ==",
- "dev": true,
- "dependencies": {
- "@eslint-community/eslint-utils": "^4.4.0",
- "@types/json-schema": "^7.0.12",
- "@types/semver": "^7.5.0",
- "@typescript-eslint/scope-manager": "6.21.0",
- "@typescript-eslint/types": "6.21.0",
- "@typescript-eslint/typescript-estree": "6.21.0",
- "semver": "^7.5.4"
- },
- "engines": {
- "node": "^16.0.0 || >=18.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/typescript-eslint"
- },
- "peerDependencies": {
- "eslint": "^7.0.0 || ^8.0.0"
- }
- },
- "node_modules/eslint-plugin-vitest/node_modules/@typescript-eslint/visitor-keys": {
- "version": "6.21.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.21.0.tgz",
- "integrity": "sha512-JJtkDduxLi9bivAB+cYOVMtbkqdPOhZ+ZI5LC47MIRrDV4Yn2o+ZnW10Nkmr28xRpSpdJ6Sm42Hjf2+REYXm0A==",
- "dev": true,
- "dependencies": {
- "@typescript-eslint/types": "6.21.0",
- "eslint-visitor-keys": "^3.4.1"
- },
- "engines": {
- "node": "^16.0.0 || >=18.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/typescript-eslint"
- }
- },
"node_modules/eslint-plugin-vue": {
- "version": "9.22.0",
- "resolved": "https://registry.npmjs.org/eslint-plugin-vue/-/eslint-plugin-vue-9.22.0.tgz",
- "integrity": "sha512-7wCXv5zuVnBtZE/74z4yZ0CM8AjH6bk4MQGm7hZjUC2DBppKU5ioeOk5LGSg/s9a1ZJnIsdPLJpXnu1Rc+cVHg==",
+ "version": "9.23.0",
+ "resolved": "https://registry.npmjs.org/eslint-plugin-vue/-/eslint-plugin-vue-9.23.0.tgz",
+ "integrity": "sha512-Bqd/b7hGYGrlV+wP/g77tjyFmp81lh5TMw0be9093X02SyelxRRfCI6/IsGq/J7Um0YwB9s0Ry0wlFyjPdmtUw==",
"dev": true,
"dependencies": {
"@eslint-community/eslint-utils": "^4.4.0",
@@ -6542,9 +6431,9 @@
}
},
"node_modules/get-tsconfig": {
- "version": "4.7.2",
- "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.7.2.tgz",
- "integrity": "sha512-wuMsz4leaj5hbGgg4IvDU0bqJagpftG5l5cXIAvo8uZrqn0NJqwtfupTN00VnkQJPcIRrxYrm1Ue24btpCha2A==",
+ "version": "4.7.3",
+ "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.7.3.tgz",
+ "integrity": "sha512-ZvkrzoUA0PQZM6fy6+/Hce561s+faD1rsNwhnO5FelNjyy7EMGJ3Rz1AQ8GYDWjhRs/7dBLOEJvhK8MiEJOAFg==",
"dependencies": {
"resolve-pkg-maps": "^1.0.0"
},
@@ -6817,9 +6706,9 @@
"integrity": "sha512-WdZTbAByD+pHfl/g9QSsBIIwy8IT+EsPiKDs0KNX+zSHhdDLFKdZu0BQHljvO+0QI/BasbMSUa8wYNCZTvhslg=="
},
"node_modules/hasown": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.1.tgz",
- "integrity": "sha512-1/th4MHjnwncwXsIW6QMzlvYL9kG5e/CpVvLRZe4XPa8TOUNbCELqmvhDmnkNsAjwaG4+I8gJJL0JBvTTLO9qA==",
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz",
+ "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==",
"dependencies": {
"function-bind": "^1.1.2"
},
@@ -6891,9 +6780,9 @@
}
},
"node_modules/htmx.org": {
- "version": "1.9.10",
- "resolved": "https://registry.npmjs.org/htmx.org/-/htmx.org-1.9.10.tgz",
- "integrity": "sha512-UgchasltTCrTuU2DQLom3ohHrBvwr7OqpwyAVJ9VxtNBng4XKkVsqrv0Qr3srqvM9ZNI3f1MmvVQQqK7KW/bTA=="
+ "version": "1.9.11",
+ "resolved": "https://registry.npmjs.org/htmx.org/-/htmx.org-1.9.11.tgz",
+ "integrity": "sha512-WlVuICn8dfNOOgYmdYzYG8zSnP3++AdHkMHooQAzGZObWpVXYathpz/I37ycF4zikR6YduzfCvEcxk20JkIUsw=="
},
"node_modules/http-proxy-agent": {
"version": "7.0.2",
@@ -7061,9 +6950,9 @@
"integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
},
"node_modules/ini": {
- "version": "4.1.1",
- "resolved": "https://registry.npmjs.org/ini/-/ini-4.1.1.tgz",
- "integrity": "sha512-QQnnxNyfvmHFIsj7gkPcYymR8Jdw/o7mp5ZFihxn6h8Ci6fh3Dx4E1gPjpQEpIuPo9XVNY/ZUwh4BPMjGyL01g==",
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/ini/-/ini-4.1.2.tgz",
+ "integrity": "sha512-AMB1mvwR1pyBFY/nSevUX6y8nJWS63/SzUKD3JyQn97s4xgIdgQPT75IRouIiBAN4yLQBUShNYVW0+UG25daCw==",
"dev": true,
"engines": {
"node": "^14.17.0 || ^16.13.0 || >=18.0.0"
@@ -7301,10 +7190,13 @@
}
},
"node_modules/is-map": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/is-map/-/is-map-2.0.2.tgz",
- "integrity": "sha512-cOZFQQozTha1f4MxLFzlgKYPTyj26picdZTx82hbc/Xf4K/tZOOXSCkMvU4pKioRXGDLJRn0GM7Upe7kR721yg==",
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/is-map/-/is-map-2.0.3.tgz",
+ "integrity": "sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw==",
"dev": true,
+ "engines": {
+ "node": ">= 0.4"
+ },
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
@@ -7414,10 +7306,13 @@
}
},
"node_modules/is-set": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/is-set/-/is-set-2.0.2.tgz",
- "integrity": "sha512-+2cnTEZeY5z/iXGbLhPrOAaK/Mau5k5eXq9j14CpRTftq0pAJu2MwVRSZhyZWBzx3o6X795Lz6Bpb6R0GKf37g==",
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/is-set/-/is-set-2.0.3.tgz",
+ "integrity": "sha512-iPAjerrse27/ygGLxw+EBR9agv9Y6uLeYVJMu+QNCoouJ1/1ri0mGrcWpfCqFZuzzx3WjtwxG098X+n4OuRkPg==",
"dev": true,
+ "engines": {
+ "node": ">= 0.4"
+ },
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
@@ -7504,10 +7399,13 @@
}
},
"node_modules/is-weakmap": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/is-weakmap/-/is-weakmap-2.0.1.tgz",
- "integrity": "sha512-NSBR4kH5oVj1Uwvv970ruUkCV7O1mzgVFO4/rev2cLRda9Tm9HrL70ZPut4rOHgY0FNrUu9BCbXA2sdQ+x0chA==",
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/is-weakmap/-/is-weakmap-2.0.2.tgz",
+ "integrity": "sha512-K5pXYOm9wqY1RgjpL3YTkF39tni1XajUIkawTLUo9EZEVUFga5gSQJF8nNS7ZwJQ02y+1YCNYcMh+HIf1ZqE+w==",
"dev": true,
+ "engines": {
+ "node": ">= 0.4"
+ },
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
@@ -7525,13 +7423,16 @@
}
},
"node_modules/is-weakset": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/is-weakset/-/is-weakset-2.0.2.tgz",
- "integrity": "sha512-t2yVvttHkQktwnNNmBQ98AhENLdPUTDTE21uPqAQ0ARwQfGeQKRVS0NNurH7bTf7RrvcVn1OOge45CnBeHCSmg==",
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/is-weakset/-/is-weakset-2.0.3.tgz",
+ "integrity": "sha512-LvIm3/KWzS9oRFHugab7d+M/GcBXuXX5xZkzPmN+NxihdQlZUQ4dWuSV1xR/sq6upL1TJEDrfBgRepHFdBtSNQ==",
"dev": true,
"dependencies": {
- "call-bind": "^1.0.2",
- "get-intrinsic": "^1.1.1"
+ "call-bind": "^1.0.7",
+ "get-intrinsic": "^1.2.4"
+ },
+ "engines": {
+ "node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
@@ -8373,9 +8274,9 @@
}
},
"node_modules/mermaid": {
- "version": "10.8.0",
- "resolved": "https://registry.npmjs.org/mermaid/-/mermaid-10.8.0.tgz",
- "integrity": "sha512-9CzfSreRjdDJxX796+jW4zjEq0DVw5xVF0nWsqff8OTbrt+ml0TZ5PyYUjjUZJa2NYxYJZZXewEquxGiM8qZEA==",
+ "version": "10.9.0",
+ "resolved": "https://registry.npmjs.org/mermaid/-/mermaid-10.9.0.tgz",
+ "integrity": "sha512-swZju0hFox/B/qoLKK0rOxxgh8Cf7rJSfAUc1u8fezVihYMvrJAS45GzAxTVf4Q+xn9uMgitBcmWk7nWGXOs/g==",
"dependencies": {
"@braintree/sanitize-url": "^6.0.1",
"@types/d3-scale": "^4.0.3",
@@ -8388,6 +8289,7 @@
"dayjs": "^1.11.7",
"dompurify": "^3.0.5",
"elkjs": "^0.9.0",
+ "katex": "^0.16.9",
"khroma": "^2.0.0",
"lodash-es": "^4.17.21",
"mdast-util-from-markdown": "^1.3.0",
@@ -8934,9 +8836,9 @@
}
},
"node_modules/monaco-editor": {
- "version": "0.46.0",
- "resolved": "https://registry.npmjs.org/monaco-editor/-/monaco-editor-0.46.0.tgz",
- "integrity": "sha512-ADwtLIIww+9FKybWscd7OCfm9odsFYHImBRI1v9AviGce55QY8raT+9ihH8jX/E/e6QVSGM+pKj4jSUSRmALNQ=="
+ "version": "0.47.0",
+ "resolved": "https://registry.npmjs.org/monaco-editor/-/monaco-editor-0.47.0.tgz",
+ "integrity": "sha512-VabVvHvQ9QmMwXu4du008ZDuyLnHs9j7ThVFsiJoXSOQk18+LF89N4ADzPbFenm0W4V2bGHnFBztIRQTgBfxzw=="
},
"node_modules/monaco-editor-webpack-plugin": {
"version": "7.1.0",
@@ -9846,6 +9748,32 @@
"postcss": "^8.2.14"
}
},
+ "node_modules/postcss-nesting": {
+ "version": "12.1.0",
+ "resolved": "https://registry.npmjs.org/postcss-nesting/-/postcss-nesting-12.1.0.tgz",
+ "integrity": "sha512-QOYnosaZ+mlP6plQrAxFw09UUp2Sgtxj1BVHN+rSVbtV0Yx48zRt9/9F/ZOoxOKBBEsaJk2MYhhVRjeRRw5yuw==",
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/csstools"
+ },
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/csstools"
+ }
+ ],
+ "dependencies": {
+ "@csstools/selector-resolve-nested": "^1.1.0",
+ "@csstools/selector-specificity": "^3.0.2",
+ "postcss-selector-parser": "^6.0.13"
+ },
+ "engines": {
+ "node": "^14 || ^16 || >=18"
+ },
+ "peerDependencies": {
+ "postcss": "^8.4"
+ }
+ },
"node_modules/postcss-resolve-nested-selector": {
"version": "0.1.1",
"resolved": "https://registry.npmjs.org/postcss-resolve-nested-selector/-/postcss-resolve-nested-selector-0.1.1.tgz",
@@ -9895,9 +9823,9 @@
}
},
"node_modules/postcss-selector-parser": {
- "version": "6.0.15",
- "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.15.tgz",
- "integrity": "sha512-rEYkQOMUCEMhsKbK66tbEU9QVIxbhN18YiniAwA7XQYTVBqrBy+P2p5JcdqsHgKM2zWylp8d7J6eszocfds5Sw==",
+ "version": "6.0.16",
+ "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.16.tgz",
+ "integrity": "sha512-A0RVJrX+IUkVZbW3ClroRWurercFhieevHB38sr2+l9eUClMqome3LmEmnhlNy+5Mr2EYN6B2Kaw9wYdd+VHiw==",
"dependencies": {
"cssesc": "^3.0.0",
"util-deprecate": "^1.0.2"
@@ -10501,13 +10429,13 @@
}
},
"node_modules/safe-array-concat": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.1.0.tgz",
- "integrity": "sha512-ZdQ0Jeb9Ofti4hbt5lX3T2JcAamT9hfzYU1MNB+z/jaEbB6wfFfPIR/zEORmZqobkCCJhSjodobH6WHNmJ97dg==",
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.1.2.tgz",
+ "integrity": "sha512-vj6RsCsWBCf19jIeHEfkRMw8DPiBb+DMXklQ/1SGDHOMlHdPUkZXFQ2YdplS23zESTijAcurb1aSgJA3AgMu1Q==",
"dev": true,
"dependencies": {
- "call-bind": "^1.0.5",
- "get-intrinsic": "^1.2.2",
+ "call-bind": "^1.0.7",
+ "get-intrinsic": "^1.2.4",
"has-symbols": "^1.0.3",
"isarray": "^2.0.5"
},
@@ -10638,17 +10566,17 @@
}
},
"node_modules/seroval": {
- "version": "1.0.4",
- "resolved": "https://registry.npmjs.org/seroval/-/seroval-1.0.4.tgz",
- "integrity": "sha512-qQs/N+KfJu83rmszFQaTxcoJoPn6KNUruX4KmnmyD0oZkUoiNvJ1rpdYKDf4YHM05k+HOgCxa3yvf15QbVijGg==",
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/seroval/-/seroval-1.0.5.tgz",
+ "integrity": "sha512-TM+Z11tHHvQVQKeNlOUonOWnsNM+2IBwZ4vwoi4j3zKzIpc5IDw8WPwCfcc8F17wy6cBcJGbZbFOR0UCuTZHQA==",
"engines": {
"node": ">=10"
}
},
"node_modules/seroval-plugins": {
- "version": "1.0.4",
- "resolved": "https://registry.npmjs.org/seroval-plugins/-/seroval-plugins-1.0.4.tgz",
- "integrity": "sha512-DQ2IK6oQVvy8k+c2V5x5YCtUa/GGGsUwUBNN9UqohrZ0rWdUapBFpNMYP1bCyRHoxOJjdKGl+dieacFIpU/i1A==",
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/seroval-plugins/-/seroval-plugins-1.0.5.tgz",
+ "integrity": "sha512-8+pDC1vOedPXjKG7oz8o+iiHrtF2WswaMQJ7CKFpccvSYfrzmvKY9zOJWCg+881722wIHfwkdnRmiiDm9ym+zQ==",
"engines": {
"node": ">=10"
},
@@ -10657,17 +10585,17 @@
}
},
"node_modules/set-function-length": {
- "version": "1.2.1",
- "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.1.tgz",
- "integrity": "sha512-j4t6ccc+VsKwYHso+kElc5neZpjtq9EnRICFZtWyBsLojhmeF/ZBd/elqm22WJh/BziDe/SBiOeAt0m2mfLD0g==",
+ "version": "1.2.2",
+ "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz",
+ "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==",
"dev": true,
"dependencies": {
- "define-data-property": "^1.1.2",
+ "define-data-property": "^1.1.4",
"es-errors": "^1.3.0",
"function-bind": "^1.1.2",
- "get-intrinsic": "^1.2.3",
+ "get-intrinsic": "^1.2.4",
"gopd": "^1.0.1",
- "has-property-descriptors": "^1.0.1"
+ "has-property-descriptors": "^1.0.2"
},
"engines": {
"node": ">= 0.4"
@@ -11454,9 +11382,9 @@
}
},
"node_modules/swagger-ui-dist": {
- "version": "5.11.8",
- "resolved": "https://registry.npmjs.org/swagger-ui-dist/-/swagger-ui-dist-5.11.8.tgz",
- "integrity": "sha512-IfPtCPdf6opT5HXrzHO4kjL1eco0/8xJCtcs7ilhKuzatrpF2j9s+3QbOag6G3mVFKf+g+Ca5UG9DquVUs2obA=="
+ "version": "5.12.0",
+ "resolved": "https://registry.npmjs.org/swagger-ui-dist/-/swagger-ui-dist-5.12.0.tgz",
+ "integrity": "sha512-Rt1xUpbHulJVGbiQjq9yy9/r/0Pg6TmpcG+fXTaMePDc8z5WUw4LfaWts5qcNv/8ewPvBIbY7DKq7qReIKNCCQ=="
},
"node_modules/symbol-tree": {
"version": "3.2.4",
@@ -11597,10 +11525,23 @@
"node": ">=6"
}
},
+ "node_modules/temporal-polyfill": {
+ "version": "0.2.3",
+ "resolved": "https://registry.npmjs.org/temporal-polyfill/-/temporal-polyfill-0.2.3.tgz",
+ "integrity": "sha512-7ZJRc7wq/1XjrOQYkkNpgo2qfE9XLrUU8D/DS+LAC/T0bYqZ46rW6dow0sOTXTPZS4bwer8bD/0OyuKQBfA3yw==",
+ "dependencies": {
+ "temporal-spec": "^0.2.0"
+ }
+ },
+ "node_modules/temporal-spec": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/temporal-spec/-/temporal-spec-0.2.0.tgz",
+ "integrity": "sha512-r1AT0XdEp8TMQ13FLvOt8mOtAxDQsRt2QU5rSWCA7YfshddU651Y1NHVrceLANvixKdf9fYO8B/S9fXHodB7HQ=="
+ },
"node_modules/terser": {
- "version": "5.28.1",
- "resolved": "https://registry.npmjs.org/terser/-/terser-5.28.1.tgz",
- "integrity": "sha512-wM+bZp54v/E9eRRGXb5ZFDvinrJIOaTapx3WUokyVGZu5ucVCK55zEgGd5Dl2fSr3jUo5sDiERErUWLY6QPFyA==",
+ "version": "5.29.2",
+ "resolved": "https://registry.npmjs.org/terser/-/terser-5.29.2.tgz",
+ "integrity": "sha512-ZiGkhUBIM+7LwkNjXYJq8svgkd+QK3UUr0wJqY4MieaezBSAIPgbSPZyIx0idM6XWK5CMzSWa8MJIzmRcB8Caw==",
"dependencies": {
"@jridgewell/source-map": "^0.3.3",
"acorn": "^8.8.2",
@@ -11825,9 +11766,9 @@
"integrity": "sha512-B5CXihaVzXw+1UHhNFyAwUTMDk1EfoLP5Tj1VhD9yybZ1I8DZJEv8tZ1l0RJo0t0tk9ZhR8eG5tEsaCvRigmdQ=="
},
"node_modules/ts-api-utils": {
- "version": "1.2.1",
- "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.2.1.tgz",
- "integrity": "sha512-RIYA36cJn2WiH9Hy77hdF9r7oEwxAtB/TS9/S4Qd90Ap4z5FSiin5zEiTL44OII1Y3IIlEvxwxFUVgrHSZ/UpA==",
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.3.0.tgz",
+ "integrity": "sha512-UQMIo7pb8WRomKR1/+MFVLTroIvDVtMX3K6OUir8ynLyzB8Jeriont2bTAtmNPa1ekAgN7YPDyf6V+ygrdU+eQ==",
"dev": true,
"engines": {
"node": ">=16"
@@ -11986,9 +11927,9 @@
}
},
"node_modules/typescript": {
- "version": "5.3.3",
- "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.3.3.tgz",
- "integrity": "sha512-pXWcraxM0uxAS+tN0AG/BF2TyqmHO014Z070UsJ+pFvYuRSq8KH8DmWpnbXe0pEPDHXZV3FcAbJkijJ5oNEnWw==",
+ "version": "5.4.2",
+ "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.4.2.tgz",
+ "integrity": "sha512-+2/g0Fds1ERlP6JsakQQDXjZdZMM+rqpamFZJEKh4kwTIn3iDkgKtby0CeNd5ATNZ4Ry1ax15TMx0W2V+miizQ==",
"devOptional": true,
"peer": true,
"bin": {
@@ -12092,9 +12033,9 @@
}
},
"node_modules/updates": {
- "version": "15.1.2",
- "resolved": "https://registry.npmjs.org/updates/-/updates-15.1.2.tgz",
- "integrity": "sha512-+/JT4NChl82iexV9G80TY5HF3ubQ5O9UTOk3LlCo4Y4aRCYvo1h4bJE8YkP0PE7KiFRWIQq/rPmUYrY2QF8wVA==",
+ "version": "15.3.1",
+ "resolved": "https://registry.npmjs.org/updates/-/updates-15.3.1.tgz",
+ "integrity": "sha512-DqHT1aJ6p6jVLWRiAeuVx/TQotvEwUjgrY1Mlc0a2qYk+eKEQVXugQ4M+6QoVMA3X1NFAVsb02d93pmWam4bBA==",
"dev": true,
"bin": {
"updates": "bin/updates.js"
@@ -12190,9 +12131,9 @@
}
},
"node_modules/vite": {
- "version": "5.1.4",
- "resolved": "https://registry.npmjs.org/vite/-/vite-5.1.4.tgz",
- "integrity": "sha512-n+MPqzq+d9nMVTKyewqw6kSt+R3CkvF9QAKY8obiQn8g1fwTscKxyfaYnC632HtBXAQGc1Yjomphwn1dtwGAHg==",
+ "version": "5.1.6",
+ "resolved": "https://registry.npmjs.org/vite/-/vite-5.1.6.tgz",
+ "integrity": "sha512-yYIAZs9nVfRJ/AiOLCA91zzhjsHUgMjB+EigzFb6W2XTLO8JixBCKCjvhKZaye+NKYHCrkv3Oh50dH9EdLU2RA==",
"dev": true,
"dependencies": {
"esbuild": "^0.19.3",
@@ -12272,12 +12213,418 @@
"integrity": "sha512-KRCIFX3PWVUuEjpi9O7EKLT9E27OqOA3RimIvVx6cziLAUxvnk2VvHQfMrP+mKkqyqqSmnnYyTig3OyDnK/zlA==",
"dev": true
},
+ "node_modules/vite/node_modules/@esbuild/aix-ppc64": {
+ "version": "0.19.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.19.12.tgz",
+ "integrity": "sha512-bmoCYyWdEL3wDQIVbcyzRyeKLgk2WtWLTWz1ZIAZF/EGbNOwSA6ew3PftJ1PqMiOOGu0OyFMzG53L0zqIpPeNA==",
+ "cpu": [
+ "ppc64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "aix"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/vite/node_modules/@esbuild/android-arm": {
+ "version": "0.19.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.19.12.tgz",
+ "integrity": "sha512-qg/Lj1mu3CdQlDEEiWrlC4eaPZ1KztwGJ9B6J+/6G+/4ewxJg7gqj8eVYWvao1bXrqGiW2rsBZFSX3q2lcW05w==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/vite/node_modules/@esbuild/android-arm64": {
+ "version": "0.19.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.19.12.tgz",
+ "integrity": "sha512-P0UVNGIienjZv3f5zq0DP3Nt2IE/3plFzuaS96vihvD0Hd6H/q4WXUGpCxD/E8YrSXfNyRPbpTq+T8ZQioSuPA==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/vite/node_modules/@esbuild/android-x64": {
+ "version": "0.19.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.19.12.tgz",
+ "integrity": "sha512-3k7ZoUW6Q6YqhdhIaq/WZ7HwBpnFBlW905Fa4s4qWJyiNOgT1dOqDiVAQFwBH7gBRZr17gLrlFCRzF6jFh7Kew==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/vite/node_modules/@esbuild/darwin-arm64": {
+ "version": "0.19.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.19.12.tgz",
+ "integrity": "sha512-B6IeSgZgtEzGC42jsI+YYu9Z3HKRxp8ZT3cqhvliEHovq8HSX2YX8lNocDn79gCKJXOSaEot9MVYky7AKjCs8g==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/vite/node_modules/@esbuild/darwin-x64": {
+ "version": "0.19.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.19.12.tgz",
+ "integrity": "sha512-hKoVkKzFiToTgn+41qGhsUJXFlIjxI/jSYeZf3ugemDYZldIXIxhvwN6erJGlX4t5h417iFuheZ7l+YVn05N3A==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/vite/node_modules/@esbuild/freebsd-arm64": {
+ "version": "0.19.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.19.12.tgz",
+ "integrity": "sha512-4aRvFIXmwAcDBw9AueDQ2YnGmz5L6obe5kmPT8Vd+/+x/JMVKCgdcRwH6APrbpNXsPz+K653Qg8HB/oXvXVukA==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "freebsd"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/vite/node_modules/@esbuild/freebsd-x64": {
+ "version": "0.19.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.19.12.tgz",
+ "integrity": "sha512-EYoXZ4d8xtBoVN7CEwWY2IN4ho76xjYXqSXMNccFSx2lgqOG/1TBPW0yPx1bJZk94qu3tX0fycJeeQsKovA8gg==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "freebsd"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/vite/node_modules/@esbuild/linux-arm": {
+ "version": "0.19.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.19.12.tgz",
+ "integrity": "sha512-J5jPms//KhSNv+LO1S1TX1UWp1ucM6N6XuL6ITdKWElCu8wXP72l9MM0zDTzzeikVyqFE6U8YAV9/tFyj0ti+w==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/vite/node_modules/@esbuild/linux-arm64": {
+ "version": "0.19.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.19.12.tgz",
+ "integrity": "sha512-EoTjyYyLuVPfdPLsGVVVC8a0p1BFFvtpQDB/YLEhaXyf/5bczaGeN15QkR+O4S5LeJ92Tqotve7i1jn35qwvdA==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/vite/node_modules/@esbuild/linux-ia32": {
+ "version": "0.19.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.19.12.tgz",
+ "integrity": "sha512-Thsa42rrP1+UIGaWz47uydHSBOgTUnwBwNq59khgIwktK6x60Hivfbux9iNR0eHCHzOLjLMLfUMLCypBkZXMHA==",
+ "cpu": [
+ "ia32"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/vite/node_modules/@esbuild/linux-loong64": {
+ "version": "0.19.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.19.12.tgz",
+ "integrity": "sha512-LiXdXA0s3IqRRjm6rV6XaWATScKAXjI4R4LoDlvO7+yQqFdlr1Bax62sRwkVvRIrwXxvtYEHHI4dm50jAXkuAA==",
+ "cpu": [
+ "loong64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/vite/node_modules/@esbuild/linux-mips64el": {
+ "version": "0.19.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.19.12.tgz",
+ "integrity": "sha512-fEnAuj5VGTanfJ07ff0gOA6IPsvrVHLVb6Lyd1g2/ed67oU1eFzL0r9WL7ZzscD+/N6i3dWumGE1Un4f7Amf+w==",
+ "cpu": [
+ "mips64el"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/vite/node_modules/@esbuild/linux-ppc64": {
+ "version": "0.19.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.19.12.tgz",
+ "integrity": "sha512-nYJA2/QPimDQOh1rKWedNOe3Gfc8PabU7HT3iXWtNUbRzXS9+vgB0Fjaqr//XNbd82mCxHzik2qotuI89cfixg==",
+ "cpu": [
+ "ppc64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/vite/node_modules/@esbuild/linux-riscv64": {
+ "version": "0.19.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.19.12.tgz",
+ "integrity": "sha512-2MueBrlPQCw5dVJJpQdUYgeqIzDQgw3QtiAHUC4RBz9FXPrskyyU3VI1hw7C0BSKB9OduwSJ79FTCqtGMWqJHg==",
+ "cpu": [
+ "riscv64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/vite/node_modules/@esbuild/linux-s390x": {
+ "version": "0.19.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.19.12.tgz",
+ "integrity": "sha512-+Pil1Nv3Umes4m3AZKqA2anfhJiVmNCYkPchwFJNEJN5QxmTs1uzyy4TvmDrCRNT2ApwSari7ZIgrPeUx4UZDg==",
+ "cpu": [
+ "s390x"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/vite/node_modules/@esbuild/linux-x64": {
+ "version": "0.19.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.19.12.tgz",
+ "integrity": "sha512-B71g1QpxfwBvNrfyJdVDexenDIt1CiDN1TIXLbhOw0KhJzE78KIFGX6OJ9MrtC0oOqMWf+0xop4qEU8JrJTwCg==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/vite/node_modules/@esbuild/netbsd-x64": {
+ "version": "0.19.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.19.12.tgz",
+ "integrity": "sha512-3ltjQ7n1owJgFbuC61Oj++XhtzmymoCihNFgT84UAmJnxJfm4sYCiSLTXZtE00VWYpPMYc+ZQmB6xbSdVh0JWA==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "netbsd"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/vite/node_modules/@esbuild/openbsd-x64": {
+ "version": "0.19.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.19.12.tgz",
+ "integrity": "sha512-RbrfTB9SWsr0kWmb9srfF+L933uMDdu9BIzdA7os2t0TXhCRjrQyCeOt6wVxr79CKD4c+p+YhCj31HBkYcXebw==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "openbsd"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/vite/node_modules/@esbuild/sunos-x64": {
+ "version": "0.19.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.19.12.tgz",
+ "integrity": "sha512-HKjJwRrW8uWtCQnQOz9qcU3mUZhTUQvi56Q8DPTLLB+DawoiQdjsYq+j+D3s9I8VFtDr+F9CjgXKKC4ss89IeA==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "sunos"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/vite/node_modules/@esbuild/win32-arm64": {
+ "version": "0.19.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.19.12.tgz",
+ "integrity": "sha512-URgtR1dJnmGvX864pn1B2YUYNzjmXkuJOIqG2HdU62MVS4EHpU2946OZoTMnRUHklGtJdJZ33QfzdjGACXhn1A==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/vite/node_modules/@esbuild/win32-ia32": {
+ "version": "0.19.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.19.12.tgz",
+ "integrity": "sha512-+ZOE6pUkMOJfmxmBZElNOx72NKpIa/HFOMGzu8fqzQJ5kgf6aTGrcJaFsNiVMH4JKpMipyK+7k0n2UXN7a8YKQ==",
+ "cpu": [
+ "ia32"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/vite/node_modules/@esbuild/win32-x64": {
+ "version": "0.19.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.19.12.tgz",
+ "integrity": "sha512-T1QyPSDCyMXaO3pzBkF96E8xMkiRYbUEZADd29SyPGabqxMViNoii+NcK7eWJAEoU6RZyEm5lVSIjTmcdoB9HA==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
"node_modules/vite/node_modules/@types/estree": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz",
"integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==",
"dev": true
},
+ "node_modules/vite/node_modules/esbuild": {
+ "version": "0.19.12",
+ "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.19.12.tgz",
+ "integrity": "sha512-aARqgq8roFBj054KvQr5f1sFu0D65G+miZRCuJyJ0G13Zwx7vRar5Zhn2tkQNzIXcBrNVsv/8stehpj+GAjgbg==",
+ "dev": true,
+ "hasInstallScript": true,
+ "bin": {
+ "esbuild": "bin/esbuild"
+ },
+ "engines": {
+ "node": ">=12"
+ },
+ "optionalDependencies": {
+ "@esbuild/aix-ppc64": "0.19.12",
+ "@esbuild/android-arm": "0.19.12",
+ "@esbuild/android-arm64": "0.19.12",
+ "@esbuild/android-x64": "0.19.12",
+ "@esbuild/darwin-arm64": "0.19.12",
+ "@esbuild/darwin-x64": "0.19.12",
+ "@esbuild/freebsd-arm64": "0.19.12",
+ "@esbuild/freebsd-x64": "0.19.12",
+ "@esbuild/linux-arm": "0.19.12",
+ "@esbuild/linux-arm64": "0.19.12",
+ "@esbuild/linux-ia32": "0.19.12",
+ "@esbuild/linux-loong64": "0.19.12",
+ "@esbuild/linux-mips64el": "0.19.12",
+ "@esbuild/linux-ppc64": "0.19.12",
+ "@esbuild/linux-riscv64": "0.19.12",
+ "@esbuild/linux-s390x": "0.19.12",
+ "@esbuild/linux-x64": "0.19.12",
+ "@esbuild/netbsd-x64": "0.19.12",
+ "@esbuild/openbsd-x64": "0.19.12",
+ "@esbuild/sunos-x64": "0.19.12",
+ "@esbuild/win32-arm64": "0.19.12",
+ "@esbuild/win32-ia32": "0.19.12",
+ "@esbuild/win32-x64": "0.19.12"
+ }
+ },
"node_modules/vite/node_modules/fsevents": {
"version": "2.3.3",
"resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",
@@ -12293,9 +12640,9 @@
}
},
"node_modules/vite/node_modules/rollup": {
- "version": "4.12.0",
- "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.12.0.tgz",
- "integrity": "sha512-wz66wn4t1OHIJw3+XU7mJJQV/2NAfw5OAk6G6Hoo3zcvz/XOfQ52Vgi+AN4Uxoxi0KBBwk2g8zPrTDA4btSB/Q==",
+ "version": "4.13.0",
+ "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.13.0.tgz",
+ "integrity": "sha512-3YegKemjoQnYKmsBlOHfMLVPPA5xLkQ8MHLLSw/fBrFaVkEayL51DilPpNNLq1exr98F2B1TzrV0FUlN3gWRPg==",
"dev": true,
"dependencies": {
"@types/estree": "1.0.5"
@@ -12308,19 +12655,19 @@
"npm": ">=8.0.0"
},
"optionalDependencies": {
- "@rollup/rollup-android-arm-eabi": "4.12.0",
- "@rollup/rollup-android-arm64": "4.12.0",
- "@rollup/rollup-darwin-arm64": "4.12.0",
- "@rollup/rollup-darwin-x64": "4.12.0",
- "@rollup/rollup-linux-arm-gnueabihf": "4.12.0",
- "@rollup/rollup-linux-arm64-gnu": "4.12.0",
- "@rollup/rollup-linux-arm64-musl": "4.12.0",
- "@rollup/rollup-linux-riscv64-gnu": "4.12.0",
- "@rollup/rollup-linux-x64-gnu": "4.12.0",
- "@rollup/rollup-linux-x64-musl": "4.12.0",
- "@rollup/rollup-win32-arm64-msvc": "4.12.0",
- "@rollup/rollup-win32-ia32-msvc": "4.12.0",
- "@rollup/rollup-win32-x64-msvc": "4.12.0",
+ "@rollup/rollup-android-arm-eabi": "4.13.0",
+ "@rollup/rollup-android-arm64": "4.13.0",
+ "@rollup/rollup-darwin-arm64": "4.13.0",
+ "@rollup/rollup-darwin-x64": "4.13.0",
+ "@rollup/rollup-linux-arm-gnueabihf": "4.13.0",
+ "@rollup/rollup-linux-arm64-gnu": "4.13.0",
+ "@rollup/rollup-linux-arm64-musl": "4.13.0",
+ "@rollup/rollup-linux-riscv64-gnu": "4.13.0",
+ "@rollup/rollup-linux-x64-gnu": "4.13.0",
+ "@rollup/rollup-linux-x64-musl": "4.13.0",
+ "@rollup/rollup-win32-arm64-msvc": "4.13.0",
+ "@rollup/rollup-win32-ia32-msvc": "4.13.0",
+ "@rollup/rollup-win32-x64-msvc": "4.13.0",
"fsevents": "~2.3.2"
}
},
@@ -12390,9 +12737,9 @@
}
},
"node_modules/vitest/node_modules/magic-string": {
- "version": "0.30.7",
- "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.7.tgz",
- "integrity": "sha512-8vBuFF/I/+OSLRmdf2wwFCJCz+nSn0m6DPvGH1fS/KiQoSaR+sETbov0eIk9KhEKy8CYqIkIAnbohxT/4H0kuA==",
+ "version": "0.30.8",
+ "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.8.tgz",
+ "integrity": "sha512-ISQTe55T2ao7XtlAStud6qwYPZjE4GK1S/BeVPus4jrq6JuOnQ00YKQC581RWhR122W7msZV263KzVeLoqidyQ==",
"dev": true,
"dependencies": {
"@jridgewell/sourcemap-codec": "^1.4.15"
@@ -12518,9 +12865,9 @@
}
},
"node_modules/watchpack": {
- "version": "2.4.0",
- "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.0.tgz",
- "integrity": "sha512-Lcvm7MGST/4fup+ifyKi2hjyIAwcdI4HRgtvTpIUxBRhB+RFtUh8XtDOxUfctVCnhVi+QQj49i91OyvzkJl6cg==",
+ "version": "2.4.1",
+ "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.1.tgz",
+ "integrity": "sha512-8wrBCMtVhqcXP2Sup1ctSkga6uc2Bx0IIvKyT7yTFier5AXHooSI+QyQQAtTb7+E0IUCCKyTFmXqdqgum2XWGg==",
"dependencies": {
"glob-to-regexp": "^0.4.1",
"graceful-fs": "^4.1.2"
@@ -12832,31 +13179,34 @@
}
},
"node_modules/which-collection": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/which-collection/-/which-collection-1.0.1.tgz",
- "integrity": "sha512-W8xeTUwaln8i3K/cY1nGXzdnVZlidBcagyNFtBdD5kxnb4TvGKR7FfSIS3mYpwWS1QUCutfKz8IY8RjftB0+1A==",
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/which-collection/-/which-collection-1.0.2.tgz",
+ "integrity": "sha512-K4jVyjnBdgvc86Y6BkaLZEN933SwYOuBFkdmBu9ZfkcAbdVbpITnDmjvZ/aQjRXQrv5EPkTnD1s39GiiqbngCw==",
"dev": true,
"dependencies": {
- "is-map": "^2.0.1",
- "is-set": "^2.0.1",
- "is-weakmap": "^2.0.1",
- "is-weakset": "^2.0.1"
+ "is-map": "^2.0.3",
+ "is-set": "^2.0.3",
+ "is-weakmap": "^2.0.2",
+ "is-weakset": "^2.0.3"
+ },
+ "engines": {
+ "node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/which-typed-array": {
- "version": "1.1.14",
- "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.14.tgz",
- "integrity": "sha512-VnXFiIW8yNn9kIHN88xvZ4yOWchftKDsRJ8fEPacX/wl1lOvBrhsJ/OeJCXq7B0AaijRuqgzSKalJoPk+D8MPg==",
+ "version": "1.1.15",
+ "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.15.tgz",
+ "integrity": "sha512-oV0jmFtUky6CXfkqehVvBP/LSWJ2sy4vWMioiENyJLePrBO/yKyV9OyJySfAKosh+RYkIl5zJCNZ8/4JncrpdA==",
"dev": true,
"dependencies": {
- "available-typed-arrays": "^1.0.6",
- "call-bind": "^1.0.5",
+ "available-typed-arrays": "^1.0.7",
+ "call-bind": "^1.0.7",
"for-each": "^0.3.3",
"gopd": "^1.0.1",
- "has-tostringtag": "^1.0.1"
+ "has-tostringtag": "^1.0.2"
},
"engines": {
"node": ">= 0.4"
@@ -13045,9 +13395,9 @@
"integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A=="
},
"node_modules/yaml": {
- "version": "2.4.0",
- "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.4.0.tgz",
- "integrity": "sha512-j9iR8g+/t0lArF4V6NE/QCfT+CO7iLqrXAHZbJdo+LfjqP1vR8Fg5bSiaq6Q2lOD1AUEVrEVIgABvBFYojJVYQ==",
+ "version": "2.4.1",
+ "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.4.1.tgz",
+ "integrity": "sha512-pIXzoImaqmfOrL7teGUBt/T7ZDnyeGBWyXQBvOVhLkWLN37GXv8NMLK406UY6dS51JfcQHsmcW5cJ441bHg6Lg==",
"bin": {
"yaml": "bin.mjs"
},
diff --git a/package.json b/package.json
index 1152bfef72..1be87e8b39 100644
--- a/package.json
+++ b/package.json
@@ -4,9 +4,9 @@
"node": ">= 18.0.0"
},
"dependencies": {
- "@citation-js/core": "0.7.6",
- "@citation-js/plugin-bibtex": "0.7.8",
- "@citation-js/plugin-csl": "0.7.6",
+ "@citation-js/core": "0.7.9",
+ "@citation-js/plugin-bibtex": "0.7.9",
+ "@citation-js/plugin-csl": "0.7.9",
"@citation-js/plugin-software-formats": "0.6.1",
"@claviska/jquery-minicolors": "2.3.6",
"@github/markdown-toolbar-element": "2.2.3",
@@ -14,7 +14,6 @@
"@github/text-expander-element": "2.6.1",
"@mcaptcha/vanilla-glue": "0.1.0-alpha-3",
"@primer/octicons": "19.8.0",
- "@webcomponents/custom-elements": "1.6.0",
"add-asset-webpack-plugin": "2.0.1",
"ansi_up": "6.0.2",
"asciinema-player": "3.7.0",
@@ -23,30 +22,31 @@
"chartjs-plugin-zoom": "2.0.1",
"clippie": "4.0.7",
"css-loader": "6.10.0",
- "css-variables-parser": "1.0.1",
"dayjs": "1.11.10",
"dropzone": "6.0.0-beta.2",
"easymde": "2.18.0",
- "esbuild-loader": "4.0.3",
+ "esbuild-loader": "4.1.0",
"escape-goat": "4.0.0",
"fast-glob": "3.3.2",
- "htmx.org": "1.9.10",
+ "htmx.org": "1.9.11",
"idiomorph": "0.3.0",
"jquery": "3.7.1",
"katex": "0.16.9",
"license-checker-webpack-plugin": "0.2.1",
- "mermaid": "10.8.0",
+ "mermaid": "10.9.0",
"mini-css-extract-plugin": "2.8.1",
"minimatch": "9.0.3",
- "monaco-editor": "0.46.0",
+ "monaco-editor": "0.47.0",
"monaco-editor-webpack-plugin": "7.1.0",
"pdfobject": "2.3.0",
"postcss": "8.4.35",
"postcss-loader": "8.1.1",
+ "postcss-nesting": "12.1.0",
"pretty-ms": "9.0.0",
"sortablejs": "1.15.2",
- "swagger-ui-dist": "5.11.8",
+ "swagger-ui-dist": "5.12.0",
"tailwindcss": "3.4.1",
+ "temporal-polyfill": "0.2.3",
"throttle-debounce": "5.0.0",
"tinycolor2": "1.6.0",
"tippy.js": "6.3.7",
@@ -66,7 +66,7 @@
"@eslint-community/eslint-plugin-eslint-comments": "4.1.0",
"@playwright/test": "1.42.1",
"@stoplight/spectral-cli": "6.11.0",
- "@stylistic/eslint-plugin-js": "1.6.3",
+ "@stylistic/eslint-plugin-js": "1.7.0",
"@stylistic/stylelint-plugin": "2.1.0",
"@vitejs/plugin-vue": "5.0.4",
"eslint": "8.57.0",
@@ -76,12 +76,12 @@
"eslint-plugin-jquery": "1.5.1",
"eslint-plugin-no-jquery": "2.7.0",
"eslint-plugin-no-use-extend-native": "0.5.0",
- "eslint-plugin-regexp": "2.2.0",
+ "eslint-plugin-regexp": "2.3.0",
"eslint-plugin-sonarjs": "0.24.0",
"eslint-plugin-unicorn": "51.0.1",
- "eslint-plugin-vitest": "0.3.22",
+ "eslint-plugin-vitest": "0.3.26",
"eslint-plugin-vitest-globals": "1.4.0",
- "eslint-plugin-vue": "9.22.0",
+ "eslint-plugin-vue": "9.23.0",
"eslint-plugin-vue-scoped-css": "2.7.2",
"eslint-plugin-wc": "2.0.4",
"jsdom": "24.0.0",
@@ -91,7 +91,7 @@
"stylelint-declaration-block-no-ignored-properties": "2.8.0",
"stylelint-declaration-strict-value": "1.10.4",
"svgo": "3.2.0",
- "updates": "15.1.2",
+ "updates": "15.3.1",
"vite-string-plugin": "1.1.5",
"vitest": "1.3.1"
},
diff --git a/public/assets/img/svg/gitea-bitbucket.svg b/public/assets/img/svg/gitea-bitbucket.svg
index b900335ea1..83e4c5c6e7 100644
--- a/public/assets/img/svg/gitea-bitbucket.svg
+++ b/public/assets/img/svg/gitea-bitbucket.svg
@@ -1 +1 @@
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/public/assets/img/svg/gitea-facebook.svg b/public/assets/img/svg/gitea-facebook.svg
index cbeb76b127..6101becad2 100644
--- a/public/assets/img/svg/gitea-facebook.svg
+++ b/public/assets/img/svg/gitea-facebook.svg
@@ -1 +1 @@
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/public/assets/img/svg/gitea-jetbrains.svg b/public/assets/img/svg/gitea-jetbrains.svg
new file mode 100644
index 0000000000..5821736225
--- /dev/null
+++ b/public/assets/img/svg/gitea-jetbrains.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/public/assets/img/svg/gitea-microsoftonline.svg b/public/assets/img/svg/gitea-microsoftonline.svg
index ce4f1a5c8f..f2ce13ac22 100644
--- a/public/assets/img/svg/gitea-microsoftonline.svg
+++ b/public/assets/img/svg/gitea-microsoftonline.svg
@@ -1 +1 @@
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/public/assets/img/svg/gitea-open-with-jetbrains.svg b/public/assets/img/svg/gitea-open-with-jetbrains.svg
new file mode 100644
index 0000000000..2b1491b541
--- /dev/null
+++ b/public/assets/img/svg/gitea-open-with-jetbrains.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/public/assets/img/svg/gitea-open-with-vscode.svg b/public/assets/img/svg/gitea-open-with-vscode.svg
new file mode 100644
index 0000000000..151c45e210
--- /dev/null
+++ b/public/assets/img/svg/gitea-open-with-vscode.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/public/assets/img/svg/gitea-open-with-vscodium.svg b/public/assets/img/svg/gitea-open-with-vscodium.svg
new file mode 100644
index 0000000000..9f70878ba6
--- /dev/null
+++ b/public/assets/img/svg/gitea-open-with-vscodium.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/public/assets/img/svg/gitea-twitter.svg b/public/assets/img/svg/gitea-twitter.svg
index 5d11c6eaec..5ed1e264ca 100644
--- a/public/assets/img/svg/gitea-twitter.svg
+++ b/public/assets/img/svg/gitea-twitter.svg
@@ -1 +1 @@
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/public/assets/img/svg/gitea-vscode.svg b/public/assets/img/svg/gitea-vscode.svg
deleted file mode 100644
index 453b9befcc..0000000000
--- a/public/assets/img/svg/gitea-vscode.svg
+++ /dev/null
@@ -1 +0,0 @@
-
\ No newline at end of file
diff --git a/public/assets/img/svg/gitea-vscodium.svg b/public/assets/img/svg/gitea-vscodium.svg
new file mode 100644
index 0000000000..6aad3d3a64
--- /dev/null
+++ b/public/assets/img/svg/gitea-vscodium.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/routers/api/actions/runner/utils.go b/routers/api/actions/runner/utils.go
index a7cb31288c..ff6ec5bd54 100644
--- a/routers/api/actions/runner/utils.go
+++ b/routers/api/actions/runner/utils.go
@@ -15,7 +15,6 @@ import (
"code.gitea.io/gitea/modules/git"
"code.gitea.io/gitea/modules/json"
"code.gitea.io/gitea/modules/log"
- secret_module "code.gitea.io/gitea/modules/secret"
"code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/services/actions"
@@ -32,14 +31,24 @@ func pickTask(ctx context.Context, runner *actions_model.ActionRunner) (*runnerv
return nil, false, nil
}
+ secrets, err := secret_model.GetSecretsOfTask(ctx, t)
+ if err != nil {
+ return nil, false, fmt.Errorf("GetSecretsOfTask: %w", err)
+ }
+
+ vars, err := actions_model.GetVariablesOfRun(ctx, t.Job.Run)
+ if err != nil {
+ return nil, false, fmt.Errorf("GetVariablesOfRun: %w", err)
+ }
+
actions.CreateCommitStatus(ctx, t.Job)
task := &runnerv1.Task{
Id: t.ID,
WorkflowPayload: t.Job.WorkflowPayload,
Context: generateTaskContext(t),
- Secrets: getSecretsOfTask(ctx, t),
- Vars: getVariablesOfTask(ctx, t),
+ Secrets: secrets,
+ Vars: vars,
}
if needs, err := findTaskNeeds(ctx, t); err != nil {
@@ -55,71 +64,6 @@ func pickTask(ctx context.Context, runner *actions_model.ActionRunner) (*runnerv
return task, true, nil
}
-func getSecretsOfTask(ctx context.Context, task *actions_model.ActionTask) map[string]string {
- secrets := map[string]string{}
-
- secrets["GITHUB_TOKEN"] = task.Token
- secrets["GITEA_TOKEN"] = task.Token
-
- if task.Job.Run.IsForkPullRequest && task.Job.Run.TriggerEvent != actions_module.GithubEventPullRequestTarget {
- // ignore secrets for fork pull request, except GITHUB_TOKEN and GITEA_TOKEN which are automatically generated.
- // for the tasks triggered by pull_request_target event, they could access the secrets because they will run in the context of the base branch
- // see the documentation: https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#pull_request_target
- return secrets
- }
-
- ownerSecrets, err := db.Find[secret_model.Secret](ctx, secret_model.FindSecretsOptions{OwnerID: task.Job.Run.Repo.OwnerID})
- if err != nil {
- log.Error("find secrets of owner %v: %v", task.Job.Run.Repo.OwnerID, err)
- // go on
- }
- repoSecrets, err := db.Find[secret_model.Secret](ctx, secret_model.FindSecretsOptions{RepoID: task.Job.Run.RepoID})
- if err != nil {
- log.Error("find secrets of repo %v: %v", task.Job.Run.RepoID, err)
- // go on
- }
-
- for _, secret := range append(ownerSecrets, repoSecrets...) {
- if v, err := secret_module.DecryptSecret(setting.SecretKey, secret.Data); err != nil {
- log.Error("decrypt secret %v %q: %v", secret.ID, secret.Name, err)
- // go on
- } else {
- secrets[secret.Name] = v
- }
- }
-
- return secrets
-}
-
-func getVariablesOfTask(ctx context.Context, task *actions_model.ActionTask) map[string]string {
- variables := map[string]string{}
-
- // Global
- globalVariables, err := db.Find[actions_model.ActionVariable](ctx, actions_model.FindVariablesOpts{})
- if err != nil {
- log.Error("find global variables: %v", err)
- }
-
- // Org / User level
- ownerVariables, err := db.Find[actions_model.ActionVariable](ctx, actions_model.FindVariablesOpts{OwnerID: task.Job.Run.Repo.OwnerID})
- if err != nil {
- log.Error("find variables of org: %d, error: %v", task.Job.Run.Repo.OwnerID, err)
- }
-
- // Repo level
- repoVariables, err := db.Find[actions_model.ActionVariable](ctx, actions_model.FindVariablesOpts{RepoID: task.Job.Run.RepoID})
- if err != nil {
- log.Error("find variables of repo: %d, error: %v", task.Job.Run.RepoID, err)
- }
-
- // Level precedence: Repo > Org / User > Global
- for _, v := range append(globalVariables, append(ownerVariables, repoVariables...)...) {
- variables[v.Name] = v.Data
- }
-
- return variables
-}
-
func generateTaskContext(t *actions_model.ActionTask) *structpb.Struct {
event := map[string]any{}
_ = json.Unmarshal([]byte(t.Job.Run.EventPayload), &event)
diff --git a/routers/api/forgejo/v1/api.go b/routers/api/forgejo/v1/api.go
index 33e9eb1967..88c7502e66 100644
--- a/routers/api/forgejo/v1/api.go
+++ b/routers/api/forgejo/v1/api.go
@@ -5,10 +5,14 @@ package v1
import (
"code.gitea.io/gitea/modules/web"
+ "code.gitea.io/gitea/routers/api/shared"
)
func Routes() *web.Route {
m := web.NewRoute()
+
+ m.Use(shared.Middlewares()...)
+
forgejo := NewForgejo()
m.Get("", Root)
m.Get("/version", forgejo.GetVersion)
diff --git a/routers/api/shared/middleware.go b/routers/api/shared/middleware.go
new file mode 100644
index 0000000000..e2ff004024
--- /dev/null
+++ b/routers/api/shared/middleware.go
@@ -0,0 +1,152 @@
+// Copyright 2024 The Forgejo Authors. All rights reserved.
+// SPDX-License-Identifier: MIT
+
+package shared
+
+import (
+ "net/http"
+
+ auth_model "code.gitea.io/gitea/models/auth"
+ "code.gitea.io/gitea/models/db"
+ "code.gitea.io/gitea/modules/log"
+ "code.gitea.io/gitea/modules/setting"
+ "code.gitea.io/gitea/routers/common"
+ "code.gitea.io/gitea/services/auth"
+ "code.gitea.io/gitea/services/context"
+
+ "github.com/go-chi/cors"
+)
+
+func Middlewares() (stack []any) {
+ stack = append(stack, securityHeaders())
+
+ if setting.CORSConfig.Enabled {
+ stack = append(stack, cors.Handler(cors.Options{
+ AllowedOrigins: setting.CORSConfig.AllowDomain,
+ AllowedMethods: setting.CORSConfig.Methods,
+ AllowCredentials: setting.CORSConfig.AllowCredentials,
+ AllowedHeaders: append([]string{"Authorization", "X-Gitea-OTP", "X-Forgejo-OTP"}, setting.CORSConfig.Headers...),
+ MaxAge: int(setting.CORSConfig.MaxAge.Seconds()),
+ }))
+ }
+ return append(stack,
+ context.APIContexter(),
+
+ checkDeprecatedAuthMethods,
+ // Get user from session if logged in.
+ apiAuth(buildAuthGroup()),
+ verifyAuthWithOptions(&common.VerifyOptions{
+ SignInRequired: setting.Service.RequireSignInView,
+ }),
+ )
+}
+
+func buildAuthGroup() *auth.Group {
+ group := auth.NewGroup(
+ &auth.OAuth2{},
+ &auth.HTTPSign{},
+ &auth.Basic{}, // FIXME: this should be removed once we don't allow basic auth in API
+ )
+ if setting.Service.EnableReverseProxyAuthAPI {
+ group.Add(&auth.ReverseProxy{})
+ }
+
+ if setting.IsWindows && auth_model.IsSSPIEnabled(db.DefaultContext) {
+ group.Add(&auth.SSPI{}) // it MUST be the last, see the comment of SSPI
+ }
+
+ return group
+}
+
+func apiAuth(authMethod auth.Method) func(*context.APIContext) {
+ return func(ctx *context.APIContext) {
+ ar, err := common.AuthShared(ctx.Base, nil, authMethod)
+ if err != nil {
+ ctx.Error(http.StatusUnauthorized, "APIAuth", err)
+ return
+ }
+ ctx.Doer = ar.Doer
+ ctx.IsSigned = ar.Doer != nil
+ ctx.IsBasicAuth = ar.IsBasicAuth
+ }
+}
+
+// verifyAuthWithOptions checks authentication according to options
+func verifyAuthWithOptions(options *common.VerifyOptions) func(ctx *context.APIContext) {
+ return func(ctx *context.APIContext) {
+ // Check prohibit login users.
+ if ctx.IsSigned {
+ if !ctx.Doer.IsActive && setting.Service.RegisterEmailConfirm {
+ ctx.Data["Title"] = ctx.Tr("auth.active_your_account")
+ ctx.JSON(http.StatusForbidden, map[string]string{
+ "message": "This account is not activated.",
+ })
+ return
+ }
+ if !ctx.Doer.IsActive || ctx.Doer.ProhibitLogin {
+ log.Info("Failed authentication attempt for %s from %s", ctx.Doer.Name, ctx.RemoteAddr())
+ ctx.Data["Title"] = ctx.Tr("auth.prohibit_login")
+ ctx.JSON(http.StatusForbidden, map[string]string{
+ "message": "This account is prohibited from signing in, please contact your site administrator.",
+ })
+ return
+ }
+
+ if ctx.Doer.MustChangePassword {
+ ctx.JSON(http.StatusForbidden, map[string]string{
+ "message": "You must change your password. Change it at: " + setting.AppURL + "/user/change_password",
+ })
+ return
+ }
+ }
+
+ // Redirect to dashboard if user tries to visit any non-login page.
+ if options.SignOutRequired && ctx.IsSigned && ctx.Req.URL.RequestURI() != "/" {
+ ctx.Redirect(setting.AppSubURL + "/")
+ return
+ }
+
+ if options.SignInRequired {
+ if !ctx.IsSigned {
+ // Restrict API calls with error message.
+ ctx.JSON(http.StatusForbidden, map[string]string{
+ "message": "Only signed in user is allowed to call APIs.",
+ })
+ return
+ } else if !ctx.Doer.IsActive && setting.Service.RegisterEmailConfirm {
+ ctx.Data["Title"] = ctx.Tr("auth.active_your_account")
+ ctx.JSON(http.StatusForbidden, map[string]string{
+ "message": "This account is not activated.",
+ })
+ return
+ }
+ }
+
+ if options.AdminRequired {
+ if !ctx.Doer.IsAdmin {
+ ctx.JSON(http.StatusForbidden, map[string]string{
+ "message": "You have no permission to request for this.",
+ })
+ return
+ }
+ }
+ }
+}
+
+// check for and warn against deprecated authentication options
+func checkDeprecatedAuthMethods(ctx *context.APIContext) {
+ if ctx.FormString("token") != "" || ctx.FormString("access_token") != "" {
+ ctx.Resp.Header().Set("Warning", "token and access_token API authentication is deprecated and will be removed in gitea 1.23. Please use AuthorizationHeaderToken instead. Existing queries will continue to work but without authorization.")
+ }
+}
+
+func securityHeaders() func(http.Handler) http.Handler {
+ return func(next http.Handler) http.Handler {
+ return http.HandlerFunc(func(resp http.ResponseWriter, req *http.Request) {
+ // CORB: https://www.chromium.org/Home/chromium-security/corb-for-developers
+ // http://stackoverflow.com/a/3146618/244009
+ resp.Header().Set("x-content-type-options", "nosniff")
+ next.ServeHTTP(resp, req)
+ })
+ }
+}
diff --git a/routers/api/v1/admin/user.go b/routers/api/v1/admin/user.go
index 64315108b0..87a5b28fad 100644
--- a/routers/api/v1/admin/user.go
+++ b/routers/api/v1/admin/user.go
@@ -133,7 +133,7 @@ func CreateUser(ctx *context.APIContext) {
u.UpdatedUnix = u.CreatedUnix
}
- if err := user_model.CreateUser(ctx, u, overwriteDefault); err != nil {
+ if err := user_model.AdminCreateUser(ctx, u, overwriteDefault); err != nil {
if user_model.IsErrUserAlreadyExist(err) ||
user_model.IsErrEmailAlreadyUsed(err) ||
db.IsErrNameReserved(err) ||
@@ -147,6 +147,11 @@ func CreateUser(ctx *context.APIContext) {
}
return
}
+
+ if !user_model.IsEmailDomainAllowed(u.Email) {
+ ctx.Resp.Header().Add("X-Gitea-Warning", fmt.Sprintf("the domain of user email %s conflicts with EMAIL_DOMAIN_ALLOWLIST or EMAIL_DOMAIN_BLOCKLIST", u.Email))
+ }
+
log.Trace("Account created by admin (%s): %s", ctx.Doer.Name, u.Name)
// Send email notification.
@@ -209,7 +214,7 @@ func EditUser(ctx *context.APIContext) {
}
if form.Email != nil {
- if err := user_service.AddOrSetPrimaryEmailAddress(ctx, ctx.ContextUser, *form.Email); err != nil {
+ if err := user_service.AdminAddOrSetPrimaryEmailAddress(ctx, ctx.ContextUser, *form.Email); err != nil {
switch {
case user_model.IsErrEmailCharIsNotSupported(err), user_model.IsErrEmailInvalid(err):
ctx.Error(http.StatusBadRequest, "EmailInvalid", err)
@@ -220,6 +225,10 @@ func EditUser(ctx *context.APIContext) {
}
return
}
+
+ if !user_model.IsEmailDomainAllowed(*form.Email) {
+ ctx.Resp.Header().Add("X-Gitea-Warning", fmt.Sprintf("the domain of user email %s conflicts with EMAIL_DOMAIN_ALLOWLIST or EMAIL_DOMAIN_BLOCKLIST", *form.Email))
+ }
}
opts := &user_service.UpdateOptions{
diff --git a/routers/api/v1/api.go b/routers/api/v1/api.go
index c296cac799..b202e32e4e 100644
--- a/routers/api/v1/api.go
+++ b/routers/api/v1/api.go
@@ -72,7 +72,6 @@ import (
actions_model "code.gitea.io/gitea/models/actions"
auth_model "code.gitea.io/gitea/models/auth"
- "code.gitea.io/gitea/models/db"
issues_model "code.gitea.io/gitea/models/issues"
"code.gitea.io/gitea/models/organization"
"code.gitea.io/gitea/models/perm"
@@ -84,6 +83,7 @@ import (
"code.gitea.io/gitea/modules/setting"
api "code.gitea.io/gitea/modules/structs"
"code.gitea.io/gitea/modules/web"
+ "code.gitea.io/gitea/routers/api/shared"
"code.gitea.io/gitea/routers/api/v1/activitypub"
"code.gitea.io/gitea/routers/api/v1/admin"
"code.gitea.io/gitea/routers/api/v1/misc"
@@ -93,7 +93,6 @@ import (
"code.gitea.io/gitea/routers/api/v1/repo"
"code.gitea.io/gitea/routers/api/v1/settings"
"code.gitea.io/gitea/routers/api/v1/user"
- "code.gitea.io/gitea/routers/common"
"code.gitea.io/gitea/services/auth"
"code.gitea.io/gitea/services/context"
"code.gitea.io/gitea/services/forms"
@@ -101,7 +100,6 @@ import (
_ "code.gitea.io/gitea/routers/api/v1/swagger" // for swagger generation
"gitea.com/go-chi/binding"
- "github.com/go-chi/cors"
)
func sudo() func(ctx *context.APIContext) {
@@ -731,98 +729,6 @@ func bind[T any](_ T) any {
}
}
-func buildAuthGroup() *auth.Group {
- group := auth.NewGroup(
- &auth.OAuth2{},
- &auth.HTTPSign{},
- &auth.Basic{}, // FIXME: this should be removed once we don't allow basic auth in API
- )
- if setting.Service.EnableReverseProxyAuthAPI {
- group.Add(&auth.ReverseProxy{})
- }
-
- if setting.IsWindows && auth_model.IsSSPIEnabled(db.DefaultContext) {
- group.Add(&auth.SSPI{}) // it MUST be the last, see the comment of SSPI
- }
-
- return group
-}
-
-func apiAuth(authMethod auth.Method) func(*context.APIContext) {
- return func(ctx *context.APIContext) {
- ar, err := common.AuthShared(ctx.Base, nil, authMethod)
- if err != nil {
- ctx.Error(http.StatusUnauthorized, "APIAuth", err)
- return
- }
- ctx.Doer = ar.Doer
- ctx.IsSigned = ar.Doer != nil
- ctx.IsBasicAuth = ar.IsBasicAuth
- }
-}
-
-// verifyAuthWithOptions checks authentication according to options
-func verifyAuthWithOptions(options *common.VerifyOptions) func(ctx *context.APIContext) {
- return func(ctx *context.APIContext) {
- // Check prohibit login users.
- if ctx.IsSigned {
- if !ctx.Doer.IsActive && setting.Service.RegisterEmailConfirm {
- ctx.Data["Title"] = ctx.Tr("auth.active_your_account")
- ctx.JSON(http.StatusForbidden, map[string]string{
- "message": "This account is not activated.",
- })
- return
- }
- if !ctx.Doer.IsActive || ctx.Doer.ProhibitLogin {
- log.Info("Failed authentication attempt for %s from %s", ctx.Doer.Name, ctx.RemoteAddr())
- ctx.Data["Title"] = ctx.Tr("auth.prohibit_login")
- ctx.JSON(http.StatusForbidden, map[string]string{
- "message": "This account is prohibited from signing in, please contact your site administrator.",
- })
- return
- }
-
- if ctx.Doer.MustChangePassword {
- ctx.JSON(http.StatusForbidden, map[string]string{
- "message": "You must change your password. Change it at: " + setting.AppURL + "/user/change_password",
- })
- return
- }
- }
-
- // Redirect to dashboard if user tries to visit any non-login page.
- if options.SignOutRequired && ctx.IsSigned && ctx.Req.URL.RequestURI() != "/" {
- ctx.Redirect(setting.AppSubURL + "/")
- return
- }
-
- if options.SignInRequired {
- if !ctx.IsSigned {
- // Restrict API calls with error message.
- ctx.JSON(http.StatusForbidden, map[string]string{
- "message": "Only signed in user is allowed to call APIs.",
- })
- return
- } else if !ctx.Doer.IsActive && setting.Service.RegisterEmailConfirm {
- ctx.Data["Title"] = ctx.Tr("auth.active_your_account")
- ctx.JSON(http.StatusForbidden, map[string]string{
- "message": "This account is not activated.",
- })
- return
- }
- }
-
- if options.AdminRequired {
- if !ctx.Doer.IsAdmin {
- ctx.JSON(http.StatusForbidden, map[string]string{
- "message": "You have no permission to request for this.",
- })
- return
- }
- }
- }
-}
-
func individualPermsChecker(ctx *context.APIContext) {
// org permissions have been checked in context.OrgAssignment(), but individual permissions haven't been checked.
if ctx.ContextUser.IsIndividual() {
@@ -841,37 +747,11 @@ func individualPermsChecker(ctx *context.APIContext) {
}
}
-// check for and warn against deprecated authentication options
-func checkDeprecatedAuthMethods(ctx *context.APIContext) {
- if ctx.FormString("token") != "" || ctx.FormString("access_token") != "" {
- ctx.Resp.Header().Set("Warning", "token and access_token API authentication is deprecated and will be removed in gitea 1.23. Please use AuthorizationHeaderToken instead. Existing queries will continue to work but without authorization.")
- }
-}
-
// Routes registers all v1 APIs routes to web application.
func Routes() *web.Route {
m := web.NewRoute()
- m.Use(securityHeaders())
- if setting.CORSConfig.Enabled {
- m.Use(cors.Handler(cors.Options{
- AllowedOrigins: setting.CORSConfig.AllowDomain,
- AllowedMethods: setting.CORSConfig.Methods,
- AllowCredentials: setting.CORSConfig.AllowCredentials,
- AllowedHeaders: append([]string{"Authorization", "X-Gitea-OTP", "X-Forgejo-OTP"}, setting.CORSConfig.Headers...),
- MaxAge: int(setting.CORSConfig.MaxAge.Seconds()),
- }))
- }
- m.Use(context.APIContexter())
-
- m.Use(checkDeprecatedAuthMethods)
-
- // Get user from session if logged in.
- m.Use(apiAuth(buildAuthGroup()))
-
- m.Use(verifyAuthWithOptions(&common.VerifyOptions{
- SignInRequired: setting.Service.RequireSignInView,
- }))
+ m.Use(shared.Middlewares()...)
m.Group("", func() {
// Miscellaneous (no scope required)
@@ -1627,14 +1507,3 @@ func Routes() *web.Route {
return m
}
-
-func securityHeaders() func(http.Handler) http.Handler {
- return func(next http.Handler) http.Handler {
- return http.HandlerFunc(func(resp http.ResponseWriter, req *http.Request) {
- // CORB: https://www.chromium.org/Home/chromium-security/corb-for-developers
- // http://stackoverflow.com/a/3146618/244009
- resp.Header().Set("x-content-type-options", "nosniff")
- next.ServeHTTP(resp, req)
- })
- }
-}
diff --git a/routers/api/v1/misc/markup_test.go b/routers/api/v1/misc/markup_test.go
index f499501c2f..5236fd06ae 100644
--- a/routers/api/v1/misc/markup_test.go
+++ b/routers/api/v1/misc/markup_test.go
@@ -20,9 +20,9 @@ import (
)
const (
- AppURL = "http://localhost:3000/"
- Repo = "gogits/gogs"
- AppSubURL = AppURL + Repo + "/"
+ AppURL = "http://localhost:3000/"
+ Repo = "gogits/gogs"
+ FullURL = AppURL + Repo + "/"
)
func testRenderMarkup(t *testing.T, mode, filePath, text, responseBody string, responseCode int) {
@@ -74,20 +74,20 @@ func TestAPI_RenderGFM(t *testing.T) {
// rendered
`Wiki! Enjoy :)
-- Links, Language bindings, Engine bindings
-- Tips
+- Links, Language bindings, Engine bindings
+- Tips
- Bezier widget (by @r-lyeh) https://github.com/ocornut/imgui/issues/786
`,
// Guard wiki sidebar: special syntax
`[[Guardfile-DSL / Configuring-Guard|Guardfile-DSL---Configuring-Guard]]`,
// rendered
- `Guardfile-DSL / Configuring-Guard
+ `Guardfile-DSL / Configuring-Guard
`,
// special syntax
`[[Name|Link]]`,
// rendered
- `
+ `
`,
// empty
``,
@@ -111,8 +111,8 @@ Here are some links to the most important topics. You can find the full list of
Wine Staging on website wine-staging.com.
Quick Links
Here are some links to the most important topics. You can find the full list of pages at the sidebar.
-
+
`,
}
diff --git a/routers/api/v1/repo/issue.go b/routers/api/v1/repo/issue.go
index af3f890f88..843da55139 100644
--- a/routers/api/v1/repo/issue.go
+++ b/routers/api/v1/repo/issue.go
@@ -269,28 +269,28 @@ func SearchIssues(ctx *context.APIContext) {
}
if since != 0 {
- searchOpt.UpdatedAfterUnix = &since
+ searchOpt.UpdatedAfterUnix = optional.Some(since)
}
if before != 0 {
- searchOpt.UpdatedBeforeUnix = &before
+ searchOpt.UpdatedBeforeUnix = optional.Some(before)
}
if ctx.IsSigned {
ctxUserID := ctx.Doer.ID
if ctx.FormBool("created") {
- searchOpt.PosterID = &ctxUserID
+ searchOpt.PosterID = optional.Some(ctxUserID)
}
if ctx.FormBool("assigned") {
- searchOpt.AssigneeID = &ctxUserID
+ searchOpt.AssigneeID = optional.Some(ctxUserID)
}
if ctx.FormBool("mentioned") {
- searchOpt.MentionID = &ctxUserID
+ searchOpt.MentionID = optional.Some(ctxUserID)
}
if ctx.FormBool("review_requested") {
- searchOpt.ReviewRequestedID = &ctxUserID
+ searchOpt.ReviewRequestedID = optional.Some(ctxUserID)
}
if ctx.FormBool("reviewed") {
- searchOpt.ReviewedID = &ctxUserID
+ searchOpt.ReviewedID = optional.Some(ctxUserID)
}
}
@@ -368,7 +368,7 @@ func ListIssues(ctx *context.APIContext) {
// required: false
// - name: created_by
// in: query
- // description: Only show items which were created by the the given user
+ // description: Only show items which were created by the given user
// type: string
// - name: assigned_by
// in: query
@@ -502,10 +502,10 @@ func ListIssues(ctx *context.APIContext) {
SortBy: issue_indexer.SortByCreatedDesc,
}
if since != 0 {
- searchOpt.UpdatedAfterUnix = &since
+ searchOpt.UpdatedAfterUnix = optional.Some(since)
}
if before != 0 {
- searchOpt.UpdatedBeforeUnix = &before
+ searchOpt.UpdatedBeforeUnix = optional.Some(before)
}
if len(labelIDs) == 1 && labelIDs[0] == 0 {
searchOpt.NoLabelOnly = true
@@ -526,13 +526,13 @@ func ListIssues(ctx *context.APIContext) {
}
if createdByID > 0 {
- searchOpt.PosterID = &createdByID
+ searchOpt.PosterID = optional.Some(createdByID)
}
if assignedByID > 0 {
- searchOpt.AssigneeID = &assignedByID
+ searchOpt.AssigneeID = optional.Some(assignedByID)
}
if mentionedByID > 0 {
- searchOpt.MentionID = &mentionedByID
+ searchOpt.MentionID = optional.Some(mentionedByID)
}
ids, total, err := issue_indexer.SearchIssues(ctx, searchOpt)
diff --git a/routers/api/v1/repo/pull.go b/routers/api/v1/repo/pull.go
index f78e34d7b3..c2d86541b6 100644
--- a/routers/api/v1/repo/pull.go
+++ b/routers/api/v1/repo/pull.go
@@ -1065,6 +1065,8 @@ func parseCompareInfo(ctx *context.APIContext, form api.CreatePullRequestOption)
return nil, nil, nil, nil, "", ""
}
headBranch = headInfos[1]
+ // The head repository can also point to the same repo
+ isSameRepo = ctx.Repo.Owner.ID == headUser.ID
} else {
ctx.NotFound()
diff --git a/routers/api/v1/repo/pull_review.go b/routers/api/v1/repo/pull_review.go
index 6860d6e773..9ccbb57c52 100644
--- a/routers/api/v1/repo/pull_review.go
+++ b/routers/api/v1/repo/pull_review.go
@@ -692,7 +692,7 @@ func prepareSingleReview(ctx *context.APIContext) (*issues_model.Review, *issues
return nil, nil, true
}
- // validate the the review is for the given PR
+ // validate the review is for the given PR
if review.IssueID != pr.IssueID {
ctx.NotFound("ReviewNotInPR")
return nil, nil, true
diff --git a/routers/api/v1/repo/repo.go b/routers/api/v1/repo/repo.go
index 40960144c7..316a1161da 100644
--- a/routers/api/v1/repo/repo.go
+++ b/routers/api/v1/repo/repo.go
@@ -720,7 +720,7 @@ func updateBasicProperties(ctx *context.APIContext, opts api.EditRepoOption) err
if ctx.Repo.GitRepo == nil && !repo.IsEmpty {
var err error
- ctx.Repo.GitRepo, err = gitrepo.OpenRepository(ctx, ctx.Repo.Repository)
+ ctx.Repo.GitRepo, err = gitrepo.OpenRepository(ctx, repo)
if err != nil {
ctx.Error(http.StatusInternalServerError, "Unable to OpenRepository", err)
return err
@@ -731,7 +731,7 @@ func updateBasicProperties(ctx *context.APIContext, opts api.EditRepoOption) err
// Default branch only updated if changed and exist or the repository is empty
if opts.DefaultBranch != nil && repo.DefaultBranch != *opts.DefaultBranch && (repo.IsEmpty || ctx.Repo.GitRepo.IsBranchExist(*opts.DefaultBranch)) {
if !repo.IsEmpty {
- if err := ctx.Repo.GitRepo.SetDefaultBranch(*opts.DefaultBranch); err != nil {
+ if err := gitrepo.SetDefaultBranch(ctx, ctx.Repo.Repository, *opts.DefaultBranch); err != nil {
if !git.IsErrUnsupportedVersion(err) {
ctx.Error(http.StatusInternalServerError, "SetDefaultBranch", err)
return err
diff --git a/routers/api/v1/repo/status.go b/routers/api/v1/repo/status.go
index 53711bedeb..9e36ea0aed 100644
--- a/routers/api/v1/repo/status.go
+++ b/routers/api/v1/repo/status.go
@@ -14,7 +14,7 @@ import (
"code.gitea.io/gitea/routers/api/v1/utils"
"code.gitea.io/gitea/services/context"
"code.gitea.io/gitea/services/convert"
- files_service "code.gitea.io/gitea/services/repository/files"
+ commitstatus_service "code.gitea.io/gitea/services/repository/commitstatus"
)
// NewCommitStatus creates a new CommitStatus
@@ -64,7 +64,7 @@ func NewCommitStatus(ctx *context.APIContext) {
Description: form.Description,
Context: form.Context,
}
- if err := files_service.CreateCommitStatus(ctx, ctx.Repo.Repository, ctx.Doer, sha, status); err != nil {
+ if err := commitstatus_service.CreateCommitStatus(ctx, ctx.Repo.Repository, ctx.Doer, sha, status); err != nil {
ctx.Error(http.StatusInternalServerError, "CreateCommitStatus", err)
return
}
diff --git a/routers/api/v1/user/key.go b/routers/api/v1/user/key.go
index ada6759f8e..bcbfd93bd3 100644
--- a/routers/api/v1/user/key.go
+++ b/routers/api/v1/user/key.go
@@ -5,6 +5,7 @@ package user
import (
std_ctx "context"
+ "fmt"
"net/http"
asymkey_model "code.gitea.io/gitea/models/asymkey"
@@ -198,6 +199,11 @@ func GetPublicKey(ctx *context.APIContext) {
// CreateUserPublicKey creates new public key to given user by ID.
func CreateUserPublicKey(ctx *context.APIContext, form api.CreateKeyOption, uid int64) {
+ if setting.Admin.UserDisabledFeatures.Contains(setting.UserFeatureManageSSHKeys) {
+ ctx.NotFound("Not Found", fmt.Errorf("ssh keys setting is not allowed to be visited"))
+ return
+ }
+
content, err := asymkey_model.CheckPublicKeyString(form.Key)
if err != nil {
repo.HandleCheckKeyStringError(ctx, err)
@@ -263,6 +269,11 @@ func DeletePublicKey(ctx *context.APIContext) {
// "404":
// "$ref": "#/responses/notFound"
+ if setting.Admin.UserDisabledFeatures.Contains(setting.UserFeatureManageSSHKeys) {
+ ctx.NotFound("Not Found", fmt.Errorf("ssh keys setting is not allowed to be visited"))
+ return
+ }
+
id := ctx.ParamsInt64(":id")
externallyManaged, err := asymkey_model.PublicKeyIsExternallyManaged(ctx, id)
if err != nil {
diff --git a/routers/common/markup.go b/routers/common/markup.go
index 7819ee7227..2d5638ef61 100644
--- a/routers/common/markup.go
+++ b/routers/common/markup.go
@@ -34,7 +34,8 @@ func RenderMarkup(ctx *context.Base, repo *context.Repository, mode, text, urlPr
if err := markdown.RenderRaw(&markup.RenderContext{
Ctx: ctx,
Links: markup.Links{
- Base: urlPrefix,
+ AbsolutePrefix: true,
+ Base: urlPrefix,
},
}, strings.NewReader(text), ctx.Resp); err != nil {
ctx.Error(http.StatusInternalServerError, err.Error())
@@ -79,7 +80,8 @@ func RenderMarkup(ctx *context.Base, repo *context.Repository, mode, text, urlPr
if err := markup.Render(&markup.RenderContext{
Ctx: ctx,
Links: markup.Links{
- Base: urlPrefix,
+ AbsolutePrefix: true,
+ Base: urlPrefix,
},
Metas: meta,
IsWiki: wiki,
diff --git a/routers/private/default_branch.go b/routers/private/default_branch.go
index 2e323129ef..33890be6a9 100644
--- a/routers/private/default_branch.go
+++ b/routers/private/default_branch.go
@@ -9,6 +9,7 @@ import (
repo_model "code.gitea.io/gitea/models/repo"
"code.gitea.io/gitea/modules/git"
+ "code.gitea.io/gitea/modules/gitrepo"
"code.gitea.io/gitea/modules/private"
gitea_context "code.gitea.io/gitea/services/context"
)
@@ -20,7 +21,7 @@ func SetDefaultBranch(ctx *gitea_context.PrivateContext) {
branch := ctx.Params(":branch")
ctx.Repo.Repository.DefaultBranch = branch
- if err := ctx.Repo.GitRepo.SetDefaultBranch(ctx.Repo.Repository.DefaultBranch); err != nil {
+ if err := gitrepo.SetDefaultBranch(ctx, ctx.Repo.Repository, ctx.Repo.Repository.DefaultBranch); err != nil {
if !git.IsErrUnsupportedVersion(err) {
ctx.JSON(http.StatusInternalServerError, private.Response{
Err: fmt.Sprintf("Unable to set default branch on repository: %s/%s Error: %v", ownerName, repoName, err),
diff --git a/routers/private/hook_post_receive.go b/routers/private/hook_post_receive.go
index f4c698d3ea..f5527cb15b 100644
--- a/routers/private/hook_post_receive.go
+++ b/routers/private/hook_post_receive.go
@@ -8,9 +8,11 @@ import (
"net/http"
"strconv"
+ git_model "code.gitea.io/gitea/models/git"
issues_model "code.gitea.io/gitea/models/issues"
repo_model "code.gitea.io/gitea/models/repo"
"code.gitea.io/gitea/modules/git"
+ "code.gitea.io/gitea/modules/gitrepo"
"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/private"
repo_module "code.gitea.io/gitea/modules/repository"
@@ -27,6 +29,7 @@ func HookPostReceive(ctx *gitea_context.PrivateContext) {
// We don't rely on RepoAssignment here because:
// a) we don't need the git repo in this function
+ // OUT OF DATE: we do need the git repo to sync the branch to the db now.
// b) our update function will likely change the repository in the db so we will need to refresh it
// c) we don't always need the repo
@@ -34,7 +37,11 @@ func HookPostReceive(ctx *gitea_context.PrivateContext) {
repoName := ctx.Params(":repo")
// defer getting the repository at this point - as we should only retrieve it if we're going to call update
- var repo *repo_model.Repository
+ var (
+ repo *repo_model.Repository
+ gitRepo *git.Repository
+ )
+ defer gitRepo.Close() // it's safe to call Close on a nil pointer
updates := make([]*repo_module.PushUpdateOptions, 0, len(opts.OldCommitIDs))
wasEmpty := false
@@ -75,6 +82,61 @@ func HookPostReceive(ctx *gitea_context.PrivateContext) {
}
if repo != nil && len(updates) > 0 {
+ branchesToSync := make([]*repo_module.PushUpdateOptions, 0, len(updates))
+ for _, update := range updates {
+ if !update.RefFullName.IsBranch() {
+ continue
+ }
+ if repo == nil {
+ repo = loadRepository(ctx, ownerName, repoName)
+ if ctx.Written() {
+ return
+ }
+ wasEmpty = repo.IsEmpty
+ }
+
+ if update.IsDelRef() {
+ if err := git_model.AddDeletedBranch(ctx, repo.ID, update.RefFullName.BranchName(), update.PusherID); err != nil {
+ log.Error("Failed to add deleted branch: %s/%s Error: %v", ownerName, repoName, err)
+ ctx.JSON(http.StatusInternalServerError, private.HookPostReceiveResult{
+ Err: fmt.Sprintf("Failed to add deleted branch: %s/%s Error: %v", ownerName, repoName, err),
+ })
+ return
+ }
+ } else {
+ branchesToSync = append(branchesToSync, update)
+ }
+ }
+ if len(branchesToSync) > 0 {
+ if gitRepo == nil {
+ var err error
+ gitRepo, err = gitrepo.OpenRepository(ctx, repo)
+ if err != nil {
+ log.Error("Failed to open repository: %s/%s Error: %v", ownerName, repoName, err)
+ ctx.JSON(http.StatusInternalServerError, private.HookPostReceiveResult{
+ Err: fmt.Sprintf("Failed to open repository: %s/%s Error: %v", ownerName, repoName, err),
+ })
+ return
+ }
+ }
+
+ var (
+ branchNames = make([]string, 0, len(branchesToSync))
+ commitIDs = make([]string, 0, len(branchesToSync))
+ )
+ for _, update := range branchesToSync {
+ branchNames = append(branchNames, update.RefFullName.BranchName())
+ commitIDs = append(commitIDs, update.NewCommitID)
+ }
+
+ if err := repo_service.SyncBranchesToDB(ctx, repo.ID, opts.UserID, branchNames, commitIDs, gitRepo.GetCommit); err != nil {
+ ctx.JSON(http.StatusInternalServerError, private.HookPostReceiveResult{
+ Err: fmt.Sprintf("Failed to sync branch to DB in repository: %s/%s Error: %v", ownerName, repoName, err),
+ })
+ return
+ }
+ }
+
if err := repo_service.PushUpdates(updates); err != nil {
log.Error("Failed to Update: %s/%s Total Updates: %d", ownerName, repoName, len(updates))
for i, update := range updates {
diff --git a/routers/web/admin/admin_test.go b/routers/web/admin/admin_test.go
index c73780d60f..3518869ede 100644
--- a/routers/web/admin/admin_test.go
+++ b/routers/web/admin/admin_test.go
@@ -11,6 +11,7 @@ import (
"code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/modules/test"
"code.gitea.io/gitea/services/contexttest"
+
"github.com/stretchr/testify/assert"
)
diff --git a/routers/web/admin/config.go b/routers/web/admin/config.go
index d9b1973332..2f5f17e201 100644
--- a/routers/web/admin/config.go
+++ b/routers/web/admin/config.go
@@ -7,11 +7,11 @@ package admin
import (
"net/http"
"net/url"
+ "strconv"
"strings"
system_model "code.gitea.io/gitea/models/system"
"code.gitea.io/gitea/modules/base"
- "code.gitea.io/gitea/modules/container"
"code.gitea.io/gitea/modules/git"
"code.gitea.io/gitea/modules/json"
"code.gitea.io/gitea/modules/log"
@@ -24,7 +24,10 @@ import (
"gitea.com/go-chi/session"
)
-const tplConfig base.TplName = "admin/config"
+const (
+ tplConfig base.TplName = "admin/config"
+ tplConfigSettings base.TplName = "admin/config_settings"
+)
// SendTestMail send test mail to confirm mail service is OK
func SendTestMail(ctx *context.Context) {
@@ -98,8 +101,9 @@ func shadowPassword(provider, cfgItem string) string {
// Config show admin config page
func Config(ctx *context.Context) {
- ctx.Data["Title"] = ctx.Tr("admin.config")
+ ctx.Data["Title"] = ctx.Tr("admin.config_summary")
ctx.Data["PageIsAdminConfig"] = true
+ ctx.Data["PageIsAdminConfigSummary"] = true
ctx.Data["CustomConf"] = setting.CustomConf
ctx.Data["AppUrl"] = setting.AppURL
@@ -161,23 +165,70 @@ func Config(ctx *context.Context) {
ctx.Data["Loggers"] = log.GetManager().DumpLoggers()
config.GetDynGetter().InvalidateCache()
- ctx.Data["SystemConfig"] = setting.Config()
prepareDeprecatedWarningsAlert(ctx)
ctx.HTML(http.StatusOK, tplConfig)
}
+func ConfigSettings(ctx *context.Context) {
+ ctx.Data["Title"] = ctx.Tr("admin.config_settings")
+ ctx.Data["PageIsAdminConfig"] = true
+ ctx.Data["PageIsAdminConfigSettings"] = true
+ ctx.Data["DefaultOpenWithEditorAppsString"] = setting.DefaultOpenWithEditorApps().ToTextareaString()
+ ctx.HTML(http.StatusOK, tplConfigSettings)
+}
+
func ChangeConfig(ctx *context.Context) {
key := strings.TrimSpace(ctx.FormString("key"))
value := ctx.FormString("value")
cfg := setting.Config()
- allowedKeys := container.SetOf(cfg.Picture.DisableGravatar.DynKey(), cfg.Picture.EnableFederatedAvatar.DynKey())
- if !allowedKeys.Contains(key) {
+
+ marshalBool := func(v string) (string, error) {
+ if b, _ := strconv.ParseBool(v); b {
+ return "true", nil
+ }
+ return "false", nil
+ }
+ marshalOpenWithApps := func(value string) (string, error) {
+ lines := strings.Split(value, "\n")
+ var openWithEditorApps setting.OpenWithEditorAppsType
+ for _, line := range lines {
+ line = strings.TrimSpace(line)
+ if line == "" {
+ continue
+ }
+ displayName, openURL, ok := strings.Cut(line, "=")
+ displayName, openURL = strings.TrimSpace(displayName), strings.TrimSpace(openURL)
+ if !ok || displayName == "" || openURL == "" {
+ continue
+ }
+ openWithEditorApps = append(openWithEditorApps, setting.OpenWithEditorApp{
+ DisplayName: strings.TrimSpace(displayName),
+ OpenURL: strings.TrimSpace(openURL),
+ })
+ }
+ b, err := json.Marshal(openWithEditorApps)
+ if err != nil {
+ return "", err
+ }
+ return string(b), nil
+ }
+ marshallers := map[string]func(string) (string, error){
+ cfg.Picture.DisableGravatar.DynKey(): marshalBool,
+ cfg.Picture.EnableFederatedAvatar.DynKey(): marshalBool,
+ cfg.Repository.OpenWithEditorApps.DynKey(): marshalOpenWithApps,
+ }
+ marshaller, hasMarshaller := marshallers[key]
+ if !hasMarshaller {
ctx.JSONError(ctx.Tr("admin.config.set_setting_failed", key))
return
}
- if err := system_model.SetSettings(ctx, map[string]string{key: value}); err != nil {
- log.Error("set setting failed: %v", err)
+ marshaledValue, err := marshaller(value)
+ if err != nil {
+ ctx.JSONError(ctx.Tr("admin.config.set_setting_failed", key))
+ return
+ }
+ if err = system_model.SetSettings(ctx, map[string]string{key: marshaledValue}); err != nil {
ctx.JSONError(ctx.Tr("admin.config.set_setting_failed", key))
return
}
diff --git a/routers/web/admin/users.go b/routers/web/admin/users.go
index a34e0d0f0d..6dfcfc3d9a 100644
--- a/routers/web/admin/users.go
+++ b/routers/web/admin/users.go
@@ -177,7 +177,7 @@ func NewUserPost(ctx *context.Context) {
u.MustChangePassword = form.MustChangePassword
}
- if err := user_model.CreateUser(ctx, u, overwriteDefault); err != nil {
+ if err := user_model.AdminCreateUser(ctx, u, overwriteDefault); err != nil {
switch {
case user_model.IsErrUserAlreadyExist(err):
ctx.Data["Err_UserName"] = true
@@ -202,6 +202,11 @@ func NewUserPost(ctx *context.Context) {
}
return
}
+
+ if !user_model.IsEmailDomainAllowed(u.Email) {
+ ctx.Flash.Warning(ctx.Tr("form.email_domain_is_not_allowed", u.Email))
+ }
+
log.Trace("Account created by admin (%s): %s", ctx.Doer.Name, u.Name)
// Send email notification.
@@ -412,7 +417,7 @@ func EditUserPost(ctx *context.Context) {
}
if form.Email != "" {
- if err := user_service.AddOrSetPrimaryEmailAddress(ctx, u, form.Email); err != nil {
+ if err := user_service.AdminAddOrSetPrimaryEmailAddress(ctx, u, form.Email); err != nil {
switch {
case user_model.IsErrEmailCharIsNotSupported(err), user_model.IsErrEmailInvalid(err):
ctx.Data["Err_Email"] = true
@@ -425,6 +430,9 @@ func EditUserPost(ctx *context.Context) {
}
return
}
+ if !user_model.IsEmailDomainAllowed(form.Email) {
+ ctx.Flash.Warning(ctx.Tr("form.email_domain_is_not_allowed", form.Email))
+ }
}
opts := &user_service.UpdateOptions{
diff --git a/routers/web/auth/auth.go b/routers/web/auth/auth.go
index 09469385d0..2a8f5c05d7 100644
--- a/routers/web/auth/auth.go
+++ b/routers/web/auth/auth.go
@@ -135,9 +135,21 @@ func resetLocale(ctx *context.Context, u *user_model.User) error {
return nil
}
+func RedirectAfterLogin(ctx *context.Context) {
+ redirectTo := ctx.FormString("redirect_to")
+ if redirectTo == "" {
+ redirectTo = ctx.GetSiteCookie("redirect_to")
+ }
+ middleware.DeleteRedirectToCookie(ctx.Resp)
+ nextRedirectTo := setting.AppSubURL + string(setting.LandingPageURL)
+ if setting.LandingPageURL == setting.LandingPageLogin {
+ nextRedirectTo = setting.AppSubURL + "/" // do not cycle-redirect to the login page
+ }
+ ctx.RedirectToFirst(redirectTo, nextRedirectTo)
+}
+
func CheckAutoLogin(ctx *context.Context) bool {
- // Check auto-login
- isSucceed, err := autoSignIn(ctx)
+ isSucceed, err := autoSignIn(ctx) // try to auto-login
if err != nil {
ctx.ServerError("autoSignIn", err)
return true
@@ -146,17 +158,10 @@ func CheckAutoLogin(ctx *context.Context) bool {
redirectTo := ctx.FormString("redirect_to")
if len(redirectTo) > 0 {
middleware.SetRedirectToCookie(ctx.Resp, redirectTo)
- } else {
- redirectTo = ctx.GetSiteCookie("redirect_to")
}
if isSucceed {
- middleware.DeleteRedirectToCookie(ctx.Resp)
- nextRedirectTo := setting.AppSubURL + string(setting.LandingPageURL)
- if setting.LandingPageURL == setting.LandingPageLogin {
- nextRedirectTo = setting.AppSubURL + "/" // do not cycle-redirect to the login page
- }
- ctx.RedirectToFirst(redirectTo, nextRedirectTo)
+ RedirectAfterLogin(ctx)
return true
}
@@ -171,6 +176,11 @@ func SignIn(ctx *context.Context) {
return
}
+ if ctx.IsSigned {
+ RedirectAfterLogin(ctx)
+ return
+ }
+
oauth2Providers, err := oauth2.GetOAuth2Providers(ctx, optional.Some(true))
if err != nil {
ctx.ServerError("UserSignIn", err)
diff --git a/routers/web/auth/auth_test.go b/routers/web/auth/auth_test.go
new file mode 100644
index 0000000000..c6afbf877c
--- /dev/null
+++ b/routers/web/auth/auth_test.go
@@ -0,0 +1,43 @@
+// Copyright 2024 The Gitea Authors. All rights reserved.
+// SPDX-License-Identifier: MIT
+
+package auth
+
+import (
+ "net/http"
+ "net/url"
+ "testing"
+
+ "code.gitea.io/gitea/modules/test"
+ "code.gitea.io/gitea/services/contexttest"
+
+ "github.com/stretchr/testify/assert"
+)
+
+func TestUserLogin(t *testing.T) {
+ ctx, resp := contexttest.MockContext(t, "/user/login")
+ SignIn(ctx)
+ assert.Equal(t, http.StatusOK, resp.Code)
+
+ ctx, resp = contexttest.MockContext(t, "/user/login")
+ ctx.IsSigned = true
+ SignIn(ctx)
+ assert.Equal(t, http.StatusSeeOther, resp.Code)
+ assert.Equal(t, "/", test.RedirectURL(resp))
+
+ ctx, resp = contexttest.MockContext(t, "/user/login?redirect_to=/other")
+ ctx.IsSigned = true
+ SignIn(ctx)
+ assert.Equal(t, "/other", test.RedirectURL(resp))
+
+ ctx, resp = contexttest.MockContext(t, "/user/login")
+ ctx.Req.AddCookie(&http.Cookie{Name: "redirect_to", Value: "/other-cookie"})
+ ctx.IsSigned = true
+ SignIn(ctx)
+ assert.Equal(t, "/other-cookie", test.RedirectURL(resp))
+
+ ctx, resp = contexttest.MockContext(t, "/user/login?redirect_to="+url.QueryEscape("https://example.com"))
+ ctx.IsSigned = true
+ SignIn(ctx)
+ assert.Equal(t, "/", test.RedirectURL(resp))
+}
diff --git a/routers/web/explore/code.go b/routers/web/explore/code.go
index 2cde8b655e..75bd0f3d24 100644
--- a/routers/web/explore/code.go
+++ b/routers/web/explore/code.go
@@ -6,6 +6,7 @@ package explore
import (
"net/http"
+ "code.gitea.io/gitea/models/db"
repo_model "code.gitea.io/gitea/models/repo"
"code.gitea.io/gitea/modules/base"
code_indexer "code.gitea.io/gitea/modules/indexer/code"
@@ -35,7 +36,7 @@ func Code(ctx *context.Context) {
keyword := ctx.FormTrim("q")
queryType := ctx.FormTrim("t")
- isMatch := queryType == "match"
+ isFuzzy := queryType != "match"
ctx.Data["Keyword"] = keyword
ctx.Data["Language"] = language
@@ -77,7 +78,16 @@ func Code(ctx *context.Context) {
)
if (len(repoIDs) > 0) || isAdmin {
- total, searchResults, searchResultLanguages, err = code_indexer.PerformSearch(ctx, repoIDs, language, keyword, page, setting.UI.RepoSearchPagingNum, isMatch)
+ total, searchResults, searchResultLanguages, err = code_indexer.PerformSearch(ctx, &code_indexer.SearchOptions{
+ RepoIDs: repoIDs,
+ Keyword: keyword,
+ IsKeywordFuzzy: isFuzzy,
+ Language: language,
+ Paginator: &db.ListOptions{
+ Page: page,
+ PageSize: setting.UI.RepoSearchPagingNum,
+ },
+ })
if err != nil {
if code_indexer.IsAvailable(ctx) {
ctx.ServerError("SearchResults", err)
diff --git a/routers/web/repo/badges/badges.go b/routers/web/repo/badges/badges.go
index 7f4549d606..ed40e982a1 100644
--- a/routers/web/repo/badges/badges.go
+++ b/routers/web/repo/badges/badges.go
@@ -18,8 +18,8 @@ import (
func getBadgeURL(ctx *context_module.Context, label, text, color string) string {
sb := &strings.Builder{}
_ = setting.Badges.GeneratorURLTemplateTemplate.Execute(sb, map[string]string{
- "label": url.PathEscape(label),
- "text": url.PathEscape(text),
+ "label": url.PathEscape(strings.ReplaceAll(label, "-", "--")),
+ "text": url.PathEscape(strings.ReplaceAll(text, "-", "--")),
"color": url.PathEscape(color),
})
diff --git a/routers/web/repo/branch.go b/routers/web/repo/branch.go
index ae51f0596b..f879a98786 100644
--- a/routers/web/repo/branch.go
+++ b/routers/web/repo/branch.go
@@ -148,12 +148,7 @@ func RestoreBranchPost(ctx *context.Context) {
return
}
- objectFormat, err := git.GetObjectFormatOfRepo(ctx, ctx.Repo.Repository.RepoPath())
- if err != nil {
- log.Error("RestoreBranch: CreateBranch: %w", err)
- ctx.Flash.Error(ctx.Tr("repo.branch.restore_failed", deletedBranch.Name))
- return
- }
+ objectFormat := git.ObjectFormatFromName(ctx.Repo.Repository.ObjectFormatName)
// Don't return error below this
if err := repo_service.PushUpdate(
diff --git a/routers/web/repo/issue.go b/routers/web/repo/issue.go
index 2e2d12672e..e4193e9b79 100644
--- a/routers/web/repo/issue.go
+++ b/routers/web/repo/issue.go
@@ -2636,9 +2636,9 @@ func SearchIssues(ctx *context.Context) {
}
}
- var projectID *int64
+ projectID := optional.None[int64]()
if v := ctx.FormInt64("project"); v > 0 {
- projectID = &v
+ projectID = optional.Some(v)
}
// this api is also used in UI,
@@ -2667,28 +2667,28 @@ func SearchIssues(ctx *context.Context) {
}
if since != 0 {
- searchOpt.UpdatedAfterUnix = &since
+ searchOpt.UpdatedAfterUnix = optional.Some(since)
}
if before != 0 {
- searchOpt.UpdatedBeforeUnix = &before
+ searchOpt.UpdatedBeforeUnix = optional.Some(before)
}
if ctx.IsSigned {
ctxUserID := ctx.Doer.ID
if ctx.FormBool("created") {
- searchOpt.PosterID = &ctxUserID
+ searchOpt.PosterID = optional.Some(ctxUserID)
}
if ctx.FormBool("assigned") {
- searchOpt.AssigneeID = &ctxUserID
+ searchOpt.AssigneeID = optional.Some(ctxUserID)
}
if ctx.FormBool("mentioned") {
- searchOpt.MentionID = &ctxUserID
+ searchOpt.MentionID = optional.Some(ctxUserID)
}
if ctx.FormBool("review_requested") {
- searchOpt.ReviewRequestedID = &ctxUserID
+ searchOpt.ReviewRequestedID = optional.Some(ctxUserID)
}
if ctx.FormBool("reviewed") {
- searchOpt.ReviewedID = &ctxUserID
+ searchOpt.ReviewedID = optional.Some(ctxUserID)
}
}
@@ -2795,9 +2795,9 @@ func ListIssues(ctx *context.Context) {
}
}
- var projectID *int64
+ projectID := optional.None[int64]()
if v := ctx.FormInt64("project"); v > 0 {
- projectID = &v
+ projectID = optional.Some(v)
}
isPull := optional.None[bool]()
@@ -2835,10 +2835,10 @@ func ListIssues(ctx *context.Context) {
SortBy: issue_indexer.SortByCreatedDesc,
}
if since != 0 {
- searchOpt.UpdatedAfterUnix = &since
+ searchOpt.UpdatedAfterUnix = optional.Some(since)
}
if before != 0 {
- searchOpt.UpdatedBeforeUnix = &before
+ searchOpt.UpdatedBeforeUnix = optional.Some(before)
}
if len(labelIDs) == 1 && labelIDs[0] == 0 {
searchOpt.NoLabelOnly = true
@@ -2859,13 +2859,13 @@ func ListIssues(ctx *context.Context) {
}
if createdByID > 0 {
- searchOpt.PosterID = &createdByID
+ searchOpt.PosterID = optional.Some(createdByID)
}
if assignedByID > 0 {
- searchOpt.AssigneeID = &assignedByID
+ searchOpt.AssigneeID = optional.Some(assignedByID)
}
if mentionedByID > 0 {
- searchOpt.MentionID = &mentionedByID
+ searchOpt.MentionID = optional.Some(mentionedByID)
}
ids, total, err := issue_indexer.SearchIssues(ctx, searchOpt)
diff --git a/routers/web/repo/pull.go b/routers/web/repo/pull.go
index c93d342e62..8727f3d1e3 100644
--- a/routers/web/repo/pull.go
+++ b/routers/web/repo/pull.go
@@ -186,7 +186,7 @@ func updateForkRepositoryInContext(ctx *context.Context, forkRepo *repo_model.Re
ctx.Data["ContextUser"] = orgs[0]
} else {
ctx.Data["CanForkRepo"] = false
- ctx.Flash.Error(ctx.Tr("repo.fork_no_valid_owners"), true)
+ ctx.RenderWithErr(ctx.Tr("repo.fork_no_valid_owners"), tplFork, nil)
return false
}
diff --git a/routers/web/repo/repo.go b/routers/web/repo/repo.go
index 77aab8354b..07e6c937b0 100644
--- a/routers/web/repo/repo.go
+++ b/routers/web/repo/repo.go
@@ -35,6 +35,7 @@ import (
"code.gitea.io/gitea/services/forms"
repo_service "code.gitea.io/gitea/services/repository"
archiver_service "code.gitea.io/gitea/services/repository/archiver"
+ commitstatus_service "code.gitea.io/gitea/services/repository/commitstatus"
)
const (
@@ -542,9 +543,13 @@ func InitiateDownload(ctx *context.Context) {
// SearchRepo repositories via options
func SearchRepo(ctx *context.Context) {
+ page := ctx.FormInt("page")
+ if page <= 0 {
+ page = 1
+ }
opts := &repo_model.SearchRepoOptions{
ListOptions: db.ListOptions{
- Page: ctx.FormInt("page"),
+ Page: page,
PageSize: convert.ToCorrectPageSize(ctx.FormInt("limit")),
},
Actor: ctx.Doer,
@@ -630,30 +635,14 @@ func SearchRepo(ctx *context.Context) {
return
}
- // collect the latest commit of each repo
- // at most there are dozens of repos (limited by MaxResponseItems), so it's not a big problem at the moment
- repoBranchNames := make(map[int64]string, len(repos))
- for _, repo := range repos {
- repoBranchNames[repo.ID] = repo.DefaultBranch
- }
-
- repoIDsToLatestCommitSHAs, err := git_model.FindBranchesByRepoAndBranchName(ctx, repoBranchNames)
+ latestCommitStatuses, err := commitstatus_service.FindReposLastestCommitStatuses(ctx, repos)
if err != nil {
- log.Error("FindBranchesByRepoAndBranchName: %v", err)
- return
- }
-
- // call the database O(1) times to get the commit statuses for all repos
- repoToItsLatestCommitStatuses, err := git_model.GetLatestCommitStatusForPairs(ctx, repoIDsToLatestCommitSHAs, db.ListOptionsAll)
- if err != nil {
- log.Error("GetLatestCommitStatusForPairs: %v", err)
+ log.Error("FindReposLastestCommitStatuses: %v", err)
return
}
results := make([]*repo_service.WebSearchRepository, len(repos))
for i, repo := range repos {
- latestCommitStatus := git_model.CalcCommitStatus(repoToItsLatestCommitStatuses[repo.ID])
-
results[i] = &repo_service.WebSearchRepository{
Repository: &api.Repository{
ID: repo.ID,
@@ -667,8 +656,11 @@ func SearchRepo(ctx *context.Context) {
Link: repo.Link(),
Internal: !repo.IsPrivate && repo.Owner.Visibility == api.VisibleTypePrivate,
},
- LatestCommitStatus: latestCommitStatus,
- LocaleLatestCommitStatus: latestCommitStatus.LocaleString(ctx.Locale),
+ }
+
+ if latestCommitStatuses[i] != nil {
+ results[i].LatestCommitStatus = latestCommitStatuses[i]
+ results[i].LocaleLatestCommitStatus = latestCommitStatuses[i].LocaleString(ctx.Locale)
}
}
diff --git a/routers/web/repo/search.go b/routers/web/repo/search.go
index 74970c02c9..d22a691a70 100644
--- a/routers/web/repo/search.go
+++ b/routers/web/repo/search.go
@@ -6,6 +6,7 @@ package repo
import (
"net/http"
+ "code.gitea.io/gitea/models/db"
"code.gitea.io/gitea/modules/base"
code_indexer "code.gitea.io/gitea/modules/indexer/code"
"code.gitea.io/gitea/modules/setting"
@@ -21,7 +22,7 @@ func Search(ctx *context.Context) {
keyword := ctx.FormTrim("q")
queryType := ctx.FormTrim("t")
- isMatch := queryType == "match"
+ isFuzzy := queryType != "match"
ctx.Data["Keyword"] = keyword
ctx.Data["Language"] = language
@@ -43,8 +44,16 @@ func Search(ctx *context.Context) {
if setting.Indexer.RepoIndexerEnabled {
ctx.Data["CodeIndexerEnabled"] = true
- total, searchResults, searchResultLanguages, err := code_indexer.PerformSearch(ctx, []int64{ctx.Repo.Repository.ID},
- language, keyword, page, setting.UI.RepoSearchPagingNum, isMatch)
+ total, searchResults, searchResultLanguages, err := code_indexer.PerformSearch(ctx, &code_indexer.SearchOptions{
+ RepoIDs: []int64{ctx.Repo.Repository.ID},
+ Keyword: keyword,
+ IsKeywordFuzzy: isFuzzy,
+ Language: language,
+ Paginator: &db.ListOptions{
+ Page: page,
+ PageSize: setting.UI.RepoSearchPagingNum,
+ },
+ })
if err != nil {
if code_indexer.IsAvailable(ctx) {
ctx.ServerError("SearchResults", err)
diff --git a/routers/web/repo/setting/default_branch.go b/routers/web/repo/setting/default_branch.go
index 610fc5bcdf..d0b32ef079 100644
--- a/routers/web/repo/setting/default_branch.go
+++ b/routers/web/repo/setting/default_branch.go
@@ -8,6 +8,7 @@ import (
repo_model "code.gitea.io/gitea/models/repo"
"code.gitea.io/gitea/modules/git"
+ "code.gitea.io/gitea/modules/gitrepo"
"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/routers/web/repo"
@@ -40,7 +41,7 @@ func SetDefaultBranchPost(ctx *context.Context) {
return
} else if repo.DefaultBranch != branch {
repo.DefaultBranch = branch
- if err := ctx.Repo.GitRepo.SetDefaultBranch(branch); err != nil {
+ if err := gitrepo.SetDefaultBranch(ctx, repo, branch); err != nil {
if !git.IsErrUnsupportedVersion(err) {
ctx.ServerError("SetDefaultBranch", err)
return
diff --git a/routers/web/repo/setting/webhook.go b/routers/web/repo/setting/webhook.go
index 4e967c86d6..2e703a197a 100644
--- a/routers/web/repo/setting/webhook.go
+++ b/routers/web/repo/setting/webhook.go
@@ -616,6 +616,7 @@ func checkWebhook(ctx *context.Context) (*ownerRepoCtx, *webhook.Webhook) {
return nil, nil
}
ctx.Data["BaseLink"] = orCtx.Link
+ ctx.Data["BaseLinkNew"] = orCtx.LinkNew
var w *webhook.Webhook
if orCtx.RepoID > 0 {
@@ -684,12 +685,7 @@ func TestWebhook(ctx *context.Context) {
commit := ctx.Repo.Commit
if commit == nil {
ghost := user_model.NewGhostUser()
- objectFormat, err := git.GetObjectFormatOfRepo(ctx, ctx.Repo.Repository.RepoPath())
- if err != nil {
- ctx.Flash.Error("GetObjectFormatOfRepo: " + err.Error())
- ctx.Status(http.StatusInternalServerError)
- return
- }
+ objectFormat := git.ObjectFormatFromName(ctx.Repo.Repository.ObjectFormatName)
commit = &git.Commit{
ID: objectFormat.EmptyObjectID(),
Author: ghost.NewGitSig(),
diff --git a/routers/web/repo/view.go b/routers/web/repo/view.go
index 27984e7621..8ddfd92aa1 100644
--- a/routers/web/repo/view.go
+++ b/routers/web/repo/view.go
@@ -36,6 +36,7 @@ import (
"code.gitea.io/gitea/modules/base"
"code.gitea.io/gitea/modules/charset"
"code.gitea.io/gitea/modules/git"
+ "code.gitea.io/gitea/modules/gitrepo"
"code.gitea.io/gitea/modules/highlight"
"code.gitea.io/gitea/modules/lfs"
"code.gitea.io/gitea/modules/log"
@@ -43,6 +44,7 @@ import (
repo_module "code.gitea.io/gitea/modules/repository"
"code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/modules/structs"
+ "code.gitea.io/gitea/modules/svg"
"code.gitea.io/gitea/modules/typesniffer"
"code.gitea.io/gitea/modules/util"
"code.gitea.io/gitea/routers/web/feed"
@@ -811,7 +813,7 @@ func Home(ctx *context.Context) {
return
}
- renderCode(ctx)
+ renderHomeCode(ctx)
}
// LastCommit returns lastCommit data for the provided branch/tag/commit and directory (in url) and filenames in body
@@ -931,9 +933,33 @@ func renderRepoTopics(ctx *context.Context) {
ctx.Data["Topics"] = topics
}
-func renderCode(ctx *context.Context) {
+func prepareOpenWithEditorApps(ctx *context.Context) {
+ var tmplApps []map[string]any
+ apps := setting.Config().Repository.OpenWithEditorApps.Value(ctx)
+ if len(apps) == 0 {
+ apps = setting.DefaultOpenWithEditorApps()
+ }
+ for _, app := range apps {
+ schema, _, _ := strings.Cut(app.OpenURL, ":")
+ var iconHTML template.HTML
+ if schema == "vscode" || schema == "vscodium" || schema == "jetbrains" {
+ iconHTML = svg.RenderHTML(fmt.Sprintf("gitea-open-with-%s", schema), 16, "gt-mr-3")
+ } else {
+ iconHTML = svg.RenderHTML("gitea-git", 16, "gt-mr-3") // TODO: it could support user's customized icon in the future
+ }
+ tmplApps = append(tmplApps, map[string]any{
+ "DisplayName": app.DisplayName,
+ "OpenURL": app.OpenURL,
+ "IconHTML": iconHTML,
+ })
+ }
+ ctx.Data["OpenWithEditorApps"] = tmplApps
+}
+
+func renderHomeCode(ctx *context.Context) {
ctx.Data["PageIsViewCode"] = true
ctx.Data["RepositoryUploadEnabled"] = setting.Repository.Upload.Enabled
+ prepareOpenWithEditorApps(ctx)
if ctx.Repo.Commit == nil || ctx.Repo.Repository.IsEmpty || ctx.Repo.Repository.IsBroken() {
showEmpty := true
@@ -996,6 +1022,8 @@ func renderCode(ctx *context.Context) {
return
}
+ checkOutdatedBranch(ctx)
+
checkCitationFile(ctx, entry)
if ctx.Written() {
return
@@ -1071,7 +1099,7 @@ func renderCode(ctx *context.Context) {
if err != nil {
continue
}
- defaultBranch, err := gitRepo.GetDefaultBranch()
+ defaultBranch, err := gitrepo.GetDefaultBranch(ctx, repo)
if err != nil {
continue
}
@@ -1121,18 +1149,43 @@ PostRecentBranchCheck:
ctx.HTML(http.StatusOK, tplRepoHome)
}
+func checkOutdatedBranch(ctx *context.Context) {
+ if !(ctx.Repo.IsAdmin() || ctx.Repo.IsOwner()) {
+ return
+ }
+
+ // get the head commit of the branch since ctx.Repo.CommitID is not always the head commit of `ctx.Repo.BranchName`
+ commit, err := ctx.Repo.GitRepo.GetBranchCommit(ctx.Repo.BranchName)
+ if err != nil {
+ log.Error("GetBranchCommitID: %v", err)
+ // Don't return an error page, as it can be rechecked the next time the user opens the page.
+ return
+ }
+
+ dbBranch, err := git_model.GetBranch(ctx, ctx.Repo.Repository.ID, ctx.Repo.BranchName)
+ if err != nil {
+ log.Error("GetBranch: %v", err)
+ // Don't return an error page, as it can be rechecked the next time the user opens the page.
+ return
+ }
+
+ if dbBranch.CommitID != commit.ID.String() {
+ ctx.Flash.Warning(ctx.Tr("repo.error.broken_git_hook", "https://docs.gitea.com/help/faq#push-hook--webhook--actions-arent-running"), true)
+ }
+}
+
// RenderUserCards render a page show users according the input template
func RenderUserCards(ctx *context.Context, total int, getter func(opts db.ListOptions) ([]*user_model.User, error), tpl base.TplName) {
page := ctx.FormInt("page")
if page <= 0 {
page = 1
}
- pager := context.NewPagination(total, setting.ItemsPerPage, page, 5)
+ pager := context.NewPagination(total, setting.MaxUserCardsPerPage, page, 5)
ctx.Data["Page"] = pager
items, err := getter(db.ListOptions{
Page: pager.Paginater.Current(),
- PageSize: setting.ItemsPerPage,
+ PageSize: setting.MaxUserCardsPerPage,
})
if err != nil {
ctx.ServerError("getter", err)
@@ -1173,12 +1226,12 @@ func Forks(ctx *context.Context) {
page = 1
}
- pager := context.NewPagination(ctx.Repo.Repository.NumForks, setting.ItemsPerPage, page, 5)
+ pager := context.NewPagination(ctx.Repo.Repository.NumForks, setting.MaxForksPerPage, page, 5)
ctx.Data["Page"] = pager
forks, err := repo_model.GetForks(ctx, ctx.Repo.Repository, db.ListOptions{
Page: pager.Paginater.Current(),
- PageSize: setting.ItemsPerPage,
+ PageSize: setting.MaxForksPerPage,
})
if err != nil {
ctx.ServerError("GetForks", err)
diff --git a/routers/web/repo/wiki_test.go b/routers/web/repo/wiki_test.go
index 49c83cfef5..719cca3049 100644
--- a/routers/web/repo/wiki_test.go
+++ b/routers/web/repo/wiki_test.go
@@ -79,7 +79,7 @@ func assertPagesMetas(t *testing.T, expectedNames []string, metas any) {
func TestWiki(t *testing.T) {
unittest.PrepareTestEnv(t)
- ctx, _ := contexttest.MockContext(t, "user2/repo1/wiki/?action=_pages")
+ ctx, _ := contexttest.MockContext(t, "user2/repo1/wiki")
ctx.SetParams("*", "Home")
contexttest.LoadRepo(t, ctx, 1)
Wiki(ctx)
diff --git a/routers/web/shared/packages/packages.go b/routers/web/shared/packages/packages.go
index 57671ad8f1..af960f1c0c 100644
--- a/routers/web/shared/packages/packages.go
+++ b/routers/web/shared/packages/packages.go
@@ -4,16 +4,19 @@
package packages
import (
+ "errors"
"fmt"
"net/http"
"time"
"code.gitea.io/gitea/models/db"
packages_model "code.gitea.io/gitea/models/packages"
+ repo_model "code.gitea.io/gitea/models/repo"
user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/modules/base"
"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/optional"
+ "code.gitea.io/gitea/modules/util"
"code.gitea.io/gitea/modules/web"
"code.gitea.io/gitea/services/context"
"code.gitea.io/gitea/services/forms"
@@ -29,6 +32,12 @@ func SetPackagesContext(ctx *context.Context, owner *user_model.User) {
}
ctx.Data["CleanupRules"] = pcrs
+
+ ctx.Data["CargoIndexExists"], err = repo_model.IsRepositoryModelExist(ctx, owner, cargo_service.IndexRepositoryName)
+ if err != nil {
+ ctx.ServerError("IsRepositoryModelExist", err)
+ return
+ }
}
func SetRuleAddContext(ctx *context.Context) {
@@ -240,7 +249,11 @@ func RebuildCargoIndex(ctx *context.Context, owner *user_model.User) {
err := cargo_service.RebuildIndex(ctx, owner, owner)
if err != nil {
log.Error("RebuildIndex failed: %v", err)
- ctx.Flash.Error(ctx.Tr("packages.owner.settings.cargo.rebuild.error", err))
+ if errors.Is(err, util.ErrNotExist) {
+ ctx.Flash.Error(ctx.Tr("packages.owner.settings.cargo.rebuild.no_index"))
+ } else {
+ ctx.Flash.Error(ctx.Tr("packages.owner.settings.cargo.rebuild.error", err))
+ }
} else {
ctx.Flash.Success(ctx.Tr("packages.owner.settings.cargo.rebuild.success"))
}
diff --git a/routers/web/user/code.go b/routers/web/user/code.go
index eb711b76eb..d2afdd8905 100644
--- a/routers/web/user/code.go
+++ b/routers/web/user/code.go
@@ -6,6 +6,7 @@ package user
import (
"net/http"
+ "code.gitea.io/gitea/models/db"
repo_model "code.gitea.io/gitea/models/repo"
"code.gitea.io/gitea/modules/base"
code_indexer "code.gitea.io/gitea/modules/indexer/code"
@@ -40,7 +41,7 @@ func CodeSearch(ctx *context.Context) {
keyword := ctx.FormTrim("q")
queryType := ctx.FormTrim("t")
- isMatch := queryType == "match"
+ isFuzzy := queryType != "match"
ctx.Data["Keyword"] = keyword
ctx.Data["Language"] = language
@@ -75,7 +76,16 @@ func CodeSearch(ctx *context.Context) {
)
if len(repoIDs) > 0 {
- total, searchResults, searchResultLanguages, err = code_indexer.PerformSearch(ctx, repoIDs, language, keyword, page, setting.UI.RepoSearchPagingNum, isMatch)
+ total, searchResults, searchResultLanguages, err = code_indexer.PerformSearch(ctx, &code_indexer.SearchOptions{
+ RepoIDs: repoIDs,
+ Keyword: keyword,
+ IsKeywordFuzzy: isFuzzy,
+ Language: language,
+ Paginator: &db.ListOptions{
+ Page: page,
+ PageSize: setting.UI.RepoSearchPagingNum,
+ },
+ })
if err != nil {
if code_indexer.IsAvailable(ctx) {
ctx.ServerError("SearchResults", err)
diff --git a/routers/web/user/home.go b/routers/web/user/home.go
index 3ff4efc489..e58fb95131 100644
--- a/routers/web/user/home.go
+++ b/routers/web/user/home.go
@@ -743,7 +743,6 @@ func UsernameSubRoute(ctx *context.Context) {
return
}
if reloadParam(".rss") {
- context.UserAssignmentWeb()(ctx)
feed.ShowUserFeedRSS(ctx)
}
case strings.HasSuffix(username, ".atom"):
@@ -792,15 +791,15 @@ func getUserIssueStats(ctx *context.Context, ctxUser *user_model.User, filterMod
case issues_model.FilterModeYourRepositories:
openClosedOpts.AllPublic = false
case issues_model.FilterModeAssign:
- openClosedOpts.AssigneeID = &doerID
+ openClosedOpts.AssigneeID = optional.Some(doerID)
case issues_model.FilterModeCreate:
- openClosedOpts.PosterID = &doerID
+ openClosedOpts.PosterID = optional.Some(doerID)
case issues_model.FilterModeMention:
- openClosedOpts.MentionID = &doerID
+ openClosedOpts.MentionID = optional.Some(doerID)
case issues_model.FilterModeReviewRequested:
- openClosedOpts.ReviewRequestedID = &doerID
+ openClosedOpts.ReviewRequestedID = optional.Some(doerID)
case issues_model.FilterModeReviewed:
- openClosedOpts.ReviewedID = &doerID
+ openClosedOpts.ReviewedID = optional.Some(doerID)
}
openClosedOpts.IsClosed = optional.Some(false)
ret.OpenCount, err = issue_indexer.CountIssues(ctx, openClosedOpts)
@@ -818,23 +817,23 @@ func getUserIssueStats(ctx *context.Context, ctxUser *user_model.User, filterMod
if err != nil {
return nil, err
}
- ret.AssignCount, err = issue_indexer.CountIssues(ctx, opts.Copy(func(o *issue_indexer.SearchOptions) { o.AssigneeID = &doerID }))
+ ret.AssignCount, err = issue_indexer.CountIssues(ctx, opts.Copy(func(o *issue_indexer.SearchOptions) { o.AssigneeID = optional.Some(doerID) }))
if err != nil {
return nil, err
}
- ret.CreateCount, err = issue_indexer.CountIssues(ctx, opts.Copy(func(o *issue_indexer.SearchOptions) { o.PosterID = &doerID }))
+ ret.CreateCount, err = issue_indexer.CountIssues(ctx, opts.Copy(func(o *issue_indexer.SearchOptions) { o.PosterID = optional.Some(doerID) }))
if err != nil {
return nil, err
}
- ret.MentionCount, err = issue_indexer.CountIssues(ctx, opts.Copy(func(o *issue_indexer.SearchOptions) { o.MentionID = &doerID }))
+ ret.MentionCount, err = issue_indexer.CountIssues(ctx, opts.Copy(func(o *issue_indexer.SearchOptions) { o.MentionID = optional.Some(doerID) }))
if err != nil {
return nil, err
}
- ret.ReviewRequestedCount, err = issue_indexer.CountIssues(ctx, opts.Copy(func(o *issue_indexer.SearchOptions) { o.ReviewRequestedID = &doerID }))
+ ret.ReviewRequestedCount, err = issue_indexer.CountIssues(ctx, opts.Copy(func(o *issue_indexer.SearchOptions) { o.ReviewRequestedID = optional.Some(doerID) }))
if err != nil {
return nil, err
}
- ret.ReviewedCount, err = issue_indexer.CountIssues(ctx, opts.Copy(func(o *issue_indexer.SearchOptions) { o.ReviewedID = &doerID }))
+ ret.ReviewedCount, err = issue_indexer.CountIssues(ctx, opts.Copy(func(o *issue_indexer.SearchOptions) { o.ReviewedID = optional.Some(doerID) }))
if err != nil {
return nil, err
}
diff --git a/routers/web/user/setting/account.go b/routers/web/user/setting/account.go
index ef02cd24a7..386309aa71 100644
--- a/routers/web/user/setting/account.go
+++ b/routers/web/user/setting/account.go
@@ -19,6 +19,8 @@ import (
"code.gitea.io/gitea/modules/timeutil"
"code.gitea.io/gitea/modules/web"
"code.gitea.io/gitea/services/auth"
+ "code.gitea.io/gitea/services/auth/source/db"
+ "code.gitea.io/gitea/services/auth/source/smtp"
"code.gitea.io/gitea/services/context"
"code.gitea.io/gitea/services/forms"
"code.gitea.io/gitea/services/mailer"
@@ -251,11 +253,24 @@ func DeleteAccount(ctx *context.Context) {
ctx.Data["PageIsSettingsAccount"] = true
if _, _, err := auth.UserSignIn(ctx, ctx.Doer.Name, ctx.FormString("password")); err != nil {
- if user_model.IsErrUserNotExist(err) {
+ switch {
+ case user_model.IsErrUserNotExist(err):
+ loadAccountData(ctx)
+
+ ctx.RenderWithErr(ctx.Tr("form.user_not_exist"), tplSettingsAccount, nil)
+ case errors.Is(err, smtp.ErrUnsupportedLoginType):
+ loadAccountData(ctx)
+
+ ctx.RenderWithErr(ctx.Tr("form.unsupported_login_type"), tplSettingsAccount, nil)
+ case errors.As(err, &db.ErrUserPasswordNotSet{}):
+ loadAccountData(ctx)
+
+ ctx.RenderWithErr(ctx.Tr("form.unset_password"), tplSettingsAccount, nil)
+ case errors.As(err, &db.ErrUserPasswordInvalid{}):
loadAccountData(ctx)
ctx.RenderWithErr(ctx.Tr("form.enterred_invalid_password"), tplSettingsAccount, nil)
- } else {
+ default:
ctx.ServerError("UserSignIn", err)
}
return
diff --git a/routers/web/user/setting/keys.go b/routers/web/user/setting/keys.go
index cb01913bda..d2b60fc809 100644
--- a/routers/web/user/setting/keys.go
+++ b/routers/web/user/setting/keys.go
@@ -159,6 +159,11 @@ func KeysPost(ctx *context.Context) {
ctx.Flash.Success(ctx.Tr("settings.verify_gpg_key_success", keyID))
ctx.Redirect(setting.AppSubURL + "/user/settings/keys")
case "ssh":
+ if setting.Admin.UserDisabledFeatures.Contains(setting.UserFeatureManageSSHKeys) {
+ ctx.NotFound("Not Found", fmt.Errorf("ssh keys setting is not allowed to be visited"))
+ return
+ }
+
content, err := asymkey_model.CheckPublicKeyString(form.Content)
if err != nil {
if db.IsErrSSHDisabled(err) {
@@ -198,6 +203,11 @@ func KeysPost(ctx *context.Context) {
ctx.Flash.Success(ctx.Tr("settings.add_key_success", form.Title))
ctx.Redirect(setting.AppSubURL + "/user/settings/keys")
case "verify_ssh":
+ if setting.Admin.UserDisabledFeatures.Contains(setting.UserFeatureManageSSHKeys) {
+ ctx.NotFound("Not Found", fmt.Errorf("ssh keys setting is not allowed to be visited"))
+ return
+ }
+
token := asymkey_model.VerificationToken(ctx.Doer, 1)
lastToken := asymkey_model.VerificationToken(ctx.Doer, 0)
@@ -240,6 +250,11 @@ func DeleteKey(ctx *context.Context) {
ctx.Flash.Success(ctx.Tr("settings.gpg_key_deletion_success"))
}
case "ssh":
+ if setting.Admin.UserDisabledFeatures.Contains(setting.UserFeatureManageSSHKeys) {
+ ctx.NotFound("Not Found", fmt.Errorf("ssh keys setting is not allowed to be visited"))
+ return
+ }
+
keyID := ctx.FormInt64("id")
external, err := asymkey_model.PublicKeyIsExternallyManaged(ctx, keyID)
if err != nil {
@@ -318,4 +333,5 @@ func loadKeysData(ctx *context.Context) {
ctx.Data["VerifyingID"] = ctx.FormString("verify_gpg")
ctx.Data["VerifyingFingerprint"] = ctx.FormString("verify_ssh")
+ ctx.Data["UserDisabledFeatures"] = &setting.Admin.UserDisabledFeatures
}
diff --git a/routers/web/web.go b/routers/web/web.go
index 114a50cf08..5cd7d112b0 100644
--- a/routers/web/web.go
+++ b/routers/web/web.go
@@ -691,6 +691,7 @@ func registerRoutes(m *web.Route) {
m.Get("", admin.Config)
m.Post("", admin.ChangeConfig)
m.Post("/test_mail", admin.SendTestMail)
+ m.Get("/settings", admin.ConfigSettings)
})
m.Group("/monitor", func() {
@@ -1413,7 +1414,7 @@ func registerRoutes(m *web.Route) {
})
m.Post("/cancel", reqRepoActionsWriter, actions.Cancel)
m.Post("/approve", reqRepoActionsWriter, actions.Approve)
- m.Post("/artifacts", actions.ArtifactsView)
+ m.Get("/artifacts", actions.ArtifactsView)
m.Get("/artifacts/{artifact_name}", actions.ArtifactsDownloadView)
m.Delete("/artifacts/{artifact_name}", reqRepoActionsWriter, actions.ArtifactsDeleteView)
m.Post("/rerun", reqRepoActionsWriter, actions.Rerun)
diff --git a/services/actions/auth.go b/services/actions/auth.go
index e0f9a9015d..8e934d89a8 100644
--- a/services/actions/auth.go
+++ b/services/actions/auth.go
@@ -9,6 +9,7 @@ import (
"strings"
"time"
+ "code.gitea.io/gitea/modules/json"
"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/setting"
@@ -21,17 +22,41 @@ type actionsClaims struct {
TaskID int64
RunID int64
JobID int64
+ Ac string `json:"ac"`
}
+type actionsCacheScope struct {
+ Scope string
+ Permission actionsCachePermission
+}
+
+type actionsCachePermission int
+
+const (
+ actionsCachePermissionRead = 1 << iota
+ actionsCachePermissionWrite
+)
+
func CreateAuthorizationToken(taskID, runID, jobID int64) (string, error) {
now := time.Now()
+ ac, err := json.Marshal(&[]actionsCacheScope{
+ {
+ Scope: "",
+ Permission: actionsCachePermissionWrite,
+ },
+ })
+ if err != nil {
+ return "", err
+ }
+
claims := actionsClaims{
RegisteredClaims: jwt.RegisteredClaims{
ExpiresAt: jwt.NewNumericDate(now.Add(24 * time.Hour)),
NotBefore: jwt.NewNumericDate(now),
},
Scp: fmt.Sprintf("Actions.Results:%d:%d", runID, jobID),
+ Ac: string(ac),
TaskID: taskID,
RunID: runID,
JobID: jobID,
diff --git a/services/actions/auth_test.go b/services/actions/auth_test.go
index 1f62f17f52..f73ae8ae4c 100644
--- a/services/actions/auth_test.go
+++ b/services/actions/auth_test.go
@@ -7,6 +7,7 @@ import (
"net/http"
"testing"
+ "code.gitea.io/gitea/modules/json"
"code.gitea.io/gitea/modules/setting"
"github.com/golang-jwt/jwt/v5"
@@ -29,6 +30,14 @@ func TestCreateAuthorizationToken(t *testing.T) {
taskIDClaim, ok := claims["TaskID"]
assert.True(t, ok, "Has TaskID claim in jwt token")
assert.Equal(t, float64(taskID), taskIDClaim, "Supplied taskid must match stored one")
+ acClaim, ok := claims["ac"]
+ assert.True(t, ok, "Has ac claim in jwt token")
+ ac, ok := acClaim.(string)
+ assert.True(t, ok, "ac claim is a string for buildx gha cache")
+ scopes := []actionsCacheScope{}
+ err = json.Unmarshal([]byte(ac), &scopes)
+ assert.NoError(t, err, "ac claim is a json list for buildx gha cache")
+ assert.GreaterOrEqual(t, len(scopes), 1, "Expected at least one action cache scope for buildx gha cache")
}
func TestParseAuthorizationToken(t *testing.T) {
diff --git a/services/actions/notifier_helper.go b/services/actions/notifier_helper.go
index 19a5c66b71..7c01226c95 100644
--- a/services/actions/notifier_helper.go
+++ b/services/actions/notifier_helper.go
@@ -154,7 +154,7 @@ func notify(ctx context.Context, input *notifyInput) error {
return fmt.Errorf("gitRepo.GetCommit: %w", err)
}
- if skipWorkflowsForCommit(input, commit) {
+ if skipWorkflows(input, commit) {
return nil
}
@@ -232,8 +232,8 @@ func SkipPullRequestEvent(ctx context.Context, event webhook_module.HookEventTyp
return exist
}
-func skipWorkflowsForCommit(input *notifyInput, commit *git.Commit) bool {
- // skip workflow runs with a configured skip-ci string in commit message if the event is push or pull_request(_sync)
+func skipWorkflows(input *notifyInput, commit *git.Commit) bool {
+ // skip workflow runs with a configured skip-ci string in commit message or pr title if the event is push or pull_request(_sync)
// https://docs.github.com/en/actions/managing-workflow-runs/skipping-workflow-runs
skipWorkflowEvents := []webhook_module.HookEventType{
webhook_module.HookEventPush,
@@ -242,6 +242,10 @@ func skipWorkflowsForCommit(input *notifyInput, commit *git.Commit) bool {
}
if slices.Contains(skipWorkflowEvents, input.Event) {
for _, s := range setting.Actions.SkipWorkflowStrings {
+ if input.PullRequest != nil && strings.Contains(input.PullRequest.Issue.Title, s) {
+ log.Debug("repo %s: skipped run for pr %v because of %s string", input.Repo.RepoPath(), input.PullRequest.Issue.ID, s)
+ return true
+ }
if strings.Contains(commit.CommitMessage, s) {
log.Debug("repo %s with commit %s: skipped run because of %s string", input.Repo.RepoPath(), commit.ID, s)
return true
@@ -305,7 +309,18 @@ func handleWorkflows(
run.NeedApproval = need
}
- jobs, err := jobparser.Parse(dwf.Content)
+ if err := run.LoadAttributes(ctx); err != nil {
+ log.Error("LoadAttributes: %v", err)
+ continue
+ }
+
+ vars, err := actions_model.GetVariablesOfRun(ctx, run)
+ if err != nil {
+ log.Error("GetVariablesOfRun: %v", err)
+ continue
+ }
+
+ jobs, err := jobparser.Parse(dwf.Content, jobparser.WithVars(vars))
if err != nil {
log.Error("jobparser.Parse: %v", err)
continue
diff --git a/services/auth/source/oauth2/providers.go b/services/auth/source/oauth2/providers.go
index ac32647839..c3edae4ab6 100644
--- a/services/auth/source/oauth2/providers.go
+++ b/services/auth/source/oauth2/providers.go
@@ -59,7 +59,7 @@ func (p *AuthSourceProvider) DisplayName() string {
func (p *AuthSourceProvider) IconHTML(size int) template.HTML {
if p.iconURL != "" {
- img := fmt.Sprintf(``,
+ img := fmt.Sprintf(``,
size,
size,
html.EscapeString(p.iconURL), html.EscapeString(p.DisplayName()),
diff --git a/services/context/base.go b/services/context/base.go
index c4aa467ff4..25ff935055 100644
--- a/services/context/base.go
+++ b/services/context/base.go
@@ -256,7 +256,7 @@ func (b *Base) Redirect(location string, status ...int) {
code = status[0]
}
- if strings.Contains(location, "://") || strings.HasPrefix(location, "//") {
+ if httplib.IsRiskyRedirectURL(location) {
// Some browsers (Safari) have buggy behavior for Cookie + Cache + External Redirection, eg: /my-path => https://other/path
// 1. the first request to "/my-path" contains cookie
// 2. some time later, the request to "/my-path" doesn't contain cookie (caused by Prevent web tracking)
diff --git a/services/context/base_test.go b/services/context/base_test.go
new file mode 100644
index 0000000000..823f20e00b
--- /dev/null
+++ b/services/context/base_test.go
@@ -0,0 +1,47 @@
+// Copyright 2024 The Gitea Authors. All rights reserved.
+// SPDX-License-Identifier: MIT
+
+package context
+
+import (
+ "net/http"
+ "net/http/httptest"
+ "testing"
+
+ "code.gitea.io/gitea/modules/setting"
+
+ "github.com/stretchr/testify/assert"
+)
+
+func TestRedirect(t *testing.T) {
+ req, _ := http.NewRequest("GET", "/", nil)
+
+ cases := []struct {
+ url string
+ keep bool
+ }{
+ {"http://test", false},
+ {"https://test", false},
+ {"//test", false},
+ {"/://test", true},
+ {"/test", true},
+ }
+ for _, c := range cases {
+ resp := httptest.NewRecorder()
+ b, cleanup := NewBaseContext(resp, req)
+ resp.Header().Add("Set-Cookie", (&http.Cookie{Name: setting.SessionConfig.CookieName, Value: "dummy"}).String())
+ b.Redirect(c.url)
+ cleanup()
+ has := resp.Header().Get("Set-Cookie") == "i_like_gitea=dummy"
+ assert.Equal(t, c.keep, has, "url = %q", c.url)
+ }
+
+ req, _ = http.NewRequest("GET", "/", nil)
+ resp := httptest.NewRecorder()
+ req.Header.Add("HX-Request", "true")
+ b, cleanup := NewBaseContext(resp, req)
+ b.Redirect("/other")
+ cleanup()
+ assert.Equal(t, "/other", resp.Header().Get("HX-Redirect"))
+ assert.Equal(t, http.StatusNoContent, resp.Code)
+}
diff --git a/services/context/context.go b/services/context/context.go
index a06ebfb0dc..3e113e76ba 100644
--- a/services/context/context.go
+++ b/services/context/context.go
@@ -192,6 +192,7 @@ func Contexter() func(next http.Handler) http.Handler {
httpcache.SetCacheControlInHeader(ctx.Resp.Header(), 0, "no-transform")
ctx.Resp.Header().Set(`X-Frame-Options`, setting.CORSConfig.XFrameOptions)
+ ctx.Data["SystemConfig"] = setting.Config()
ctx.Data["CsrfToken"] = ctx.Csrf.GetToken()
ctx.Data["CsrfTokenHtml"] = template.HTML(``)
diff --git a/services/context/repo.go b/services/context/repo.go
index e78dfc585d..43eeab8098 100644
--- a/services/context/repo.go
+++ b/services/context/repo.go
@@ -702,7 +702,7 @@ func RepoAssignment(ctx *Context) context.CancelFunc {
if len(ctx.Repo.Repository.DefaultBranch) > 0 && gitRepo.IsBranchExist(ctx.Repo.Repository.DefaultBranch) {
ctx.Repo.BranchName = ctx.Repo.Repository.DefaultBranch
} else {
- ctx.Repo.BranchName, _ = gitRepo.GetDefaultBranch()
+ ctx.Repo.BranchName, _ = gitrepo.GetDefaultBranch(ctx, ctx.Repo.Repository)
if ctx.Repo.BranchName == "" {
// If it still can't get a default branch, fall back to default branch from setting.
// Something might be wrong. Either site admin should fix the repo sync or Gitea should fix a potential bug.
diff --git a/services/contexttest/context_tests.go b/services/contexttest/context_tests.go
index 431017a30d..d3e6de7efe 100644
--- a/services/contexttest/context_tests.go
+++ b/services/contexttest/context_tests.go
@@ -7,6 +7,7 @@ package contexttest
import (
gocontext "context"
"io"
+ "maps"
"net/http"
"net/http/httptest"
"net/url"
@@ -36,7 +37,7 @@ func mockRequest(t *testing.T, reqPath string) *http.Request {
}
requestURL, err := url.Parse(path)
assert.NoError(t, err)
- req := &http.Request{Method: method, URL: requestURL, Form: url.Values{}}
+ req := &http.Request{Method: method, URL: requestURL, Form: maps.Clone(requestURL.Query()), Header: http.Header{}}
req = req.WithContext(middleware.WithContextData(req.Context()))
return req
}
diff --git a/services/forms/user_form.go b/services/forms/user_form.go
index 77316fb13a..0f3cd0ceec 100644
--- a/services/forms/user_form.go
+++ b/services/forms/user_form.go
@@ -10,9 +10,9 @@ import (
"strings"
auth_model "code.gitea.io/gitea/models/auth"
+ user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/modules/structs"
- "code.gitea.io/gitea/modules/validation"
"code.gitea.io/gitea/modules/web/middleware"
"code.gitea.io/gitea/services/context"
@@ -109,11 +109,7 @@ func (f *RegisterForm) Validate(req *http.Request, errs binding.Errors) binding.
// domains in the whitelist or if it doesn't match any of
// domains in the blocklist, if any such list is not empty.
func (f *RegisterForm) IsEmailDomainAllowed() bool {
- if len(setting.Service.EmailDomainAllowList) == 0 {
- return !validation.IsEmailDomainListed(setting.Service.EmailDomainBlockList, f.Email)
- }
-
- return validation.IsEmailDomainListed(setting.Service.EmailDomainAllowList, f.Email)
+ return user_model.IsEmailDomainAllowed(f.Email)
}
// MustChangePasswordForm form for updating your password after account creation
diff --git a/services/mailer/mail.go b/services/mailer/mail.go
index f72ae45f89..26aebd2583 100644
--- a/services/mailer/mail.go
+++ b/services/mailer/mail.go
@@ -222,7 +222,8 @@ func composeIssueCommentMessages(ctx *mailCommentContext, lang string, recipient
body, err := markdown.RenderString(&markup.RenderContext{
Ctx: ctx,
Links: markup.Links{
- Base: ctx.Issue.Repo.HTMLURL(),
+ AbsolutePrefix: true,
+ Base: ctx.Issue.Repo.HTMLURL(),
},
Metas: ctx.Issue.Repo.ComposeMetas(ctx),
}, ctx.Content)
diff --git a/services/mailer/mail_test.go b/services/mailer/mail_test.go
index e300aeccb0..d87c57ffe7 100644
--- a/services/mailer/mail_test.go
+++ b/services/mailer/mail_test.go
@@ -8,6 +8,8 @@ import (
"context"
"fmt"
"html/template"
+ "io"
+ "mime/quotedprintable"
"regexp"
"strings"
"testing"
@@ -19,6 +21,7 @@ import (
repo_model "code.gitea.io/gitea/models/repo"
"code.gitea.io/gitea/models/unittest"
user_model "code.gitea.io/gitea/models/user"
+ "code.gitea.io/gitea/modules/markup"
"code.gitea.io/gitea/modules/setting"
"github.com/stretchr/testify/assert"
@@ -67,6 +70,12 @@ func prepareMailerTest(t *testing.T) (doer *user_model.User, repo *repo_model.Re
func TestComposeIssueCommentMessage(t *testing.T) {
doer, _, issue, comment := prepareMailerTest(t)
+ markup.Init(&markup.ProcessorHelper{
+ IsUsernameMentionable: func(ctx context.Context, username string) bool {
+ return username == doer.Name
+ },
+ })
+
setting.IncomingEmail.Enabled = true
defer func() { setting.IncomingEmail.Enabled = false }()
@@ -77,7 +86,8 @@ func TestComposeIssueCommentMessage(t *testing.T) {
msgs, err := composeIssueCommentMessages(&mailCommentContext{
Context: context.TODO(), // TODO: use a correct context
Issue: issue, Doer: doer, ActionType: activities_model.ActionCommentIssue,
- Content: "test body", Comment: comment,
+ Content: fmt.Sprintf("test @%s %s#%d body", doer.Name, issue.Repo.FullName(), issue.Index),
+ Comment: comment,
}, "en-US", recipients, false, "issue comment")
assert.NoError(t, err)
assert.Len(t, msgs, 2)
@@ -96,6 +106,20 @@ func TestComposeIssueCommentMessage(t *testing.T) {
assert.Equal(t, "", gomailMsg.GetHeader("Message-ID")[0], "Message-ID header doesn't match")
assert.Equal(t, "", gomailMsg.GetHeader("List-Post")[0])
assert.Len(t, gomailMsg.GetHeader("List-Unsubscribe"), 2) // url + mailto
+
+ var buf bytes.Buffer
+ gomailMsg.WriteTo(&buf)
+
+ b, err := io.ReadAll(quotedprintable.NewReader(&buf))
+ assert.NoError(t, err)
+
+ // text/plain
+ assert.Contains(t, string(b), fmt.Sprintf(`( %s )`, doer.HTMLURL()))
+ assert.Contains(t, string(b), fmt.Sprintf(`( %s )`, issue.HTMLURL()))
+
+ // text/html
+ assert.Contains(t, string(b), fmt.Sprintf(`href="%s"`, doer.HTMLURL()))
+ assert.Contains(t, string(b), fmt.Sprintf(`href="%s"`, issue.HTMLURL()))
}
func TestComposeIssueMessage(t *testing.T) {
diff --git a/services/migrations/testdata/gitlab/full_download/_api_v4_projects_gitea%2Ftest_repo b/services/migrations/testdata/gitlab/full_download/GET_%2Fapi%2Fv4%2Fprojects%2F15578026
similarity index 94%
rename from services/migrations/testdata/gitlab/full_download/_api_v4_projects_gitea%2Ftest_repo
rename to services/migrations/testdata/gitlab/full_download/GET_%2Fapi%2Fv4%2Fprojects%2F15578026
index 490eebe791..81fb1f9e01 100644
--- a/services/migrations/testdata/gitlab/full_download/_api_v4_projects_gitea%2Ftest_repo
+++ b/services/migrations/testdata/gitlab/full_download/GET_%2Fapi%2Fv4%2Fprojects%2F15578026
@@ -1,17 +1,17 @@
-X-Frame-Options: SAMEORIGIN
-X-Gitlab-Meta: {"correlation_id":"d08798c744b97af051e81bc1f6fecabe","version":"1"}
-Cf-Cache-Status: MISS
-Vary: Origin, Accept-Encoding
-X-Runtime: 0.282076
-Gitlab-Lb: haproxy-main-43-lb-gprd
-Etag: W/"8db4917b3be5f4ca0d101a702179b75a"
-Referrer-Policy: strict-origin-when-cross-origin
-Set-Cookie: _cfuvid=q8qrvxAlkuGzqRsYQXzKrbLTHH6CWOF_x.icF64i9VQ-1709516921514-0.0.1.1-604800000; path=/; domain=.gitlab.com; HttpOnly; Secure; SameSite=None
-Content-Security-Policy: default-src 'none'
-Cache-Control: max-age=0, private, must-revalidate
-X-Content-Type-Options: nosniff
-Strict-Transport-Security: max-age=31536000
Gitlab-Sv: api-gke-us-east1-c
Content-Type: application/json
+Cache-Control: max-age=0, private, must-revalidate
+Content-Security-Policy: default-src 'none'
+Etag: W/"8db4917b3be5f4ca0d101a702179b75a"
+X-Content-Type-Options: nosniff
+X-Runtime: 0.150020
+Referrer-Policy: strict-origin-when-cross-origin
+Set-Cookie: _cfuvid=2JDVzeRhKxkwd0xbLccErO2vFlf0KnUzsvPv1ZY4.H4-1710504205506-0.0.1.1-604800000; path=/; domain=.gitlab.com; HttpOnly; Secure; SameSite=None
+X-Gitlab-Meta: {"correlation_id":"fc467ca540c06233f6a25d0deae604d2","version":"1"}
+Vary: Origin, Accept-Encoding
+X-Frame-Options: SAMEORIGIN
+Strict-Transport-Security: max-age=31536000
+Gitlab-Lb: haproxy-main-01-lb-gprd
+Cf-Cache-Status: MISS
{"id":15578026,"description":"Test repository for testing migration from gitlab to gitea","name":"test_repo","name_with_namespace":"gitea / test_repo","path":"test_repo","path_with_namespace":"gitea/test_repo","created_at":"2019-11-28T08:20:33.019Z","default_branch":"master","tag_list":["migration","test"],"topics":["migration","test"],"ssh_url_to_repo":"git@gitlab.com:gitea/test_repo.git","http_url_to_repo":"https://gitlab.com/gitea/test_repo.git","web_url":"https://gitlab.com/gitea/test_repo","readme_url":"https://gitlab.com/gitea/test_repo/-/blob/master/README.md","forks_count":1,"avatar_url":null,"star_count":0,"last_activity_at":"2020-04-19T19:46:04.527Z","namespace":{"id":3181312,"name":"gitea","path":"gitea","kind":"group","full_path":"gitea","parent_id":null,"avatar_url":"/uploads/-/system/group/avatar/3181312/gitea.png","web_url":"https://gitlab.com/groups/gitea"},"container_registry_image_prefix":"registry.gitlab.com/gitea/test_repo","_links":{"self":"https://gitlab.com/api/v4/projects/15578026","issues":"https://gitlab.com/api/v4/projects/15578026/issues","merge_requests":"https://gitlab.com/api/v4/projects/15578026/merge_requests","repo_branches":"https://gitlab.com/api/v4/projects/15578026/repository/branches","labels":"https://gitlab.com/api/v4/projects/15578026/labels","events":"https://gitlab.com/api/v4/projects/15578026/events","members":"https://gitlab.com/api/v4/projects/15578026/members","cluster_agents":"https://gitlab.com/api/v4/projects/15578026/cluster_agents"},"packages_enabled":true,"empty_repo":false,"archived":false,"visibility":"public","resolve_outdated_diff_discussions":false,"repository_object_format":"sha1","issues_enabled":true,"merge_requests_enabled":true,"wiki_enabled":true,"jobs_enabled":true,"snippets_enabled":true,"container_registry_enabled":true,"service_desk_enabled":true,"can_create_merge_request_in":true,"issues_access_level":"enabled","repository_access_level":"enabled","merge_requests_access_level":"enabled","forking_access_level":"enabled","wiki_access_level":"enabled","builds_access_level":"enabled","snippets_access_level":"enabled","pages_access_level":"enabled","analytics_access_level":"enabled","container_registry_access_level":"enabled","security_and_compliance_access_level":"private","releases_access_level":"enabled","environments_access_level":"enabled","feature_flags_access_level":"enabled","infrastructure_access_level":"enabled","monitor_access_level":"enabled","model_experiments_access_level":"enabled","model_registry_access_level":"enabled","emails_disabled":false,"emails_enabled":true,"shared_runners_enabled":true,"lfs_enabled":true,"creator_id":1241334,"import_status":"none","open_issues_count":0,"description_html":"\u003cp data-sourcepos=\"1:1-1:58\" dir=\"auto\"\u003eTest repository for testing migration from gitlab to gitea\u003c/p\u003e","updated_at":"2024-01-11T01:23:21.057Z","ci_config_path":null,"public_jobs":true,"shared_with_groups":[],"only_allow_merge_if_pipeline_succeeds":false,"allow_merge_on_skipped_pipeline":null,"request_access_enabled":true,"only_allow_merge_if_all_discussions_are_resolved":false,"remove_source_branch_after_merge":true,"printing_merge_request_link_enabled":true,"merge_method":"ff","squash_option":"default_off","enforce_auth_checks_on_uploads":true,"suggestion_commit_message":null,"merge_commit_template":null,"squash_commit_template":null,"issue_branch_template":null,"warn_about_potentially_unwanted_characters":true,"autoclose_referenced_issues":true,"external_authorization_classification_label":"","requirements_enabled":false,"requirements_access_level":"enabled","security_and_compliance_enabled":false,"compliance_frameworks":[],"permissions":{"project_access":null,"group_access":null}}
\ No newline at end of file
diff --git a/services/migrations/testdata/gitlab/full_download/_api_v4_projects_15578026_issues_1_award_emoji!page=1&per_page=2 b/services/migrations/testdata/gitlab/full_download/GET_%2Fapi%2Fv4%2Fprojects%2F15578026%2Fissues%2F1%2Faward_emoji%3Fpage=1&per_page=2
similarity index 85%
rename from services/migrations/testdata/gitlab/full_download/_api_v4_projects_15578026_issues_1_award_emoji!page=1&per_page=2
rename to services/migrations/testdata/gitlab/full_download/GET_%2Fapi%2Fv4%2Fprojects%2F15578026%2Fissues%2F1%2Faward_emoji%3Fpage=1&per_page=2
index 7b37f59f5e..cbdfdde527 100644
--- a/services/migrations/testdata/gitlab/full_download/_api_v4_projects_15578026_issues_1_award_emoji!page=1&per_page=2
+++ b/services/migrations/testdata/gitlab/full_download/GET_%2Fapi%2Fv4%2Fprojects%2F15578026%2Fissues%2F1%2Faward_emoji%3Fpage=1&per_page=2
@@ -1,24 +1,24 @@
-X-Total-Pages: 1
-Cf-Cache-Status: MISS
-Set-Cookie: _cfuvid=UtNiLvpRoIS0606tZnebN.nDbGog2IEOTI0M6iH6tKE-1709516925325-0.0.1.1-604800000; path=/; domain=.gitlab.com; HttpOnly; Secure; SameSite=None
-Content-Type: application/json
-Link: ; rel="first", ; rel="last"
-X-Gitlab-Meta: {"correlation_id":"7078187b1af666261210081509905846","version":"1"}
-Strict-Transport-Security: max-age=31536000
Vary: Origin, Accept-Encoding
-X-Total: 2
Gitlab-Sv: api-gke-us-east1-b
-Content-Security-Policy: default-src 'none'
-X-Content-Type-Options: nosniff
-X-Page: 1
-X-Frame-Options: SAMEORIGIN
-X-Prev-Page:
-X-Runtime: 0.070454
-X-Next-Page:
+X-Runtime: 0.203565
Referrer-Policy: strict-origin-when-cross-origin
-Gitlab-Lb: haproxy-main-51-lb-gprd
-X-Per-Page: 2
+X-Frame-Options: SAMEORIGIN
+X-Next-Page:
+X-Gitlab-Meta: {"correlation_id":"9ee8f715be2950b629eff875667dab37","version":"1"}
+X-Total-Pages: 1
+Gitlab-Lb: haproxy-main-57-lb-gprd
+Cf-Cache-Status: MISS
+Content-Type: application/json
Cache-Control: max-age=0, private, must-revalidate
+X-Content-Type-Options: nosniff
+Strict-Transport-Security: max-age=31536000
Etag: W/"69c922434ed11248c864d157eb8eabfc"
+X-Per-Page: 2
+X-Prev-Page:
+Set-Cookie: _cfuvid=lj07r.PfLt5YP9_Ms5dtsY_JOkTSmeFWB1sd2Z8SLuM-1710504207278-0.0.1.1-604800000; path=/; domain=.gitlab.com; HttpOnly; Secure; SameSite=None
+Content-Security-Policy: default-src 'none'
+Link: ; rel="first", ; rel="last"
+X-Page: 1
+X-Total: 2
[{"id":3009580,"name":"thumbsup","user":{"id":1241334,"username":"lafriks","name":"Lauris BH","state":"active","locked":false,"avatar_url":"https://gitlab.com/uploads/-/system/user/avatar/1241334/avatar.png","web_url":"https://gitlab.com/lafriks"},"created_at":"2019-11-28T08:43:40.322Z","updated_at":"2019-11-28T08:43:40.322Z","awardable_id":27687675,"awardable_type":"Issue","url":null},{"id":3009585,"name":"open_mouth","user":{"id":1241334,"username":"lafriks","name":"Lauris BH","state":"active","locked":false,"avatar_url":"https://gitlab.com/uploads/-/system/user/avatar/1241334/avatar.png","web_url":"https://gitlab.com/lafriks"},"created_at":"2019-11-28T08:44:01.902Z","updated_at":"2019-11-28T08:44:01.902Z","awardable_id":27687675,"awardable_type":"Issue","url":null}]
\ No newline at end of file
diff --git a/services/migrations/testdata/gitlab/full_download/_api_v4_projects_15578026_issues_1_award_emoji!page=2&per_page=2 b/services/migrations/testdata/gitlab/full_download/GET_%2Fapi%2Fv4%2Fprojects%2F15578026%2Fissues%2F1%2Faward_emoji%3Fpage=2&per_page=2
similarity index 75%
rename from services/migrations/testdata/gitlab/full_download/_api_v4_projects_15578026_issues_1_award_emoji!page=2&per_page=2
rename to services/migrations/testdata/gitlab/full_download/GET_%2Fapi%2Fv4%2Fprojects%2F15578026%2Fissues%2F1%2Faward_emoji%3Fpage=2&per_page=2
index 7f64231eb7..262bf891ee 100644
--- a/services/migrations/testdata/gitlab/full_download/_api_v4_projects_15578026_issues_1_award_emoji!page=2&per_page=2
+++ b/services/migrations/testdata/gitlab/full_download/GET_%2Fapi%2Fv4%2Fprojects%2F15578026%2Fissues%2F1%2Faward_emoji%3Fpage=2&per_page=2
@@ -1,26 +1,26 @@
-Content-Length: 2
-Cache-Control: max-age=0, private, must-revalidate
-Accept-Ranges: bytes
-Strict-Transport-Security: max-age=31536000
-Gitlab-Lb: haproxy-main-57-lb-gprd
-Gitlab-Sv: api-gke-us-east1-b
-X-Prev-Page:
-X-Runtime: 0.048686
-Cf-Cache-Status: MISS
-Vary: Origin, Accept-Encoding
-X-Per-Page: 2
-Referrer-Policy: strict-origin-when-cross-origin
-X-Gitlab-Meta: {"correlation_id":"53764b779171a3a641999caf45eb5cda","version":"1"}
-X-Page: 2
-X-Total: 2
-X-Total-Pages: 1
-Content-Type: application/json
-X-Next-Page:
-Set-Cookie: _cfuvid=.aWihkIt1YOKnLoix6oJ3avCXZ_942rAkWJpHXKtKXk-1709516926358-0.0.1.1-604800000; path=/; domain=.gitlab.com; HttpOnly; Secure; SameSite=None
-Content-Security-Policy: default-src 'none'
-X-Content-Type-Options: nosniff
-X-Frame-Options: SAMEORIGIN
-Etag: W/"4f53cda18c2baa0c0354bb5f9a3ecbe5"
Link: ; rel="first", ; rel="last"
+X-Content-Type-Options: nosniff
+X-Page: 2
+X-Per-Page: 2
+Gitlab-Sv: api-gke-us-east1-b
+Content-Type: application/json
+Etag: W/"4f53cda18c2baa0c0354bb5f9a3ecbe5"
+X-Frame-Options: SAMEORIGIN
+X-Gitlab-Meta: {"correlation_id":"05db2c172a3be5ea9e65494882e77167","version":"1"}
+X-Next-Page:
+Set-Cookie: _cfuvid=UDvTcjnLBRvcY_axm9MwnCJ0PmPtOKE9vnIQ4uoOUGE-1710504207498-0.0.1.1-604800000; path=/; domain=.gitlab.com; HttpOnly; Secure; SameSite=None
+X-Runtime: 0.061429
+X-Total-Pages: 1
+Strict-Transport-Security: max-age=31536000
+Gitlab-Lb: haproxy-main-51-lb-gprd
+Accept-Ranges: bytes
+Content-Length: 2
+Cf-Cache-Status: MISS
+Cache-Control: max-age=0, private, must-revalidate
+Content-Security-Policy: default-src 'none'
+Vary: Origin, Accept-Encoding
+X-Prev-Page:
+X-Total: 2
+Referrer-Policy: strict-origin-when-cross-origin
[]
\ No newline at end of file
diff --git a/services/migrations/testdata/gitlab/full_download/_api_v4_projects_15578026_issues_2_award_emoji!page=1&per_page=2 b/services/migrations/testdata/gitlab/full_download/GET_%2Fapi%2Fv4%2Fprojects%2F15578026%2Fissues%2F2%2Faward_emoji%3Fpage=1&per_page=2
similarity index 84%
rename from services/migrations/testdata/gitlab/full_download/_api_v4_projects_15578026_issues_2_award_emoji!page=1&per_page=2
rename to services/migrations/testdata/gitlab/full_download/GET_%2Fapi%2Fv4%2Fprojects%2F15578026%2Fissues%2F2%2Faward_emoji%3Fpage=1&per_page=2
index db1573c43c..52822db98b 100644
--- a/services/migrations/testdata/gitlab/full_download/_api_v4_projects_15578026_issues_2_award_emoji!page=1&per_page=2
+++ b/services/migrations/testdata/gitlab/full_download/GET_%2Fapi%2Fv4%2Fprojects%2F15578026%2Fissues%2F2%2Faward_emoji%3Fpage=1&per_page=2
@@ -1,24 +1,24 @@
+X-Frame-Options: SAMEORIGIN
+Referrer-Policy: strict-origin-when-cross-origin
+Gitlab-Lb: haproxy-main-40-lb-gprd
+Content-Type: application/json
+Strict-Transport-Security: max-age=31536000
Vary: Origin, Accept-Encoding
-Set-Cookie: _cfuvid=eR1OqXm9Zq42ps0oFIf0s4qBdC4lKtotvp9jBqOVcko-1709516927407-0.0.1.1-604800000; path=/; domain=.gitlab.com; HttpOnly; Secure; SameSite=None
-Content-Security-Policy: default-src 'none'
+X-Page: 1
+X-Runtime: 0.078016
+Link: ; rel="next", ; rel="first", ; rel="last"
+X-Prev-Page:
+X-Total: 6
+X-Total-Pages: 3
X-Content-Type-Options: nosniff
X-Next-Page: 2
-X-Page: 1
-X-Prev-Page:
-X-Total-Pages: 3
-Link: ; rel="next", ; rel="first", ; rel="last"
-Referrer-Policy: strict-origin-when-cross-origin
-X-Total: 6
+Gitlab-Sv: api-gke-us-east1-c
Cache-Control: max-age=0, private, must-revalidate
-X-Per-Page: 2
-Gitlab-Sv: api-gke-us-east1-d
-X-Gitlab-Meta: {"correlation_id":"05328c4fe2465085c0b9a5a5a1103836","version":"1"}
-X-Runtime: 0.075509
-Strict-Transport-Security: max-age=31536000
-Gitlab-Lb: haproxy-main-50-lb-gprd
-Content-Type: application/json
-Etag: W/"5fdbcbf64f34ba0e74ce9dd8d6e0efe3"
-X-Frame-Options: SAMEORIGIN
Cf-Cache-Status: MISS
+Set-Cookie: _cfuvid=YByIjysnuUyVymulLPR72WWURJsjsdM2aiUwKWAGtZI-1710504207733-0.0.1.1-604800000; path=/; domain=.gitlab.com; HttpOnly; Secure; SameSite=None
+Content-Security-Policy: default-src 'none'
+Etag: W/"5fdbcbf64f34ba0e74ce9dd8d6e0efe3"
+X-Gitlab-Meta: {"correlation_id":"2c82a2ec8ad8bdd3c0d2adb0e208f69a","version":"1"}
+X-Per-Page: 2
[{"id":3009627,"name":"thumbsup","user":{"id":1241334,"username":"lafriks","name":"Lauris BH","state":"active","locked":false,"avatar_url":"https://gitlab.com/uploads/-/system/user/avatar/1241334/avatar.png","web_url":"https://gitlab.com/lafriks"},"created_at":"2019-11-28T08:46:42.657Z","updated_at":"2019-11-28T08:46:42.657Z","awardable_id":27687706,"awardable_type":"Issue","url":null},{"id":3009628,"name":"thumbsdown","user":{"id":1241334,"username":"lafriks","name":"Lauris BH","state":"active","locked":false,"avatar_url":"https://gitlab.com/uploads/-/system/user/avatar/1241334/avatar.png","web_url":"https://gitlab.com/lafriks"},"created_at":"2019-11-28T08:46:43.471Z","updated_at":"2019-11-28T08:46:43.471Z","awardable_id":27687706,"awardable_type":"Issue","url":null}]
\ No newline at end of file
diff --git a/services/migrations/testdata/gitlab/full_download/_api_v4_projects_15578026_issues_2_award_emoji!page=2&per_page=2 b/services/migrations/testdata/gitlab/full_download/GET_%2Fapi%2Fv4%2Fprojects%2F15578026%2Fissues%2F2%2Faward_emoji%3Fpage=2&per_page=2
similarity index 85%
rename from services/migrations/testdata/gitlab/full_download/_api_v4_projects_15578026_issues_2_award_emoji!page=2&per_page=2
rename to services/migrations/testdata/gitlab/full_download/GET_%2Fapi%2Fv4%2Fprojects%2F15578026%2Fissues%2F2%2Faward_emoji%3Fpage=2&per_page=2
index d52e358e91..2ebb34db88 100644
--- a/services/migrations/testdata/gitlab/full_download/_api_v4_projects_15578026_issues_2_award_emoji!page=2&per_page=2
+++ b/services/migrations/testdata/gitlab/full_download/GET_%2Fapi%2Fv4%2Fprojects%2F15578026%2Fissues%2F2%2Faward_emoji%3Fpage=2&per_page=2
@@ -1,24 +1,24 @@
-X-Content-Type-Options: nosniff
-X-Runtime: 0.091658
-Set-Cookie: _cfuvid=aVGYOkTTE5ngoJripH93fZ9JhYhafbwSPqzjRZ7JCyk-1709516927910-0.0.1.1-604800000; path=/; domain=.gitlab.com; HttpOnly; Secure; SameSite=None
-Referrer-Policy: strict-origin-when-cross-origin
-X-Frame-Options: SAMEORIGIN
-X-Gitlab-Meta: {"correlation_id":"b1d1356c71e3f52fc9bccd80a711467f","version":"1"}
+X-Gitlab-Meta: {"correlation_id":"3f684de509b846cafc057f0e2982ad76","version":"1"}
X-Prev-Page: 1
+X-Total-Pages: 3
+Gitlab-Lb: haproxy-main-24-lb-gprd
+Gitlab-Sv: api-gke-us-east1-b
+Vary: Origin, Accept-Encoding
+Set-Cookie: _cfuvid=Bs.X45qZvylPDZxkoXQ0YQS72rXFkViMP2IaqBS6C0s-1710504207991-0.0.1.1-604800000; path=/; domain=.gitlab.com; HttpOnly; Secure; SameSite=None
+Etag: W/"d16c513b32212d9286fce6f53340c1cf"
+X-Content-Type-Options: nosniff
+Cache-Control: max-age=0, private, must-revalidate
+X-Next-Page: 3
Strict-Transport-Security: max-age=31536000
-Gitlab-Sv: api-gke-us-east1-c
+Referrer-Policy: strict-origin-when-cross-origin
Content-Type: application/json
Content-Security-Policy: default-src 'none'
-Vary: Origin, Accept-Encoding
+X-Frame-Options: SAMEORIGIN
+X-Runtime: 0.098833
+Cf-Cache-Status: MISS
+Link: ; rel="prev", ; rel="next", ; rel="first", ; rel="last"
X-Page: 2
X-Per-Page: 2
-Cf-Cache-Status: MISS
X-Total: 6
-Gitlab-Lb: haproxy-main-13-lb-gprd
-Etag: W/"d16c513b32212d9286fce6f53340c1cf"
-X-Next-Page: 3
-X-Total-Pages: 3
-Cache-Control: max-age=0, private, must-revalidate
-Link: ; rel="prev", ; rel="next", ; rel="first", ; rel="last"
[{"id":3009632,"name":"laughing","user":{"id":1241334,"username":"lafriks","name":"Lauris BH","state":"active","locked":false,"avatar_url":"https://gitlab.com/uploads/-/system/user/avatar/1241334/avatar.png","web_url":"https://gitlab.com/lafriks"},"created_at":"2019-11-28T08:47:14.381Z","updated_at":"2019-11-28T08:47:14.381Z","awardable_id":27687706,"awardable_type":"Issue","url":null},{"id":3009634,"name":"tada","user":{"id":1241334,"username":"lafriks","name":"Lauris BH","state":"active","locked":false,"avatar_url":"https://gitlab.com/uploads/-/system/user/avatar/1241334/avatar.png","web_url":"https://gitlab.com/lafriks"},"created_at":"2019-11-28T08:47:18.254Z","updated_at":"2019-11-28T08:47:18.254Z","awardable_id":27687706,"awardable_type":"Issue","url":null}]
\ No newline at end of file
diff --git a/services/migrations/testdata/gitlab/full_download/_api_v4_projects_15578026_issues_2_award_emoji!page=3&per_page=2 b/services/migrations/testdata/gitlab/full_download/GET_%2Fapi%2Fv4%2Fprojects%2F15578026%2Fissues%2F2%2Faward_emoji%3Fpage=3&per_page=2
similarity index 84%
rename from services/migrations/testdata/gitlab/full_download/_api_v4_projects_15578026_issues_2_award_emoji!page=3&per_page=2
rename to services/migrations/testdata/gitlab/full_download/GET_%2Fapi%2Fv4%2Fprojects%2F15578026%2Fissues%2F2%2Faward_emoji%3Fpage=3&per_page=2
index e35aa62cdf..23da417c01 100644
--- a/services/migrations/testdata/gitlab/full_download/_api_v4_projects_15578026_issues_2_award_emoji!page=3&per_page=2
+++ b/services/migrations/testdata/gitlab/full_download/GET_%2Fapi%2Fv4%2Fprojects%2F15578026%2Fissues%2F2%2Faward_emoji%3Fpage=3&per_page=2
@@ -1,24 +1,24 @@
-Gitlab-Lb: haproxy-main-13-lb-gprd
-Set-Cookie: _cfuvid=t4_LSY2Wo_P8jPVZKgbX7DhNDlsiazGyv6awHkbP29M-1709516929175-0.0.1.1-604800000; path=/; domain=.gitlab.com; HttpOnly; Secure; SameSite=None
-Cache-Control: max-age=0, private, must-revalidate
-Vary: Origin, Accept-Encoding
-Referrer-Policy: strict-origin-when-cross-origin
-Cf-Cache-Status: MISS
-X-Total: 6
X-Total-Pages: 3
-Etag: W/"165d37bf09a54bb31f4619cca8722cb4"
-Link: ; rel="prev", ; rel="first", ; rel="last"
-Gitlab-Sv: api-gke-us-east1-c
-X-Runtime: 0.084688
-Strict-Transport-Security: max-age=31536000
-Content-Type: application/json
-X-Content-Type-Options: nosniff
-X-Prev-Page: 2
-X-Next-Page:
-X-Page: 3
-X-Frame-Options: SAMEORIGIN
-X-Gitlab-Meta: {"correlation_id":"3d4b896e9b25fba2880f8cf4179b4db3","version":"1"}
Content-Security-Policy: default-src 'none'
+Vary: Origin, Accept-Encoding
+X-Page: 3
+Strict-Transport-Security: max-age=31536000
+Etag: W/"165d37bf09a54bb31f4619cca8722cb4"
+X-Next-Page:
+X-Frame-Options: SAMEORIGIN
+X-Prev-Page: 2
+Cf-Cache-Status: MISS
+Set-Cookie: _cfuvid=HHUVNinfPq8fL7PXFgbDm8yTm6pwWCXctd6JjWwfzY4-1710504208221-0.0.1.1-604800000; path=/; domain=.gitlab.com; HttpOnly; Secure; SameSite=None
+X-Runtime: 0.071448
+X-Total: 6
+Cache-Control: max-age=0, private, must-revalidate
+X-Gitlab-Meta: {"correlation_id":"886dbf65fe0de14ba39622416ae0ca1b","version":"1"}
+Referrer-Policy: strict-origin-when-cross-origin
+Link: ; rel="prev", ; rel="first", ; rel="last"
+X-Content-Type-Options: nosniff
+Content-Type: application/json
+Gitlab-Lb: haproxy-main-50-lb-gprd
+Gitlab-Sv: api-gke-us-east1-d
X-Per-Page: 2
[{"id":3009636,"name":"confused","user":{"id":1241334,"username":"lafriks","name":"Lauris BH","state":"active","locked":false,"avatar_url":"https://gitlab.com/uploads/-/system/user/avatar/1241334/avatar.png","web_url":"https://gitlab.com/lafriks"},"created_at":"2019-11-28T08:47:27.248Z","updated_at":"2019-11-28T08:47:27.248Z","awardable_id":27687706,"awardable_type":"Issue","url":null},{"id":3009640,"name":"hearts","user":{"id":1241334,"username":"lafriks","name":"Lauris BH","state":"active","locked":false,"avatar_url":"https://gitlab.com/uploads/-/system/user/avatar/1241334/avatar.png","web_url":"https://gitlab.com/lafriks"},"created_at":"2019-11-28T08:47:33.059Z","updated_at":"2019-11-28T08:47:33.059Z","awardable_id":27687706,"awardable_type":"Issue","url":null}]
\ No newline at end of file
diff --git a/services/migrations/testdata/gitlab/full_download/_api_v4_projects_15578026_issues_2_award_emoji!page=4&per_page=2 b/services/migrations/testdata/gitlab/full_download/GET_%2Fapi%2Fv4%2Fprojects%2F15578026%2Fissues%2F2%2Faward_emoji%3Fpage=4&per_page=2
similarity index 75%
rename from services/migrations/testdata/gitlab/full_download/_api_v4_projects_15578026_issues_2_award_emoji!page=4&per_page=2
rename to services/migrations/testdata/gitlab/full_download/GET_%2Fapi%2Fv4%2Fprojects%2F15578026%2Fissues%2F2%2Faward_emoji%3Fpage=4&per_page=2
index 2c757e2034..086cfcd3b5 100644
--- a/services/migrations/testdata/gitlab/full_download/_api_v4_projects_15578026_issues_2_award_emoji!page=4&per_page=2
+++ b/services/migrations/testdata/gitlab/full_download/GET_%2Fapi%2Fv4%2Fprojects%2F15578026%2Fissues%2F2%2Faward_emoji%3Fpage=4&per_page=2
@@ -1,26 +1,26 @@
-Vary: Origin, Accept-Encoding
-Content-Length: 2
-Etag: W/"4f53cda18c2baa0c0354bb5f9a3ecbe5"
-X-Next-Page:
-X-Page: 4
-Strict-Transport-Security: max-age=31536000
-Gitlab-Lb: haproxy-main-40-lb-gprd
-Set-Cookie: _cfuvid=V6zFYEypjQbDjYSsP9fTmKa2nKJP5kvVJDoSbH7rU34-1709516930295-0.0.1.1-604800000; path=/; domain=.gitlab.com; HttpOnly; Secure; SameSite=None
-Content-Type: application/json
-X-Gitlab-Meta: {"correlation_id":"58338440ce0dd25dea95208140617efc","version":"1"}
X-Total-Pages: 3
-Cf-Cache-Status: MISS
-Cache-Control: max-age=0, private, must-revalidate
+Gitlab-Lb: haproxy-main-52-lb-gprd
+X-Next-Page:
+Content-Security-Policy: default-src 'none'
+Content-Type: application/json
+Content-Length: 2
+X-Content-Type-Options: nosniff
+X-Per-Page: 2
+X-Runtime: 0.083061
+Referrer-Policy: strict-origin-when-cross-origin
+X-Gitlab-Meta: {"correlation_id":"561369f96102c1a6ab8acd558d16a4d0","version":"1"}
+X-Prev-Page:
+Vary: Origin, Accept-Encoding
X-Frame-Options: SAMEORIGIN
X-Total: 6
-X-Prev-Page:
-Accept-Ranges: bytes
-X-Content-Type-Options: nosniff
-X-Runtime: 0.052295
-Referrer-Policy: strict-origin-when-cross-origin
-Gitlab-Sv: api-gke-us-east1-c
-Content-Security-Policy: default-src 'none'
-X-Per-Page: 2
+Cache-Control: max-age=0, private, must-revalidate
Link: ; rel="first", ; rel="last"
+Gitlab-Sv: api-gke-us-east1-c
+Accept-Ranges: bytes
+Strict-Transport-Security: max-age=31536000
+Cf-Cache-Status: MISS
+Set-Cookie: _cfuvid=GkrvFxTx5xbwrDM0Jz5hSAycmMJcwb02y6n04i5gv2s-1710504208464-0.0.1.1-604800000; path=/; domain=.gitlab.com; HttpOnly; Secure; SameSite=None
+Etag: W/"4f53cda18c2baa0c0354bb5f9a3ecbe5"
+X-Page: 4
[]
\ No newline at end of file
diff --git a/services/migrations/testdata/gitlab/full_download/_api_v4_projects_15578026_issues_2_discussions!page=1&per_page=100 b/services/migrations/testdata/gitlab/full_download/GET_%2Fapi%2Fv4%2Fprojects%2F15578026%2Fissues%2F2%2Fdiscussions%3Fpage=1&per_page=100
similarity index 93%
rename from services/migrations/testdata/gitlab/full_download/_api_v4_projects_15578026_issues_2_discussions!page=1&per_page=100
rename to services/migrations/testdata/gitlab/full_download/GET_%2Fapi%2Fv4%2Fprojects%2F15578026%2Fissues%2F2%2Fdiscussions%3Fpage=1&per_page=100
index 2dc290a405..6b62a85016 100644
--- a/services/migrations/testdata/gitlab/full_download/_api_v4_projects_15578026_issues_2_discussions!page=1&per_page=100
+++ b/services/migrations/testdata/gitlab/full_download/GET_%2Fapi%2Fv4%2Fprojects%2F15578026%2Fissues%2F2%2Fdiscussions%3Fpage=1&per_page=100
@@ -1,24 +1,24 @@
-X-Gitlab-Meta: {"correlation_id":"f7ea96beef459528c06bcf21a37f8950","version":"1"}
-X-Per-Page: 100
-X-Runtime: 0.294630
-Cache-Control: max-age=0, private, must-revalidate
-Gitlab-Sv: gke-cny-api
-X-Frame-Options: SAMEORIGIN
-X-Next-Page:
-Etag: W/"bcc91e8a7b2eac98b4d96ae791e0649d"
-X-Total: 4
-X-Page: 1
-Referrer-Policy: strict-origin-when-cross-origin
-Gitlab-Lb: haproxy-main-32-lb-gprd
Strict-Transport-Security: max-age=31536000
-Set-Cookie: _cfuvid=bVDOhVwoTt.rATMQeCGhPoIH4lvwoCZQqEHaWL0EOVY-1709516931074-0.0.1.1-604800000; path=/; domain=.gitlab.com; HttpOnly; Secure; SameSite=None
-Link: ; rel="first", ; rel="last"
-X-Content-Type-Options: nosniff
-X-Prev-Page:
+Gitlab-Lb: haproxy-main-32-lb-gprd
Content-Type: application/json
-Cf-Cache-Status: MISS
-Content-Security-Policy: default-src 'none'
-Vary: Origin, Accept-Encoding
+Link: ; rel="first", ; rel="last"
+Set-Cookie: _cfuvid=CZZEZqJQZ97MpqkqjenLKOUdtc5tMbwPjVBKat9VrFo-1710504208832-0.0.1.1-604800000; path=/; domain=.gitlab.com; HttpOnly; Secure; SameSite=None
+Cache-Control: max-age=0, private, must-revalidate
+Referrer-Policy: strict-origin-when-cross-origin
+Gitlab-Sv: gke-cny-api
X-Total-Pages: 1
+X-Page: 1
+X-Per-Page: 100
+X-Total: 4
+X-Content-Type-Options: nosniff
+X-Runtime: 0.215193
+X-Frame-Options: SAMEORIGIN
+Vary: Origin, Accept-Encoding
+X-Gitlab-Meta: {"correlation_id":"d84b389e2f5604d766104c7236dbfdf8","version":"1"}
+X-Next-Page:
+Content-Security-Policy: default-src 'none'
+Etag: W/"bcc91e8a7b2eac98b4d96ae791e0649d"
+X-Prev-Page:
+Cf-Cache-Status: MISS
[{"id":"617967369d98d8b73b6105a40318fe839f931a24","individual_note":true,"notes":[{"id":251637434,"type":null,"body":"This is a comment","attachment":null,"author":{"id":1241334,"username":"lafriks","name":"Lauris BH","state":"active","locked":false,"avatar_url":"https://gitlab.com/uploads/-/system/user/avatar/1241334/avatar.png","web_url":"https://gitlab.com/lafriks"},"created_at":"2019-11-28T08:44:52.501Z","updated_at":"2019-11-28T08:44:52.501Z","system":false,"noteable_id":27687706,"noteable_type":"Issue","project_id":15578026,"resolvable":false,"confidential":false,"internal":false,"noteable_iid":2,"commands_changes":{}}]},{"id":"b92d74daee411a17d844041bcd3c267ade58f680","individual_note":true,"notes":[{"id":251637528,"type":null,"body":"changed milestone to %2","attachment":null,"author":{"id":1241334,"username":"lafriks","name":"Lauris BH","state":"active","locked":false,"avatar_url":"https://gitlab.com/uploads/-/system/user/avatar/1241334/avatar.png","web_url":"https://gitlab.com/lafriks"},"created_at":"2019-11-28T08:45:02.329Z","updated_at":"2019-11-28T08:45:02.335Z","system":true,"noteable_id":27687706,"noteable_type":"Issue","project_id":15578026,"resolvable":false,"confidential":false,"internal":false,"noteable_iid":2,"commands_changes":{}}]},{"id":"6010f567d2b58758ef618070372c97891ac75349","individual_note":true,"notes":[{"id":251637892,"type":null,"body":"closed","attachment":null,"author":{"id":1241334,"username":"lafriks","name":"Lauris BH","state":"active","locked":false,"avatar_url":"https://gitlab.com/uploads/-/system/user/avatar/1241334/avatar.png","web_url":"https://gitlab.com/lafriks"},"created_at":"2019-11-28T08:45:45.007Z","updated_at":"2019-11-28T08:45:45.010Z","system":true,"noteable_id":27687706,"noteable_type":"Issue","project_id":15578026,"resolvable":false,"confidential":false,"internal":false,"noteable_iid":2,"commands_changes":{}}]},{"id":"632d0cbfd6a1a08f38aaf9ef7715116f4b188ebb","individual_note":true,"notes":[{"id":251637999,"type":null,"body":"A second comment","attachment":null,"author":{"id":1241334,"username":"lafriks","name":"Lauris BH","state":"active","locked":false,"avatar_url":"https://gitlab.com/uploads/-/system/user/avatar/1241334/avatar.png","web_url":"https://gitlab.com/lafriks"},"created_at":"2019-11-28T08:45:53.501Z","updated_at":"2019-11-28T08:45:53.501Z","system":false,"noteable_id":27687706,"noteable_type":"Issue","project_id":15578026,"resolvable":false,"confidential":false,"internal":false,"noteable_iid":2,"commands_changes":{}}]}]
\ No newline at end of file
diff --git a/services/migrations/testdata/gitlab/full_download/_api_v4_projects_15578026_issues_2_resource_state_events!page=1&per_page=100 b/services/migrations/testdata/gitlab/full_download/GET_%2Fapi%2Fv4%2Fprojects%2F15578026%2Fissues%2F2%2Fresource_state_events%3Fpage=1&per_page=100
similarity index 73%
rename from services/migrations/testdata/gitlab/full_download/_api_v4_projects_15578026_issues_2_resource_state_events!page=1&per_page=100
rename to services/migrations/testdata/gitlab/full_download/GET_%2Fapi%2Fv4%2Fprojects%2F15578026%2Fissues%2F2%2Fresource_state_events%3Fpage=1&per_page=100
index a67d0c45b7..33dce623cf 100644
--- a/services/migrations/testdata/gitlab/full_download/_api_v4_projects_15578026_issues_2_resource_state_events!page=1&per_page=100
+++ b/services/migrations/testdata/gitlab/full_download/GET_%2Fapi%2Fv4%2Fprojects%2F15578026%2Fissues%2F2%2Fresource_state_events%3Fpage=1&per_page=100
@@ -1,26 +1,26 @@
-Cf-Cache-Status: MISS
-Etag: W/"4f53cda18c2baa0c0354bb5f9a3ecbe5"
-X-Content-Type-Options: nosniff
-Referrer-Policy: strict-origin-when-cross-origin
-Gitlab-Lb: haproxy-main-52-lb-gprd
-Content-Length: 2
-X-Prev-Page:
-Set-Cookie: _cfuvid=W2TdoA.hvJeMOjx.ZmMBWpZVvCP6nNxmeM6PQsr8.Kw-1709516931498-0.0.1.1-604800000; path=/; domain=.gitlab.com; HttpOnly; Secure; SameSite=None
-Link: ; rel="first", ; rel="last"
-X-Frame-Options: SAMEORIGIN
-Strict-Transport-Security: max-age=31536000
-Vary: Origin, Accept-Encoding
-Content-Security-Policy: default-src 'none'
-X-Gitlab-Meta: {"correlation_id":"527e08a612a163b94cd95046842d5e64","version":"1"}
-X-Page: 1
+Cache-Control: max-age=0, private, must-revalidate
+X-Gitlab-Meta: {"correlation_id":"9564d6f62bbab2cb1f60ca66015e3840","version":"1"}
+X-Runtime: 0.091327
X-Per-Page: 100
X-Total: 0
-Content-Type: application/json
-Accept-Ranges: bytes
-Cache-Control: max-age=0, private, must-revalidate
-X-Next-Page:
X-Total-Pages: 1
-Gitlab-Sv: api-gke-us-east1-c
-X-Runtime: 0.123529
+Gitlab-Sv: api-gke-us-east1-d
+Cf-Cache-Status: MISS
+X-Prev-Page:
+Content-Length: 2
+Content-Security-Policy: default-src 'none'
+X-Content-Type-Options: nosniff
+X-Frame-Options: SAMEORIGIN
+X-Next-Page:
+Link: ; rel="first", ; rel="last"
+Vary: Origin, Accept-Encoding
+Set-Cookie: _cfuvid=JAECWgzRO1L40L3GhX4c7HSSpyYna2z1sybaZdKrJ18-1710504209104-0.0.1.1-604800000; path=/; domain=.gitlab.com; HttpOnly; Secure; SameSite=None
+Strict-Transport-Security: max-age=31536000
+Referrer-Policy: strict-origin-when-cross-origin
+Gitlab-Lb: haproxy-main-11-lb-gprd
+Content-Type: application/json
+Etag: W/"4f53cda18c2baa0c0354bb5f9a3ecbe5"
+X-Page: 1
+Accept-Ranges: bytes
[]
\ No newline at end of file
diff --git a/services/migrations/testdata/gitlab/full_download/_api_v4_projects_15578026_issues!page=1&per_page=2&sort=asc&state=all b/services/migrations/testdata/gitlab/full_download/GET_%2Fapi%2Fv4%2Fprojects%2F15578026%2Fissues%3Fpage=1&per_page=2&sort=asc&state=all
similarity index 94%
rename from services/migrations/testdata/gitlab/full_download/_api_v4_projects_15578026_issues!page=1&per_page=2&sort=asc&state=all
rename to services/migrations/testdata/gitlab/full_download/GET_%2Fapi%2Fv4%2Fprojects%2F15578026%2Fissues%3Fpage=1&per_page=2&sort=asc&state=all
index 17139efa29..ff6128e8ac 100644
--- a/services/migrations/testdata/gitlab/full_download/_api_v4_projects_15578026_issues!page=1&per_page=2&sort=asc&state=all
+++ b/services/migrations/testdata/gitlab/full_download/GET_%2Fapi%2Fv4%2Fprojects%2F15578026%2Fissues%3Fpage=1&per_page=2&sort=asc&state=all
@@ -1,24 +1,24 @@
+Content-Security-Policy: default-src 'none'
+Etag: W/"4c0531a3595f741f229f5a105e013b95"
+Link: ; rel="first", ; rel="last"
+X-Next-Page:
+Cf-Cache-Status: MISS
+Strict-Transport-Security: max-age=31536000
X-Content-Type-Options: nosniff
-X-Per-Page: 2
-X-Total-Pages: 1
-Content-Type: application/json
-X-Prev-Page:
X-Total: 2
+X-Total-Pages: 1
+Gitlab-Lb: haproxy-main-16-lb-gprd
Cache-Control: max-age=0, private, must-revalidate
Vary: Origin, Accept-Encoding
-Referrer-Policy: strict-origin-when-cross-origin
-Gitlab-Sv: api-gke-us-east1-d
-X-Gitlab-Meta: {"correlation_id":"52846fcab419461a2c2f29f707dbd103","version":"1"}
-X-Next-Page:
-Strict-Transport-Security: max-age=31536000
-Cf-Cache-Status: MISS
-Link: ; rel="first", ; rel="last"
-Etag: W/"4c0531a3595f741f229f5a105e013b95"
-X-Frame-Options: SAMEORIGIN
+X-Runtime: 0.143514
+Gitlab-Sv: api-gke-us-east1-c
+X-Gitlab-Meta: {"correlation_id":"6e8b9d619f3148fd839ba0c5f6747df9","version":"1"}
X-Page: 1
-Content-Security-Policy: default-src 'none'
-Set-Cookie: _cfuvid=0ScIwDvsVw_dRSgtT9czuTLY6R5TGzB2UIk9653BEf0-1709516924974-0.0.1.1-604800000; path=/; domain=.gitlab.com; HttpOnly; Secure; SameSite=None
-Gitlab-Lb: haproxy-main-38-lb-gprd
-X-Runtime: 0.187797
+Content-Type: application/json
+X-Per-Page: 2
+Referrer-Policy: strict-origin-when-cross-origin
+X-Frame-Options: SAMEORIGIN
+X-Prev-Page:
+Set-Cookie: _cfuvid=9pOTnEAVQzMgmNMabGvRXD3ad16MkUCZTAQQameWnO8-1710504206909-0.0.1.1-604800000; path=/; domain=.gitlab.com; HttpOnly; Secure; SameSite=None
[{"id":27687675,"iid":1,"project_id":15578026,"title":"Please add an animated gif icon to the merge button","description":"I just want the merge button to hurt my eyes a little. :stuck_out_tongue_closed_eyes:","state":"closed","created_at":"2019-11-28T08:43:35.459Z","updated_at":"2019-11-28T08:46:23.304Z","closed_at":"2019-11-28T08:46:23.275Z","closed_by":{"id":1241334,"username":"lafriks","name":"Lauris BH","state":"active","locked":false,"avatar_url":"https://gitlab.com/uploads/-/system/user/avatar/1241334/avatar.png","web_url":"https://gitlab.com/lafriks"},"labels":["bug","discussion"],"milestone":{"id":1082926,"iid":1,"project_id":15578026,"title":"1.0.0","description":"","state":"closed","created_at":"2019-11-28T08:42:30.301Z","updated_at":"2019-11-28T15:57:52.401Z","due_date":null,"start_date":null,"expired":false,"web_url":"https://gitlab.com/gitea/test_repo/-/milestones/1"},"assignees":[],"author":{"id":1241334,"username":"lafriks","name":"Lauris BH","state":"active","locked":false,"avatar_url":"https://gitlab.com/uploads/-/system/user/avatar/1241334/avatar.png","web_url":"https://gitlab.com/lafriks"},"type":"ISSUE","assignee":null,"user_notes_count":0,"merge_requests_count":0,"upvotes":1,"downvotes":0,"due_date":null,"confidential":false,"discussion_locked":null,"issue_type":"issue","web_url":"https://gitlab.com/gitea/test_repo/-/issues/1","time_stats":{"time_estimate":0,"total_time_spent":0,"human_time_estimate":null,"human_total_time_spent":null},"task_completion_status":{"count":0,"completed_count":0},"blocking_issues_count":0,"has_tasks":true,"task_status":"0 of 0 checklist items completed","_links":{"self":"https://gitlab.com/api/v4/projects/15578026/issues/1","notes":"https://gitlab.com/api/v4/projects/15578026/issues/1/notes","award_emoji":"https://gitlab.com/api/v4/projects/15578026/issues/1/award_emoji","project":"https://gitlab.com/api/v4/projects/15578026","closed_as_duplicate_of":null},"references":{"short":"#1","relative":"#1","full":"gitea/test_repo#1"},"severity":"UNKNOWN","moved_to_id":null,"service_desk_reply_to":null},{"id":27687706,"iid":2,"project_id":15578026,"title":"Test issue","description":"This is test issue 2, do not touch!","state":"closed","created_at":"2019-11-28T08:44:46.277Z","updated_at":"2019-11-28T08:45:44.987Z","closed_at":"2019-11-28T08:45:44.959Z","closed_by":{"id":1241334,"username":"lafriks","name":"Lauris BH","state":"active","locked":false,"avatar_url":"https://gitlab.com/uploads/-/system/user/avatar/1241334/avatar.png","web_url":"https://gitlab.com/lafriks"},"labels":["duplicate"],"milestone":{"id":1082927,"iid":2,"project_id":15578026,"title":"1.1.0","description":"","state":"active","created_at":"2019-11-28T08:42:44.575Z","updated_at":"2019-11-28T08:42:44.575Z","due_date":null,"start_date":null,"expired":false,"web_url":"https://gitlab.com/gitea/test_repo/-/milestones/2"},"assignees":[],"author":{"id":1241334,"username":"lafriks","name":"Lauris BH","state":"active","locked":false,"avatar_url":"https://gitlab.com/uploads/-/system/user/avatar/1241334/avatar.png","web_url":"https://gitlab.com/lafriks"},"type":"ISSUE","assignee":null,"user_notes_count":2,"merge_requests_count":0,"upvotes":1,"downvotes":1,"due_date":null,"confidential":false,"discussion_locked":null,"issue_type":"issue","web_url":"https://gitlab.com/gitea/test_repo/-/issues/2","time_stats":{"time_estimate":0,"total_time_spent":0,"human_time_estimate":null,"human_total_time_spent":null},"task_completion_status":{"count":0,"completed_count":0},"blocking_issues_count":0,"has_tasks":true,"task_status":"0 of 0 checklist items completed","_links":{"self":"https://gitlab.com/api/v4/projects/15578026/issues/2","notes":"https://gitlab.com/api/v4/projects/15578026/issues/2/notes","award_emoji":"https://gitlab.com/api/v4/projects/15578026/issues/2/award_emoji","project":"https://gitlab.com/api/v4/projects/15578026","closed_as_duplicate_of":null},"references":{"short":"#2","relative":"#2","full":"gitea/test_repo#2"},"severity":"UNKNOWN","moved_to_id":null,"service_desk_reply_to":null}]
\ No newline at end of file
diff --git a/services/migrations/testdata/gitlab/full_download/_api_v4_projects_15578026_labels!page=1&per_page=100 b/services/migrations/testdata/gitlab/full_download/GET_%2Fapi%2Fv4%2Fprojects%2F15578026%2Flabels%3Fpage=1&per_page=100
similarity index 88%
rename from services/migrations/testdata/gitlab/full_download/_api_v4_projects_15578026_labels!page=1&per_page=100
rename to services/migrations/testdata/gitlab/full_download/GET_%2Fapi%2Fv4%2Fprojects%2F15578026%2Flabels%3Fpage=1&per_page=100
index 03a46d057b..95924923d1 100644
--- a/services/migrations/testdata/gitlab/full_download/_api_v4_projects_15578026_labels!page=1&per_page=100
+++ b/services/migrations/testdata/gitlab/full_download/GET_%2Fapi%2Fv4%2Fprojects%2F15578026%2Flabels%3Fpage=1&per_page=100
@@ -1,24 +1,24 @@
-X-Prev-Page:
-Referrer-Policy: strict-origin-when-cross-origin
-Content-Type: application/json
X-Per-Page: 100
+X-Prev-Page:
X-Total: 9
-X-Runtime: 0.114167
-X-Total-Pages: 1
-Set-Cookie: _cfuvid=UMIyFl_InnSbX4Uxs5X.6ssGMrTVlv5uJzGE_UhDR3w-1709516923392-0.0.1.1-604800000; path=/; domain=.gitlab.com; HttpOnly; Secure; SameSite=None
-Cache-Control: max-age=0, private, must-revalidate
-Link: ; rel="first", ; rel="last"
+Content-Type: application/json
+X-Next-Page:
X-Content-Type-Options: nosniff
-Gitlab-Sv: api-gke-us-east1-b
+Gitlab-Lb: haproxy-main-56-lb-gprd
+Cf-Cache-Status: MISS
+Set-Cookie: _cfuvid=5K2rwnMRyftEWt3OXSN3FeV8T9nf3Cgb20WFj.p4hyw-1710504206334-0.0.1.1-604800000; path=/; domain=.gitlab.com; HttpOnly; Secure; SameSite=None
+Cache-Control: max-age=0, private, must-revalidate
+X-Runtime: 0.424823
+Strict-Transport-Security: max-age=31536000
+Link: ; rel="first", ; rel="last"
Content-Security-Policy: default-src 'none'
Vary: Origin, Accept-Encoding
-X-Next-Page:
-X-Frame-Options: SAMEORIGIN
-X-Gitlab-Meta: {"correlation_id":"3b4e48efc61f09520ea23b3bca5ea469","version":"1"}
+X-Gitlab-Meta: {"correlation_id":"b02b63b76c2351a971670a8db9c57af9","version":"1"}
X-Page: 1
-Cf-Cache-Status: MISS
+X-Total-Pages: 1
Etag: W/"5a3fb9bc7b1018070943f4aa1353f8b6"
-Strict-Transport-Security: max-age=31536000
-Gitlab-Lb: haproxy-main-30-lb-gprd
+X-Frame-Options: SAMEORIGIN
+Referrer-Policy: strict-origin-when-cross-origin
+Gitlab-Sv: api-gke-us-east1-d
[{"id":12959095,"name":"bug","description":null,"description_html":"","text_color":"#FFFFFF","color":"#d9534f","subscribed":false,"priority":null,"is_project_label":true},{"id":12959097,"name":"confirmed","description":null,"description_html":"","text_color":"#FFFFFF","color":"#d9534f","subscribed":false,"priority":null,"is_project_label":true},{"id":12959096,"name":"critical","description":null,"description_html":"","text_color":"#FFFFFF","color":"#d9534f","subscribed":false,"priority":null,"is_project_label":true},{"id":12959100,"name":"discussion","description":null,"description_html":"","text_color":"#FFFFFF","color":"#428bca","subscribed":false,"priority":null,"is_project_label":true},{"id":12959098,"name":"documentation","description":null,"description_html":"","text_color":"#1F1E24","color":"#f0ad4e","subscribed":false,"priority":null,"is_project_label":true},{"id":12959554,"name":"duplicate","description":null,"description_html":"","text_color":"#FFFFFF","color":"#7F8C8D","subscribed":false,"priority":null,"is_project_label":true},{"id":12959102,"name":"enhancement","description":null,"description_html":"","text_color":"#FFFFFF","color":"#5cb85c","subscribed":false,"priority":null,"is_project_label":true},{"id":12959101,"name":"suggestion","description":null,"description_html":"","text_color":"#FFFFFF","color":"#428bca","subscribed":false,"priority":null,"is_project_label":true},{"id":12959099,"name":"support","description":null,"description_html":"","text_color":"#1F1E24","color":"#f0ad4e","subscribed":false,"priority":null,"is_project_label":true}]
\ No newline at end of file
diff --git a/services/migrations/testdata/gitlab/full_download/_api_v4_projects_15578026_merge_requests_1_approvals b/services/migrations/testdata/gitlab/full_download/GET_%2Fapi%2Fv4%2Fprojects%2F15578026%2Fmerge_requests%2F1%2Fapprovals
similarity index 84%
rename from services/migrations/testdata/gitlab/full_download/_api_v4_projects_15578026_merge_requests_1_approvals
rename to services/migrations/testdata/gitlab/full_download/GET_%2Fapi%2Fv4%2Fprojects%2F15578026%2Fmerge_requests%2F1%2Fapprovals
index 7a3ab6b858..6a16667f83 100644
--- a/services/migrations/testdata/gitlab/full_download/_api_v4_projects_15578026_merge_requests_1_approvals
+++ b/services/migrations/testdata/gitlab/full_download/GET_%2Fapi%2Fv4%2Fprojects%2F15578026%2Fmerge_requests%2F1%2Fapprovals
@@ -1,17 +1,17 @@
+Gitlab-Sv: api-gke-us-east1-c
+Set-Cookie: _cfuvid=zeoNBfBKfrdVGUvp0nfh4oigIhB1U14XXmzniKufB0A-1710504211497-0.0.1.1-604800000; path=/; domain=.gitlab.com; HttpOnly; Secure; SameSite=None
+X-Runtime: 0.137677
Cache-Control: max-age=0, private, must-revalidate
-Content-Security-Policy: default-src 'none'
-Strict-Transport-Security: max-age=31536000
-X-Content-Type-Options: nosniff
-X-Frame-Options: SAMEORIGIN
-Set-Cookie: _cfuvid=z0y3rhqnpB208dDD5k02RKi_y6HV6.i7lc65_MGJIHM-1709516935718-0.0.1.1-604800000; path=/; domain=.gitlab.com; HttpOnly; Secure; SameSite=None
-Content-Type: application/json
Vary: Origin, Accept-Encoding
-Gitlab-Sv: api-gke-us-east1-d
-Referrer-Policy: strict-origin-when-cross-origin
-Gitlab-Lb: haproxy-main-38-lb-gprd
-Cf-Cache-Status: MISS
+X-Frame-Options: SAMEORIGIN
+X-Gitlab-Meta: {"correlation_id":"8585fe858d5623c4d3d1b77cfcdad845","version":"1"}
+Content-Security-Policy: default-src 'none'
Etag: W/"632b3d0f41fe1650d82b84feaa7b125d"
-X-Gitlab-Meta: {"correlation_id":"68a6a29f5330b299ef95868936bd1b4b","version":"1"}
-X-Runtime: 0.150028
+Strict-Transport-Security: max-age=31536000
+Cf-Cache-Status: MISS
+Content-Type: application/json
+X-Content-Type-Options: nosniff
+Referrer-Policy: strict-origin-when-cross-origin
+Gitlab-Lb: haproxy-main-55-lb-gprd
{"id":43486906,"iid":1,"project_id":15578026,"title":"Update README.md","description":"add warning to readme","state":"merged","created_at":"2019-11-28T08:54:41.034Z","updated_at":"2019-11-28T16:02:08.377Z","merge_status":"can_be_merged","approved":true,"approvals_required":0,"approvals_left":0,"require_password_to_approve":false,"approved_by":[{"user":{"id":527793,"username":"axifive","name":"Alexey Terentyev","state":"active","locked":false,"avatar_url":"https://secure.gravatar.com/avatar/b5eee878c9129969b55d221a823fd15e55aad8dc15d521f4170e3c93728e02b6?s=80\u0026d=identicon","web_url":"https://gitlab.com/axifive"}},{"user":{"id":4102996,"username":"zeripath","name":"zeripath","state":"active","locked":false,"avatar_url":"https://secure.gravatar.com/avatar/3bad2cdad37aa0bbb3ad276ce8f77e32a1a9567a7083f0866d8df8ed0e92e5b5?s=80\u0026d=identicon","web_url":"https://gitlab.com/zeripath"}}],"suggested_approvers":[],"approvers":[],"approver_groups":[],"user_has_approved":false,"user_can_approve":false,"approval_rules_left":[],"has_approval_rules":true,"merge_request_approvers_available":false,"multiple_approval_rules_available":false,"invalid_approvers_rules":[]}
\ No newline at end of file
diff --git a/services/migrations/testdata/gitlab/full_download/_api_v4_projects_15578026_merge_requests_2 b/services/migrations/testdata/gitlab/full_download/GET_%2Fapi%2Fv4%2Fprojects%2F15578026%2Fmerge_requests%2F2
similarity index 91%
rename from services/migrations/testdata/gitlab/full_download/_api_v4_projects_15578026_merge_requests_2
rename to services/migrations/testdata/gitlab/full_download/GET_%2Fapi%2Fv4%2Fprojects%2F15578026%2Fmerge_requests%2F2
index 73441c917c..8848af8e48 100644
--- a/services/migrations/testdata/gitlab/full_download/_api_v4_projects_15578026_merge_requests_2
+++ b/services/migrations/testdata/gitlab/full_download/GET_%2Fapi%2Fv4%2Fprojects%2F15578026%2Fmerge_requests%2F2
@@ -1,17 +1,17 @@
-X-Content-Type-Options: nosniff
-X-Gitlab-Meta: {"correlation_id":"d351bb99dc07c885c71d8f5299208320","version":"1"}
-Gitlab-Lb: haproxy-main-56-lb-gprd
-X-Frame-Options: SAMEORIGIN
-Content-Type: application/json
-Referrer-Policy: strict-origin-when-cross-origin
-X-Runtime: 0.237643
-Strict-Transport-Security: max-age=31536000
-Gitlab-Sv: api-gke-us-east1-d
Cache-Control: max-age=0, private, must-revalidate
-Content-Security-Policy: default-src 'none'
+X-Content-Type-Options: nosniff
Etag: W/"914149155d75f8d8f7ed2e5351f0fadb"
+Referrer-Policy: strict-origin-when-cross-origin
+Content-Security-Policy: default-src 'none'
Vary: Origin, Accept-Encoding
+X-Runtime: 0.634688
Cf-Cache-Status: MISS
-Set-Cookie: _cfuvid=yE9p3NWSIseWCeQl9amdJ0bfdfTyf7TIEOGJSzjcxTQ-1709516933254-0.0.1.1-604800000; path=/; domain=.gitlab.com; HttpOnly; Secure; SameSite=None
+Set-Cookie: _cfuvid=Z._ut3jKk_GobWpwV3pdT8AP8FDBG3hXVJphHhFBiBg-1710504210170-0.0.1.1-604800000; path=/; domain=.gitlab.com; HttpOnly; Secure; SameSite=None
+Content-Type: application/json
+X-Gitlab-Meta: {"correlation_id":"c36a4f0267a05143404246325892000a","version":"1"}
+Strict-Transport-Security: max-age=31536000
+Gitlab-Lb: haproxy-main-59-lb-gprd
+Gitlab-Sv: api-gke-us-east1-d
+X-Frame-Options: SAMEORIGIN
{"id":43524600,"iid":2,"project_id":15578026,"title":"Test branch","description":"do not merge this PR","state":"opened","created_at":"2019-11-28T15:56:54.104Z","updated_at":"2020-04-19T19:24:21.108Z","merged_by":null,"merge_user":null,"merged_at":null,"closed_by":null,"closed_at":null,"target_branch":"master","source_branch":"feat/test","user_notes_count":0,"upvotes":1,"downvotes":0,"author":{"id":1241334,"username":"lafriks","name":"Lauris BH","state":"active","locked":false,"avatar_url":"https://gitlab.com/uploads/-/system/user/avatar/1241334/avatar.png","web_url":"https://gitlab.com/lafriks"},"assignees":[],"assignee":null,"reviewers":[],"source_project_id":15578026,"target_project_id":15578026,"labels":["bug"],"draft":false,"work_in_progress":false,"milestone":{"id":1082926,"iid":1,"project_id":15578026,"title":"1.0.0","description":"","state":"closed","created_at":"2019-11-28T08:42:30.301Z","updated_at":"2019-11-28T15:57:52.401Z","due_date":null,"start_date":null,"expired":false,"web_url":"https://gitlab.com/gitea/test_repo/-/milestones/1"},"merge_when_pipeline_succeeds":false,"merge_status":"can_be_merged","detailed_merge_status":"mergeable","sha":"9f733b96b98a4175276edf6a2e1231489c3bdd23","merge_commit_sha":null,"squash_commit_sha":null,"discussion_locked":null,"should_remove_source_branch":null,"force_remove_source_branch":true,"prepared_at":"2019-11-28T15:56:54.104Z","reference":"!2","references":{"short":"!2","relative":"!2","full":"gitea/test_repo!2"},"web_url":"https://gitlab.com/gitea/test_repo/-/merge_requests/2","time_stats":{"time_estimate":0,"total_time_spent":0,"human_time_estimate":null,"human_total_time_spent":null},"squash":true,"squash_on_merge":true,"task_completion_status":{"count":0,"completed_count":0},"has_conflicts":false,"blocking_discussions_resolved":true,"approvals_before_merge":null,"subscribed":false,"changes_count":"1","latest_build_started_at":null,"latest_build_finished_at":null,"first_deployed_to_production_at":null,"pipeline":null,"head_pipeline":null,"diff_refs":{"base_sha":"c59c9b451acca9d106cc19d61d87afe3fbbb8b83","head_sha":"9f733b96b98a4175276edf6a2e1231489c3bdd23","start_sha":"c59c9b451acca9d106cc19d61d87afe3fbbb8b83"},"merge_error":null,"first_contribution":false,"user":{"can_merge":false}}
\ No newline at end of file
diff --git a/services/migrations/testdata/gitlab/full_download/_api_v4_projects_15578026_merge_requests_2_approvals b/services/migrations/testdata/gitlab/full_download/GET_%2Fapi%2Fv4%2Fprojects%2F15578026%2Fmerge_requests%2F2%2Fapprovals
similarity index 88%
rename from services/migrations/testdata/gitlab/full_download/_api_v4_projects_15578026_merge_requests_2_approvals
rename to services/migrations/testdata/gitlab/full_download/GET_%2Fapi%2Fv4%2Fprojects%2F15578026%2Fmerge_requests%2F2%2Fapprovals
index e9e5f3ad0c..be119c18b7 100644
--- a/services/migrations/testdata/gitlab/full_download/_api_v4_projects_15578026_merge_requests_2_approvals
+++ b/services/migrations/testdata/gitlab/full_download/GET_%2Fapi%2Fv4%2Fprojects%2F15578026%2Fmerge_requests%2F2%2Fapprovals
@@ -1,17 +1,17 @@
-Gitlab-Sv: api-gke-us-east1-c
+Set-Cookie: _cfuvid=sImrE_lz4VAFrw_o2FHA_8y6kxUoFm4G31.BEqR9M_E-1710504211811-0.0.1.1-604800000; path=/; domain=.gitlab.com; HttpOnly; Secure; SameSite=None
+X-Content-Type-Options: nosniff
+X-Frame-Options: SAMEORIGIN
+X-Gitlab-Meta: {"correlation_id":"cf4eeb7f9cb45f6d15ef0297231a3250","version":"1"}
+X-Runtime: 0.163465
Content-Type: application/json
Vary: Origin, Accept-Encoding
-Gitlab-Lb: haproxy-main-49-lb-gprd
-X-Gitlab-Meta: {"correlation_id":"ea044fc89155ed7f76093b9cc3a7d4ea","version":"1"}
-X-Runtime: 0.144068
-Strict-Transport-Security: max-age=31536000
-Etag: W/"58109b687618e6b9e49ff812d5a911df"
-X-Content-Type-Options: nosniff
-Cache-Control: max-age=0, private, must-revalidate
-X-Frame-Options: SAMEORIGIN
-Set-Cookie: _cfuvid=bjDdu13341ZREKL1340bXPm8TFCQkeafZBecRxoqNv0-1709516936936-0.0.1.1-604800000; path=/; domain=.gitlab.com; HttpOnly; Secure; SameSite=None
-Cf-Cache-Status: MISS
-Content-Security-Policy: default-src 'none'
+Gitlab-Lb: haproxy-main-17-lb-gprd
+Gitlab-Sv: api-gke-us-east1-d
Referrer-Policy: strict-origin-when-cross-origin
+Cf-Cache-Status: MISS
+Cache-Control: max-age=0, private, must-revalidate
+Content-Security-Policy: default-src 'none'
+Etag: W/"58109b687618e6b9e49ff812d5a911df"
+Strict-Transport-Security: max-age=31536000
{"id":43524600,"iid":2,"project_id":15578026,"title":"Test branch","description":"do not merge this PR","state":"opened","created_at":"2019-11-28T15:56:54.104Z","updated_at":"2020-04-19T19:24:21.108Z","merge_status":"can_be_merged","approved":true,"approvals_required":0,"approvals_left":0,"require_password_to_approve":false,"approved_by":[{"user":{"id":4575606,"username":"real6543","name":"6543","state":"active","locked":false,"avatar_url":"https://gitlab.com/uploads/-/system/user/avatar/4575606/avatar.png","web_url":"https://gitlab.com/real6543"}}],"suggested_approvers":[],"approvers":[],"approver_groups":[{"group":{"id":3181312,"web_url":"https://gitlab.com/groups/gitea","name":"gitea","path":"gitea","description":"Mirror of Gitea source code repositories","visibility":"public","share_with_group_lock":false,"require_two_factor_authentication":false,"two_factor_grace_period":48,"project_creation_level":"maintainer","auto_devops_enabled":null,"subgroup_creation_level":"owner","emails_disabled":false,"emails_enabled":true,"mentions_disabled":null,"lfs_enabled":true,"math_rendering_limits_enabled":true,"lock_math_rendering_limits_enabled":false,"default_branch_protection":2,"default_branch_protection_defaults":{"allowed_to_push":[{"access_level":30}],"allow_force_push":true,"allowed_to_merge":[{"access_level":30}]},"avatar_url":"https://gitlab.com/uploads/-/system/group/avatar/3181312/gitea.png","request_access_enabled":true,"full_name":"gitea","full_path":"gitea","created_at":"2018-07-04T16:32:10.176Z","parent_id":null,"organization_id":1,"shared_runners_setting":"enabled","ldap_cn":null,"ldap_access":null,"wiki_access_level":"enabled"}}],"user_has_approved":false,"user_can_approve":false,"approval_rules_left":[],"has_approval_rules":true,"merge_request_approvers_available":false,"multiple_approval_rules_available":false,"invalid_approvers_rules":[]}
\ No newline at end of file
diff --git a/services/migrations/testdata/gitlab/full_download/_api_v4_projects_15578026_merge_requests_2_award_emoji!page=1&per_page=1 b/services/migrations/testdata/gitlab/full_download/GET_%2Fapi%2Fv4%2Fprojects%2F15578026%2Fmerge_requests%2F2%2Faward_emoji%3Fpage=1&per_page=1
similarity index 83%
rename from services/migrations/testdata/gitlab/full_download/_api_v4_projects_15578026_merge_requests_2_award_emoji!page=1&per_page=1
rename to services/migrations/testdata/gitlab/full_download/GET_%2Fapi%2Fv4%2Fprojects%2F15578026%2Fmerge_requests%2F2%2Faward_emoji%3Fpage=1&per_page=1
index 3d99cfbe24..eb72d3fc54 100644
--- a/services/migrations/testdata/gitlab/full_download/_api_v4_projects_15578026_merge_requests_2_award_emoji!page=1&per_page=1
+++ b/services/migrations/testdata/gitlab/full_download/GET_%2Fapi%2Fv4%2Fprojects%2F15578026%2Fmerge_requests%2F2%2Faward_emoji%3Fpage=1&per_page=1
@@ -1,24 +1,24 @@
-Set-Cookie: _cfuvid=2_c1M0pqgnG1D4bNm2QluJ9AGXZ7FyB14t_v4ittTjY-1709516933765-0.0.1.1-604800000; path=/; domain=.gitlab.com; HttpOnly; Secure; SameSite=None
Etag: W/"798718b23a2ec66b16cce20cb7155116"
-X-Runtime: 0.125829
-X-Total-Pages: 2
-Gitlab-Sv: api-gke-us-east1-b
-Cf-Cache-Status: MISS
-X-Prev-Page:
-Cache-Control: max-age=0, private, must-revalidate
+X-Gitlab-Meta: {"correlation_id":"64dce1b90fe8fbfda281a99e34d0905c","version":"1"}
Link: ; rel="next", ; rel="first", ; rel="last"
+X-Frame-Options: SAMEORIGIN
+X-Runtime: 0.092139
Content-Type: application/json
X-Content-Type-Options: nosniff
-X-Gitlab-Meta: {"correlation_id":"9d8976ef2244076825f1e8a8bae3a090","version":"1"}
-Vary: Origin, Accept-Encoding
-Strict-Transport-Security: max-age=31536000
+X-Prev-Page:
+Referrer-Policy: strict-origin-when-cross-origin
+X-Per-Page: 1
X-Total: 2
-X-Frame-Options: SAMEORIGIN
+Strict-Transport-Security: max-age=31536000
+Content-Security-Policy: default-src 'none'
+Cache-Control: max-age=0, private, must-revalidate
+Vary: Origin, Accept-Encoding
+Gitlab-Lb: haproxy-main-30-lb-gprd
+Cf-Cache-Status: MISS
+Gitlab-Sv: api-gke-us-east1-b
+Set-Cookie: _cfuvid=vG12ThddZrDMG_flNdCfEfuN3Vma3YHPWrU1MJOBFhY-1710504210427-0.0.1.1-604800000; path=/; domain=.gitlab.com; HttpOnly; Secure; SameSite=None
X-Next-Page: 2
X-Page: 1
-X-Per-Page: 1
-Content-Security-Policy: default-src 'none'
-Referrer-Policy: strict-origin-when-cross-origin
-Gitlab-Lb: haproxy-main-45-lb-gprd
+X-Total-Pages: 2
[{"id":5541414,"name":"thumbsup","user":{"id":4575606,"username":"real6543","name":"6543","state":"active","locked":false,"avatar_url":"https://gitlab.com/uploads/-/system/user/avatar/4575606/avatar.png","web_url":"https://gitlab.com/real6543"},"created_at":"2020-09-02T23:42:34.310Z","updated_at":"2020-09-02T23:42:34.310Z","awardable_id":43524600,"awardable_type":"MergeRequest","url":null}]
\ No newline at end of file
diff --git a/services/migrations/testdata/gitlab/full_download/_api_v4_projects_15578026_merge_requests_2_award_emoji!page=2&per_page=1 b/services/migrations/testdata/gitlab/full_download/GET_%2Fapi%2Fv4%2Fprojects%2F15578026%2Fmerge_requests%2F2%2Faward_emoji%3Fpage=2&per_page=1
similarity index 81%
rename from services/migrations/testdata/gitlab/full_download/_api_v4_projects_15578026_merge_requests_2_award_emoji!page=2&per_page=1
rename to services/migrations/testdata/gitlab/full_download/GET_%2Fapi%2Fv4%2Fprojects%2F15578026%2Fmerge_requests%2F2%2Faward_emoji%3Fpage=2&per_page=1
index 9981fc1c38..63f7d02a17 100644
--- a/services/migrations/testdata/gitlab/full_download/_api_v4_projects_15578026_merge_requests_2_award_emoji!page=2&per_page=1
+++ b/services/migrations/testdata/gitlab/full_download/GET_%2Fapi%2Fv4%2Fprojects%2F15578026%2Fmerge_requests%2F2%2Faward_emoji%3Fpage=2&per_page=1
@@ -1,24 +1,24 @@
-X-Content-Type-Options: nosniff
-Gitlab-Lb: haproxy-main-32-lb-gprd
+X-Next-Page:
+Content-Type: application/json
+Vary: Origin, Accept-Encoding
+Cf-Cache-Status: MISS
+Content-Security-Policy: default-src 'none'
+X-Frame-Options: SAMEORIGIN
+X-Page: 2
+Strict-Transport-Security: max-age=31536000
+Set-Cookie: _cfuvid=VgzG7aSZyu0lycKl6YVe9GTRYeLa0XUB5lv3pROs3tk-1710504210672-0.0.1.1-604800000; path=/; domain=.gitlab.com; HttpOnly; Secure; SameSite=None
+Referrer-Policy: strict-origin-when-cross-origin
Cache-Control: max-age=0, private, must-revalidate
Etag: W/"e6776aaa57e6a81bf8a2d8823272cc70"
X-Prev-Page: 1
-X-Runtime: 0.066771
-Referrer-Policy: strict-origin-when-cross-origin
-Content-Security-Policy: default-src 'none'
-Vary: Origin, Accept-Encoding
-X-Frame-Options: SAMEORIGIN
-X-Next-Page:
-X-Per-Page: 1
-Set-Cookie: _cfuvid=XlmPD5BVPxHofXNdPbazM3JF2i5DbLlQUVqNW9K6Y28-1709516934208-0.0.1.1-604800000; path=/; domain=.gitlab.com; HttpOnly; Secure; SameSite=None
-X-Gitlab-Meta: {"correlation_id":"e51679dffc5216e7c77a018a26343380","version":"1"}
+X-Runtime: 0.073747
+Link: ; rel="prev", ; rel="first", ; rel="last"
+X-Gitlab-Meta: {"correlation_id":"50f2f6c2fa586f2699010189215c0531","version":"1"}
X-Total: 2
X-Total-Pages: 2
-Content-Type: application/json
-X-Page: 2
-Strict-Transport-Security: max-age=31536000
-Cf-Cache-Status: MISS
-Link: ; rel="prev", ; rel="first", ; rel="last"
-Gitlab-Sv: api-gke-us-east1-d
+Gitlab-Lb: haproxy-main-60-lb-gprd
+X-Content-Type-Options: nosniff
+X-Per-Page: 1
+Gitlab-Sv: api-gke-us-east1-b
[{"id":5541415,"name":"tada","user":{"id":4575606,"username":"real6543","name":"6543","state":"active","locked":false,"avatar_url":"https://gitlab.com/uploads/-/system/user/avatar/4575606/avatar.png","web_url":"https://gitlab.com/real6543"},"created_at":"2020-09-02T23:42:59.060Z","updated_at":"2020-09-02T23:42:59.060Z","awardable_id":43524600,"awardable_type":"MergeRequest","url":null}]
\ No newline at end of file
diff --git a/services/migrations/testdata/gitlab/full_download/_api_v4_projects_15578026_merge_requests_2_award_emoji!page=3&per_page=1 b/services/migrations/testdata/gitlab/full_download/GET_%2Fapi%2Fv4%2Fprojects%2F15578026%2Fmerge_requests%2F2%2Faward_emoji%3Fpage=3&per_page=1
similarity index 73%
rename from services/migrations/testdata/gitlab/full_download/_api_v4_projects_15578026_merge_requests_2_award_emoji!page=3&per_page=1
rename to services/migrations/testdata/gitlab/full_download/GET_%2Fapi%2Fv4%2Fprojects%2F15578026%2Fmerge_requests%2F2%2Faward_emoji%3Fpage=3&per_page=1
index 07ff6e5ba4..9cce5e0bdb 100644
--- a/services/migrations/testdata/gitlab/full_download/_api_v4_projects_15578026_merge_requests_2_award_emoji!page=3&per_page=1
+++ b/services/migrations/testdata/gitlab/full_download/GET_%2Fapi%2Fv4%2Fprojects%2F15578026%2Fmerge_requests%2F2%2Faward_emoji%3Fpage=3&per_page=1
@@ -1,26 +1,26 @@
-X-Content-Type-Options: nosniff
-X-Prev-Page:
-Accept-Ranges: bytes
-Gitlab-Sv: api-gke-us-east1-d
-X-Gitlab-Meta: {"correlation_id":"e19c4433df21888b10c912bab5311ecd","version":"1"}
-X-Next-Page:
-Strict-Transport-Security: max-age=31536000
-Gitlab-Lb: haproxy-main-26-lb-gprd
-Etag: W/"4f53cda18c2baa0c0354bb5f9a3ecbe5"
-Link: ; rel="first", ; rel="last"
-X-Per-Page: 1
-Set-Cookie: _cfuvid=Lv9tmhZRx2Sa.lToTQ.C73MDyRvwOtmVmgEi4cbTrkQ-1709516935278-0.0.1.1-604800000; path=/; domain=.gitlab.com; HttpOnly; Secure; SameSite=None
X-Total-Pages: 2
-Cf-Cache-Status: MISS
-Content-Length: 2
-X-Page: 3
-X-Total: 2
-X-Frame-Options: SAMEORIGIN
-Referrer-Policy: strict-origin-when-cross-origin
-Content-Type: application/json
Cache-Control: max-age=0, private, must-revalidate
+Link: ; rel="first", ; rel="last"
+X-Prev-Page:
+Content-Type: application/json
+Etag: W/"4f53cda18c2baa0c0354bb5f9a3ecbe5"
+X-Per-Page: 1
+Cf-Cache-Status: MISS
+Accept-Ranges: bytes
+X-Content-Type-Options: nosniff
+X-Runtime: 0.064101
+X-Total: 2
+Gitlab-Lb: haproxy-main-18-lb-gprd
+Content-Length: 2
+Referrer-Policy: strict-origin-when-cross-origin
+Set-Cookie: _cfuvid=I18ivb.i14P1hql2L0PDHGFAIFBr6CdHc5Xp3CQ7Z78-1710504211202-0.0.1.1-604800000; path=/; domain=.gitlab.com; HttpOnly; Secure; SameSite=None
Vary: Origin, Accept-Encoding
-X-Runtime: 0.056300
+X-Next-Page:
+Gitlab-Sv: api-gke-us-east1-b
+Strict-Transport-Security: max-age=31536000
Content-Security-Policy: default-src 'none'
+X-Frame-Options: SAMEORIGIN
+X-Gitlab-Meta: {"correlation_id":"6c902fe6782c24f23059e0ab39caf051","version":"1"}
+X-Page: 3
[]
\ No newline at end of file
diff --git a/services/migrations/testdata/gitlab/full_download/_api_v4_projects_15578026_merge_requests!page=1&per_page=1&view=simple b/services/migrations/testdata/gitlab/full_download/GET_%2Fapi%2Fv4%2Fprojects%2F15578026%2Fmerge_requests%3Fpage=1&per_page=1&view=simple
similarity index 84%
rename from services/migrations/testdata/gitlab/full_download/_api_v4_projects_15578026_merge_requests!page=1&per_page=1&view=simple
rename to services/migrations/testdata/gitlab/full_download/GET_%2Fapi%2Fv4%2Fprojects%2F15578026%2Fmerge_requests%3Fpage=1&per_page=1&view=simple
index 6f8d70200c..1beb5e698c 100644
--- a/services/migrations/testdata/gitlab/full_download/_api_v4_projects_15578026_merge_requests!page=1&per_page=1&view=simple
+++ b/services/migrations/testdata/gitlab/full_download/GET_%2Fapi%2Fv4%2Fprojects%2F15578026%2Fmerge_requests%3Fpage=1&per_page=1&view=simple
@@ -1,24 +1,24 @@
-Content-Security-Policy: default-src 'none'
Etag: W/"14f72c1f555b0e6348d338190e9e4839"
-Strict-Transport-Security: max-age=31536000
-Cf-Cache-Status: MISS
-Set-Cookie: _cfuvid=V__PxQ60qzlepbd7My22SIsuTFfjEafoCsqahPDPjMg-1709516932676-0.0.1.1-604800000; path=/; domain=.gitlab.com; HttpOnly; Secure; SameSite=None
-X-Frame-Options: SAMEORIGIN
-X-Per-Page: 1
-X-Total: 2
-X-Total-Pages: 2
-Gitlab-Sv: api-gke-us-east1-d
-Content-Type: application/json
-X-Content-Type-Options: nosniff
-X-Next-Page: 2
+X-Page: 1
Referrer-Policy: strict-origin-when-cross-origin
-Vary: Origin, Accept-Encoding
+Gitlab-Lb: haproxy-main-44-lb-gprd
+Content-Type: application/json
+Content-Security-Policy: default-src 'none'
+Set-Cookie: _cfuvid=xtxwnC3sB7qZrUtCFdAaMiSOKDnQPiLD3iYq9hTj39I-1710504209365-0.0.1.1-604800000; path=/; domain=.gitlab.com; HttpOnly; Secure; SameSite=None
+X-Per-Page: 1
+X-Runtime: 0.102877
+X-Gitlab-Meta: {"correlation_id":"a779d4e8ffae8bdf01f20a6d0c545247","version":"1"}
+Cf-Cache-Status: MISS
+X-Frame-Options: SAMEORIGIN
+X-Total-Pages: 2
Cache-Control: max-age=0, private, must-revalidate
Link: ; rel="next", ; rel="first", ; rel="last"
X-Prev-Page:
-X-Gitlab-Meta: {"correlation_id":"7e815ab626b3ec958eb45b614106a759","version":"1"}
-X-Page: 1
-X-Runtime: 0.130064
-Gitlab-Lb: haproxy-main-38-lb-gprd
+X-Content-Type-Options: nosniff
+X-Next-Page: 2
+Gitlab-Sv: api-gke-us-east1-d
+Vary: Origin, Accept-Encoding
+Strict-Transport-Security: max-age=31536000
+X-Total: 2
[{"id":43524600,"iid":2,"project_id":15578026,"title":"Test branch","description":"do not merge this PR","state":"opened","created_at":"2019-11-28T15:56:54.104Z","updated_at":"2020-04-19T19:24:21.108Z","web_url":"https://gitlab.com/gitea/test_repo/-/merge_requests/2"}]
\ No newline at end of file
diff --git a/services/migrations/testdata/gitlab/full_download/_api_v4_projects_15578026_milestones!page=1&per_page=100&state=all b/services/migrations/testdata/gitlab/full_download/GET_%2Fapi%2Fv4%2Fprojects%2F15578026%2Fmilestones%3Fpage=1&per_page=100&state=all
similarity index 81%
rename from services/migrations/testdata/gitlab/full_download/_api_v4_projects_15578026_milestones!page=1&per_page=100&state=all
rename to services/migrations/testdata/gitlab/full_download/GET_%2Fapi%2Fv4%2Fprojects%2F15578026%2Fmilestones%3Fpage=1&per_page=100&state=all
index 14a40dc505..6d7d482138 100644
--- a/services/migrations/testdata/gitlab/full_download/_api_v4_projects_15578026_milestones!page=1&per_page=100&state=all
+++ b/services/migrations/testdata/gitlab/full_download/GET_%2Fapi%2Fv4%2Fprojects%2F15578026%2Fmilestones%3Fpage=1&per_page=100&state=all
@@ -1,24 +1,24 @@
-X-Total: 2
+X-Prev-Page:
+Vary: Origin, Accept-Encoding
+X-Gitlab-Meta: {"correlation_id":"2998cbf0e39d3b81710b1d1b82c03b80","version":"1"}
Referrer-Policy: strict-origin-when-cross-origin
-Gitlab-Sv: api-gke-us-east1-d
-X-Content-Type-Options: nosniff
-X-Frame-Options: SAMEORIGIN
-X-Next-Page:
-X-Total-Pages: 1
+Link: ; rel="first", ; rel="last"
+X-Page: 1
+Etag: W/"c8e2d3a5f05ee29c58b665c86684f9f9"
+Content-Security-Policy: default-src 'none'
+X-Total: 2
Cf-Cache-Status: MISS
Content-Type: application/json
+X-Next-Page:
+X-Frame-Options: SAMEORIGIN
+X-Total-Pages: 1
+Gitlab-Lb: haproxy-main-24-lb-gprd
+Set-Cookie: _cfuvid=UO1GaUJc3jsd8W85u2xy74QFY1Ez71cmGWi0WbQoYpU-1710504205756-0.0.1.1-604800000; path=/; domain=.gitlab.com; HttpOnly; Secure; SameSite=None
Cache-Control: max-age=0, private, must-revalidate
-Link: ; rel="first", ; rel="last"
-Gitlab-Lb: haproxy-main-02-lb-gprd
-Vary: Origin, Accept-Encoding
-X-Per-Page: 100
-X-Runtime: 0.072314
+X-Content-Type-Options: nosniff
Strict-Transport-Security: max-age=31536000
-Set-Cookie: _cfuvid=AAzb4a45dTRraCeBWB2eYtD0LUdZnyMdcLZpKLKFKQY-1709516922946-0.0.1.1-604800000; path=/; domain=.gitlab.com; HttpOnly; Secure; SameSite=None
-X-Page: 1
-Content-Security-Policy: default-src 'none'
-Etag: W/"c8e2d3a5f05ee29c58b665c86684f9f9"
-X-Gitlab-Meta: {"correlation_id":"3786d93aa260a78e86bd229427022c67","version":"1"}
-X-Prev-Page:
+Gitlab-Sv: api-gke-us-east1-b
+X-Per-Page: 100
+X-Runtime: 0.078614
[{"id":1082927,"iid":2,"project_id":15578026,"title":"1.1.0","description":"","state":"active","created_at":"2019-11-28T08:42:44.575Z","updated_at":"2019-11-28T08:42:44.575Z","due_date":null,"start_date":null,"expired":false,"web_url":"https://gitlab.com/gitea/test_repo/-/milestones/2"},{"id":1082926,"iid":1,"project_id":15578026,"title":"1.0.0","description":"","state":"closed","created_at":"2019-11-28T08:42:30.301Z","updated_at":"2019-11-28T15:57:52.401Z","due_date":null,"start_date":null,"expired":false,"web_url":"https://gitlab.com/gitea/test_repo/-/milestones/1"}]
\ No newline at end of file
diff --git a/services/migrations/testdata/gitlab/full_download/_api_v4_projects_15578026_releases!page=1&per_page=100 b/services/migrations/testdata/gitlab/full_download/GET_%2Fapi%2Fv4%2Fprojects%2F15578026%2Freleases%3Fpage=1&per_page=100
similarity index 91%
rename from services/migrations/testdata/gitlab/full_download/_api_v4_projects_15578026_releases!page=1&per_page=100
rename to services/migrations/testdata/gitlab/full_download/GET_%2Fapi%2Fv4%2Fprojects%2F15578026%2Freleases%3Fpage=1&per_page=100
index 5e0f064cde..fc63173e9f 100644
--- a/services/migrations/testdata/gitlab/full_download/_api_v4_projects_15578026_releases!page=1&per_page=100
+++ b/services/migrations/testdata/gitlab/full_download/GET_%2Fapi%2Fv4%2Fprojects%2F15578026%2Freleases%3Fpage=1&per_page=100
@@ -1,24 +1,24 @@
-Gitlab-Lb: haproxy-main-38-lb-gprd
-X-Gitlab-Meta: {"correlation_id":"fe487506ab79b2641f2798820a003e65","version":"1"}
-X-Runtime: 0.126232
-X-Total-Pages: 1
-X-Prev-Page:
-Cache-Control: max-age=0, private, must-revalidate
-Link: ; rel="first", ; rel="last"
-X-Page: 1
-X-Per-Page: 100
Content-Type: application/json
-Vary: Origin, Accept-Encoding
-X-Frame-Options: SAMEORIGIN
-X-Next-Page:
-Gitlab-Sv: api-gke-us-east1-d
-X-Content-Type-Options: nosniff
-Referrer-Policy: strict-origin-when-cross-origin
-Cf-Cache-Status: MISS
-Strict-Transport-Security: max-age=31536000
-Set-Cookie: _cfuvid=2dextQvrlcispQRNmodfvb.IH__P1bCF5jvS5aFrRjY-1709516924499-0.0.1.1-604800000; path=/; domain=.gitlab.com; HttpOnly; Secure; SameSite=None
-Etag: W/"dccc7159dc4b46989d13128a7d6ee859"
Content-Security-Policy: default-src 'none'
+Link: ; rel="first", ; rel="last"
+X-Prev-Page:
+Gitlab-Sv: api-gke-us-east1-b
+X-Content-Type-Options: nosniff
+X-Runtime: 0.123532
+Vary: Origin, Accept-Encoding
+X-Per-Page: 100
+Referrer-Policy: strict-origin-when-cross-origin
+Set-Cookie: _cfuvid=Eoqdcle3awcN8Jyrig.dSmC4hTIPuXqZ5ruJIG9c56I-1710504206613-0.0.1.1-604800000; path=/; domain=.gitlab.com; HttpOnly; Secure; SameSite=None
X-Total: 1
+Cf-Cache-Status: MISS
+X-Next-Page:
+Cache-Control: max-age=0, private, must-revalidate
+X-Gitlab-Meta: {"correlation_id":"1c01187e563b0819c5ad553bc7525ce8","version":"1"}
+Etag: W/"dccc7159dc4b46989d13128a7d6ee859"
+X-Page: 1
+Gitlab-Lb: haproxy-main-30-lb-gprd
+X-Frame-Options: SAMEORIGIN
+X-Total-Pages: 1
+Strict-Transport-Security: max-age=31536000
[{"name":"First Release","tag_name":"v0.9.99","description":"A test release","created_at":"2019-11-28T09:09:48.840Z","released_at":"2019-11-28T09:09:48.836Z","upcoming_release":false,"author":{"id":1241334,"username":"lafriks","name":"Lauris BH","state":"active","locked":false,"avatar_url":"https://gitlab.com/uploads/-/system/user/avatar/1241334/avatar.png","web_url":"https://gitlab.com/lafriks"},"commit":{"id":"0720a3ec57c1f843568298117b874319e7deee75","short_id":"0720a3ec","created_at":"2019-11-28T08:49:16.000+00:00","parent_ids":["93ea21ce45d35690c35e80961d239645139e872c"],"title":"Add new file","message":"Add new file","author_name":"Lauris BH","author_email":"lauris@nix.lv","authored_date":"2019-11-28T08:49:16.000+00:00","committer_name":"Lauris BH","committer_email":"lauris@nix.lv","committed_date":"2019-11-28T08:49:16.000+00:00","trailers":{},"extended_trailers":{},"web_url":"https://gitlab.com/gitea/test_repo/-/commit/0720a3ec57c1f843568298117b874319e7deee75"},"commit_path":"/gitea/test_repo/-/commit/0720a3ec57c1f843568298117b874319e7deee75","tag_path":"/gitea/test_repo/-/tags/v0.9.99","assets":{"count":4,"sources":[{"format":"zip","url":"https://gitlab.com/gitea/test_repo/-/archive/v0.9.99/test_repo-v0.9.99.zip"},{"format":"tar.gz","url":"https://gitlab.com/gitea/test_repo/-/archive/v0.9.99/test_repo-v0.9.99.tar.gz"},{"format":"tar.bz2","url":"https://gitlab.com/gitea/test_repo/-/archive/v0.9.99/test_repo-v0.9.99.tar.bz2"},{"format":"tar","url":"https://gitlab.com/gitea/test_repo/-/archive/v0.9.99/test_repo-v0.9.99.tar"}],"links":[]},"evidences":[{"sha":"89f1223473ee01f192a83d0cb89f4d1eac1de74f01ad","filepath":"https://gitlab.com/gitea/test_repo/-/releases/v0.9.99/evidences/52147.json","collected_at":"2019-11-28T09:09:48.888Z"}],"_links":{"closed_issues_url":"https://gitlab.com/gitea/test_repo/-/issues?release_tag=v0.9.99\u0026scope=all\u0026state=closed","closed_merge_requests_url":"https://gitlab.com/gitea/test_repo/-/merge_requests?release_tag=v0.9.99\u0026scope=all\u0026state=closed","merged_merge_requests_url":"https://gitlab.com/gitea/test_repo/-/merge_requests?release_tag=v0.9.99\u0026scope=all\u0026state=merged","opened_issues_url":"https://gitlab.com/gitea/test_repo/-/issues?release_tag=v0.9.99\u0026scope=all\u0026state=opened","opened_merge_requests_url":"https://gitlab.com/gitea/test_repo/-/merge_requests?release_tag=v0.9.99\u0026scope=all\u0026state=opened","self":"https://gitlab.com/gitea/test_repo/-/releases/v0.9.99"}}]
\ No newline at end of file
diff --git a/services/migrations/testdata/gitlab/full_download/_api_v4_projects_15578026 b/services/migrations/testdata/gitlab/full_download/GET_%2Fapi%2Fv4%2Fprojects%2Fgitea%252Ftest_repo
similarity index 94%
rename from services/migrations/testdata/gitlab/full_download/_api_v4_projects_15578026
rename to services/migrations/testdata/gitlab/full_download/GET_%2Fapi%2Fv4%2Fprojects%2Fgitea%252Ftest_repo
index e102c2ee11..96f1ea86b5 100644
--- a/services/migrations/testdata/gitlab/full_download/_api_v4_projects_15578026
+++ b/services/migrations/testdata/gitlab/full_download/GET_%2Fapi%2Fv4%2Fprojects%2Fgitea%252Ftest_repo
@@ -1,17 +1,17 @@
-X-Frame-Options: SAMEORIGIN
-Vary: Origin, Accept-Encoding
-Strict-Transport-Security: max-age=31536000
-Cache-Control: max-age=0, private, must-revalidate
-X-Content-Type-Options: nosniff
-X-Gitlab-Meta: {"correlation_id":"fcbfb8d789b3f092196e301b01add051","version":"1"}
-Gitlab-Sv: api-gke-us-east1-b
-Cf-Cache-Status: MISS
-Content-Security-Policy: default-src 'none'
-Etag: W/"8db4917b3be5f4ca0d101a702179b75a"
-X-Runtime: 0.230015
Referrer-Policy: strict-origin-when-cross-origin
-Gitlab-Lb: haproxy-main-39-lb-gprd
-Set-Cookie: _cfuvid=cvUyaJC1KTpP.SBvDCjaIYRgZYh4zbY7BihbhwIUzt4-1709516922501-0.0.1.1-604800000; path=/; domain=.gitlab.com; HttpOnly; Secure; SameSite=None
+Gitlab-Lb: haproxy-main-51-lb-gprd
+Cf-Cache-Status: MISS
+Etag: W/"8db4917b3be5f4ca0d101a702179b75a"
+X-Content-Type-Options: nosniff
+Strict-Transport-Security: max-age=31536000
+Gitlab-Sv: api-gke-us-east1-b
Content-Type: application/json
+Cache-Control: max-age=0, private, must-revalidate
+X-Gitlab-Meta: {"correlation_id":"9b3859cf6d73ce5de261a56d286072a5","version":"1"}
+X-Runtime: 0.119487
+Content-Security-Policy: default-src 'none'
+Vary: Origin, Accept-Encoding
+Set-Cookie: _cfuvid=Cmc.ycVkdwA_tBvmR2tOVLQ5B.khzzU39ZUxgf4RNlw-1710504204838-0.0.1.1-604800000; path=/; domain=.gitlab.com; HttpOnly; Secure; SameSite=None
+X-Frame-Options: SAMEORIGIN
{"id":15578026,"description":"Test repository for testing migration from gitlab to gitea","name":"test_repo","name_with_namespace":"gitea / test_repo","path":"test_repo","path_with_namespace":"gitea/test_repo","created_at":"2019-11-28T08:20:33.019Z","default_branch":"master","tag_list":["migration","test"],"topics":["migration","test"],"ssh_url_to_repo":"git@gitlab.com:gitea/test_repo.git","http_url_to_repo":"https://gitlab.com/gitea/test_repo.git","web_url":"https://gitlab.com/gitea/test_repo","readme_url":"https://gitlab.com/gitea/test_repo/-/blob/master/README.md","forks_count":1,"avatar_url":null,"star_count":0,"last_activity_at":"2020-04-19T19:46:04.527Z","namespace":{"id":3181312,"name":"gitea","path":"gitea","kind":"group","full_path":"gitea","parent_id":null,"avatar_url":"/uploads/-/system/group/avatar/3181312/gitea.png","web_url":"https://gitlab.com/groups/gitea"},"container_registry_image_prefix":"registry.gitlab.com/gitea/test_repo","_links":{"self":"https://gitlab.com/api/v4/projects/15578026","issues":"https://gitlab.com/api/v4/projects/15578026/issues","merge_requests":"https://gitlab.com/api/v4/projects/15578026/merge_requests","repo_branches":"https://gitlab.com/api/v4/projects/15578026/repository/branches","labels":"https://gitlab.com/api/v4/projects/15578026/labels","events":"https://gitlab.com/api/v4/projects/15578026/events","members":"https://gitlab.com/api/v4/projects/15578026/members","cluster_agents":"https://gitlab.com/api/v4/projects/15578026/cluster_agents"},"packages_enabled":true,"empty_repo":false,"archived":false,"visibility":"public","resolve_outdated_diff_discussions":false,"repository_object_format":"sha1","issues_enabled":true,"merge_requests_enabled":true,"wiki_enabled":true,"jobs_enabled":true,"snippets_enabled":true,"container_registry_enabled":true,"service_desk_enabled":true,"can_create_merge_request_in":true,"issues_access_level":"enabled","repository_access_level":"enabled","merge_requests_access_level":"enabled","forking_access_level":"enabled","wiki_access_level":"enabled","builds_access_level":"enabled","snippets_access_level":"enabled","pages_access_level":"enabled","analytics_access_level":"enabled","container_registry_access_level":"enabled","security_and_compliance_access_level":"private","releases_access_level":"enabled","environments_access_level":"enabled","feature_flags_access_level":"enabled","infrastructure_access_level":"enabled","monitor_access_level":"enabled","model_experiments_access_level":"enabled","model_registry_access_level":"enabled","emails_disabled":false,"emails_enabled":true,"shared_runners_enabled":true,"lfs_enabled":true,"creator_id":1241334,"import_status":"none","open_issues_count":0,"description_html":"\u003cp data-sourcepos=\"1:1-1:58\" dir=\"auto\"\u003eTest repository for testing migration from gitlab to gitea\u003c/p\u003e","updated_at":"2024-01-11T01:23:21.057Z","ci_config_path":null,"public_jobs":true,"shared_with_groups":[],"only_allow_merge_if_pipeline_succeeds":false,"allow_merge_on_skipped_pipeline":null,"request_access_enabled":true,"only_allow_merge_if_all_discussions_are_resolved":false,"remove_source_branch_after_merge":true,"printing_merge_request_link_enabled":true,"merge_method":"ff","squash_option":"default_off","enforce_auth_checks_on_uploads":true,"suggestion_commit_message":null,"merge_commit_template":null,"squash_commit_template":null,"issue_branch_template":null,"warn_about_potentially_unwanted_characters":true,"autoclose_referenced_issues":true,"external_authorization_classification_label":"","requirements_enabled":false,"requirements_access_level":"enabled","security_and_compliance_enabled":false,"compliance_frameworks":[],"permissions":{"project_access":null,"group_access":null}}
\ No newline at end of file
diff --git a/services/migrations/testdata/gitlab/full_download/GET_%2Fapi%2Fv4%2Fversion b/services/migrations/testdata/gitlab/full_download/GET_%2Fapi%2Fv4%2Fversion
new file mode 100644
index 0000000000..b8561d4303
--- /dev/null
+++ b/services/migrations/testdata/gitlab/full_download/GET_%2Fapi%2Fv4%2Fversion
@@ -0,0 +1,17 @@
+Content-Type: application/json
+Cache-Control: max-age=0, private, must-revalidate
+Vary: Origin, Accept-Encoding
+X-Frame-Options: SAMEORIGIN
+Strict-Transport-Security: max-age=31536000
+X-Gitlab-Meta: {"correlation_id":"5e1b0f0c600e3127952b0bc933bfe0fd","version":"1"}
+Referrer-Policy: strict-origin-when-cross-origin
+Gitlab-Sv: api-gke-us-east1-b
+Set-Cookie: _cfuvid=ve7lWeCgOflkqyU5mzcjS4rdE91f0uaUXBG.po.9VLs-1710504204253-0.0.1.1-604800000; path=/; domain=.gitlab.com; HttpOnly; Secure; SameSite=None
+Etag: W/"a7e5ac2ae5500f226c1020b94327a605"
+X-Runtime: 0.025760
+Content-Security-Policy: default-src 'none'
+X-Content-Type-Options: nosniff
+Gitlab-Lb: haproxy-main-39-lb-gprd
+Cf-Cache-Status: MISS
+
+{"version":"16.10.0-pre","revision":"7da39369465","kas":{"enabled":true,"externalUrl":"wss://kas.gitlab.com","version":"v16.10.1"},"enterprise":true}
\ No newline at end of file
diff --git a/services/migrations/testdata/gitlab/full_download/_api_v4_version b/services/migrations/testdata/gitlab/full_download/_api_v4_version
deleted file mode 100644
index e61313f6bc..0000000000
--- a/services/migrations/testdata/gitlab/full_download/_api_v4_version
+++ /dev/null
@@ -1,17 +0,0 @@
-Etag: W/"796348ca31c2f886c4bf67753358302b"
-X-Content-Type-Options: nosniff
-Gitlab-Lb: haproxy-main-22-lb-gprd
-Set-Cookie: _cfuvid=XONUYaYMv2vYBZLhOZoclracol_W8SXVwL7kwoXROjM-1709516920902-0.0.1.1-604800000; path=/; domain=.gitlab.com; HttpOnly; Secure; SameSite=None
-X-Gitlab-Meta: {"correlation_id":"0defa7748a7bd70616af6bd0f338094c","version":"1"}
-Strict-Transport-Security: max-age=31536000
-Gitlab-Sv: api-gke-us-east1-c
-Cf-Cache-Status: MISS
-Content-Type: application/json
-Cache-Control: max-age=0, private, must-revalidate
-Content-Security-Policy: default-src 'none'
-X-Frame-Options: SAMEORIGIN
-X-Runtime: 0.035674
-Vary: Origin, Accept-Encoding
-Referrer-Policy: strict-origin-when-cross-origin
-
-{"version":"16.10.0-pre","revision":"432cc3c7389","kas":{"enabled":true,"externalUrl":"wss://kas.gitlab.com","version":"v16.10.0-rc1"},"enterprise":true}
\ No newline at end of file
diff --git a/services/migrations/testdata/gitlab/skipped_issue_number/_api_v4_projects_6590996 b/services/migrations/testdata/gitlab/skipped_issue_number/GET_%2Fapi%2Fv4%2Fprojects%2F6590996
similarity index 100%
rename from services/migrations/testdata/gitlab/skipped_issue_number/_api_v4_projects_6590996
rename to services/migrations/testdata/gitlab/skipped_issue_number/GET_%2Fapi%2Fv4%2Fprojects%2F6590996
diff --git a/services/migrations/testdata/gitlab/skipped_issue_number/_api_v4_projects_6590996_issues_2_award_emoji!page=1&per_page=10 b/services/migrations/testdata/gitlab/skipped_issue_number/GET_%2Fapi%2Fv4%2Fprojects%2F6590996%2Fissues%2F2%2Faward_emoji%3Fpage=1&per_page=10
similarity index 100%
rename from services/migrations/testdata/gitlab/skipped_issue_number/_api_v4_projects_6590996_issues_2_award_emoji!page=1&per_page=10
rename to services/migrations/testdata/gitlab/skipped_issue_number/GET_%2Fapi%2Fv4%2Fprojects%2F6590996%2Fissues%2F2%2Faward_emoji%3Fpage=1&per_page=10
diff --git a/services/migrations/testdata/gitlab/skipped_issue_number/_api_v4_projects_6590996_issues!page=1&per_page=10&sort=asc&state=all b/services/migrations/testdata/gitlab/skipped_issue_number/GET_%2Fapi%2Fv4%2Fprojects%2F6590996%2Fissues%3Fpage=1&per_page=10&sort=asc&state=all
similarity index 100%
rename from services/migrations/testdata/gitlab/skipped_issue_number/_api_v4_projects_6590996_issues!page=1&per_page=10&sort=asc&state=all
rename to services/migrations/testdata/gitlab/skipped_issue_number/GET_%2Fapi%2Fv4%2Fprojects%2F6590996%2Fissues%3Fpage=1&per_page=10&sort=asc&state=all
diff --git a/services/migrations/testdata/gitlab/skipped_issue_number/_api_v4_projects_6590996_merge_requests_1 b/services/migrations/testdata/gitlab/skipped_issue_number/GET_%2Fapi%2Fv4%2Fprojects%2F6590996%2Fmerge_requests%2F1
similarity index 100%
rename from services/migrations/testdata/gitlab/skipped_issue_number/_api_v4_projects_6590996_merge_requests_1
rename to services/migrations/testdata/gitlab/skipped_issue_number/GET_%2Fapi%2Fv4%2Fprojects%2F6590996%2Fmerge_requests%2F1
diff --git a/services/migrations/testdata/gitlab/skipped_issue_number/_api_v4_projects_6590996_merge_requests_1_award_emoji!page=1&per_page=10 b/services/migrations/testdata/gitlab/skipped_issue_number/GET_%2Fapi%2Fv4%2Fprojects%2F6590996%2Fmerge_requests%2F1%2Faward_emoji%3Fpage=1&per_page=10
similarity index 100%
rename from services/migrations/testdata/gitlab/skipped_issue_number/_api_v4_projects_6590996_merge_requests_1_award_emoji!page=1&per_page=10
rename to services/migrations/testdata/gitlab/skipped_issue_number/GET_%2Fapi%2Fv4%2Fprojects%2F6590996%2Fmerge_requests%2F1%2Faward_emoji%3Fpage=1&per_page=10
diff --git a/services/migrations/testdata/gitlab/skipped_issue_number/_api_v4_projects_6590996_merge_requests!page=1&per_page=10&view=simple b/services/migrations/testdata/gitlab/skipped_issue_number/GET_%2Fapi%2Fv4%2Fprojects%2F6590996%2Fmerge_requests%3Fpage=1&per_page=10&view=simple
similarity index 100%
rename from services/migrations/testdata/gitlab/skipped_issue_number/_api_v4_projects_6590996_merge_requests!page=1&per_page=10&view=simple
rename to services/migrations/testdata/gitlab/skipped_issue_number/GET_%2Fapi%2Fv4%2Fprojects%2F6590996%2Fmerge_requests%3Fpage=1&per_page=10&view=simple
diff --git a/services/migrations/testdata/gitlab/skipped_issue_number/_api_v4_projects_troyengel%2Farchbuild b/services/migrations/testdata/gitlab/skipped_issue_number/GET_%2Fapi%2Fv4%2Fprojects%2Ftroyengel%252Farchbuild
similarity index 100%
rename from services/migrations/testdata/gitlab/skipped_issue_number/_api_v4_projects_troyengel%2Farchbuild
rename to services/migrations/testdata/gitlab/skipped_issue_number/GET_%2Fapi%2Fv4%2Fprojects%2Ftroyengel%252Farchbuild
diff --git a/services/migrations/testdata/gitlab/skipped_issue_number/_api_v4_version b/services/migrations/testdata/gitlab/skipped_issue_number/GET_%2Fapi%2Fv4%2Fversion
similarity index 100%
rename from services/migrations/testdata/gitlab/skipped_issue_number/_api_v4_version
rename to services/migrations/testdata/gitlab/skipped_issue_number/GET_%2Fapi%2Fv4%2Fversion
diff --git a/services/mirror/mirror_pull.go b/services/mirror/mirror_pull.go
index 3418cf90df..2a38d4ba55 100644
--- a/services/mirror/mirror_pull.go
+++ b/services/mirror/mirror_pull.go
@@ -479,10 +479,7 @@ func SyncPullMirror(ctx context.Context, repoID int64) bool {
log.Error("SyncMirrors [repo: %-v]: unable to GetRefCommitID [ref_name: %s]: %v", m.Repo, result.refName, err)
continue
}
- objectFormat, err := git.GetObjectFormatOfRepo(ctx, m.Repo.RepoPath())
- if err != nil {
- log.Error("SyncMirrors [repo: %-v]: unable to GetHashTypeOfRepo: %v", m.Repo, err)
- }
+ objectFormat := git.ObjectFormatFromName(m.Repo.ObjectFormatName)
notify_service.SyncPushCommits(ctx, m.Repo.MustOwner(ctx), m.Repo, &repo_module.PushUpdateOptions{
RefFullName: result.refName,
OldCommitID: objectFormat.EmptyObjectID().String(),
@@ -593,7 +590,7 @@ func checkAndUpdateEmptyRepository(ctx context.Context, m *repo_model.Mirror, gi
m.Repo.DefaultBranch = firstName
}
// Update the git repository default branch
- if err := gitRepo.SetDefaultBranch(m.Repo.DefaultBranch); err != nil {
+ if err := gitrepo.SetDefaultBranch(ctx, m.Repo, m.Repo.DefaultBranch); err != nil {
if !git.IsErrUnsupportedVersion(err) {
log.Error("Failed to update default branch of underlying git repository %-v. Error: %v", m.Repo, err)
desc := fmt.Sprintf("Failed to update default branch of underlying git repository '%s': %v", m.Repo.RepoPath(), err)
diff --git a/services/packages/cargo/index.go b/services/packages/cargo/index.go
index e8a8313625..59823cd3de 100644
--- a/services/packages/cargo/index.go
+++ b/services/packages/cargo/index.go
@@ -62,9 +62,9 @@ func InitializeIndexRepository(ctx context.Context, doer, owner *user_model.User
}
func RebuildIndex(ctx context.Context, doer, owner *user_model.User) error {
- repo, err := getOrCreateIndexRepository(ctx, doer, owner)
+ repo, err := repo_model.GetRepositoryByOwnerAndName(ctx, owner.Name, IndexRepositoryName)
if err != nil {
- return err
+ return fmt.Errorf("GetRepositoryByOwnerAndName: %w", err)
}
ps, err := packages_model.GetPackagesByType(ctx, owner.ID, packages_model.TypeCargo)
diff --git a/services/pull/commit_status.go b/services/pull/commit_status.go
index 27ee572640..514bcee8f1 100644
--- a/services/pull/commit_status.go
+++ b/services/pull/commit_status.go
@@ -36,9 +36,9 @@ func MergeRequiredContextsCommitStatus(commitStatuses []*git_model.CommitStatus,
}
}
- for _, commitStatus := range commitStatuses {
+ for _, gp := range requiredContextsGlob {
var targetStatus structs.CommitStatusState
- for _, gp := range requiredContextsGlob {
+ for _, commitStatus := range commitStatuses {
if gp.Match(commitStatus.Context) {
targetStatus = commitStatus.State
matchedCount++
@@ -46,17 +46,21 @@ func MergeRequiredContextsCommitStatus(commitStatuses []*git_model.CommitStatus,
}
}
- if targetStatus != "" && targetStatus.NoBetterThan(returnedStatus) {
+ // If required rule not match any action, then it is pending
+ if targetStatus == "" {
+ if structs.CommitStatusPending.NoBetterThan(returnedStatus) {
+ returnedStatus = structs.CommitStatusPending
+ }
+ break
+ }
+
+ if targetStatus.NoBetterThan(returnedStatus) {
returnedStatus = targetStatus
}
}
}
- if matchedCount != len(requiredContexts) {
- return structs.CommitStatusPending
- }
-
- if matchedCount == 0 {
+ if matchedCount == 0 && returnedStatus == structs.CommitStatusSuccess {
status := git_model.CalcCommitStatus(commitStatuses)
if status != nil {
return status.State
diff --git a/services/pull/commit_status_test.go b/services/pull/commit_status_test.go
new file mode 100644
index 0000000000..592acdd55c
--- /dev/null
+++ b/services/pull/commit_status_test.go
@@ -0,0 +1,65 @@
+// Copyright 2024 The Gitea Authors.
+// All rights reserved.
+// SPDX-License-Identifier: MIT
+
+package pull
+
+import (
+ "testing"
+
+ git_model "code.gitea.io/gitea/models/git"
+ "code.gitea.io/gitea/modules/structs"
+
+ "github.com/stretchr/testify/assert"
+)
+
+func TestMergeRequiredContextsCommitStatus(t *testing.T) {
+ testCases := [][]*git_model.CommitStatus{
+ {
+ {Context: "Build 1", State: structs.CommitStatusSuccess},
+ {Context: "Build 2", State: structs.CommitStatusSuccess},
+ {Context: "Build 3", State: structs.CommitStatusSuccess},
+ },
+ {
+ {Context: "Build 1", State: structs.CommitStatusSuccess},
+ {Context: "Build 2", State: structs.CommitStatusSuccess},
+ {Context: "Build 2t", State: structs.CommitStatusPending},
+ },
+ {
+ {Context: "Build 1", State: structs.CommitStatusSuccess},
+ {Context: "Build 2", State: structs.CommitStatusSuccess},
+ {Context: "Build 2t", State: structs.CommitStatusFailure},
+ },
+ {
+ {Context: "Build 1", State: structs.CommitStatusSuccess},
+ {Context: "Build 2", State: structs.CommitStatusSuccess},
+ {Context: "Build 2t", State: structs.CommitStatusSuccess},
+ },
+ {
+ {Context: "Build 1", State: structs.CommitStatusSuccess},
+ {Context: "Build 2", State: structs.CommitStatusSuccess},
+ {Context: "Build 2t", State: structs.CommitStatusSuccess},
+ },
+ }
+ testCasesRequiredContexts := [][]string{
+ {"Build*"},
+ {"Build*", "Build 2t*"},
+ {"Build*", "Build 2t*"},
+ {"Build*", "Build 2t*", "Build 3*"},
+ {"Build*", "Build *", "Build 2t*", "Build 1*"},
+ }
+
+ testCasesExpected := []structs.CommitStatusState{
+ structs.CommitStatusSuccess,
+ structs.CommitStatusPending,
+ structs.CommitStatusFailure,
+ structs.CommitStatusPending,
+ structs.CommitStatusSuccess,
+ }
+
+ for i, commitStatuses := range testCases {
+ if MergeRequiredContextsCommitStatus(commitStatuses, testCasesRequiredContexts[i]) != testCasesExpected[i] {
+ assert.Fail(t, "Test case failed", "Test case %d failed", i+1)
+ }
+ }
+}
diff --git a/services/pull/pull.go b/services/pull/pull.go
index 34f3391a63..29a49fb4dc 100644
--- a/services/pull/pull.go
+++ b/services/pull/pull.go
@@ -351,7 +351,7 @@ func TestPullRequest(ctx context.Context, doer *user_model.User, repoID, maxPR i
}
if err == nil {
for _, pr := range prs {
- objectFormat, _ := git.GetObjectFormatOfRepo(ctx, pr.BaseRepo.RepoPath())
+ objectFormat := git.ObjectFormatFromName(pr.BaseRepo.ObjectFormatName)
if newCommitID != "" && newCommitID != objectFormat.EmptyObjectID().String() {
changed, err := checkIfPRContentChanged(ctx, pr, oldCommitID, newCommitID)
if err != nil {
diff --git a/services/release/release.go b/services/release/release.go
index a359e5078e..ba5fd1dd98 100644
--- a/services/release/release.go
+++ b/services/release/release.go
@@ -326,10 +326,7 @@ func DeleteReleaseByID(ctx context.Context, repo *repo_model.Repository, rel *re
}
refName := git.RefNameFromTag(rel.TagName)
- objectFormat, err := git.GetObjectFormatOfRepo(ctx, repo.RepoPath())
- if err != nil {
- return err
- }
+ objectFormat := git.ObjectFormatFromName(repo.ObjectFormatName)
notify_service.PushCommits(
ctx, doer, repo,
&repository.PushUpdateOptions{
diff --git a/services/repository/adopt.go b/services/repository/adopt.go
index 7ca68776b5..0ac3c774b7 100644
--- a/services/repository/adopt.go
+++ b/services/repository/adopt.go
@@ -127,24 +127,17 @@ func adoptRepository(ctx context.Context, repoPath string, u *user_model.User, r
repo.IsEmpty = false
- // Don't bother looking this repo in the context it won't be there
- gitRepo, err := gitrepo.OpenRepository(ctx, repo)
- if err != nil {
- return fmt.Errorf("openRepository: %w", err)
- }
- defer gitRepo.Close()
-
if len(defaultBranch) > 0 {
repo.DefaultBranch = defaultBranch
- if err = gitRepo.SetDefaultBranch(repo.DefaultBranch); err != nil {
+ if err = gitrepo.SetDefaultBranch(ctx, repo, repo.DefaultBranch); err != nil {
return fmt.Errorf("setDefaultBranch: %w", err)
}
} else {
- repo.DefaultBranch, err = gitRepo.GetDefaultBranch()
+ repo.DefaultBranch, err = gitrepo.GetDefaultBranch(ctx, repo)
if err != nil {
repo.DefaultBranch = setting.Repository.DefaultBranch
- if err = gitRepo.SetDefaultBranch(repo.DefaultBranch); err != nil {
+ if err = gitrepo.SetDefaultBranch(ctx, repo, repo.DefaultBranch); err != nil {
return fmt.Errorf("setDefaultBranch: %w", err)
}
}
@@ -188,7 +181,7 @@ func adoptRepository(ctx context.Context, repoPath string, u *user_model.User, r
repo.DefaultBranch = setting.Repository.DefaultBranch
}
- if err = gitRepo.SetDefaultBranch(repo.DefaultBranch); err != nil {
+ if err = gitrepo.SetDefaultBranch(ctx, repo, repo.DefaultBranch); err != nil {
return fmt.Errorf("setDefaultBranch: %w", err)
}
}
@@ -197,6 +190,13 @@ func adoptRepository(ctx context.Context, repoPath string, u *user_model.User, r
return fmt.Errorf("updateRepository: %w", err)
}
+ // Don't bother looking this repo in the context it won't be there
+ gitRepo, err := gitrepo.OpenRepository(ctx, repo)
+ if err != nil {
+ return fmt.Errorf("openRepository: %w", err)
+ }
+ defer gitRepo.Close()
+
if err = repo_module.SyncReleasesWithTags(ctx, repo, gitRepo); err != nil {
return fmt.Errorf("SyncReleasesWithTags: %w", err)
}
diff --git a/services/repository/branch.go b/services/repository/branch.go
index c3a7282f43..b683553245 100644
--- a/services/repository/branch.go
+++ b/services/repository/branch.go
@@ -225,44 +225,91 @@ func checkBranchName(ctx context.Context, repo *repo_model.Repository, name stri
return err
}
-// syncBranchToDB sync the branch information in the database. It will try to update the branch first,
-// if updated success with affect records > 0, then all are done. Because that means the branch has been in the database.
-// If no record is affected, that means the branch does not exist in database. So there are two possibilities.
-// One is this is a new branch, then we just need to insert the record. Another is the branches haven't been synced,
-// then we need to sync all the branches into database.
-func syncBranchToDB(ctx context.Context, repoID, pusherID int64, branchName string, commit *git.Commit) error {
- cnt, err := git_model.UpdateBranch(ctx, repoID, pusherID, branchName, commit)
- if err != nil {
- return fmt.Errorf("git_model.UpdateBranch %d:%s failed: %v", repoID, branchName, err)
- }
- if cnt > 0 { // This means branch does exist, so it's a normal update. It also means the branch has been synced.
- return nil
+// SyncBranchesToDB sync the branch information in the database.
+// It will check whether the branches of the repository have never been synced before.
+// If so, it will sync all branches of the repository.
+// Otherwise, it will sync the branches that need to be updated.
+func SyncBranchesToDB(ctx context.Context, repoID, pusherID int64, branchNames, commitIDs []string, getCommit func(commitID string) (*git.Commit, error)) error {
+ // Some designs that make the code look strange but are made for performance optimization purposes:
+ // 1. Sync branches in a batch to reduce the number of DB queries.
+ // 2. Lazy load commit information since it may be not necessary.
+ // 3. Exit early if synced all branches of git repo when there's no branch in DB.
+ // 4. Check the branches in DB if they are already synced.
+ //
+ // If the user pushes many branches at once, the Git hook will call the internal API in batches, rather than all at once.
+ // See https://github.com/go-gitea/gitea/blob/cb52b17f92e2d2293f7c003649743464492bca48/cmd/hook.go#L27
+ // For the first batch, it will hit optimization 3.
+ // For other batches, it will hit optimization 4.
+
+ if len(branchNames) != len(commitIDs) {
+ return fmt.Errorf("branchNames and commitIDs length not match")
}
- // if user haven't visit UI but directly push to a branch after upgrading from 1.20 -> 1.21,
- // we cannot simply insert the branch but need to check we have branches or not
- hasBranch, err := db.Exist[git_model.Branch](ctx, git_model.FindBranchOptions{
- RepoID: repoID,
- IsDeletedBranch: optional.Some(false),
- }.ToConds())
- if err != nil {
- return err
- }
- if !hasBranch {
- if _, err = repo_module.SyncRepoBranches(ctx, repoID, pusherID); err != nil {
- return fmt.Errorf("repo_module.SyncRepoBranches %d:%s failed: %v", repoID, branchName, err)
+ return db.WithTx(ctx, func(ctx context.Context) error {
+ branches, err := git_model.GetBranches(ctx, repoID, branchNames)
+ if err != nil {
+ return fmt.Errorf("git_model.GetBranches: %v", err)
+ }
+
+ if len(branches) == 0 {
+ // if user haven't visit UI but directly push to a branch after upgrading from 1.20 -> 1.21,
+ // we cannot simply insert the branch but need to check we have branches or not
+ hasBranch, err := db.Exist[git_model.Branch](ctx, git_model.FindBranchOptions{
+ RepoID: repoID,
+ IsDeletedBranch: optional.Some(false),
+ }.ToConds())
+ if err != nil {
+ return err
+ }
+ if !hasBranch {
+ if _, err = repo_module.SyncRepoBranches(ctx, repoID, pusherID); err != nil {
+ return fmt.Errorf("repo_module.SyncRepoBranches %d failed: %v", repoID, err)
+ }
+ return nil
+ }
+ }
+
+ branchMap := make(map[string]*git_model.Branch, len(branches))
+ for _, branch := range branches {
+ branchMap[branch.Name] = branch
+ }
+
+ newBranches := make([]*git_model.Branch, 0, len(branchNames))
+
+ for i, branchName := range branchNames {
+ commitID := commitIDs[i]
+ branch, exist := branchMap[branchName]
+ if exist && branch.CommitID == commitID && !branch.IsDeleted {
+ continue
+ }
+
+ commit, err := getCommit(commitID)
+ if err != nil {
+ return fmt.Errorf("get commit of %s failed: %v", branchName, err)
+ }
+
+ if exist {
+ if _, err := git_model.UpdateBranch(ctx, repoID, pusherID, branchName, commit); err != nil {
+ return fmt.Errorf("git_model.UpdateBranch %d:%s failed: %v", repoID, branchName, err)
+ }
+ return nil
+ }
+
+ // if database have branches but not this branch, it means this is a new branch
+ newBranches = append(newBranches, &git_model.Branch{
+ RepoID: repoID,
+ Name: branchName,
+ CommitID: commit.ID.String(),
+ CommitMessage: commit.Summary(),
+ PusherID: pusherID,
+ CommitTime: timeutil.TimeStamp(commit.Committer.When.Unix()),
+ })
+ }
+
+ if len(newBranches) > 0 {
+ return db.Insert(ctx, newBranches)
}
return nil
- }
-
- // if database have branches but not this branch, it means this is a new branch
- return db.Insert(ctx, &git_model.Branch{
- RepoID: repoID,
- Name: branchName,
- CommitID: commit.ID.String(),
- CommitMessage: commit.Summary(),
- PusherID: pusherID,
- CommitTime: timeutil.TimeStamp(commit.Committer.When.Unix()),
})
}
@@ -317,7 +364,7 @@ func RenameBranch(ctx context.Context, repo *repo_model.Repository, doer *user_m
}
if isDefault {
- err2 = gitRepo.SetDefaultBranch(to)
+ err2 = gitrepo.SetDefaultBranch(ctx, repo, to)
if err2 != nil {
return err2
}
diff --git a/services/repository/commitstatus/commitstatus.go b/services/repository/commitstatus/commitstatus.go
new file mode 100644
index 0000000000..145fc7d53c
--- /dev/null
+++ b/services/repository/commitstatus/commitstatus.go
@@ -0,0 +1,135 @@
+// Copyright 2024 The Gitea Authors. All rights reserved.
+// SPDX-License-Identifier: MIT
+
+package commitstatus
+
+import (
+ "context"
+ "crypto/sha256"
+ "fmt"
+
+ "code.gitea.io/gitea/models/db"
+ git_model "code.gitea.io/gitea/models/git"
+ repo_model "code.gitea.io/gitea/models/repo"
+ user_model "code.gitea.io/gitea/models/user"
+ "code.gitea.io/gitea/modules/cache"
+ "code.gitea.io/gitea/modules/git"
+ "code.gitea.io/gitea/modules/gitrepo"
+ "code.gitea.io/gitea/modules/log"
+ api "code.gitea.io/gitea/modules/structs"
+ "code.gitea.io/gitea/services/automerge"
+)
+
+func getCacheKey(repoID int64, brancheName string) string {
+ hashBytes := sha256.Sum256([]byte(fmt.Sprintf("%d:%s", repoID, brancheName)))
+ return fmt.Sprintf("commit_status:%x", hashBytes)
+}
+
+func updateCommitStatusCache(ctx context.Context, repoID int64, branchName string, status api.CommitStatusState) error {
+ c := cache.GetCache()
+ return c.Put(getCacheKey(repoID, branchName), string(status), 3*24*60)
+}
+
+func deleteCommitStatusCache(ctx context.Context, repoID int64, branchName string) error {
+ c := cache.GetCache()
+ return c.Delete(getCacheKey(repoID, branchName))
+}
+
+// CreateCommitStatus creates a new CommitStatus given a bunch of parameters
+// NOTE: All text-values will be trimmed from whitespaces.
+// Requires: Repo, Creator, SHA
+func CreateCommitStatus(ctx context.Context, repo *repo_model.Repository, creator *user_model.User, sha string, status *git_model.CommitStatus) error {
+ repoPath := repo.RepoPath()
+
+ // confirm that commit is exist
+ gitRepo, closer, err := gitrepo.RepositoryFromContextOrOpen(ctx, repo)
+ if err != nil {
+ return fmt.Errorf("OpenRepository[%s]: %w", repoPath, err)
+ }
+ defer closer.Close()
+
+ objectFormat := git.ObjectFormatFromName(repo.ObjectFormatName)
+
+ commit, err := gitRepo.GetCommit(sha)
+ if err != nil {
+ return fmt.Errorf("GetCommit[%s]: %w", sha, err)
+ }
+ if len(sha) != objectFormat.FullLength() {
+ // use complete commit sha
+ sha = commit.ID.String()
+ }
+
+ if err := git_model.NewCommitStatus(ctx, git_model.NewCommitStatusOptions{
+ Repo: repo,
+ Creator: creator,
+ SHA: commit.ID,
+ CommitStatus: status,
+ }); err != nil {
+ return fmt.Errorf("NewCommitStatus[repo_id: %d, user_id: %d, sha: %s]: %w", repo.ID, creator.ID, sha, err)
+ }
+
+ defaultBranchCommit, err := gitRepo.GetBranchCommit(repo.DefaultBranch)
+ if err != nil {
+ return fmt.Errorf("GetBranchCommit[%s]: %w", repo.DefaultBranch, err)
+ }
+
+ if commit.ID.String() == defaultBranchCommit.ID.String() { // since one commit status updated, the combined commit status should be invalid
+ if err := deleteCommitStatusCache(ctx, repo.ID, repo.DefaultBranch); err != nil {
+ log.Error("deleteCommitStatusCache[%d:%s] failed: %v", repo.ID, repo.DefaultBranch, err)
+ }
+ }
+
+ if status.State.IsSuccess() {
+ if err := automerge.MergeScheduledPullRequest(ctx, sha, repo); err != nil {
+ return fmt.Errorf("MergeScheduledPullRequest[repo_id: %d, user_id: %d, sha: %s]: %w", repo.ID, creator.ID, sha, err)
+ }
+ }
+
+ return nil
+}
+
+// FindReposLastestCommitStatuses loading repository default branch latest combinded commit status with cache
+func FindReposLastestCommitStatuses(ctx context.Context, repos []*repo_model.Repository) ([]*git_model.CommitStatus, error) {
+ results := make([]*git_model.CommitStatus, len(repos))
+ c := cache.GetCache()
+
+ for i, repo := range repos {
+ status, ok := c.Get(getCacheKey(repo.ID, repo.DefaultBranch)).(string)
+ if ok && status != "" {
+ results[i] = &git_model.CommitStatus{State: api.CommitStatusState(status)}
+ }
+ }
+
+ // collect the latest commit of each repo
+ // at most there are dozens of repos (limited by MaxResponseItems), so it's not a big problem at the moment
+ repoBranchNames := make(map[int64]string, len(repos))
+ for i, repo := range repos {
+ if results[i] == nil {
+ repoBranchNames[repo.ID] = repo.DefaultBranch
+ }
+ }
+
+ repoIDsToLatestCommitSHAs, err := git_model.FindBranchesByRepoAndBranchName(ctx, repoBranchNames)
+ if err != nil {
+ return nil, fmt.Errorf("FindBranchesByRepoAndBranchName: %v", err)
+ }
+
+ // call the database O(1) times to get the commit statuses for all repos
+ repoToItsLatestCommitStatuses, err := git_model.GetLatestCommitStatusForPairs(ctx, repoIDsToLatestCommitSHAs, db.ListOptionsAll)
+ if err != nil {
+ return nil, fmt.Errorf("GetLatestCommitStatusForPairs: %v", err)
+ }
+
+ for i, repo := range repos {
+ if results[i] == nil {
+ results[i] = git_model.CalcCommitStatus(repoToItsLatestCommitStatuses[repo.ID])
+ if results[i].State != "" {
+ if err := updateCommitStatusCache(ctx, repo.ID, repo.DefaultBranch, results[i].State); err != nil {
+ log.Error("updateCommitStatusCache[%d:%s] failed: %v", repo.ID, repo.DefaultBranch, err)
+ }
+ }
+ }
+ }
+
+ return results, nil
+}
diff --git a/services/repository/create.go b/services/repository/create.go
index 9bc0b93eff..d092d02a1f 100644
--- a/services/repository/create.go
+++ b/services/repository/create.go
@@ -177,12 +177,7 @@ func initRepository(ctx context.Context, repoPath string, u *user_model.User, re
if len(opts.DefaultBranch) > 0 {
repo.DefaultBranch = opts.DefaultBranch
- gitRepo, err := gitrepo.OpenRepository(ctx, repo)
- if err != nil {
- return fmt.Errorf("openRepository: %w", err)
- }
- defer gitRepo.Close()
- if err = gitRepo.SetDefaultBranch(repo.DefaultBranch); err != nil {
+ if err = gitrepo.SetDefaultBranch(ctx, repo, repo.DefaultBranch); err != nil {
return fmt.Errorf("setDefaultBranch: %w", err)
}
diff --git a/services/repository/files/commit.go b/services/repository/files/commit.go
index 512aec7c81..e0dad29273 100644
--- a/services/repository/files/commit.go
+++ b/services/repository/files/commit.go
@@ -5,61 +5,13 @@ package files
import (
"context"
- "fmt"
asymkey_model "code.gitea.io/gitea/models/asymkey"
- git_model "code.gitea.io/gitea/models/git"
repo_model "code.gitea.io/gitea/models/repo"
- user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/modules/git"
- "code.gitea.io/gitea/modules/gitrepo"
"code.gitea.io/gitea/modules/structs"
- "code.gitea.io/gitea/services/automerge"
)
-// CreateCommitStatus creates a new CommitStatus given a bunch of parameters
-// NOTE: All text-values will be trimmed from whitespaces.
-// Requires: Repo, Creator, SHA
-func CreateCommitStatus(ctx context.Context, repo *repo_model.Repository, creator *user_model.User, sha string, status *git_model.CommitStatus) error {
- repoPath := repo.RepoPath()
-
- // confirm that commit is exist
- gitRepo, closer, err := gitrepo.RepositoryFromContextOrOpen(ctx, repo)
- if err != nil {
- return fmt.Errorf("OpenRepository[%s]: %w", repoPath, err)
- }
- defer closer.Close()
-
- objectFormat := git.ObjectFormatFromName(repo.ObjectFormatName)
-
- commit, err := gitRepo.GetCommit(sha)
- if err != nil {
- gitRepo.Close()
- return fmt.Errorf("GetCommit[%s]: %w", sha, err)
- } else if len(sha) != objectFormat.FullLength() {
- // use complete commit sha
- sha = commit.ID.String()
- }
- gitRepo.Close()
-
- if err := git_model.NewCommitStatus(ctx, git_model.NewCommitStatusOptions{
- Repo: repo,
- Creator: creator,
- SHA: commit.ID,
- CommitStatus: status,
- }); err != nil {
- return fmt.Errorf("NewCommitStatus[repo_id: %d, user_id: %d, sha: %s]: %w", repo.ID, creator.ID, sha, err)
- }
-
- if status.State.IsSuccess() {
- if err := automerge.MergeScheduledPullRequest(ctx, sha, repo); err != nil {
- return fmt.Errorf("MergeScheduledPullRequest[repo_id: %d, user_id: %d, sha: %s]: %w", repo.ID, creator.ID, sha, err)
- }
- }
-
- return nil
-}
-
// CountDivergingCommits determines how many commits a branch is ahead or behind the repository's base branch
func CountDivergingCommits(ctx context.Context, repo *repo_model.Repository, branch string) (*git.DivergeObject, error) {
divergence, err := git.GetDivergingCommits(ctx, repo.RepoPath(), repo.DefaultBranch, branch)
diff --git a/services/repository/files/search.go b/services/repository/files/search.go
index f8317c4892..09c3ab5bf3 100644
--- a/services/repository/files/search.go
+++ b/services/repository/files/search.go
@@ -16,14 +16,18 @@ import (
)
type Result struct {
- RepoID int64 // ignored
- Filename string
- CommitID string // branch
- UpdatedUnix timeutil.TimeStamp // ignored
- Language string
- Color string
- LineNumbers []int64
- FormattedLines template.HTML
+ RepoID int64 // ignored
+ Filename string
+ CommitID string // branch
+ UpdatedUnix timeutil.TimeStamp // ignored
+ Language string
+ Color string
+ Lines []ResultLine
+}
+
+type ResultLine struct {
+ Num int64
+ FormattedContent template.HTML
}
const pHEAD = "HEAD:"
@@ -46,7 +50,8 @@ func NewRepoGrep(ctx context.Context, repo *repo_model.Repository, keyword strin
"-n", // line nums
"-i", // ignore case
"--full-name", // full file path, rel to repo
- //"--column", // for adding better highlighting support
+ //"--column", // for adding better highlighting support
+ "-e", // for queries starting with "-"
).
AddDynamicArguments(keyword).
AddArguments("HEAD").
@@ -57,6 +62,8 @@ func NewRepoGrep(ctx context.Context, repo *repo_model.Repository, keyword strin
for _, block := range strings.Split(stdout, "\n\n") {
res := Result{CommitID: repo.DefaultBranch}
+
+ linenum := []int64{}
code := []string{}
for _, line := range strings.Split(block, "\n") {
@@ -71,18 +78,32 @@ func NewRepoGrep(ctx context.Context, repo *repo_model.Repository, keyword strin
continue
}
- res.LineNumbers = append(res.LineNumbers, i)
+ linenum = append(linenum, i)
code = append(code, after)
}
}
- if res.Filename == "" || len(code) == 0 || len(res.LineNumbers) == 0 {
+ if res.Filename == "" || len(code) == 0 || len(linenum) == 0 {
continue
}
- res.FormattedLines, res.Language = highlight.Code(res.Filename, "", strings.Join(code, "\n"))
+ var hl template.HTML
+
+ hl, res.Language = highlight.Code(res.Filename, "", strings.Join(code, "\n"))
res.Color = enry.GetColor(res.Language)
+ hlCode := strings.Split(string(hl), "\n")
+ n := min(len(hlCode), len(linenum))
+
+ res.Lines = make([]ResultLine, n)
+
+ for i := 0; i < n; i++ {
+ res.Lines[i] = ResultLine{
+ Num: linenum[i],
+ FormattedContent: template.HTML(hlCode[i]),
+ }
+ }
+
data = append(data, &res)
}
diff --git a/services/repository/files/search_test.go b/services/repository/files/search_test.go
index 959ddaa9f9..2f2f87368d 100644
--- a/services/repository/files/search_test.go
+++ b/services/repository/files/search_test.go
@@ -25,14 +25,16 @@ func TestNewRepoGrep(t *testing.T) {
expected := []*Result{
{
- RepoID: 0,
- Filename: "README.md",
- CommitID: "master",
- UpdatedUnix: 0,
- Language: "Markdown",
- Color: "#083fa1",
- LineNumbers: []int64{2, 3},
- FormattedLines: "\nDescription for repo1",
+ RepoID: 0,
+ Filename: "README.md",
+ CommitID: "master",
+ UpdatedUnix: 0,
+ Language: "Markdown",
+ Color: "#083fa1",
+ Lines: []ResultLine{
+ {Num: 2, FormattedContent: ""},
+ {Num: 3, FormattedContent: "Description for repo1"},
+ },
},
}
diff --git a/services/repository/generate.go b/services/repository/generate.go
index c444b60b2c..9b09e271ab 100644
--- a/services/repository/generate.go
+++ b/services/repository/generate.go
@@ -272,12 +272,7 @@ func generateGitContent(ctx context.Context, repo, templateRepo, generateRepo *r
repo.DefaultBranch = templateRepo.DefaultBranch
}
- gitRepo, err := gitrepo.OpenRepository(ctx, repo)
- if err != nil {
- return fmt.Errorf("openRepository: %w", err)
- }
- defer gitRepo.Close()
- if err = gitRepo.SetDefaultBranch(repo.DefaultBranch); err != nil {
+ if err = gitrepo.SetDefaultBranch(ctx, repo, repo.DefaultBranch); err != nil {
return fmt.Errorf("setDefaultBranch: %w", err)
}
if err = UpdateRepository(ctx, repo, false); err != nil {
diff --git a/services/repository/migrate.go b/services/repository/migrate.go
index b218a2ef46..5800f2b5cb 100644
--- a/services/repository/migrate.go
+++ b/services/repository/migrate.go
@@ -16,6 +16,7 @@ import (
repo_model "code.gitea.io/gitea/models/repo"
user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/modules/git"
+ "code.gitea.io/gitea/modules/gitrepo"
"code.gitea.io/gitea/modules/lfs"
"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/migration"
@@ -97,7 +98,7 @@ func MigrateRepositoryGitData(ctx context.Context, u *user_model.User,
}
defer gitRepo.Close()
- branch, err := gitRepo.GetDefaultBranch()
+ branch, err := gitrepo.GetDefaultBranch(ctx, repo)
if err != nil {
log.Warn("Failed to get the default branch of a migrated wiki repo: %v", err)
if err := util.RemoveAll(wikiPath); err != nil {
diff --git a/services/repository/push.go b/services/repository/push.go
index bb080e30cc..8b27f07196 100644
--- a/services/repository/push.go
+++ b/services/repository/push.go
@@ -11,7 +11,6 @@ import (
"time"
"code.gitea.io/gitea/models/db"
- git_model "code.gitea.io/gitea/models/git"
repo_model "code.gitea.io/gitea/models/repo"
user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/modules/cache"
@@ -183,7 +182,7 @@ func pushUpdates(optsList []*repo_module.PushUpdateOptions) error {
repo.DefaultBranch = refName
repo.IsEmpty = false
if repo.DefaultBranch != setting.Repository.DefaultBranch {
- if err := gitRepo.SetDefaultBranch(repo.DefaultBranch); err != nil {
+ if err := gitrepo.SetDefaultBranch(ctx, repo, repo.DefaultBranch); err != nil {
if !git.IsErrUnsupportedVersion(err) {
return err
}
@@ -259,10 +258,6 @@ func pushUpdates(optsList []*repo_module.PushUpdateOptions) error {
commits.Commits = commits.Commits[:setting.UI.FeedMaxCommitNum]
}
- if err = syncBranchToDB(ctx, repo.ID, opts.PusherID, branch, newCommit); err != nil {
- return fmt.Errorf("git_model.UpdateBranch %s:%s failed: %v", repo.FullName(), branch, err)
- }
-
notify_service.PushCommits(ctx, pusher, repo, opts, commits)
// Cache for big repository
@@ -275,10 +270,6 @@ func pushUpdates(optsList []*repo_module.PushUpdateOptions) error {
// close all related pulls
log.Error("close related pull request failed: %v", err)
}
-
- if err := git_model.AddDeletedBranch(ctx, repo.ID, branch, pusher.ID); err != nil {
- return fmt.Errorf("AddDeletedBranch %s:%s failed: %v", repo.FullName(), branch, err)
- }
}
// Even if user delete a branch on a repository which he didn't watch, he will be watch that.
diff --git a/services/user/email.go b/services/user/email.go
index 0b579cf792..9dc5270842 100644
--- a/services/user/email.go
+++ b/services/user/email.go
@@ -14,12 +14,13 @@ import (
"code.gitea.io/gitea/modules/util"
)
-func AddOrSetPrimaryEmailAddress(ctx context.Context, u *user_model.User, emailStr string) error {
+// AdminAddOrSetPrimaryEmailAddress is used by admins to add or set a user's primary email address
+func AdminAddOrSetPrimaryEmailAddress(ctx context.Context, u *user_model.User, emailStr string) error {
if strings.EqualFold(u.Email, emailStr) {
return nil
}
- if err := user_model.ValidateEmail(emailStr); err != nil {
+ if err := user_model.ValidateEmailForAdmin(emailStr); err != nil {
return err
}
diff --git a/services/user/email_test.go b/services/user/email_test.go
index 66d4821346..0784b4f803 100644
--- a/services/user/email_test.go
+++ b/services/user/email_test.go
@@ -10,11 +10,13 @@ import (
organization_model "code.gitea.io/gitea/models/organization"
"code.gitea.io/gitea/models/unittest"
user_model "code.gitea.io/gitea/models/user"
+ "code.gitea.io/gitea/modules/setting"
+ "github.com/gobwas/glob"
"github.com/stretchr/testify/assert"
)
-func TestAddOrSetPrimaryEmailAddress(t *testing.T) {
+func TestAdminAddOrSetPrimaryEmailAddress(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 27})
@@ -28,7 +30,7 @@ func TestAddOrSetPrimaryEmailAddress(t *testing.T) {
assert.NotEqual(t, "new-primary@example.com", primary.Email)
assert.Equal(t, user.Email, primary.Email)
- assert.NoError(t, AddOrSetPrimaryEmailAddress(db.DefaultContext, user, "new-primary@example.com"))
+ assert.NoError(t, AdminAddOrSetPrimaryEmailAddress(db.DefaultContext, user, "new-primary@example.com"))
primary, err = user_model.GetPrimaryEmailAddressOfUser(db.DefaultContext, user.ID)
assert.NoError(t, err)
@@ -39,7 +41,19 @@ func TestAddOrSetPrimaryEmailAddress(t *testing.T) {
assert.NoError(t, err)
assert.Len(t, emails, 2)
- assert.NoError(t, AddOrSetPrimaryEmailAddress(db.DefaultContext, user, "user27@example.com"))
+ setting.Service.EmailDomainAllowList = []glob.Glob{glob.MustCompile("example.org")}
+ defer func() {
+ setting.Service.EmailDomainAllowList = []glob.Glob{}
+ }()
+
+ assert.NoError(t, AdminAddOrSetPrimaryEmailAddress(db.DefaultContext, user, "new-primary2@example2.com"))
+
+ primary, err = user_model.GetPrimaryEmailAddressOfUser(db.DefaultContext, user.ID)
+ assert.NoError(t, err)
+ assert.Equal(t, "new-primary2@example2.com", primary.Email)
+ assert.Equal(t, user.Email, primary.Email)
+
+ assert.NoError(t, AdminAddOrSetPrimaryEmailAddress(db.DefaultContext, user, "user27@example.com"))
primary, err = user_model.GetPrimaryEmailAddressOfUser(db.DefaultContext, user.ID)
assert.NoError(t, err)
@@ -48,7 +62,7 @@ func TestAddOrSetPrimaryEmailAddress(t *testing.T) {
emails, err = user_model.GetEmailAddresses(db.DefaultContext, user.ID)
assert.NoError(t, err)
- assert.Len(t, emails, 2)
+ assert.Len(t, emails, 3)
}
func TestReplacePrimaryEmailAddress(t *testing.T) {
diff --git a/services/webhook/deliver.go b/services/webhook/deliver.go
index 16819f846a..32f1a3de45 100644
--- a/services/webhook/deliver.go
+++ b/services/webhook/deliver.go
@@ -32,36 +32,17 @@ import (
"github.com/gobwas/glob"
)
-// Deliver deliver hook task
-func Deliver(ctx context.Context, t *webhook_model.HookTask) error {
- w, err := webhook_model.GetWebhookByID(ctx, t.HookID)
- if err != nil {
- return err
- }
-
- defer func() {
- err := recover()
- if err == nil {
- return
- }
- // There was a panic whilst delivering a hook...
- log.Error("PANIC whilst trying to deliver webhook task[%d] to webhook %s Panic: %v\nStacktrace: %s", t.ID, w.URL, err, log.Stack(2))
- }()
-
- t.IsDelivered = true
-
- var req *http.Request
-
+func newDefaultRequest(ctx context.Context, w *webhook_model.Webhook, t *webhook_model.HookTask) (req *http.Request, body []byte, err error) {
switch w.HTTPMethod {
case "":
- log.Info("HTTP Method for webhook %s empty, setting to POST as default", w.URL)
+ log.Info("HTTP Method for %s webhook %s [ID: %d] is not set, defaulting to POST", w.Type, w.URL, w.ID)
fallthrough
case http.MethodPost:
switch w.ContentType {
case webhook_model.ContentTypeJSON:
req, err = http.NewRequest("POST", w.URL, strings.NewReader(t.PayloadContent))
if err != nil {
- return err
+ return nil, nil, err
}
req.Header.Set("Content-Type", "application/json")
@@ -72,50 +53,58 @@ func Deliver(ctx context.Context, t *webhook_model.HookTask) error {
req, err = http.NewRequest("POST", w.URL, strings.NewReader(forms.Encode()))
if err != nil {
- return err
+ return nil, nil, err
}
req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
+ default:
+ return nil, nil, fmt.Errorf("invalid content type: %v", w.ContentType)
}
case http.MethodGet:
u, err := url.Parse(w.URL)
if err != nil {
- return fmt.Errorf("unable to deliver webhook task[%d] as cannot parse webhook url %s: %w", t.ID, w.URL, err)
+ return nil, nil, fmt.Errorf("invalid URL: %w", err)
}
vals := u.Query()
vals["payload"] = []string{t.PayloadContent}
u.RawQuery = vals.Encode()
req, err = http.NewRequest("GET", u.String(), nil)
if err != nil {
- return fmt.Errorf("unable to deliver webhook task[%d] as unable to create HTTP request for webhook url %s: %w", t.ID, w.URL, err)
+ return nil, nil, err
}
case http.MethodPut:
switch w.Type {
- case webhook_module.MATRIX:
+ case webhook_module.MATRIX: // used when t.Version == 1
txnID, err := getMatrixTxnID([]byte(t.PayloadContent))
if err != nil {
- return err
+ return nil, nil, err
}
url := fmt.Sprintf("%s/%s", w.URL, url.PathEscape(txnID))
req, err = http.NewRequest("PUT", url, strings.NewReader(t.PayloadContent))
if err != nil {
- return fmt.Errorf("unable to deliver webhook task[%d] as cannot create matrix request for webhook url %s: %w", t.ID, w.URL, err)
+ return nil, nil, err
}
default:
- return fmt.Errorf("invalid http method for webhook task[%d] in webhook %s: %v", t.ID, w.URL, w.HTTPMethod)
+ return nil, nil, fmt.Errorf("invalid http method: %v", w.HTTPMethod)
}
default:
- return fmt.Errorf("invalid http method for webhook task[%d] in webhook %s: %v", t.ID, w.URL, w.HTTPMethod)
+ return nil, nil, fmt.Errorf("invalid http method: %v", w.HTTPMethod)
}
+ body = []byte(t.PayloadContent)
+ return req, body, addDefaultHeaders(req, []byte(w.Secret), t, body)
+}
+
+func addDefaultHeaders(req *http.Request, secret []byte, t *webhook_model.HookTask, payloadContent []byte) error {
var signatureSHA1 string
var signatureSHA256 string
- if len(w.Secret) > 0 {
- sig1 := hmac.New(sha1.New, []byte(w.Secret))
- sig256 := hmac.New(sha256.New, []byte(w.Secret))
- _, err = io.MultiWriter(sig1, sig256).Write([]byte(t.PayloadContent))
+ if len(secret) > 0 {
+ sig1 := hmac.New(sha1.New, secret)
+ sig256 := hmac.New(sha256.New, secret)
+ _, err := io.MultiWriter(sig1, sig256).Write(payloadContent)
if err != nil {
- log.Error("prepareWebhooks.sigWrite: %v", err)
+ // this error should never happen, since the hashes are writing to []byte and always return a nil error.
+ return fmt.Errorf("prepareWebhooks.sigWrite: %w", err)
}
signatureSHA1 = hex.EncodeToString(sig1.Sum(nil))
signatureSHA256 = hex.EncodeToString(sig256.Sum(nil))
@@ -140,15 +129,36 @@ func Deliver(ctx context.Context, t *webhook_model.HookTask) error {
req.Header["X-GitHub-Delivery"] = []string{t.UUID}
req.Header["X-GitHub-Event"] = []string{event}
req.Header["X-GitHub-Event-Type"] = []string{eventType}
+ return nil
+}
- // Add Authorization Header
- authorization, err := w.HeaderAuthorization()
+// Deliver creates the [http.Request] (depending on the webhook type), sends it
+// and records the status and response.
+func Deliver(ctx context.Context, t *webhook_model.HookTask) error {
+ w, err := webhook_model.GetWebhookByID(ctx, t.HookID)
if err != nil {
- log.Error("Webhook could not get Authorization header [%d]: %v", w.ID, err)
return err
}
- if authorization != "" {
- req.Header["Authorization"] = []string{authorization}
+
+ defer func() {
+ err := recover()
+ if err == nil {
+ return
+ }
+ // There was a panic whilst delivering a hook...
+ log.Error("PANIC whilst trying to deliver webhook task[%d] to webhook %s Panic: %v\nStacktrace: %s", t.ID, w.URL, err, log.Stack(2))
+ }()
+
+ t.IsDelivered = true
+
+ newRequest := webhookRequesters[w.Type]
+ if t.PayloadVersion == 1 || newRequest == nil {
+ newRequest = newDefaultRequest
+ }
+
+ req, body, err := newRequest(ctx, w, t)
+ if err != nil {
+ return fmt.Errorf("cannot create http request for webhook %s[%d %s]: %w", w.Type, w.ID, w.URL, err)
}
// Record delivery information.
@@ -156,11 +166,22 @@ func Deliver(ctx context.Context, t *webhook_model.HookTask) error {
URL: req.URL.String(),
HTTPMethod: req.Method,
Headers: map[string]string{},
+ Body: string(body),
}
for k, vals := range req.Header {
t.RequestInfo.Headers[k] = strings.Join(vals, ",")
}
+ // Add Authorization Header
+ authorization, err := w.HeaderAuthorization()
+ if err != nil {
+ return fmt.Errorf("cannot get Authorization header for webhook %s[%d %s]: %w", w.Type, w.ID, w.URL, err)
+ }
+ if authorization != "" {
+ req.Header.Set("Authorization", authorization)
+ t.RequestInfo.Headers["Authorization"] = "******"
+ }
+
t.ResponseInfo = &webhook_model.HookResponse{
Headers: map[string]string{},
}
diff --git a/services/webhook/deliver_test.go b/services/webhook/deliver_test.go
index eca2ba244b..bc06e43e03 100644
--- a/services/webhook/deliver_test.go
+++ b/services/webhook/deliver_test.go
@@ -5,10 +5,12 @@ package webhook
import (
"context"
+ "io"
"net/http"
"net/http/httptest"
"net/url"
"os"
+ "strings"
"testing"
"time"
@@ -17,7 +19,6 @@ import (
webhook_model "code.gitea.io/gitea/models/webhook"
"code.gitea.io/gitea/modules/hostmatcher"
"code.gitea.io/gitea/modules/setting"
- api "code.gitea.io/gitea/modules/structs"
webhook_module "code.gitea.io/gitea/modules/webhook"
"github.com/stretchr/testify/assert"
@@ -114,13 +115,15 @@ func TestWebhookDeliverAuthorizationHeader(t *testing.T) {
assert.NoError(t, webhook_model.CreateWebhook(db.DefaultContext, hook))
db.GetEngine(db.DefaultContext).NoAutoTime().DB().Logger.ShowSQL(true)
- hookTask := &webhook_model.HookTask{HookID: hook.ID, EventType: webhook_module.HookEventPush, Payloader: &api.PushPayload{}}
+ hookTask := &webhook_model.HookTask{
+ HookID: hook.ID,
+ EventType: webhook_module.HookEventPush,
+ PayloadVersion: 2,
+ }
hookTask, err = webhook_model.CreateHookTask(db.DefaultContext, hookTask)
assert.NoError(t, err)
- if !assert.NotNil(t, hookTask) {
- return
- }
+ assert.NotNil(t, hookTask)
assert.NoError(t, Deliver(context.Background(), hookTask))
select {
@@ -130,4 +133,202 @@ func TestWebhookDeliverAuthorizationHeader(t *testing.T) {
}
assert.True(t, hookTask.IsSucceed)
+ assert.Equal(t, "******", hookTask.RequestInfo.Headers["Authorization"])
+}
+
+func TestWebhookDeliverHookTask(t *testing.T) {
+ assert.NoError(t, unittest.PrepareTestDatabase())
+
+ done := make(chan struct{}, 1)
+ s := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
+ assert.Equal(t, "PUT", r.Method)
+ switch r.URL.Path {
+ case "/webhook/66d222a5d6349e1311f551e50722d837e30fce98":
+ // Version 1
+ assert.Equal(t, "push", r.Header.Get("X-GitHub-Event"))
+ assert.Equal(t, "", r.Header.Get("Content-Type"))
+ body, err := io.ReadAll(r.Body)
+ assert.NoError(t, err)
+ assert.Equal(t, `{"data": 42}`, string(body))
+
+ case "/webhook/6db5dc1e282529a8c162c7fe93dd2667494eeb51":
+ // Version 2
+ assert.Equal(t, "push", r.Header.Get("X-GitHub-Event"))
+ assert.Equal(t, "application/json", r.Header.Get("Content-Type"))
+ body, err := io.ReadAll(r.Body)
+ assert.NoError(t, err)
+ assert.Len(t, body, 2147)
+
+ default:
+ w.WriteHeader(404)
+ t.Fatalf("unexpected url path %s", r.URL.Path)
+ return
+ }
+ w.WriteHeader(200)
+ done <- struct{}{}
+ }))
+ t.Cleanup(s.Close)
+
+ hook := &webhook_model.Webhook{
+ RepoID: 3,
+ IsActive: true,
+ Type: webhook_module.MATRIX,
+ URL: s.URL + "/webhook",
+ HTTPMethod: "PUT",
+ ContentType: webhook_model.ContentTypeJSON,
+ Meta: `{"message_type":0}`, // text
+ }
+ assert.NoError(t, webhook_model.CreateWebhook(db.DefaultContext, hook))
+
+ t.Run("Version 1", func(t *testing.T) {
+ hookTask := &webhook_model.HookTask{
+ HookID: hook.ID,
+ EventType: webhook_module.HookEventPush,
+ PayloadContent: `{"data": 42}`,
+ PayloadVersion: 1,
+ }
+
+ hookTask, err := webhook_model.CreateHookTask(db.DefaultContext, hookTask)
+ assert.NoError(t, err)
+ assert.NotNil(t, hookTask)
+
+ assert.NoError(t, Deliver(context.Background(), hookTask))
+ select {
+ case <-done:
+ case <-time.After(5 * time.Second):
+ t.Fatal("waited to long for request to happen")
+ }
+
+ assert.True(t, hookTask.IsSucceed)
+ })
+
+ t.Run("Version 2", func(t *testing.T) {
+ p := pushTestPayload()
+ data, err := p.JSONPayload()
+ assert.NoError(t, err)
+
+ hookTask := &webhook_model.HookTask{
+ HookID: hook.ID,
+ EventType: webhook_module.HookEventPush,
+ PayloadContent: string(data),
+ PayloadVersion: 2,
+ }
+
+ hookTask, err = webhook_model.CreateHookTask(db.DefaultContext, hookTask)
+ assert.NoError(t, err)
+ assert.NotNil(t, hookTask)
+
+ assert.NoError(t, Deliver(context.Background(), hookTask))
+ select {
+ case <-done:
+ case <-time.After(5 * time.Second):
+ t.Fatal("waited to long for request to happen")
+ }
+
+ assert.True(t, hookTask.IsSucceed)
+ })
+}
+
+func TestWebhookDeliverSpecificTypes(t *testing.T) {
+ assert.NoError(t, unittest.PrepareTestDatabase())
+
+ type hookCase struct {
+ gotBody chan []byte
+ expectedMethod string
+ }
+
+ cases := map[string]hookCase{
+ webhook_module.SLACK: {
+ gotBody: make(chan []byte, 1),
+ },
+ webhook_module.DISCORD: {
+ gotBody: make(chan []byte, 1),
+ },
+ webhook_module.DINGTALK: {
+ gotBody: make(chan []byte, 1),
+ },
+ webhook_module.TELEGRAM: {
+ gotBody: make(chan []byte, 1),
+ },
+ webhook_module.MSTEAMS: {
+ gotBody: make(chan []byte, 1),
+ },
+ webhook_module.FEISHU: {
+ gotBody: make(chan []byte, 1),
+ },
+ webhook_module.MATRIX: {
+ gotBody: make(chan []byte, 1),
+ expectedMethod: "PUT",
+ },
+ webhook_module.WECHATWORK: {
+ gotBody: make(chan []byte, 1),
+ },
+ webhook_module.PACKAGIST: {
+ gotBody: make(chan []byte, 1),
+ },
+ }
+
+ s := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
+ assert.Equal(t, "application/json", r.Header.Get("Content-Type"), r.URL.Path)
+
+ typ := strings.Split(r.URL.Path, "/")[1] // take first segment (after skipping leading slash)
+ hc := cases[typ]
+
+ if hc.expectedMethod != "" {
+ assert.Equal(t, hc.expectedMethod, r.Method, r.URL.Path)
+ } else {
+ assert.Equal(t, "POST", r.Method, r.URL.Path)
+ }
+
+ require.NotNil(t, hc.gotBody, r.URL.Path)
+ body, err := io.ReadAll(r.Body)
+ assert.NoError(t, err)
+ w.WriteHeader(200)
+ hc.gotBody <- body
+ }))
+ t.Cleanup(s.Close)
+
+ p := pushTestPayload()
+ data, err := p.JSONPayload()
+ assert.NoError(t, err)
+
+ for typ, hc := range cases {
+ typ := typ
+ hc := hc
+ t.Run(typ, func(t *testing.T) {
+ t.Parallel()
+ hook := &webhook_model.Webhook{
+ RepoID: 3,
+ IsActive: true,
+ Type: typ,
+ URL: s.URL + "/" + typ,
+ HTTPMethod: "", // should fallback to POST, when left unset by the specific hook
+ ContentType: 0, // set to 0 so that falling back to default request fails with "invalid content type"
+ Meta: "{}",
+ }
+ assert.NoError(t, webhook_model.CreateWebhook(db.DefaultContext, hook))
+
+ hookTask := &webhook_model.HookTask{
+ HookID: hook.ID,
+ EventType: webhook_module.HookEventPush,
+ PayloadContent: string(data),
+ PayloadVersion: 2,
+ }
+
+ hookTask, err := webhook_model.CreateHookTask(db.DefaultContext, hookTask)
+ assert.NoError(t, err)
+ assert.NotNil(t, hookTask)
+
+ assert.NoError(t, Deliver(context.Background(), hookTask))
+ select {
+ case gotBody := <-hc.gotBody:
+ assert.NotEqual(t, string(data), string(gotBody), "request body must be different from the event payload")
+ assert.Equal(t, hookTask.RequestInfo.Body, string(gotBody), "request body was not saved")
+ case <-time.After(5 * time.Second):
+ t.Fatal("waited to long for request to happen")
+ }
+
+ assert.True(t, hookTask.IsSucceed)
+ })
+ }
}
diff --git a/services/webhook/dingtalk.go b/services/webhook/dingtalk.go
index d615e7254f..c57d04415a 100644
--- a/services/webhook/dingtalk.go
+++ b/services/webhook/dingtalk.go
@@ -4,12 +4,14 @@
package webhook
import (
+ "context"
"fmt"
+ "net/http"
"net/url"
"strings"
+ webhook_model "code.gitea.io/gitea/models/webhook"
"code.gitea.io/gitea/modules/git"
- "code.gitea.io/gitea/modules/json"
api "code.gitea.io/gitea/modules/structs"
"code.gitea.io/gitea/modules/util"
webhook_module "code.gitea.io/gitea/modules/webhook"
@@ -22,19 +24,8 @@ type (
DingtalkPayload dingtalk.Payload
)
-var _ PayloadConvertor = &DingtalkPayload{}
-
-// JSONPayload Marshals the DingtalkPayload to json
-func (d *DingtalkPayload) JSONPayload() ([]byte, error) {
- data, err := json.MarshalIndent(d, "", " ")
- if err != nil {
- return []byte{}, err
- }
- return data, nil
-}
-
// Create implements PayloadConvertor Create method
-func (d *DingtalkPayload) Create(p *api.CreatePayload) (api.Payloader, error) {
+func (dc dingtalkConvertor) Create(p *api.CreatePayload) (DingtalkPayload, error) {
// created tag/branch
refName := git.RefName(p.Ref).ShortName()
title := fmt.Sprintf("[%s] %s %s created", p.Repo.FullName, p.RefType, refName)
@@ -43,7 +34,7 @@ func (d *DingtalkPayload) Create(p *api.CreatePayload) (api.Payloader, error) {
}
// Delete implements PayloadConvertor Delete method
-func (d *DingtalkPayload) Delete(p *api.DeletePayload) (api.Payloader, error) {
+func (dc dingtalkConvertor) Delete(p *api.DeletePayload) (DingtalkPayload, error) {
// created tag/branch
refName := git.RefName(p.Ref).ShortName()
title := fmt.Sprintf("[%s] %s %s deleted", p.Repo.FullName, p.RefType, refName)
@@ -52,14 +43,14 @@ func (d *DingtalkPayload) Delete(p *api.DeletePayload) (api.Payloader, error) {
}
// Fork implements PayloadConvertor Fork method
-func (d *DingtalkPayload) Fork(p *api.ForkPayload) (api.Payloader, error) {
+func (dc dingtalkConvertor) Fork(p *api.ForkPayload) (DingtalkPayload, error) {
title := fmt.Sprintf("%s is forked to %s", p.Forkee.FullName, p.Repo.FullName)
return createDingtalkPayload(title, title, fmt.Sprintf("view forked repo %s", p.Repo.FullName), p.Repo.HTMLURL), nil
}
// Push implements PayloadConvertor Push method
-func (d *DingtalkPayload) Push(p *api.PushPayload) (api.Payloader, error) {
+func (dc dingtalkConvertor) Push(p *api.PushPayload) (DingtalkPayload, error) {
var (
branchName = git.RefName(p.Ref).ShortName()
commitDesc string
@@ -100,14 +91,14 @@ func (d *DingtalkPayload) Push(p *api.PushPayload) (api.Payloader, error) {
}
// Issue implements PayloadConvertor Issue method
-func (d *DingtalkPayload) Issue(p *api.IssuePayload) (api.Payloader, error) {
+func (dc dingtalkConvertor) Issue(p *api.IssuePayload) (DingtalkPayload, error) {
text, issueTitle, attachmentText, _ := getIssuesPayloadInfo(p, noneLinkFormatter, true)
return createDingtalkPayload(issueTitle, text+"\r\n\r\n"+attachmentText, "view issue", p.Issue.HTMLURL), nil
}
// Wiki implements PayloadConvertor Wiki method
-func (d *DingtalkPayload) Wiki(p *api.WikiPayload) (api.Payloader, error) {
+func (dc dingtalkConvertor) Wiki(p *api.WikiPayload) (DingtalkPayload, error) {
text, _, _ := getWikiPayloadInfo(p, noneLinkFormatter, true)
url := p.Repository.HTMLURL + "/wiki/" + url.PathEscape(p.Page)
@@ -115,27 +106,27 @@ func (d *DingtalkPayload) Wiki(p *api.WikiPayload) (api.Payloader, error) {
}
// IssueComment implements PayloadConvertor IssueComment method
-func (d *DingtalkPayload) IssueComment(p *api.IssueCommentPayload) (api.Payloader, error) {
+func (dc dingtalkConvertor) IssueComment(p *api.IssueCommentPayload) (DingtalkPayload, error) {
text, issueTitle, _ := getIssueCommentPayloadInfo(p, noneLinkFormatter, true)
return createDingtalkPayload(issueTitle, text+"\r\n\r\n"+p.Comment.Body, "view issue comment", p.Comment.HTMLURL), nil
}
// PullRequest implements PayloadConvertor PullRequest method
-func (d *DingtalkPayload) PullRequest(p *api.PullRequestPayload) (api.Payloader, error) {
+func (dc dingtalkConvertor) PullRequest(p *api.PullRequestPayload) (DingtalkPayload, error) {
text, issueTitle, attachmentText, _ := getPullRequestPayloadInfo(p, noneLinkFormatter, true)
return createDingtalkPayload(issueTitle, text+"\r\n\r\n"+attachmentText, "view pull request", p.PullRequest.HTMLURL), nil
}
// Review implements PayloadConvertor Review method
-func (d *DingtalkPayload) Review(p *api.PullRequestPayload, event webhook_module.HookEventType) (api.Payloader, error) {
+func (dc dingtalkConvertor) Review(p *api.PullRequestPayload, event webhook_module.HookEventType) (DingtalkPayload, error) {
var text, title string
switch p.Action {
case api.HookIssueReviewed:
action, err := parseHookPullRequestEventType(event)
if err != nil {
- return nil, err
+ return DingtalkPayload{}, err
}
title = fmt.Sprintf("[%s] Pull request review %s : #%d %s", p.Repository.FullName, action, p.Index, p.PullRequest.Title)
@@ -146,14 +137,14 @@ func (d *DingtalkPayload) Review(p *api.PullRequestPayload, event webhook_module
}
// Repository implements PayloadConvertor Repository method
-func (d *DingtalkPayload) Repository(p *api.RepositoryPayload) (api.Payloader, error) {
+func (dc dingtalkConvertor) Repository(p *api.RepositoryPayload) (DingtalkPayload, error) {
switch p.Action {
case api.HookRepoCreated:
title := fmt.Sprintf("[%s] Repository created", p.Repository.FullName)
return createDingtalkPayload(title, title, "view repository", p.Repository.HTMLURL), nil
case api.HookRepoDeleted:
title := fmt.Sprintf("[%s] Repository deleted", p.Repository.FullName)
- return &DingtalkPayload{
+ return DingtalkPayload{
MsgType: "text",
Text: struct {
Content string `json:"content"`
@@ -163,24 +154,24 @@ func (d *DingtalkPayload) Repository(p *api.RepositoryPayload) (api.Payloader, e
}, nil
}
- return nil, nil
+ return DingtalkPayload{}, nil
}
// Release implements PayloadConvertor Release method
-func (d *DingtalkPayload) Release(p *api.ReleasePayload) (api.Payloader, error) {
+func (dc dingtalkConvertor) Release(p *api.ReleasePayload) (DingtalkPayload, error) {
text, _ := getReleasePayloadInfo(p, noneLinkFormatter, true)
return createDingtalkPayload(text, text, "view release", p.Release.HTMLURL), nil
}
-func (d *DingtalkPayload) Package(p *api.PackagePayload) (api.Payloader, error) {
+func (dc dingtalkConvertor) Package(p *api.PackagePayload) (DingtalkPayload, error) {
text, _ := getPackagePayloadInfo(p, noneLinkFormatter, true)
return createDingtalkPayload(text, text, "view package", p.Package.HTMLURL), nil
}
-func createDingtalkPayload(title, text, singleTitle, singleURL string) *DingtalkPayload {
- return &DingtalkPayload{
+func createDingtalkPayload(title, text, singleTitle, singleURL string) DingtalkPayload {
+ return DingtalkPayload{
MsgType: "actionCard",
ActionCard: dingtalk.ActionCard{
Text: strings.TrimSpace(text),
@@ -195,7 +186,10 @@ func createDingtalkPayload(title, text, singleTitle, singleURL string) *Dingtalk
}
}
-// GetDingtalkPayload converts a ding talk webhook into a DingtalkPayload
-func GetDingtalkPayload(p api.Payloader, event webhook_module.HookEventType, _ string) (api.Payloader, error) {
- return convertPayloader(new(DingtalkPayload), p, event)
+type dingtalkConvertor struct{}
+
+var _ payloadConvertor[DingtalkPayload] = dingtalkConvertor{}
+
+func newDingtalkRequest(ctx context.Context, w *webhook_model.Webhook, t *webhook_model.HookTask) (*http.Request, []byte, error) {
+ return newJSONRequest(dingtalkConvertor{}, w, t, true)
}
diff --git a/services/webhook/dingtalk_test.go b/services/webhook/dingtalk_test.go
index a03fa46f14..25f47347d0 100644
--- a/services/webhook/dingtalk_test.go
+++ b/services/webhook/dingtalk_test.go
@@ -4,9 +4,12 @@
package webhook
import (
+ "context"
"net/url"
"testing"
+ webhook_model "code.gitea.io/gitea/models/webhook"
+ "code.gitea.io/gitea/modules/json"
api "code.gitea.io/gitea/modules/structs"
webhook_module "code.gitea.io/gitea/modules/webhook"
@@ -24,248 +27,226 @@ func TestDingTalkPayload(t *testing.T) {
}
return ""
}
+ dc := dingtalkConvertor{}
t.Run("Create", func(t *testing.T) {
p := createTestPayload()
- d := new(DingtalkPayload)
- pl, err := d.Create(p)
+ pl, err := dc.Create(p)
require.NoError(t, err)
- require.NotNil(t, pl)
- require.IsType(t, &DingtalkPayload{}, pl)
- assert.Equal(t, "[test/repo] branch test created", pl.(*DingtalkPayload).ActionCard.Text)
- assert.Equal(t, "[test/repo] branch test created", pl.(*DingtalkPayload).ActionCard.Title)
- assert.Equal(t, "view ref test", pl.(*DingtalkPayload).ActionCard.SingleTitle)
- assert.Equal(t, "http://localhost:3000/test/repo/src/test", parseRealSingleURL(pl.(*DingtalkPayload).ActionCard.SingleURL))
+ assert.Equal(t, "[test/repo] branch test created", pl.ActionCard.Text)
+ assert.Equal(t, "[test/repo] branch test created", pl.ActionCard.Title)
+ assert.Equal(t, "view ref test", pl.ActionCard.SingleTitle)
+ assert.Equal(t, "http://localhost:3000/test/repo/src/test", parseRealSingleURL(pl.ActionCard.SingleURL))
})
t.Run("Delete", func(t *testing.T) {
p := deleteTestPayload()
- d := new(DingtalkPayload)
- pl, err := d.Delete(p)
+ pl, err := dc.Delete(p)
require.NoError(t, err)
- require.NotNil(t, pl)
- require.IsType(t, &DingtalkPayload{}, pl)
- assert.Equal(t, "[test/repo] branch test deleted", pl.(*DingtalkPayload).ActionCard.Text)
- assert.Equal(t, "[test/repo] branch test deleted", pl.(*DingtalkPayload).ActionCard.Title)
- assert.Equal(t, "view ref test", pl.(*DingtalkPayload).ActionCard.SingleTitle)
- assert.Equal(t, "http://localhost:3000/test/repo/src/test", parseRealSingleURL(pl.(*DingtalkPayload).ActionCard.SingleURL))
+ assert.Equal(t, "[test/repo] branch test deleted", pl.ActionCard.Text)
+ assert.Equal(t, "[test/repo] branch test deleted", pl.ActionCard.Title)
+ assert.Equal(t, "view ref test", pl.ActionCard.SingleTitle)
+ assert.Equal(t, "http://localhost:3000/test/repo/src/test", parseRealSingleURL(pl.ActionCard.SingleURL))
})
t.Run("Fork", func(t *testing.T) {
p := forkTestPayload()
- d := new(DingtalkPayload)
- pl, err := d.Fork(p)
+ pl, err := dc.Fork(p)
require.NoError(t, err)
- require.NotNil(t, pl)
- require.IsType(t, &DingtalkPayload{}, pl)
- assert.Equal(t, "test/repo2 is forked to test/repo", pl.(*DingtalkPayload).ActionCard.Text)
- assert.Equal(t, "test/repo2 is forked to test/repo", pl.(*DingtalkPayload).ActionCard.Title)
- assert.Equal(t, "view forked repo test/repo", pl.(*DingtalkPayload).ActionCard.SingleTitle)
- assert.Equal(t, "http://localhost:3000/test/repo", parseRealSingleURL(pl.(*DingtalkPayload).ActionCard.SingleURL))
+ assert.Equal(t, "test/repo2 is forked to test/repo", pl.ActionCard.Text)
+ assert.Equal(t, "test/repo2 is forked to test/repo", pl.ActionCard.Title)
+ assert.Equal(t, "view forked repo test/repo", pl.ActionCard.SingleTitle)
+ assert.Equal(t, "http://localhost:3000/test/repo", parseRealSingleURL(pl.ActionCard.SingleURL))
})
t.Run("Push", func(t *testing.T) {
p := pushTestPayload()
- d := new(DingtalkPayload)
- pl, err := d.Push(p)
+ pl, err := dc.Push(p)
require.NoError(t, err)
- require.NotNil(t, pl)
- require.IsType(t, &DingtalkPayload{}, pl)
- assert.Equal(t, "[2020558](http://localhost:3000/test/repo/commit/2020558fe2e34debb818a514715839cabd25e778) commit message - user1\r\n[2020558](http://localhost:3000/test/repo/commit/2020558fe2e34debb818a514715839cabd25e778) commit message - user1", pl.(*DingtalkPayload).ActionCard.Text)
- assert.Equal(t, "[test/repo:test] 2 new commits", pl.(*DingtalkPayload).ActionCard.Title)
- assert.Equal(t, "view commits", pl.(*DingtalkPayload).ActionCard.SingleTitle)
- assert.Equal(t, "http://localhost:3000/test/repo/src/test", parseRealSingleURL(pl.(*DingtalkPayload).ActionCard.SingleURL))
+ assert.Equal(t, "[2020558](http://localhost:3000/test/repo/commit/2020558fe2e34debb818a514715839cabd25e778) commit message - user1\r\n[2020558](http://localhost:3000/test/repo/commit/2020558fe2e34debb818a514715839cabd25e778) commit message - user1", pl.ActionCard.Text)
+ assert.Equal(t, "[test/repo:test] 2 new commits", pl.ActionCard.Title)
+ assert.Equal(t, "view commits", pl.ActionCard.SingleTitle)
+ assert.Equal(t, "http://localhost:3000/test/repo/src/test", parseRealSingleURL(pl.ActionCard.SingleURL))
})
t.Run("Issue", func(t *testing.T) {
p := issueTestPayload()
- d := new(DingtalkPayload)
p.Action = api.HookIssueOpened
- pl, err := d.Issue(p)
+ pl, err := dc.Issue(p)
require.NoError(t, err)
- require.NotNil(t, pl)
- require.IsType(t, &DingtalkPayload{}, pl)
- assert.Equal(t, "[test/repo] Issue opened: #2 crash by user1\r\n\r\nissue body", pl.(*DingtalkPayload).ActionCard.Text)
- assert.Equal(t, "#2 crash", pl.(*DingtalkPayload).ActionCard.Title)
- assert.Equal(t, "view issue", pl.(*DingtalkPayload).ActionCard.SingleTitle)
- assert.Equal(t, "http://localhost:3000/test/repo/issues/2", parseRealSingleURL(pl.(*DingtalkPayload).ActionCard.SingleURL))
+ assert.Equal(t, "[test/repo] Issue opened: #2 crash by user1\r\n\r\nissue body", pl.ActionCard.Text)
+ assert.Equal(t, "#2 crash", pl.ActionCard.Title)
+ assert.Equal(t, "view issue", pl.ActionCard.SingleTitle)
+ assert.Equal(t, "http://localhost:3000/test/repo/issues/2", parseRealSingleURL(pl.ActionCard.SingleURL))
p.Action = api.HookIssueClosed
- pl, err = d.Issue(p)
+ pl, err = dc.Issue(p)
require.NoError(t, err)
- require.NotNil(t, pl)
- require.IsType(t, &DingtalkPayload{}, pl)
- assert.Equal(t, "[test/repo] Issue closed: #2 crash by user1", pl.(*DingtalkPayload).ActionCard.Text)
- assert.Equal(t, "#2 crash", pl.(*DingtalkPayload).ActionCard.Title)
- assert.Equal(t, "view issue", pl.(*DingtalkPayload).ActionCard.SingleTitle)
- assert.Equal(t, "http://localhost:3000/test/repo/issues/2", parseRealSingleURL(pl.(*DingtalkPayload).ActionCard.SingleURL))
+ assert.Equal(t, "[test/repo] Issue closed: #2 crash by user1", pl.ActionCard.Text)
+ assert.Equal(t, "#2 crash", pl.ActionCard.Title)
+ assert.Equal(t, "view issue", pl.ActionCard.SingleTitle)
+ assert.Equal(t, "http://localhost:3000/test/repo/issues/2", parseRealSingleURL(pl.ActionCard.SingleURL))
})
t.Run("IssueComment", func(t *testing.T) {
p := issueCommentTestPayload()
- d := new(DingtalkPayload)
- pl, err := d.IssueComment(p)
+ pl, err := dc.IssueComment(p)
require.NoError(t, err)
- require.NotNil(t, pl)
- require.IsType(t, &DingtalkPayload{}, pl)
- assert.Equal(t, "[test/repo] New comment on issue #2 crash by user1\r\n\r\nmore info needed", pl.(*DingtalkPayload).ActionCard.Text)
- assert.Equal(t, "#2 crash", pl.(*DingtalkPayload).ActionCard.Title)
- assert.Equal(t, "view issue comment", pl.(*DingtalkPayload).ActionCard.SingleTitle)
- assert.Equal(t, "http://localhost:3000/test/repo/issues/2#issuecomment-4", parseRealSingleURL(pl.(*DingtalkPayload).ActionCard.SingleURL))
+ assert.Equal(t, "[test/repo] New comment on issue #2 crash by user1\r\n\r\nmore info needed", pl.ActionCard.Text)
+ assert.Equal(t, "#2 crash", pl.ActionCard.Title)
+ assert.Equal(t, "view issue comment", pl.ActionCard.SingleTitle)
+ assert.Equal(t, "http://localhost:3000/test/repo/issues/2#issuecomment-4", parseRealSingleURL(pl.ActionCard.SingleURL))
})
t.Run("PullRequest", func(t *testing.T) {
p := pullRequestTestPayload()
- d := new(DingtalkPayload)
- pl, err := d.PullRequest(p)
+ pl, err := dc.PullRequest(p)
require.NoError(t, err)
- require.NotNil(t, pl)
- require.IsType(t, &DingtalkPayload{}, pl)
- assert.Equal(t, "[test/repo] Pull request opened: #12 Fix bug by user1\r\n\r\nfixes bug #2", pl.(*DingtalkPayload).ActionCard.Text)
- assert.Equal(t, "#12 Fix bug", pl.(*DingtalkPayload).ActionCard.Title)
- assert.Equal(t, "view pull request", pl.(*DingtalkPayload).ActionCard.SingleTitle)
- assert.Equal(t, "http://localhost:3000/test/repo/pulls/12", parseRealSingleURL(pl.(*DingtalkPayload).ActionCard.SingleURL))
+ assert.Equal(t, "[test/repo] Pull request opened: #12 Fix bug by user1\r\n\r\nfixes bug #2", pl.ActionCard.Text)
+ assert.Equal(t, "#12 Fix bug", pl.ActionCard.Title)
+ assert.Equal(t, "view pull request", pl.ActionCard.SingleTitle)
+ assert.Equal(t, "http://localhost:3000/test/repo/pulls/12", parseRealSingleURL(pl.ActionCard.SingleURL))
})
t.Run("PullRequestComment", func(t *testing.T) {
p := pullRequestCommentTestPayload()
- d := new(DingtalkPayload)
- pl, err := d.IssueComment(p)
+ pl, err := dc.IssueComment(p)
require.NoError(t, err)
- require.NotNil(t, pl)
- require.IsType(t, &DingtalkPayload{}, pl)
- assert.Equal(t, "[test/repo] New comment on pull request #12 Fix bug by user1\r\n\r\nchanges requested", pl.(*DingtalkPayload).ActionCard.Text)
- assert.Equal(t, "#12 Fix bug", pl.(*DingtalkPayload).ActionCard.Title)
- assert.Equal(t, "view issue comment", pl.(*DingtalkPayload).ActionCard.SingleTitle)
- assert.Equal(t, "http://localhost:3000/test/repo/pulls/12#issuecomment-4", parseRealSingleURL(pl.(*DingtalkPayload).ActionCard.SingleURL))
+ assert.Equal(t, "[test/repo] New comment on pull request #12 Fix bug by user1\r\n\r\nchanges requested", pl.ActionCard.Text)
+ assert.Equal(t, "#12 Fix bug", pl.ActionCard.Title)
+ assert.Equal(t, "view issue comment", pl.ActionCard.SingleTitle)
+ assert.Equal(t, "http://localhost:3000/test/repo/pulls/12#issuecomment-4", parseRealSingleURL(pl.ActionCard.SingleURL))
})
t.Run("Review", func(t *testing.T) {
p := pullRequestTestPayload()
p.Action = api.HookIssueReviewed
- d := new(DingtalkPayload)
- pl, err := d.Review(p, webhook_module.HookEventPullRequestReviewApproved)
+ pl, err := dc.Review(p, webhook_module.HookEventPullRequestReviewApproved)
require.NoError(t, err)
- require.NotNil(t, pl)
- require.IsType(t, &DingtalkPayload{}, pl)
- assert.Equal(t, "[test/repo] Pull request review approved : #12 Fix bug\r\n\r\ngood job", pl.(*DingtalkPayload).ActionCard.Text)
- assert.Equal(t, "[test/repo] Pull request review approved : #12 Fix bug", pl.(*DingtalkPayload).ActionCard.Title)
- assert.Equal(t, "view pull request", pl.(*DingtalkPayload).ActionCard.SingleTitle)
- assert.Equal(t, "http://localhost:3000/test/repo/pulls/12", parseRealSingleURL(pl.(*DingtalkPayload).ActionCard.SingleURL))
+ assert.Equal(t, "[test/repo] Pull request review approved : #12 Fix bug\r\n\r\ngood job", pl.ActionCard.Text)
+ assert.Equal(t, "[test/repo] Pull request review approved : #12 Fix bug", pl.ActionCard.Title)
+ assert.Equal(t, "view pull request", pl.ActionCard.SingleTitle)
+ assert.Equal(t, "http://localhost:3000/test/repo/pulls/12", parseRealSingleURL(pl.ActionCard.SingleURL))
})
t.Run("Repository", func(t *testing.T) {
p := repositoryTestPayload()
- d := new(DingtalkPayload)
- pl, err := d.Repository(p)
+ pl, err := dc.Repository(p)
require.NoError(t, err)
- require.NotNil(t, pl)
- require.IsType(t, &DingtalkPayload{}, pl)
- assert.Equal(t, "[test/repo] Repository created", pl.(*DingtalkPayload).ActionCard.Text)
- assert.Equal(t, "[test/repo] Repository created", pl.(*DingtalkPayload).ActionCard.Title)
- assert.Equal(t, "view repository", pl.(*DingtalkPayload).ActionCard.SingleTitle)
- assert.Equal(t, "http://localhost:3000/test/repo", parseRealSingleURL(pl.(*DingtalkPayload).ActionCard.SingleURL))
+ assert.Equal(t, "[test/repo] Repository created", pl.ActionCard.Text)
+ assert.Equal(t, "[test/repo] Repository created", pl.ActionCard.Title)
+ assert.Equal(t, "view repository", pl.ActionCard.SingleTitle)
+ assert.Equal(t, "http://localhost:3000/test/repo", parseRealSingleURL(pl.ActionCard.SingleURL))
})
t.Run("Package", func(t *testing.T) {
p := packageTestPayload()
- d := new(DingtalkPayload)
- pl, err := d.Package(p)
+ pl, err := dc.Package(p)
require.NoError(t, err)
- require.NotNil(t, pl)
- require.IsType(t, &DingtalkPayload{}, pl)
- assert.Equal(t, "Package created: GiteaContainer:latest by user1", pl.(*DingtalkPayload).ActionCard.Text)
- assert.Equal(t, "Package created: GiteaContainer:latest by user1", pl.(*DingtalkPayload).ActionCard.Title)
- assert.Equal(t, "view package", pl.(*DingtalkPayload).ActionCard.SingleTitle)
- assert.Equal(t, "http://localhost:3000/user1/-/packages/container/GiteaContainer/latest", parseRealSingleURL(pl.(*DingtalkPayload).ActionCard.SingleURL))
+ assert.Equal(t, "Package created: GiteaContainer:latest by user1", pl.ActionCard.Text)
+ assert.Equal(t, "Package created: GiteaContainer:latest by user1", pl.ActionCard.Title)
+ assert.Equal(t, "view package", pl.ActionCard.SingleTitle)
+ assert.Equal(t, "http://localhost:3000/user1/-/packages/container/GiteaContainer/latest", parseRealSingleURL(pl.ActionCard.SingleURL))
})
t.Run("Wiki", func(t *testing.T) {
p := wikiTestPayload()
- d := new(DingtalkPayload)
p.Action = api.HookWikiCreated
- pl, err := d.Wiki(p)
+ pl, err := dc.Wiki(p)
require.NoError(t, err)
- require.NotNil(t, pl)
- require.IsType(t, &DingtalkPayload{}, pl)
- assert.Equal(t, "[test/repo] New wiki page 'index' (Wiki change comment) by user1", pl.(*DingtalkPayload).ActionCard.Text)
- assert.Equal(t, "[test/repo] New wiki page 'index' (Wiki change comment) by user1", pl.(*DingtalkPayload).ActionCard.Title)
- assert.Equal(t, "view wiki", pl.(*DingtalkPayload).ActionCard.SingleTitle)
- assert.Equal(t, "http://localhost:3000/test/repo/wiki/index", parseRealSingleURL(pl.(*DingtalkPayload).ActionCard.SingleURL))
+ assert.Equal(t, "[test/repo] New wiki page 'index' (Wiki change comment) by user1", pl.ActionCard.Text)
+ assert.Equal(t, "[test/repo] New wiki page 'index' (Wiki change comment) by user1", pl.ActionCard.Title)
+ assert.Equal(t, "view wiki", pl.ActionCard.SingleTitle)
+ assert.Equal(t, "http://localhost:3000/test/repo/wiki/index", parseRealSingleURL(pl.ActionCard.SingleURL))
p.Action = api.HookWikiEdited
- pl, err = d.Wiki(p)
+ pl, err = dc.Wiki(p)
require.NoError(t, err)
- require.NotNil(t, pl)
- require.IsType(t, &DingtalkPayload{}, pl)
- assert.Equal(t, "[test/repo] Wiki page 'index' edited (Wiki change comment) by user1", pl.(*DingtalkPayload).ActionCard.Text)
- assert.Equal(t, "[test/repo] Wiki page 'index' edited (Wiki change comment) by user1", pl.(*DingtalkPayload).ActionCard.Title)
- assert.Equal(t, "view wiki", pl.(*DingtalkPayload).ActionCard.SingleTitle)
- assert.Equal(t, "http://localhost:3000/test/repo/wiki/index", parseRealSingleURL(pl.(*DingtalkPayload).ActionCard.SingleURL))
+ assert.Equal(t, "[test/repo] Wiki page 'index' edited (Wiki change comment) by user1", pl.ActionCard.Text)
+ assert.Equal(t, "[test/repo] Wiki page 'index' edited (Wiki change comment) by user1", pl.ActionCard.Title)
+ assert.Equal(t, "view wiki", pl.ActionCard.SingleTitle)
+ assert.Equal(t, "http://localhost:3000/test/repo/wiki/index", parseRealSingleURL(pl.ActionCard.SingleURL))
p.Action = api.HookWikiDeleted
- pl, err = d.Wiki(p)
+ pl, err = dc.Wiki(p)
require.NoError(t, err)
- require.NotNil(t, pl)
- require.IsType(t, &DingtalkPayload{}, pl)
- assert.Equal(t, "[test/repo] Wiki page 'index' deleted by user1", pl.(*DingtalkPayload).ActionCard.Text)
- assert.Equal(t, "[test/repo] Wiki page 'index' deleted by user1", pl.(*DingtalkPayload).ActionCard.Title)
- assert.Equal(t, "view wiki", pl.(*DingtalkPayload).ActionCard.SingleTitle)
- assert.Equal(t, "http://localhost:3000/test/repo/wiki/index", parseRealSingleURL(pl.(*DingtalkPayload).ActionCard.SingleURL))
+ assert.Equal(t, "[test/repo] Wiki page 'index' deleted by user1", pl.ActionCard.Text)
+ assert.Equal(t, "[test/repo] Wiki page 'index' deleted by user1", pl.ActionCard.Title)
+ assert.Equal(t, "view wiki", pl.ActionCard.SingleTitle)
+ assert.Equal(t, "http://localhost:3000/test/repo/wiki/index", parseRealSingleURL(pl.ActionCard.SingleURL))
})
t.Run("Release", func(t *testing.T) {
p := pullReleaseTestPayload()
- d := new(DingtalkPayload)
- pl, err := d.Release(p)
+ pl, err := dc.Release(p)
require.NoError(t, err)
- require.NotNil(t, pl)
- require.IsType(t, &DingtalkPayload{}, pl)
- assert.Equal(t, "[test/repo] Release created: v1.0 by user1", pl.(*DingtalkPayload).ActionCard.Text)
- assert.Equal(t, "[test/repo] Release created: v1.0 by user1", pl.(*DingtalkPayload).ActionCard.Title)
- assert.Equal(t, "view release", pl.(*DingtalkPayload).ActionCard.SingleTitle)
- assert.Equal(t, "http://localhost:3000/test/repo/releases/tag/v1.0", parseRealSingleURL(pl.(*DingtalkPayload).ActionCard.SingleURL))
+ assert.Equal(t, "[test/repo] Release created: v1.0 by user1", pl.ActionCard.Text)
+ assert.Equal(t, "[test/repo] Release created: v1.0 by user1", pl.ActionCard.Title)
+ assert.Equal(t, "view release", pl.ActionCard.SingleTitle)
+ assert.Equal(t, "http://localhost:3000/test/repo/releases/tag/v1.0", parseRealSingleURL(pl.ActionCard.SingleURL))
})
}
func TestDingTalkJSONPayload(t *testing.T) {
p := pushTestPayload()
-
- pl, err := new(DingtalkPayload).Push(p)
+ data, err := p.JSONPayload()
require.NoError(t, err)
- require.NotNil(t, pl)
- require.IsType(t, &DingtalkPayload{}, pl)
- json, err := pl.JSONPayload()
+ hook := &webhook_model.Webhook{
+ RepoID: 3,
+ IsActive: true,
+ Type: webhook_module.DINGTALK,
+ URL: "https://dingtalk.example.com/",
+ Meta: ``,
+ HTTPMethod: "POST",
+ }
+ task := &webhook_model.HookTask{
+ HookID: hook.ID,
+ EventType: webhook_module.HookEventPush,
+ PayloadContent: string(data),
+ PayloadVersion: 2,
+ }
+
+ req, reqBody, err := newDingtalkRequest(context.Background(), hook, task)
+ require.NotNil(t, req)
+ require.NotNil(t, reqBody)
require.NoError(t, err)
- assert.NotEmpty(t, json)
+
+ assert.Equal(t, "POST", req.Method)
+ assert.Equal(t, "https://dingtalk.example.com/", req.URL.String())
+ assert.Equal(t, "sha256=", req.Header.Get("X-Hub-Signature-256"))
+ assert.Equal(t, "application/json", req.Header.Get("Content-Type"))
+ var body DingtalkPayload
+ err = json.NewDecoder(req.Body).Decode(&body)
+ assert.NoError(t, err)
+ assert.Equal(t, "[2020558](http://localhost:3000/test/repo/commit/2020558fe2e34debb818a514715839cabd25e778) commit message - user1\r\n[2020558](http://localhost:3000/test/repo/commit/2020558fe2e34debb818a514715839cabd25e778) commit message - user1", body.ActionCard.Text)
}
diff --git a/services/webhook/discord.go b/services/webhook/discord.go
index e2ac1410b8..659754d5e0 100644
--- a/services/webhook/discord.go
+++ b/services/webhook/discord.go
@@ -4,8 +4,10 @@
package webhook
import (
+ "context"
"errors"
"fmt"
+ "net/http"
"net/url"
"strconv"
"strings"
@@ -98,19 +100,8 @@ var (
redColor = color("ff3232")
)
-// JSONPayload Marshals the DiscordPayload to json
-func (d *DiscordPayload) JSONPayload() ([]byte, error) {
- data, err := json.MarshalIndent(d, "", " ")
- if err != nil {
- return []byte{}, err
- }
- return data, nil
-}
-
-var _ PayloadConvertor = &DiscordPayload{}
-
// Create implements PayloadConvertor Create method
-func (d *DiscordPayload) Create(p *api.CreatePayload) (api.Payloader, error) {
+func (d discordConvertor) Create(p *api.CreatePayload) (DiscordPayload, error) {
// created tag/branch
refName := git.RefName(p.Ref).ShortName()
title := fmt.Sprintf("[%s] %s %s created", p.Repo.FullName, p.RefType, refName)
@@ -119,7 +110,7 @@ func (d *DiscordPayload) Create(p *api.CreatePayload) (api.Payloader, error) {
}
// Delete implements PayloadConvertor Delete method
-func (d *DiscordPayload) Delete(p *api.DeletePayload) (api.Payloader, error) {
+func (d discordConvertor) Delete(p *api.DeletePayload) (DiscordPayload, error) {
// deleted tag/branch
refName := git.RefName(p.Ref).ShortName()
title := fmt.Sprintf("[%s] %s %s deleted", p.Repo.FullName, p.RefType, refName)
@@ -128,14 +119,14 @@ func (d *DiscordPayload) Delete(p *api.DeletePayload) (api.Payloader, error) {
}
// Fork implements PayloadConvertor Fork method
-func (d *DiscordPayload) Fork(p *api.ForkPayload) (api.Payloader, error) {
+func (d discordConvertor) Fork(p *api.ForkPayload) (DiscordPayload, error) {
title := fmt.Sprintf("%s is forked to %s", p.Forkee.FullName, p.Repo.FullName)
return d.createPayload(p.Sender, title, "", p.Repo.HTMLURL, greenColor), nil
}
// Push implements PayloadConvertor Push method
-func (d *DiscordPayload) Push(p *api.PushPayload) (api.Payloader, error) {
+func (d discordConvertor) Push(p *api.PushPayload) (DiscordPayload, error) {
var (
branchName = git.RefName(p.Ref).ShortName()
commitDesc string
@@ -170,35 +161,35 @@ func (d *DiscordPayload) Push(p *api.PushPayload) (api.Payloader, error) {
}
// Issue implements PayloadConvertor Issue method
-func (d *DiscordPayload) Issue(p *api.IssuePayload) (api.Payloader, error) {
+func (d discordConvertor) Issue(p *api.IssuePayload) (DiscordPayload, error) {
title, _, text, color := getIssuesPayloadInfo(p, noneLinkFormatter, false)
return d.createPayload(p.Sender, title, text, p.Issue.HTMLURL, color), nil
}
// IssueComment implements PayloadConvertor IssueComment method
-func (d *DiscordPayload) IssueComment(p *api.IssueCommentPayload) (api.Payloader, error) {
+func (d discordConvertor) IssueComment(p *api.IssueCommentPayload) (DiscordPayload, error) {
title, _, color := getIssueCommentPayloadInfo(p, noneLinkFormatter, false)
return d.createPayload(p.Sender, title, p.Comment.Body, p.Comment.HTMLURL, color), nil
}
// PullRequest implements PayloadConvertor PullRequest method
-func (d *DiscordPayload) PullRequest(p *api.PullRequestPayload) (api.Payloader, error) {
+func (d discordConvertor) PullRequest(p *api.PullRequestPayload) (DiscordPayload, error) {
title, _, text, color := getPullRequestPayloadInfo(p, noneLinkFormatter, false)
return d.createPayload(p.Sender, title, text, p.PullRequest.HTMLURL, color), nil
}
// Review implements PayloadConvertor Review method
-func (d *DiscordPayload) Review(p *api.PullRequestPayload, event webhook_module.HookEventType) (api.Payloader, error) {
+func (d discordConvertor) Review(p *api.PullRequestPayload, event webhook_module.HookEventType) (DiscordPayload, error) {
var text, title string
var color int
switch p.Action {
case api.HookIssueReviewed:
action, err := parseHookPullRequestEventType(event)
if err != nil {
- return nil, err
+ return DiscordPayload{}, err
}
title = fmt.Sprintf("[%s] Pull request review %s: #%d %s", p.Repository.FullName, action, p.Index, p.PullRequest.Title)
@@ -220,7 +211,7 @@ func (d *DiscordPayload) Review(p *api.PullRequestPayload, event webhook_module.
}
// Repository implements PayloadConvertor Repository method
-func (d *DiscordPayload) Repository(p *api.RepositoryPayload) (api.Payloader, error) {
+func (d discordConvertor) Repository(p *api.RepositoryPayload) (DiscordPayload, error) {
var title, url string
var color int
switch p.Action {
@@ -237,7 +228,7 @@ func (d *DiscordPayload) Repository(p *api.RepositoryPayload) (api.Payloader, er
}
// Wiki implements PayloadConvertor Wiki method
-func (d *DiscordPayload) Wiki(p *api.WikiPayload) (api.Payloader, error) {
+func (d discordConvertor) Wiki(p *api.WikiPayload) (DiscordPayload, error) {
text, color, _ := getWikiPayloadInfo(p, noneLinkFormatter, false)
htmlLink := p.Repository.HTMLURL + "/wiki/" + url.PathEscape(p.Page)
@@ -250,30 +241,35 @@ func (d *DiscordPayload) Wiki(p *api.WikiPayload) (api.Payloader, error) {
}
// Release implements PayloadConvertor Release method
-func (d *DiscordPayload) Release(p *api.ReleasePayload) (api.Payloader, error) {
+func (d discordConvertor) Release(p *api.ReleasePayload) (DiscordPayload, error) {
text, color := getReleasePayloadInfo(p, noneLinkFormatter, false)
return d.createPayload(p.Sender, text, p.Release.Note, p.Release.HTMLURL, color), nil
}
-func (d *DiscordPayload) Package(p *api.PackagePayload) (api.Payloader, error) {
+func (d discordConvertor) Package(p *api.PackagePayload) (DiscordPayload, error) {
text, color := getPackagePayloadInfo(p, noneLinkFormatter, false)
return d.createPayload(p.Sender, text, "", p.Package.HTMLURL, color), nil
}
-// GetDiscordPayload converts a discord webhook into a DiscordPayload
-func GetDiscordPayload(p api.Payloader, event webhook_module.HookEventType, meta string) (api.Payloader, error) {
- s := new(DiscordPayload)
+type discordConvertor struct {
+ Username string
+ AvatarURL string
+}
- discord := &DiscordMeta{}
- if err := json.Unmarshal([]byte(meta), &discord); err != nil {
- return s, errors.New("GetDiscordPayload meta json:" + err.Error())
+var _ payloadConvertor[DiscordPayload] = discordConvertor{}
+
+func newDiscordRequest(ctx context.Context, w *webhook_model.Webhook, t *webhook_model.HookTask) (*http.Request, []byte, error) {
+ meta := &DiscordMeta{}
+ if err := json.Unmarshal([]byte(w.Meta), meta); err != nil {
+ return nil, nil, fmt.Errorf("newDiscordRequest meta json: %w", err)
}
- s.Username = discord.Username
- s.AvatarURL = discord.IconURL
-
- return convertPayloader(s, p, event)
+ sc := discordConvertor{
+ Username: meta.Username,
+ AvatarURL: meta.IconURL,
+ }
+ return newJSONRequest(sc, w, t, true)
}
func parseHookPullRequestEventType(event webhook_module.HookEventType) (string, error) {
@@ -291,8 +287,8 @@ func parseHookPullRequestEventType(event webhook_module.HookEventType) (string,
}
}
-func (d *DiscordPayload) createPayload(s *api.User, title, text, url string, color int) *DiscordPayload {
- return &DiscordPayload{
+func (d discordConvertor) createPayload(s *api.User, title, text, url string, color int) DiscordPayload {
+ return DiscordPayload{
Username: d.Username,
AvatarURL: d.AvatarURL,
Embeds: []DiscordEmbed{
diff --git a/services/webhook/discord_test.go b/services/webhook/discord_test.go
index b567cbc395..c04b95383b 100644
--- a/services/webhook/discord_test.go
+++ b/services/webhook/discord_test.go
@@ -4,8 +4,11 @@
package webhook
import (
+ "context"
"testing"
+ webhook_model "code.gitea.io/gitea/models/webhook"
+ "code.gitea.io/gitea/modules/json"
"code.gitea.io/gitea/modules/setting"
api "code.gitea.io/gitea/modules/structs"
webhook_module "code.gitea.io/gitea/modules/webhook"
@@ -15,295 +18,274 @@ import (
)
func TestDiscordPayload(t *testing.T) {
+ dc := discordConvertor{}
+
t.Run("Create", func(t *testing.T) {
p := createTestPayload()
- d := new(DiscordPayload)
- pl, err := d.Create(p)
+ pl, err := dc.Create(p)
require.NoError(t, err)
- require.NotNil(t, pl)
- require.IsType(t, &DiscordPayload{}, pl)
- assert.Len(t, pl.(*DiscordPayload).Embeds, 1)
- assert.Equal(t, "[test/repo] branch test created", pl.(*DiscordPayload).Embeds[0].Title)
- assert.Empty(t, pl.(*DiscordPayload).Embeds[0].Description)
- assert.Equal(t, "http://localhost:3000/test/repo/src/test", pl.(*DiscordPayload).Embeds[0].URL)
- assert.Equal(t, p.Sender.UserName, pl.(*DiscordPayload).Embeds[0].Author.Name)
- assert.Equal(t, setting.AppURL+p.Sender.UserName, pl.(*DiscordPayload).Embeds[0].Author.URL)
- assert.Equal(t, p.Sender.AvatarURL, pl.(*DiscordPayload).Embeds[0].Author.IconURL)
+ assert.Len(t, pl.Embeds, 1)
+ assert.Equal(t, "[test/repo] branch test created", pl.Embeds[0].Title)
+ assert.Empty(t, pl.Embeds[0].Description)
+ assert.Equal(t, "http://localhost:3000/test/repo/src/test", pl.Embeds[0].URL)
+ assert.Equal(t, p.Sender.UserName, pl.Embeds[0].Author.Name)
+ assert.Equal(t, setting.AppURL+p.Sender.UserName, pl.Embeds[0].Author.URL)
+ assert.Equal(t, p.Sender.AvatarURL, pl.Embeds[0].Author.IconURL)
})
t.Run("Delete", func(t *testing.T) {
p := deleteTestPayload()
- d := new(DiscordPayload)
- pl, err := d.Delete(p)
+ pl, err := dc.Delete(p)
require.NoError(t, err)
- require.NotNil(t, pl)
- require.IsType(t, &DiscordPayload{}, pl)
- assert.Len(t, pl.(*DiscordPayload).Embeds, 1)
- assert.Equal(t, "[test/repo] branch test deleted", pl.(*DiscordPayload).Embeds[0].Title)
- assert.Empty(t, pl.(*DiscordPayload).Embeds[0].Description)
- assert.Equal(t, "http://localhost:3000/test/repo/src/test", pl.(*DiscordPayload).Embeds[0].URL)
- assert.Equal(t, p.Sender.UserName, pl.(*DiscordPayload).Embeds[0].Author.Name)
- assert.Equal(t, setting.AppURL+p.Sender.UserName, pl.(*DiscordPayload).Embeds[0].Author.URL)
- assert.Equal(t, p.Sender.AvatarURL, pl.(*DiscordPayload).Embeds[0].Author.IconURL)
+ assert.Len(t, pl.Embeds, 1)
+ assert.Equal(t, "[test/repo] branch test deleted", pl.Embeds[0].Title)
+ assert.Empty(t, pl.Embeds[0].Description)
+ assert.Equal(t, "http://localhost:3000/test/repo/src/test", pl.Embeds[0].URL)
+ assert.Equal(t, p.Sender.UserName, pl.Embeds[0].Author.Name)
+ assert.Equal(t, setting.AppURL+p.Sender.UserName, pl.Embeds[0].Author.URL)
+ assert.Equal(t, p.Sender.AvatarURL, pl.Embeds[0].Author.IconURL)
})
t.Run("Fork", func(t *testing.T) {
p := forkTestPayload()
- d := new(DiscordPayload)
- pl, err := d.Fork(p)
+ pl, err := dc.Fork(p)
require.NoError(t, err)
- require.NotNil(t, pl)
- require.IsType(t, &DiscordPayload{}, pl)
- assert.Len(t, pl.(*DiscordPayload).Embeds, 1)
- assert.Equal(t, "test/repo2 is forked to test/repo", pl.(*DiscordPayload).Embeds[0].Title)
- assert.Empty(t, pl.(*DiscordPayload).Embeds[0].Description)
- assert.Equal(t, "http://localhost:3000/test/repo", pl.(*DiscordPayload).Embeds[0].URL)
- assert.Equal(t, p.Sender.UserName, pl.(*DiscordPayload).Embeds[0].Author.Name)
- assert.Equal(t, setting.AppURL+p.Sender.UserName, pl.(*DiscordPayload).Embeds[0].Author.URL)
- assert.Equal(t, p.Sender.AvatarURL, pl.(*DiscordPayload).Embeds[0].Author.IconURL)
+ assert.Len(t, pl.Embeds, 1)
+ assert.Equal(t, "test/repo2 is forked to test/repo", pl.Embeds[0].Title)
+ assert.Empty(t, pl.Embeds[0].Description)
+ assert.Equal(t, "http://localhost:3000/test/repo", pl.Embeds[0].URL)
+ assert.Equal(t, p.Sender.UserName, pl.Embeds[0].Author.Name)
+ assert.Equal(t, setting.AppURL+p.Sender.UserName, pl.Embeds[0].Author.URL)
+ assert.Equal(t, p.Sender.AvatarURL, pl.Embeds[0].Author.IconURL)
})
t.Run("Push", func(t *testing.T) {
p := pushTestPayload()
- d := new(DiscordPayload)
- pl, err := d.Push(p)
+ pl, err := dc.Push(p)
require.NoError(t, err)
- require.NotNil(t, pl)
- require.IsType(t, &DiscordPayload{}, pl)
- assert.Len(t, pl.(*DiscordPayload).Embeds, 1)
- assert.Equal(t, "[test/repo:test] 2 new commits", pl.(*DiscordPayload).Embeds[0].Title)
- assert.Equal(t, "[2020558](http://localhost:3000/test/repo/commit/2020558fe2e34debb818a514715839cabd25e778) commit message - user1\n[2020558](http://localhost:3000/test/repo/commit/2020558fe2e34debb818a514715839cabd25e778) commit message - user1", pl.(*DiscordPayload).Embeds[0].Description)
- assert.Equal(t, "http://localhost:3000/test/repo/src/test", pl.(*DiscordPayload).Embeds[0].URL)
- assert.Equal(t, p.Sender.UserName, pl.(*DiscordPayload).Embeds[0].Author.Name)
- assert.Equal(t, setting.AppURL+p.Sender.UserName, pl.(*DiscordPayload).Embeds[0].Author.URL)
- assert.Equal(t, p.Sender.AvatarURL, pl.(*DiscordPayload).Embeds[0].Author.IconURL)
+ assert.Len(t, pl.Embeds, 1)
+ assert.Equal(t, "[test/repo:test] 2 new commits", pl.Embeds[0].Title)
+ assert.Equal(t, "[2020558](http://localhost:3000/test/repo/commit/2020558fe2e34debb818a514715839cabd25e778) commit message - user1\n[2020558](http://localhost:3000/test/repo/commit/2020558fe2e34debb818a514715839cabd25e778) commit message - user1", pl.Embeds[0].Description)
+ assert.Equal(t, "http://localhost:3000/test/repo/src/test", pl.Embeds[0].URL)
+ assert.Equal(t, p.Sender.UserName, pl.Embeds[0].Author.Name)
+ assert.Equal(t, setting.AppURL+p.Sender.UserName, pl.Embeds[0].Author.URL)
+ assert.Equal(t, p.Sender.AvatarURL, pl.Embeds[0].Author.IconURL)
})
t.Run("Issue", func(t *testing.T) {
p := issueTestPayload()
- d := new(DiscordPayload)
p.Action = api.HookIssueOpened
- pl, err := d.Issue(p)
+ pl, err := dc.Issue(p)
require.NoError(t, err)
- require.NotNil(t, pl)
- require.IsType(t, &DiscordPayload{}, pl)
- assert.Len(t, pl.(*DiscordPayload).Embeds, 1)
- assert.Equal(t, "[test/repo] Issue opened: #2 crash", pl.(*DiscordPayload).Embeds[0].Title)
- assert.Equal(t, "issue body", pl.(*DiscordPayload).Embeds[0].Description)
- assert.Equal(t, "http://localhost:3000/test/repo/issues/2", pl.(*DiscordPayload).Embeds[0].URL)
- assert.Equal(t, p.Sender.UserName, pl.(*DiscordPayload).Embeds[0].Author.Name)
- assert.Equal(t, setting.AppURL+p.Sender.UserName, pl.(*DiscordPayload).Embeds[0].Author.URL)
- assert.Equal(t, p.Sender.AvatarURL, pl.(*DiscordPayload).Embeds[0].Author.IconURL)
+ assert.Len(t, pl.Embeds, 1)
+ assert.Equal(t, "[test/repo] Issue opened: #2 crash", pl.Embeds[0].Title)
+ assert.Equal(t, "issue body", pl.Embeds[0].Description)
+ assert.Equal(t, "http://localhost:3000/test/repo/issues/2", pl.Embeds[0].URL)
+ assert.Equal(t, p.Sender.UserName, pl.Embeds[0].Author.Name)
+ assert.Equal(t, setting.AppURL+p.Sender.UserName, pl.Embeds[0].Author.URL)
+ assert.Equal(t, p.Sender.AvatarURL, pl.Embeds[0].Author.IconURL)
p.Action = api.HookIssueClosed
- pl, err = d.Issue(p)
+ pl, err = dc.Issue(p)
require.NoError(t, err)
- require.NotNil(t, pl)
- require.IsType(t, &DiscordPayload{}, pl)
- assert.Len(t, pl.(*DiscordPayload).Embeds, 1)
- assert.Equal(t, "[test/repo] Issue closed: #2 crash", pl.(*DiscordPayload).Embeds[0].Title)
- assert.Empty(t, pl.(*DiscordPayload).Embeds[0].Description)
- assert.Equal(t, "http://localhost:3000/test/repo/issues/2", pl.(*DiscordPayload).Embeds[0].URL)
- assert.Equal(t, p.Sender.UserName, pl.(*DiscordPayload).Embeds[0].Author.Name)
- assert.Equal(t, setting.AppURL+p.Sender.UserName, pl.(*DiscordPayload).Embeds[0].Author.URL)
- assert.Equal(t, p.Sender.AvatarURL, pl.(*DiscordPayload).Embeds[0].Author.IconURL)
+ assert.Len(t, pl.Embeds, 1)
+ assert.Equal(t, "[test/repo] Issue closed: #2 crash", pl.Embeds[0].Title)
+ assert.Empty(t, pl.Embeds[0].Description)
+ assert.Equal(t, "http://localhost:3000/test/repo/issues/2", pl.Embeds[0].URL)
+ assert.Equal(t, p.Sender.UserName, pl.Embeds[0].Author.Name)
+ assert.Equal(t, setting.AppURL+p.Sender.UserName, pl.Embeds[0].Author.URL)
+ assert.Equal(t, p.Sender.AvatarURL, pl.Embeds[0].Author.IconURL)
})
t.Run("IssueComment", func(t *testing.T) {
p := issueCommentTestPayload()
- d := new(DiscordPayload)
- pl, err := d.IssueComment(p)
+ pl, err := dc.IssueComment(p)
require.NoError(t, err)
- require.NotNil(t, pl)
- require.IsType(t, &DiscordPayload{}, pl)
- assert.Len(t, pl.(*DiscordPayload).Embeds, 1)
- assert.Equal(t, "[test/repo] New comment on issue #2 crash", pl.(*DiscordPayload).Embeds[0].Title)
- assert.Equal(t, "more info needed", pl.(*DiscordPayload).Embeds[0].Description)
- assert.Equal(t, "http://localhost:3000/test/repo/issues/2#issuecomment-4", pl.(*DiscordPayload).Embeds[0].URL)
- assert.Equal(t, p.Sender.UserName, pl.(*DiscordPayload).Embeds[0].Author.Name)
- assert.Equal(t, setting.AppURL+p.Sender.UserName, pl.(*DiscordPayload).Embeds[0].Author.URL)
- assert.Equal(t, p.Sender.AvatarURL, pl.(*DiscordPayload).Embeds[0].Author.IconURL)
+ assert.Len(t, pl.Embeds, 1)
+ assert.Equal(t, "[test/repo] New comment on issue #2 crash", pl.Embeds[0].Title)
+ assert.Equal(t, "more info needed", pl.Embeds[0].Description)
+ assert.Equal(t, "http://localhost:3000/test/repo/issues/2#issuecomment-4", pl.Embeds[0].URL)
+ assert.Equal(t, p.Sender.UserName, pl.Embeds[0].Author.Name)
+ assert.Equal(t, setting.AppURL+p.Sender.UserName, pl.Embeds[0].Author.URL)
+ assert.Equal(t, p.Sender.AvatarURL, pl.Embeds[0].Author.IconURL)
})
t.Run("PullRequest", func(t *testing.T) {
p := pullRequestTestPayload()
- d := new(DiscordPayload)
- pl, err := d.PullRequest(p)
+ pl, err := dc.PullRequest(p)
require.NoError(t, err)
- require.NotNil(t, pl)
- require.IsType(t, &DiscordPayload{}, pl)
- assert.Len(t, pl.(*DiscordPayload).Embeds, 1)
- assert.Equal(t, "[test/repo] Pull request opened: #12 Fix bug", pl.(*DiscordPayload).Embeds[0].Title)
- assert.Equal(t, "fixes bug #2", pl.(*DiscordPayload).Embeds[0].Description)
- assert.Equal(t, "http://localhost:3000/test/repo/pulls/12", pl.(*DiscordPayload).Embeds[0].URL)
- assert.Equal(t, p.Sender.UserName, pl.(*DiscordPayload).Embeds[0].Author.Name)
- assert.Equal(t, setting.AppURL+p.Sender.UserName, pl.(*DiscordPayload).Embeds[0].Author.URL)
- assert.Equal(t, p.Sender.AvatarURL, pl.(*DiscordPayload).Embeds[0].Author.IconURL)
+ assert.Len(t, pl.Embeds, 1)
+ assert.Equal(t, "[test/repo] Pull request opened: #12 Fix bug", pl.Embeds[0].Title)
+ assert.Equal(t, "fixes bug #2", pl.Embeds[0].Description)
+ assert.Equal(t, "http://localhost:3000/test/repo/pulls/12", pl.Embeds[0].URL)
+ assert.Equal(t, p.Sender.UserName, pl.Embeds[0].Author.Name)
+ assert.Equal(t, setting.AppURL+p.Sender.UserName, pl.Embeds[0].Author.URL)
+ assert.Equal(t, p.Sender.AvatarURL, pl.Embeds[0].Author.IconURL)
})
t.Run("PullRequestComment", func(t *testing.T) {
p := pullRequestCommentTestPayload()
- d := new(DiscordPayload)
- pl, err := d.IssueComment(p)
+ pl, err := dc.IssueComment(p)
require.NoError(t, err)
- require.NotNil(t, pl)
- require.IsType(t, &DiscordPayload{}, pl)
- assert.Len(t, pl.(*DiscordPayload).Embeds, 1)
- assert.Equal(t, "[test/repo] New comment on pull request #12 Fix bug", pl.(*DiscordPayload).Embeds[0].Title)
- assert.Equal(t, "changes requested", pl.(*DiscordPayload).Embeds[0].Description)
- assert.Equal(t, "http://localhost:3000/test/repo/pulls/12#issuecomment-4", pl.(*DiscordPayload).Embeds[0].URL)
- assert.Equal(t, p.Sender.UserName, pl.(*DiscordPayload).Embeds[0].Author.Name)
- assert.Equal(t, setting.AppURL+p.Sender.UserName, pl.(*DiscordPayload).Embeds[0].Author.URL)
- assert.Equal(t, p.Sender.AvatarURL, pl.(*DiscordPayload).Embeds[0].Author.IconURL)
+ assert.Len(t, pl.Embeds, 1)
+ assert.Equal(t, "[test/repo] New comment on pull request #12 Fix bug", pl.Embeds[0].Title)
+ assert.Equal(t, "changes requested", pl.Embeds[0].Description)
+ assert.Equal(t, "http://localhost:3000/test/repo/pulls/12#issuecomment-4", pl.Embeds[0].URL)
+ assert.Equal(t, p.Sender.UserName, pl.Embeds[0].Author.Name)
+ assert.Equal(t, setting.AppURL+p.Sender.UserName, pl.Embeds[0].Author.URL)
+ assert.Equal(t, p.Sender.AvatarURL, pl.Embeds[0].Author.IconURL)
})
t.Run("Review", func(t *testing.T) {
p := pullRequestTestPayload()
p.Action = api.HookIssueReviewed
- d := new(DiscordPayload)
- pl, err := d.Review(p, webhook_module.HookEventPullRequestReviewApproved)
+ pl, err := dc.Review(p, webhook_module.HookEventPullRequestReviewApproved)
require.NoError(t, err)
- require.NotNil(t, pl)
- require.IsType(t, &DiscordPayload{}, pl)
- assert.Len(t, pl.(*DiscordPayload).Embeds, 1)
- assert.Equal(t, "[test/repo] Pull request review approved: #12 Fix bug", pl.(*DiscordPayload).Embeds[0].Title)
- assert.Equal(t, "good job", pl.(*DiscordPayload).Embeds[0].Description)
- assert.Equal(t, "http://localhost:3000/test/repo/pulls/12", pl.(*DiscordPayload).Embeds[0].URL)
- assert.Equal(t, p.Sender.UserName, pl.(*DiscordPayload).Embeds[0].Author.Name)
- assert.Equal(t, setting.AppURL+p.Sender.UserName, pl.(*DiscordPayload).Embeds[0].Author.URL)
- assert.Equal(t, p.Sender.AvatarURL, pl.(*DiscordPayload).Embeds[0].Author.IconURL)
+ assert.Len(t, pl.Embeds, 1)
+ assert.Equal(t, "[test/repo] Pull request review approved: #12 Fix bug", pl.Embeds[0].Title)
+ assert.Equal(t, "good job", pl.Embeds[0].Description)
+ assert.Equal(t, "http://localhost:3000/test/repo/pulls/12", pl.Embeds[0].URL)
+ assert.Equal(t, p.Sender.UserName, pl.Embeds[0].Author.Name)
+ assert.Equal(t, setting.AppURL+p.Sender.UserName, pl.Embeds[0].Author.URL)
+ assert.Equal(t, p.Sender.AvatarURL, pl.Embeds[0].Author.IconURL)
})
t.Run("Repository", func(t *testing.T) {
p := repositoryTestPayload()
- d := new(DiscordPayload)
- pl, err := d.Repository(p)
+ pl, err := dc.Repository(p)
require.NoError(t, err)
- require.NotNil(t, pl)
- require.IsType(t, &DiscordPayload{}, pl)
- assert.Len(t, pl.(*DiscordPayload).Embeds, 1)
- assert.Equal(t, "[test/repo] Repository created", pl.(*DiscordPayload).Embeds[0].Title)
- assert.Empty(t, pl.(*DiscordPayload).Embeds[0].Description)
- assert.Equal(t, "http://localhost:3000/test/repo", pl.(*DiscordPayload).Embeds[0].URL)
- assert.Equal(t, p.Sender.UserName, pl.(*DiscordPayload).Embeds[0].Author.Name)
- assert.Equal(t, setting.AppURL+p.Sender.UserName, pl.(*DiscordPayload).Embeds[0].Author.URL)
- assert.Equal(t, p.Sender.AvatarURL, pl.(*DiscordPayload).Embeds[0].Author.IconURL)
+ assert.Len(t, pl.Embeds, 1)
+ assert.Equal(t, "[test/repo] Repository created", pl.Embeds[0].Title)
+ assert.Empty(t, pl.Embeds[0].Description)
+ assert.Equal(t, "http://localhost:3000/test/repo", pl.Embeds[0].URL)
+ assert.Equal(t, p.Sender.UserName, pl.Embeds[0].Author.Name)
+ assert.Equal(t, setting.AppURL+p.Sender.UserName, pl.Embeds[0].Author.URL)
+ assert.Equal(t, p.Sender.AvatarURL, pl.Embeds[0].Author.IconURL)
})
t.Run("Package", func(t *testing.T) {
p := packageTestPayload()
- d := new(DiscordPayload)
- pl, err := d.Package(p)
+ pl, err := dc.Package(p)
require.NoError(t, err)
- require.NotNil(t, pl)
- require.IsType(t, &DiscordPayload{}, pl)
- assert.Len(t, pl.(*DiscordPayload).Embeds, 1)
- assert.Equal(t, "Package created: GiteaContainer:latest", pl.(*DiscordPayload).Embeds[0].Title)
- assert.Empty(t, pl.(*DiscordPayload).Embeds[0].Description)
- assert.Equal(t, "http://localhost:3000/user1/-/packages/container/GiteaContainer/latest", pl.(*DiscordPayload).Embeds[0].URL)
- assert.Equal(t, p.Sender.UserName, pl.(*DiscordPayload).Embeds[0].Author.Name)
- assert.Equal(t, setting.AppURL+p.Sender.UserName, pl.(*DiscordPayload).Embeds[0].Author.URL)
- assert.Equal(t, p.Sender.AvatarURL, pl.(*DiscordPayload).Embeds[0].Author.IconURL)
+ assert.Len(t, pl.Embeds, 1)
+ assert.Equal(t, "Package created: GiteaContainer:latest", pl.Embeds[0].Title)
+ assert.Empty(t, pl.Embeds[0].Description)
+ assert.Equal(t, "http://localhost:3000/user1/-/packages/container/GiteaContainer/latest", pl.Embeds[0].URL)
+ assert.Equal(t, p.Sender.UserName, pl.Embeds[0].Author.Name)
+ assert.Equal(t, setting.AppURL+p.Sender.UserName, pl.Embeds[0].Author.URL)
+ assert.Equal(t, p.Sender.AvatarURL, pl.Embeds[0].Author.IconURL)
})
t.Run("Wiki", func(t *testing.T) {
p := wikiTestPayload()
- d := new(DiscordPayload)
p.Action = api.HookWikiCreated
- pl, err := d.Wiki(p)
+ pl, err := dc.Wiki(p)
require.NoError(t, err)
- require.NotNil(t, pl)
- require.IsType(t, &DiscordPayload{}, pl)
- assert.Len(t, pl.(*DiscordPayload).Embeds, 1)
- assert.Equal(t, "[test/repo] New wiki page 'index' (Wiki change comment)", pl.(*DiscordPayload).Embeds[0].Title)
- assert.Equal(t, "Wiki change comment", pl.(*DiscordPayload).Embeds[0].Description)
- assert.Equal(t, "http://localhost:3000/test/repo/wiki/index", pl.(*DiscordPayload).Embeds[0].URL)
- assert.Equal(t, p.Sender.UserName, pl.(*DiscordPayload).Embeds[0].Author.Name)
- assert.Equal(t, setting.AppURL+p.Sender.UserName, pl.(*DiscordPayload).Embeds[0].Author.URL)
- assert.Equal(t, p.Sender.AvatarURL, pl.(*DiscordPayload).Embeds[0].Author.IconURL)
+ assert.Len(t, pl.Embeds, 1)
+ assert.Equal(t, "[test/repo] New wiki page 'index' (Wiki change comment)", pl.Embeds[0].Title)
+ assert.Equal(t, "Wiki change comment", pl.Embeds[0].Description)
+ assert.Equal(t, "http://localhost:3000/test/repo/wiki/index", pl.Embeds[0].URL)
+ assert.Equal(t, p.Sender.UserName, pl.Embeds[0].Author.Name)
+ assert.Equal(t, setting.AppURL+p.Sender.UserName, pl.Embeds[0].Author.URL)
+ assert.Equal(t, p.Sender.AvatarURL, pl.Embeds[0].Author.IconURL)
p.Action = api.HookWikiEdited
- pl, err = d.Wiki(p)
+ pl, err = dc.Wiki(p)
require.NoError(t, err)
- require.NotNil(t, pl)
- require.IsType(t, &DiscordPayload{}, pl)
- assert.Len(t, pl.(*DiscordPayload).Embeds, 1)
- assert.Equal(t, "[test/repo] Wiki page 'index' edited (Wiki change comment)", pl.(*DiscordPayload).Embeds[0].Title)
- assert.Equal(t, "Wiki change comment", pl.(*DiscordPayload).Embeds[0].Description)
- assert.Equal(t, "http://localhost:3000/test/repo/wiki/index", pl.(*DiscordPayload).Embeds[0].URL)
- assert.Equal(t, p.Sender.UserName, pl.(*DiscordPayload).Embeds[0].Author.Name)
- assert.Equal(t, setting.AppURL+p.Sender.UserName, pl.(*DiscordPayload).Embeds[0].Author.URL)
- assert.Equal(t, p.Sender.AvatarURL, pl.(*DiscordPayload).Embeds[0].Author.IconURL)
+ assert.Len(t, pl.Embeds, 1)
+ assert.Equal(t, "[test/repo] Wiki page 'index' edited (Wiki change comment)", pl.Embeds[0].Title)
+ assert.Equal(t, "Wiki change comment", pl.Embeds[0].Description)
+ assert.Equal(t, "http://localhost:3000/test/repo/wiki/index", pl.Embeds[0].URL)
+ assert.Equal(t, p.Sender.UserName, pl.Embeds[0].Author.Name)
+ assert.Equal(t, setting.AppURL+p.Sender.UserName, pl.Embeds[0].Author.URL)
+ assert.Equal(t, p.Sender.AvatarURL, pl.Embeds[0].Author.IconURL)
p.Action = api.HookWikiDeleted
- pl, err = d.Wiki(p)
+ pl, err = dc.Wiki(p)
require.NoError(t, err)
- require.NotNil(t, pl)
- require.IsType(t, &DiscordPayload{}, pl)
- assert.Len(t, pl.(*DiscordPayload).Embeds, 1)
- assert.Equal(t, "[test/repo] Wiki page 'index' deleted", pl.(*DiscordPayload).Embeds[0].Title)
- assert.Empty(t, pl.(*DiscordPayload).Embeds[0].Description)
- assert.Equal(t, "http://localhost:3000/test/repo/wiki/index", pl.(*DiscordPayload).Embeds[0].URL)
- assert.Equal(t, p.Sender.UserName, pl.(*DiscordPayload).Embeds[0].Author.Name)
- assert.Equal(t, setting.AppURL+p.Sender.UserName, pl.(*DiscordPayload).Embeds[0].Author.URL)
- assert.Equal(t, p.Sender.AvatarURL, pl.(*DiscordPayload).Embeds[0].Author.IconURL)
+ assert.Len(t, pl.Embeds, 1)
+ assert.Equal(t, "[test/repo] Wiki page 'index' deleted", pl.Embeds[0].Title)
+ assert.Empty(t, pl.Embeds[0].Description)
+ assert.Equal(t, "http://localhost:3000/test/repo/wiki/index", pl.Embeds[0].URL)
+ assert.Equal(t, p.Sender.UserName, pl.Embeds[0].Author.Name)
+ assert.Equal(t, setting.AppURL+p.Sender.UserName, pl.Embeds[0].Author.URL)
+ assert.Equal(t, p.Sender.AvatarURL, pl.Embeds[0].Author.IconURL)
})
t.Run("Release", func(t *testing.T) {
p := pullReleaseTestPayload()
- d := new(DiscordPayload)
- pl, err := d.Release(p)
+ pl, err := dc.Release(p)
require.NoError(t, err)
- require.NotNil(t, pl)
- require.IsType(t, &DiscordPayload{}, pl)
- assert.Len(t, pl.(*DiscordPayload).Embeds, 1)
- assert.Equal(t, "[test/repo] Release created: v1.0", pl.(*DiscordPayload).Embeds[0].Title)
- assert.Equal(t, "Note of first stable release", pl.(*DiscordPayload).Embeds[0].Description)
- assert.Equal(t, "http://localhost:3000/test/repo/releases/tag/v1.0", pl.(*DiscordPayload).Embeds[0].URL)
- assert.Equal(t, p.Sender.UserName, pl.(*DiscordPayload).Embeds[0].Author.Name)
- assert.Equal(t, setting.AppURL+p.Sender.UserName, pl.(*DiscordPayload).Embeds[0].Author.URL)
- assert.Equal(t, p.Sender.AvatarURL, pl.(*DiscordPayload).Embeds[0].Author.IconURL)
+ assert.Len(t, pl.Embeds, 1)
+ assert.Equal(t, "[test/repo] Release created: v1.0", pl.Embeds[0].Title)
+ assert.Equal(t, "Note of first stable release", pl.Embeds[0].Description)
+ assert.Equal(t, "http://localhost:3000/test/repo/releases/tag/v1.0", pl.Embeds[0].URL)
+ assert.Equal(t, p.Sender.UserName, pl.Embeds[0].Author.Name)
+ assert.Equal(t, setting.AppURL+p.Sender.UserName, pl.Embeds[0].Author.URL)
+ assert.Equal(t, p.Sender.AvatarURL, pl.Embeds[0].Author.IconURL)
})
}
func TestDiscordJSONPayload(t *testing.T) {
p := pushTestPayload()
-
- pl, err := new(DiscordPayload).Push(p)
+ data, err := p.JSONPayload()
require.NoError(t, err)
- require.NotNil(t, pl)
- require.IsType(t, &DiscordPayload{}, pl)
- json, err := pl.JSONPayload()
+ hook := &webhook_model.Webhook{
+ RepoID: 3,
+ IsActive: true,
+ Type: webhook_module.DISCORD,
+ URL: "https://discord.example.com/",
+ Meta: `{}`,
+ HTTPMethod: "POST",
+ }
+ task := &webhook_model.HookTask{
+ HookID: hook.ID,
+ EventType: webhook_module.HookEventPush,
+ PayloadContent: string(data),
+ PayloadVersion: 2,
+ }
+
+ req, reqBody, err := newDiscordRequest(context.Background(), hook, task)
+ require.NotNil(t, req)
+ require.NotNil(t, reqBody)
require.NoError(t, err)
- assert.NotEmpty(t, json)
+
+ assert.Equal(t, "POST", req.Method)
+ assert.Equal(t, "https://discord.example.com/", req.URL.String())
+ assert.Equal(t, "sha256=", req.Header.Get("X-Hub-Signature-256"))
+ assert.Equal(t, "application/json", req.Header.Get("Content-Type"))
+ var body DiscordPayload
+ err = json.NewDecoder(req.Body).Decode(&body)
+ assert.NoError(t, err)
+ assert.Equal(t, "[2020558](http://localhost:3000/test/repo/commit/2020558fe2e34debb818a514715839cabd25e778) commit message - user1\n[2020558](http://localhost:3000/test/repo/commit/2020558fe2e34debb818a514715839cabd25e778) commit message - user1", body.Embeds[0].Description)
}
diff --git a/services/webhook/feishu.go b/services/webhook/feishu.go
index 556443e70b..1ec436894b 100644
--- a/services/webhook/feishu.go
+++ b/services/webhook/feishu.go
@@ -4,11 +4,13 @@
package webhook
import (
+ "context"
"fmt"
+ "net/http"
"strings"
+ webhook_model "code.gitea.io/gitea/models/webhook"
"code.gitea.io/gitea/modules/git"
- "code.gitea.io/gitea/modules/json"
api "code.gitea.io/gitea/modules/structs"
webhook_module "code.gitea.io/gitea/modules/webhook"
)
@@ -23,8 +25,8 @@ type (
}
)
-func newFeishuTextPayload(text string) *FeishuPayload {
- return &FeishuPayload{
+func newFeishuTextPayload(text string) FeishuPayload {
+ return FeishuPayload{
MsgType: "text",
Content: struct {
Text string `json:"text"`
@@ -34,19 +36,8 @@ func newFeishuTextPayload(text string) *FeishuPayload {
}
}
-// JSONPayload Marshals the FeishuPayload to json
-func (f *FeishuPayload) JSONPayload() ([]byte, error) {
- data, err := json.MarshalIndent(f, "", " ")
- if err != nil {
- return []byte{}, err
- }
- return data, nil
-}
-
-var _ PayloadConvertor = &FeishuPayload{}
-
// Create implements PayloadConvertor Create method
-func (f *FeishuPayload) Create(p *api.CreatePayload) (api.Payloader, error) {
+func (fc feishuConvertor) Create(p *api.CreatePayload) (FeishuPayload, error) {
// created tag/branch
refName := git.RefName(p.Ref).ShortName()
text := fmt.Sprintf("[%s] %s %s created", p.Repo.FullName, p.RefType, refName)
@@ -55,7 +46,7 @@ func (f *FeishuPayload) Create(p *api.CreatePayload) (api.Payloader, error) {
}
// Delete implements PayloadConvertor Delete method
-func (f *FeishuPayload) Delete(p *api.DeletePayload) (api.Payloader, error) {
+func (fc feishuConvertor) Delete(p *api.DeletePayload) (FeishuPayload, error) {
// created tag/branch
refName := git.RefName(p.Ref).ShortName()
text := fmt.Sprintf("[%s] %s %s deleted", p.Repo.FullName, p.RefType, refName)
@@ -64,14 +55,14 @@ func (f *FeishuPayload) Delete(p *api.DeletePayload) (api.Payloader, error) {
}
// Fork implements PayloadConvertor Fork method
-func (f *FeishuPayload) Fork(p *api.ForkPayload) (api.Payloader, error) {
+func (fc feishuConvertor) Fork(p *api.ForkPayload) (FeishuPayload, error) {
text := fmt.Sprintf("%s is forked to %s", p.Forkee.FullName, p.Repo.FullName)
return newFeishuTextPayload(text), nil
}
// Push implements PayloadConvertor Push method
-func (f *FeishuPayload) Push(p *api.PushPayload) (api.Payloader, error) {
+func (fc feishuConvertor) Push(p *api.PushPayload) (FeishuPayload, error) {
var (
branchName = git.RefName(p.Ref).ShortName()
commitDesc string
@@ -96,48 +87,40 @@ func (f *FeishuPayload) Push(p *api.PushPayload) (api.Payloader, error) {
}
// Issue implements PayloadConvertor Issue method
-func (f *FeishuPayload) Issue(p *api.IssuePayload) (api.Payloader, error) {
+func (fc feishuConvertor) Issue(p *api.IssuePayload) (FeishuPayload, error) {
title, link, by, operator, result, assignees := getIssuesInfo(p)
- var res api.Payloader
if assignees != "" {
if p.Action == api.HookIssueAssigned || p.Action == api.HookIssueUnassigned || p.Action == api.HookIssueMilestoned {
- res = newFeishuTextPayload(fmt.Sprintf("%s\n%s\n%s\n%s\n%s\n%s\n\n%s", title, link, by, operator, result, assignees, p.Issue.Body))
- } else {
- res = newFeishuTextPayload(fmt.Sprintf("%s\n%s\n%s\n%s\n%s\n\n%s", title, link, by, operator, assignees, p.Issue.Body))
+ return newFeishuTextPayload(fmt.Sprintf("%s\n%s\n%s\n%s\n%s\n%s\n\n%s", title, link, by, operator, result, assignees, p.Issue.Body)), nil
}
- } else {
- res = newFeishuTextPayload(fmt.Sprintf("%s\n%s\n%s\n%s\n\n%s", title, link, by, operator, p.Issue.Body))
+ return newFeishuTextPayload(fmt.Sprintf("%s\n%s\n%s\n%s\n%s\n\n%s", title, link, by, operator, assignees, p.Issue.Body)), nil
}
- return res, nil
+ return newFeishuTextPayload(fmt.Sprintf("%s\n%s\n%s\n%s\n\n%s", title, link, by, operator, p.Issue.Body)), nil
}
// IssueComment implements PayloadConvertor IssueComment method
-func (f *FeishuPayload) IssueComment(p *api.IssueCommentPayload) (api.Payloader, error) {
+func (fc feishuConvertor) IssueComment(p *api.IssueCommentPayload) (FeishuPayload, error) {
title, link, by, operator := getIssuesCommentInfo(p)
return newFeishuTextPayload(fmt.Sprintf("%s\n%s\n%s\n%s\n\n%s", title, link, by, operator, p.Comment.Body)), nil
}
// PullRequest implements PayloadConvertor PullRequest method
-func (f *FeishuPayload) PullRequest(p *api.PullRequestPayload) (api.Payloader, error) {
+func (fc feishuConvertor) PullRequest(p *api.PullRequestPayload) (FeishuPayload, error) {
title, link, by, operator, result, assignees := getPullRequestInfo(p)
- var res api.Payloader
if assignees != "" {
if p.Action == api.HookIssueAssigned || p.Action == api.HookIssueUnassigned || p.Action == api.HookIssueMilestoned {
- res = newFeishuTextPayload(fmt.Sprintf("%s\n%s\n%s\n%s\n%s\n%s\n\n%s", title, link, by, operator, result, assignees, p.PullRequest.Body))
- } else {
- res = newFeishuTextPayload(fmt.Sprintf("%s\n%s\n%s\n%s\n%s\n\n%s", title, link, by, operator, assignees, p.PullRequest.Body))
+ return newFeishuTextPayload(fmt.Sprintf("%s\n%s\n%s\n%s\n%s\n%s\n\n%s", title, link, by, operator, result, assignees, p.PullRequest.Body)), nil
}
- } else {
- res = newFeishuTextPayload(fmt.Sprintf("%s\n%s\n%s\n%s\n\n%s", title, link, by, operator, p.PullRequest.Body))
+ return newFeishuTextPayload(fmt.Sprintf("%s\n%s\n%s\n%s\n%s\n\n%s", title, link, by, operator, assignees, p.PullRequest.Body)), nil
}
- return res, nil
+ return newFeishuTextPayload(fmt.Sprintf("%s\n%s\n%s\n%s\n\n%s", title, link, by, operator, p.PullRequest.Body)), nil
}
// Review implements PayloadConvertor Review method
-func (f *FeishuPayload) Review(p *api.PullRequestPayload, event webhook_module.HookEventType) (api.Payloader, error) {
+func (fc feishuConvertor) Review(p *api.PullRequestPayload, event webhook_module.HookEventType) (FeishuPayload, error) {
action, err := parseHookPullRequestEventType(event)
if err != nil {
- return nil, err
+ return FeishuPayload{}, err
}
title := fmt.Sprintf("[%s] Pull request review %s : #%d %s", p.Repository.FullName, action, p.Index, p.PullRequest.Title)
@@ -147,7 +130,7 @@ func (f *FeishuPayload) Review(p *api.PullRequestPayload, event webhook_module.H
}
// Repository implements PayloadConvertor Repository method
-func (f *FeishuPayload) Repository(p *api.RepositoryPayload) (api.Payloader, error) {
+func (fc feishuConvertor) Repository(p *api.RepositoryPayload) (FeishuPayload, error) {
var text string
switch p.Action {
case api.HookRepoCreated:
@@ -158,30 +141,33 @@ func (f *FeishuPayload) Repository(p *api.RepositoryPayload) (api.Payloader, err
return newFeishuTextPayload(text), nil
}
- return nil, nil
+ return FeishuPayload{}, nil
}
// Wiki implements PayloadConvertor Wiki method
-func (f *FeishuPayload) Wiki(p *api.WikiPayload) (api.Payloader, error) {
+func (fc feishuConvertor) Wiki(p *api.WikiPayload) (FeishuPayload, error) {
text, _, _ := getWikiPayloadInfo(p, noneLinkFormatter, true)
return newFeishuTextPayload(text), nil
}
// Release implements PayloadConvertor Release method
-func (f *FeishuPayload) Release(p *api.ReleasePayload) (api.Payloader, error) {
+func (fc feishuConvertor) Release(p *api.ReleasePayload) (FeishuPayload, error) {
text, _ := getReleasePayloadInfo(p, noneLinkFormatter, true)
return newFeishuTextPayload(text), nil
}
-func (f *FeishuPayload) Package(p *api.PackagePayload) (api.Payloader, error) {
+func (fc feishuConvertor) Package(p *api.PackagePayload) (FeishuPayload, error) {
text, _ := getPackagePayloadInfo(p, noneLinkFormatter, true)
return newFeishuTextPayload(text), nil
}
-// GetFeishuPayload converts a ding talk webhook into a FeishuPayload
-func GetFeishuPayload(p api.Payloader, event webhook_module.HookEventType, _ string) (api.Payloader, error) {
- return convertPayloader(new(FeishuPayload), p, event)
+type feishuConvertor struct{}
+
+var _ payloadConvertor[FeishuPayload] = feishuConvertor{}
+
+func newFeishuRequest(ctx context.Context, w *webhook_model.Webhook, t *webhook_model.HookTask) (*http.Request, []byte, error) {
+ return newJSONRequest(feishuConvertor{}, w, t, true)
}
diff --git a/services/webhook/feishu_test.go b/services/webhook/feishu_test.go
index 98bc50dede..ef18333fd4 100644
--- a/services/webhook/feishu_test.go
+++ b/services/webhook/feishu_test.go
@@ -4,8 +4,11 @@
package webhook
import (
+ "context"
"testing"
+ webhook_model "code.gitea.io/gitea/models/webhook"
+ "code.gitea.io/gitea/modules/json"
api "code.gitea.io/gitea/modules/structs"
webhook_module "code.gitea.io/gitea/modules/webhook"
@@ -14,199 +17,177 @@ import (
)
func TestFeishuPayload(t *testing.T) {
+ fc := feishuConvertor{}
t.Run("Create", func(t *testing.T) {
p := createTestPayload()
- d := new(FeishuPayload)
- pl, err := d.Create(p)
+ pl, err := fc.Create(p)
require.NoError(t, err)
- require.NotNil(t, pl)
- require.IsType(t, &FeishuPayload{}, pl)
- assert.Equal(t, `[test/repo] branch test created`, pl.(*FeishuPayload).Content.Text)
+ assert.Equal(t, `[test/repo] branch test created`, pl.Content.Text)
})
t.Run("Delete", func(t *testing.T) {
p := deleteTestPayload()
- d := new(FeishuPayload)
- pl, err := d.Delete(p)
+ pl, err := fc.Delete(p)
require.NoError(t, err)
- require.NotNil(t, pl)
- require.IsType(t, &FeishuPayload{}, pl)
- assert.Equal(t, `[test/repo] branch test deleted`, pl.(*FeishuPayload).Content.Text)
+ assert.Equal(t, `[test/repo] branch test deleted`, pl.Content.Text)
})
t.Run("Fork", func(t *testing.T) {
p := forkTestPayload()
- d := new(FeishuPayload)
- pl, err := d.Fork(p)
+ pl, err := fc.Fork(p)
require.NoError(t, err)
- require.NotNil(t, pl)
- require.IsType(t, &FeishuPayload{}, pl)
- assert.Equal(t, `test/repo2 is forked to test/repo`, pl.(*FeishuPayload).Content.Text)
+ assert.Equal(t, `test/repo2 is forked to test/repo`, pl.Content.Text)
})
t.Run("Push", func(t *testing.T) {
p := pushTestPayload()
- d := new(FeishuPayload)
- pl, err := d.Push(p)
+ pl, err := fc.Push(p)
require.NoError(t, err)
- require.NotNil(t, pl)
- require.IsType(t, &FeishuPayload{}, pl)
- assert.Equal(t, "[test/repo:test] \r\n[2020558](http://localhost:3000/test/repo/commit/2020558fe2e34debb818a514715839cabd25e778) commit message - user1\r\n[2020558](http://localhost:3000/test/repo/commit/2020558fe2e34debb818a514715839cabd25e778) commit message - user1", pl.(*FeishuPayload).Content.Text)
+ assert.Equal(t, "[test/repo:test] \r\n[2020558](http://localhost:3000/test/repo/commit/2020558fe2e34debb818a514715839cabd25e778) commit message - user1\r\n[2020558](http://localhost:3000/test/repo/commit/2020558fe2e34debb818a514715839cabd25e778) commit message - user1", pl.Content.Text)
})
t.Run("Issue", func(t *testing.T) {
p := issueTestPayload()
- d := new(FeishuPayload)
p.Action = api.HookIssueOpened
- pl, err := d.Issue(p)
+ pl, err := fc.Issue(p)
require.NoError(t, err)
- require.NotNil(t, pl)
- require.IsType(t, &FeishuPayload{}, pl)
- assert.Equal(t, "[Issue-test/repo #2]: opened\ncrash\nhttp://localhost:3000/test/repo/issues/2\nIssue by user1\nOperator: user1\nAssignees: user1\n\nissue body", pl.(*FeishuPayload).Content.Text)
+ assert.Equal(t, "[Issue-test/repo #2]: opened\ncrash\nhttp://localhost:3000/test/repo/issues/2\nIssue by user1\nOperator: user1\nAssignees: user1\n\nissue body", pl.Content.Text)
p.Action = api.HookIssueClosed
- pl, err = d.Issue(p)
+ pl, err = fc.Issue(p)
require.NoError(t, err)
- require.NotNil(t, pl)
- require.IsType(t, &FeishuPayload{}, pl)
- assert.Equal(t, "[Issue-test/repo #2]: closed\ncrash\nhttp://localhost:3000/test/repo/issues/2\nIssue by user1\nOperator: user1\nAssignees: user1\n\nissue body", pl.(*FeishuPayload).Content.Text)
+ assert.Equal(t, "[Issue-test/repo #2]: closed\ncrash\nhttp://localhost:3000/test/repo/issues/2\nIssue by user1\nOperator: user1\nAssignees: user1\n\nissue body", pl.Content.Text)
})
t.Run("IssueComment", func(t *testing.T) {
p := issueCommentTestPayload()
- d := new(FeishuPayload)
- pl, err := d.IssueComment(p)
+ pl, err := fc.IssueComment(p)
require.NoError(t, err)
- require.NotNil(t, pl)
- require.IsType(t, &FeishuPayload{}, pl)
- assert.Equal(t, "[Comment-test/repo #2]: created\ncrash\nhttp://localhost:3000/test/repo/issues/2\nIssue by user1\nOperator: user1\n\nmore info needed", pl.(*FeishuPayload).Content.Text)
+ assert.Equal(t, "[Comment-test/repo #2]: created\ncrash\nhttp://localhost:3000/test/repo/issues/2\nIssue by user1\nOperator: user1\n\nmore info needed", pl.Content.Text)
})
t.Run("PullRequest", func(t *testing.T) {
p := pullRequestTestPayload()
- d := new(FeishuPayload)
- pl, err := d.PullRequest(p)
+ pl, err := fc.PullRequest(p)
require.NoError(t, err)
- require.NotNil(t, pl)
- require.IsType(t, &FeishuPayload{}, pl)
- assert.Equal(t, "[PullRequest-test/repo #12]: opened\nFix bug\nhttp://localhost:3000/test/repo/pulls/12\nPullRequest by user1\nOperator: user1\nAssignees: user1\n\nfixes bug #2", pl.(*FeishuPayload).Content.Text)
+ assert.Equal(t, "[PullRequest-test/repo #12]: opened\nFix bug\nhttp://localhost:3000/test/repo/pulls/12\nPullRequest by user1\nOperator: user1\nAssignees: user1\n\nfixes bug #2", pl.Content.Text)
})
t.Run("PullRequestComment", func(t *testing.T) {
p := pullRequestCommentTestPayload()
- d := new(FeishuPayload)
- pl, err := d.IssueComment(p)
+ pl, err := fc.IssueComment(p)
require.NoError(t, err)
- require.NotNil(t, pl)
- require.IsType(t, &FeishuPayload{}, pl)
- assert.Equal(t, "[Comment-test/repo #12]: created\nFix bug\nhttp://localhost:3000/test/repo/pulls/12\nPullRequest by user1\nOperator: user1\n\nchanges requested", pl.(*FeishuPayload).Content.Text)
+ assert.Equal(t, "[Comment-test/repo #12]: created\nFix bug\nhttp://localhost:3000/test/repo/pulls/12\nPullRequest by user1\nOperator: user1\n\nchanges requested", pl.Content.Text)
})
t.Run("Review", func(t *testing.T) {
p := pullRequestTestPayload()
p.Action = api.HookIssueReviewed
- d := new(FeishuPayload)
- pl, err := d.Review(p, webhook_module.HookEventPullRequestReviewApproved)
+ pl, err := fc.Review(p, webhook_module.HookEventPullRequestReviewApproved)
require.NoError(t, err)
- require.NotNil(t, pl)
- require.IsType(t, &FeishuPayload{}, pl)
- assert.Equal(t, "[test/repo] Pull request review approved : #12 Fix bug\r\n\r\ngood job", pl.(*FeishuPayload).Content.Text)
+ assert.Equal(t, "[test/repo] Pull request review approved : #12 Fix bug\r\n\r\ngood job", pl.Content.Text)
})
t.Run("Repository", func(t *testing.T) {
p := repositoryTestPayload()
- d := new(FeishuPayload)
- pl, err := d.Repository(p)
+ pl, err := fc.Repository(p)
require.NoError(t, err)
- require.NotNil(t, pl)
- require.IsType(t, &FeishuPayload{}, pl)
- assert.Equal(t, "[test/repo] Repository created", pl.(*FeishuPayload).Content.Text)
+ assert.Equal(t, "[test/repo] Repository created", pl.Content.Text)
})
t.Run("Package", func(t *testing.T) {
p := packageTestPayload()
- d := new(FeishuPayload)
- pl, err := d.Package(p)
+ pl, err := fc.Package(p)
require.NoError(t, err)
- require.NotNil(t, pl)
- require.IsType(t, &FeishuPayload{}, pl)
- assert.Equal(t, "Package created: GiteaContainer:latest by user1", pl.(*FeishuPayload).Content.Text)
+ assert.Equal(t, "Package created: GiteaContainer:latest by user1", pl.Content.Text)
})
t.Run("Wiki", func(t *testing.T) {
p := wikiTestPayload()
- d := new(FeishuPayload)
p.Action = api.HookWikiCreated
- pl, err := d.Wiki(p)
+ pl, err := fc.Wiki(p)
require.NoError(t, err)
- require.NotNil(t, pl)
- require.IsType(t, &FeishuPayload{}, pl)
- assert.Equal(t, "[test/repo] New wiki page 'index' (Wiki change comment) by user1", pl.(*FeishuPayload).Content.Text)
+ assert.Equal(t, "[test/repo] New wiki page 'index' (Wiki change comment) by user1", pl.Content.Text)
p.Action = api.HookWikiEdited
- pl, err = d.Wiki(p)
+ pl, err = fc.Wiki(p)
require.NoError(t, err)
- require.NotNil(t, pl)
- require.IsType(t, &FeishuPayload{}, pl)
- assert.Equal(t, "[test/repo] Wiki page 'index' edited (Wiki change comment) by user1", pl.(*FeishuPayload).Content.Text)
+ assert.Equal(t, "[test/repo] Wiki page 'index' edited (Wiki change comment) by user1", pl.Content.Text)
p.Action = api.HookWikiDeleted
- pl, err = d.Wiki(p)
+ pl, err = fc.Wiki(p)
require.NoError(t, err)
- require.NotNil(t, pl)
- require.IsType(t, &FeishuPayload{}, pl)
- assert.Equal(t, "[test/repo] Wiki page 'index' deleted by user1", pl.(*FeishuPayload).Content.Text)
+ assert.Equal(t, "[test/repo] Wiki page 'index' deleted by user1", pl.Content.Text)
})
t.Run("Release", func(t *testing.T) {
p := pullReleaseTestPayload()
- d := new(FeishuPayload)
- pl, err := d.Release(p)
+ pl, err := fc.Release(p)
require.NoError(t, err)
- require.NotNil(t, pl)
- require.IsType(t, &FeishuPayload{}, pl)
- assert.Equal(t, "[test/repo] Release created: v1.0 by user1", pl.(*FeishuPayload).Content.Text)
+ assert.Equal(t, "[test/repo] Release created: v1.0 by user1", pl.Content.Text)
})
}
func TestFeishuJSONPayload(t *testing.T) {
p := pushTestPayload()
-
- pl, err := new(FeishuPayload).Push(p)
+ data, err := p.JSONPayload()
require.NoError(t, err)
- require.NotNil(t, pl)
- require.IsType(t, &FeishuPayload{}, pl)
- json, err := pl.JSONPayload()
+ hook := &webhook_model.Webhook{
+ RepoID: 3,
+ IsActive: true,
+ Type: webhook_module.FEISHU,
+ URL: "https://feishu.example.com/",
+ Meta: `{}`,
+ HTTPMethod: "POST",
+ }
+ task := &webhook_model.HookTask{
+ HookID: hook.ID,
+ EventType: webhook_module.HookEventPush,
+ PayloadContent: string(data),
+ PayloadVersion: 2,
+ }
+
+ req, reqBody, err := newFeishuRequest(context.Background(), hook, task)
+ require.NotNil(t, req)
+ require.NotNil(t, reqBody)
require.NoError(t, err)
- assert.NotEmpty(t, json)
+
+ assert.Equal(t, "POST", req.Method)
+ assert.Equal(t, "https://feishu.example.com/", req.URL.String())
+ assert.Equal(t, "sha256=", req.Header.Get("X-Hub-Signature-256"))
+ assert.Equal(t, "application/json", req.Header.Get("Content-Type"))
+ var body FeishuPayload
+ err = json.NewDecoder(req.Body).Decode(&body)
+ assert.NoError(t, err)
+ assert.Equal(t, "[test/repo:test] \r\n[2020558](http://localhost:3000/test/repo/commit/2020558fe2e34debb818a514715839cabd25e778) commit message - user1\r\n[2020558](http://localhost:3000/test/repo/commit/2020558fe2e34debb818a514715839cabd25e778) commit message - user1", body.Content.Text)
}
diff --git a/services/webhook/matrix.go b/services/webhook/matrix.go
index 602d16ef39..0329804a8b 100644
--- a/services/webhook/matrix.go
+++ b/services/webhook/matrix.go
@@ -4,11 +4,12 @@
package webhook
import (
+ "bytes"
+ "context"
"crypto/sha1"
"encoding/hex"
- "errors"
"fmt"
- "html"
+ "net/http"
"net/url"
"regexp"
"strings"
@@ -23,6 +24,37 @@ import (
webhook_module "code.gitea.io/gitea/modules/webhook"
)
+func newMatrixRequest(ctx context.Context, w *webhook_model.Webhook, t *webhook_model.HookTask) (*http.Request, []byte, error) {
+ meta := &MatrixMeta{}
+ if err := json.Unmarshal([]byte(w.Meta), meta); err != nil {
+ return nil, nil, fmt.Errorf("GetMatrixPayload meta json: %w", err)
+ }
+ mc := matrixConvertor{
+ MsgType: messageTypeText[meta.MessageType],
+ }
+ payload, err := newPayload(mc, []byte(t.PayloadContent), t.EventType)
+ if err != nil {
+ return nil, nil, err
+ }
+
+ body, err := json.MarshalIndent(payload, "", " ")
+ if err != nil {
+ return nil, nil, err
+ }
+
+ txnID, err := getMatrixTxnID(body)
+ if err != nil {
+ return nil, nil, err
+ }
+ req, err := http.NewRequest(http.MethodPut, w.URL+"/"+txnID, bytes.NewReader(body))
+ if err != nil {
+ return nil, nil, err
+ }
+ req.Header.Set("Content-Type", "application/json")
+
+ return req, body, addDefaultHeaders(req, []byte(w.Secret), t, body) // likely useless, but has always been sent historially
+}
+
const matrixPayloadSizeLimit = 1024 * 64
// MatrixMeta contains the Matrix metadata
@@ -46,8 +78,6 @@ func GetMatrixHook(w *webhook_model.Webhook) *MatrixMeta {
return s
}
-var _ PayloadConvertor = &MatrixPayload{}
-
// MatrixPayload contains payload for a Matrix room
type MatrixPayload struct {
Body string `json:"body"`
@@ -57,90 +87,79 @@ type MatrixPayload struct {
Commits []*api.PayloadCommit `json:"io.gitea.commits,omitempty"`
}
-// JSONPayload Marshals the MatrixPayload to json
-func (m *MatrixPayload) JSONPayload() ([]byte, error) {
- data, err := json.MarshalIndent(m, "", " ")
- if err != nil {
- return []byte{}, err
- }
- return data, nil
+var _ payloadConvertor[MatrixPayload] = matrixConvertor{}
+
+type matrixConvertor struct {
+ MsgType string
}
-// MatrixLinkFormatter creates a link compatible with Matrix
-func MatrixLinkFormatter(url, text string) string {
- return fmt.Sprintf(`%s`, html.EscapeString(url), html.EscapeString(text))
+func (m matrixConvertor) newPayload(text string, commits ...*api.PayloadCommit) (MatrixPayload, error) {
+ return MatrixPayload{
+ Body: getMessageBody(text),
+ MsgType: m.MsgType,
+ Format: "org.matrix.custom.html",
+ FormattedBody: text,
+ Commits: commits,
+ }, nil
}
-// MatrixLinkToRef Matrix-formatter link to a repo ref
-func MatrixLinkToRef(repoURL, ref string) string {
- refName := git.RefName(ref).ShortName()
- switch {
- case strings.HasPrefix(ref, git.BranchPrefix):
- return MatrixLinkFormatter(repoURL+"/src/branch/"+util.PathEscapeSegments(refName), refName)
- case strings.HasPrefix(ref, git.TagPrefix):
- return MatrixLinkFormatter(repoURL+"/src/tag/"+util.PathEscapeSegments(refName), refName)
- default:
- return MatrixLinkFormatter(repoURL+"/src/commit/"+util.PathEscapeSegments(refName), refName)
- }
-}
-
-// Create implements PayloadConvertor Create method
-func (m *MatrixPayload) Create(p *api.CreatePayload) (api.Payloader, error) {
- repoLink := MatrixLinkFormatter(p.Repo.HTMLURL, p.Repo.FullName)
+// Create implements payloadConvertor Create method
+func (m matrixConvertor) Create(p *api.CreatePayload) (MatrixPayload, error) {
+ repoLink := htmlLinkFormatter(p.Repo.HTMLURL, p.Repo.FullName)
refLink := MatrixLinkToRef(p.Repo.HTMLURL, p.Ref)
text := fmt.Sprintf("[%s:%s] %s created by %s", repoLink, refLink, p.RefType, p.Sender.UserName)
- return getMatrixPayload(text, nil, m.MsgType), nil
+ return m.newPayload(text)
}
// Delete composes Matrix payload for delete a branch or tag.
-func (m *MatrixPayload) Delete(p *api.DeletePayload) (api.Payloader, error) {
+func (m matrixConvertor) Delete(p *api.DeletePayload) (MatrixPayload, error) {
refName := git.RefName(p.Ref).ShortName()
- repoLink := MatrixLinkFormatter(p.Repo.HTMLURL, p.Repo.FullName)
+ repoLink := htmlLinkFormatter(p.Repo.HTMLURL, p.Repo.FullName)
text := fmt.Sprintf("[%s:%s] %s deleted by %s", repoLink, refName, p.RefType, p.Sender.UserName)
- return getMatrixPayload(text, nil, m.MsgType), nil
+ return m.newPayload(text)
}
// Fork composes Matrix payload for forked by a repository.
-func (m *MatrixPayload) Fork(p *api.ForkPayload) (api.Payloader, error) {
- baseLink := MatrixLinkFormatter(p.Forkee.HTMLURL, p.Forkee.FullName)
- forkLink := MatrixLinkFormatter(p.Repo.HTMLURL, p.Repo.FullName)
+func (m matrixConvertor) Fork(p *api.ForkPayload) (MatrixPayload, error) {
+ baseLink := htmlLinkFormatter(p.Forkee.HTMLURL, p.Forkee.FullName)
+ forkLink := htmlLinkFormatter(p.Repo.HTMLURL, p.Repo.FullName)
text := fmt.Sprintf("%s is forked to %s", baseLink, forkLink)
- return getMatrixPayload(text, nil, m.MsgType), nil
+ return m.newPayload(text)
}
-// Issue implements PayloadConvertor Issue method
-func (m *MatrixPayload) Issue(p *api.IssuePayload) (api.Payloader, error) {
- text, _, _, _ := getIssuesPayloadInfo(p, MatrixLinkFormatter, true)
+// Issue implements payloadConvertor Issue method
+func (m matrixConvertor) Issue(p *api.IssuePayload) (MatrixPayload, error) {
+ text, _, _, _ := getIssuesPayloadInfo(p, htmlLinkFormatter, true)
- return getMatrixPayload(text, nil, m.MsgType), nil
+ return m.newPayload(text)
}
-// IssueComment implements PayloadConvertor IssueComment method
-func (m *MatrixPayload) IssueComment(p *api.IssueCommentPayload) (api.Payloader, error) {
- text, _, _ := getIssueCommentPayloadInfo(p, MatrixLinkFormatter, true)
+// IssueComment implements payloadConvertor IssueComment method
+func (m matrixConvertor) IssueComment(p *api.IssueCommentPayload) (MatrixPayload, error) {
+ text, _, _ := getIssueCommentPayloadInfo(p, htmlLinkFormatter, true)
- return getMatrixPayload(text, nil, m.MsgType), nil
+ return m.newPayload(text)
}
-// Wiki implements PayloadConvertor Wiki method
-func (m *MatrixPayload) Wiki(p *api.WikiPayload) (api.Payloader, error) {
- text, _, _ := getWikiPayloadInfo(p, MatrixLinkFormatter, true)
+// Wiki implements payloadConvertor Wiki method
+func (m matrixConvertor) Wiki(p *api.WikiPayload) (MatrixPayload, error) {
+ text, _, _ := getWikiPayloadInfo(p, htmlLinkFormatter, true)
- return getMatrixPayload(text, nil, m.MsgType), nil
+ return m.newPayload(text)
}
-// Release implements PayloadConvertor Release method
-func (m *MatrixPayload) Release(p *api.ReleasePayload) (api.Payloader, error) {
- text, _ := getReleasePayloadInfo(p, MatrixLinkFormatter, true)
+// Release implements payloadConvertor Release method
+func (m matrixConvertor) Release(p *api.ReleasePayload) (MatrixPayload, error) {
+ text, _ := getReleasePayloadInfo(p, htmlLinkFormatter, true)
- return getMatrixPayload(text, nil, m.MsgType), nil
+ return m.newPayload(text)
}
-// Push implements PayloadConvertor Push method
-func (m *MatrixPayload) Push(p *api.PushPayload) (api.Payloader, error) {
+// Push implements payloadConvertor Push method
+func (m matrixConvertor) Push(p *api.PushPayload) (MatrixPayload, error) {
var commitDesc string
if p.TotalCommits == 1 {
@@ -149,13 +168,13 @@ func (m *MatrixPayload) Push(p *api.PushPayload) (api.Payloader, error) {
commitDesc = fmt.Sprintf("%d commits", p.TotalCommits)
}
- repoLink := MatrixLinkFormatter(p.Repo.HTMLURL, p.Repo.FullName)
+ repoLink := htmlLinkFormatter(p.Repo.HTMLURL, p.Repo.FullName)
branchLink := MatrixLinkToRef(p.Repo.HTMLURL, p.Ref)
text := fmt.Sprintf("[%s] %s pushed %s to %s:
", repoLink, p.Pusher.UserName, commitDesc, branchLink)
// for each commit, generate a new line text
for i, commit := range p.Commits {
- text += fmt.Sprintf("%s: %s - %s", MatrixLinkFormatter(commit.URL, commit.ID[:7]), commit.Message, commit.Author.Name)
+ text += fmt.Sprintf("%s: %s - %s", htmlLinkFormatter(commit.URL, commit.ID[:7]), commit.Message, commit.Author.Name)
// add linebreak to each commit but the last
if i < len(p.Commits)-1 {
text += "
"
@@ -163,41 +182,41 @@ func (m *MatrixPayload) Push(p *api.PushPayload) (api.Payloader, error) {
}
- return getMatrixPayload(text, p.Commits, m.MsgType), nil
+ return m.newPayload(text, p.Commits...)
}
-// PullRequest implements PayloadConvertor PullRequest method
-func (m *MatrixPayload) PullRequest(p *api.PullRequestPayload) (api.Payloader, error) {
- text, _, _, _ := getPullRequestPayloadInfo(p, MatrixLinkFormatter, true)
+// PullRequest implements payloadConvertor PullRequest method
+func (m matrixConvertor) PullRequest(p *api.PullRequestPayload) (MatrixPayload, error) {
+ text, _, _, _ := getPullRequestPayloadInfo(p, htmlLinkFormatter, true)
- return getMatrixPayload(text, nil, m.MsgType), nil
+ return m.newPayload(text)
}
-// Review implements PayloadConvertor Review method
-func (m *MatrixPayload) Review(p *api.PullRequestPayload, event webhook_module.HookEventType) (api.Payloader, error) {
- senderLink := MatrixLinkFormatter(setting.AppURL+url.PathEscape(p.Sender.UserName), p.Sender.UserName)
+// Review implements payloadConvertor Review method
+func (m matrixConvertor) Review(p *api.PullRequestPayload, event webhook_module.HookEventType) (MatrixPayload, error) {
+ senderLink := htmlLinkFormatter(setting.AppURL+url.PathEscape(p.Sender.UserName), p.Sender.UserName)
title := fmt.Sprintf("#%d %s", p.Index, p.PullRequest.Title)
- titleLink := MatrixLinkFormatter(p.PullRequest.HTMLURL, title)
- repoLink := MatrixLinkFormatter(p.Repository.HTMLURL, p.Repository.FullName)
+ titleLink := htmlLinkFormatter(p.PullRequest.HTMLURL, title)
+ repoLink := htmlLinkFormatter(p.Repository.HTMLURL, p.Repository.FullName)
var text string
switch p.Action {
case api.HookIssueReviewed:
action, err := parseHookPullRequestEventType(event)
if err != nil {
- return nil, err
+ return MatrixPayload{}, err
}
text = fmt.Sprintf("[%s] Pull request review %s: %s by %s", repoLink, action, titleLink, senderLink)
}
- return getMatrixPayload(text, nil, m.MsgType), nil
+ return m.newPayload(text)
}
-// Repository implements PayloadConvertor Repository method
-func (m *MatrixPayload) Repository(p *api.RepositoryPayload) (api.Payloader, error) {
- senderLink := MatrixLinkFormatter(setting.AppURL+p.Sender.UserName, p.Sender.UserName)
- repoLink := MatrixLinkFormatter(p.Repository.HTMLURL, p.Repository.FullName)
+// Repository implements payloadConvertor Repository method
+func (m matrixConvertor) Repository(p *api.RepositoryPayload) (MatrixPayload, error) {
+ senderLink := htmlLinkFormatter(setting.AppURL+p.Sender.UserName, p.Sender.UserName)
+ repoLink := htmlLinkFormatter(p.Repository.HTMLURL, p.Repository.FullName)
var text string
switch p.Action {
@@ -206,13 +225,12 @@ func (m *MatrixPayload) Repository(p *api.RepositoryPayload) (api.Payloader, err
case api.HookRepoDeleted:
text = fmt.Sprintf("[%s] Repository deleted by %s", repoLink, senderLink)
}
-
- return getMatrixPayload(text, nil, m.MsgType), nil
+ return m.newPayload(text)
}
-func (m *MatrixPayload) Package(p *api.PackagePayload) (api.Payloader, error) {
- senderLink := MatrixLinkFormatter(setting.AppURL+p.Sender.UserName, p.Sender.UserName)
- packageLink := MatrixLinkFormatter(p.Package.HTMLURL, p.Package.Name)
+func (m matrixConvertor) Package(p *api.PackagePayload) (MatrixPayload, error) {
+ senderLink := htmlLinkFormatter(setting.AppURL+p.Sender.UserName, p.Sender.UserName)
+ packageLink := htmlLinkFormatter(p.Package.HTMLURL, p.Package.Name)
var text string
switch p.Action {
@@ -222,31 +240,7 @@ func (m *MatrixPayload) Package(p *api.PackagePayload) (api.Payloader, error) {
text = fmt.Sprintf("[%s] Package deleted by %s", packageLink, senderLink)
}
- return getMatrixPayload(text, nil, m.MsgType), nil
-}
-
-// GetMatrixPayload converts a Matrix webhook into a MatrixPayload
-func GetMatrixPayload(p api.Payloader, event webhook_module.HookEventType, meta string) (api.Payloader, error) {
- s := new(MatrixPayload)
-
- matrix := &MatrixMeta{}
- if err := json.Unmarshal([]byte(meta), &matrix); err != nil {
- return s, errors.New("GetMatrixPayload meta json:" + err.Error())
- }
-
- s.MsgType = messageTypeText[matrix.MessageType]
-
- return convertPayloader(s, p, event)
-}
-
-func getMatrixPayload(text string, commits []*api.PayloadCommit, msgType string) *MatrixPayload {
- p := MatrixPayload{}
- p.FormattedBody = text
- p.Body = getMessageBody(text)
- p.Format = "org.matrix.custom.html"
- p.MsgType = msgType
- p.Commits = commits
- return &p
+ return m.newPayload(text)
}
var urlRegex = regexp.MustCompile(`]*?href="([^">]*?)">(.*?)`)
@@ -271,3 +265,16 @@ func getMatrixTxnID(payload []byte) (string, error) {
return hex.EncodeToString(h.Sum(nil)), nil
}
+
+// MatrixLinkToRef Matrix-formatter link to a repo ref
+func MatrixLinkToRef(repoURL, ref string) string {
+ refName := git.RefName(ref).ShortName()
+ switch {
+ case strings.HasPrefix(ref, git.BranchPrefix):
+ return htmlLinkFormatter(repoURL+"/src/branch/"+util.PathEscapeSegments(refName), refName)
+ case strings.HasPrefix(ref, git.TagPrefix):
+ return htmlLinkFormatter(repoURL+"/src/tag/"+util.PathEscapeSegments(refName), refName)
+ default:
+ return htmlLinkFormatter(repoURL+"/src/commit/"+util.PathEscapeSegments(refName), refName)
+ }
+}
diff --git a/services/webhook/matrix_test.go b/services/webhook/matrix_test.go
index 99a22fbd7e..058f8e3c5f 100644
--- a/services/webhook/matrix_test.go
+++ b/services/webhook/matrix_test.go
@@ -4,8 +4,11 @@
package webhook
import (
+ "context"
"testing"
+ webhook_model "code.gitea.io/gitea/models/webhook"
+ "code.gitea.io/gitea/modules/json"
api "code.gitea.io/gitea/modules/structs"
webhook_module "code.gitea.io/gitea/modules/webhook"
@@ -14,217 +17,213 @@ import (
)
func TestMatrixPayload(t *testing.T) {
+ mc := matrixConvertor{
+ MsgType: "m.text",
+ }
+
t.Run("Create", func(t *testing.T) {
p := createTestPayload()
- d := new(MatrixPayload)
- pl, err := d.Create(p)
+ pl, err := mc.Create(p)
require.NoError(t, err)
require.NotNil(t, pl)
- require.IsType(t, &MatrixPayload{}, pl)
- assert.Equal(t, "[[test/repo](http://localhost:3000/test/repo):[test](http://localhost:3000/test/repo/src/branch/test)] branch created by user1", pl.(*MatrixPayload).Body)
- assert.Equal(t, `[test/repo:test] branch created by user1`, pl.(*MatrixPayload).FormattedBody)
+ assert.Equal(t, "[[test/repo](http://localhost:3000/test/repo):[test](http://localhost:3000/test/repo/src/branch/test)] branch created by user1", pl.Body)
+ assert.Equal(t, `[test/repo:test] branch created by user1`, pl.FormattedBody)
})
t.Run("Delete", func(t *testing.T) {
p := deleteTestPayload()
- d := new(MatrixPayload)
- pl, err := d.Delete(p)
+ pl, err := mc.Delete(p)
require.NoError(t, err)
require.NotNil(t, pl)
- require.IsType(t, &MatrixPayload{}, pl)
- assert.Equal(t, "[[test/repo](http://localhost:3000/test/repo):test] branch deleted by user1", pl.(*MatrixPayload).Body)
- assert.Equal(t, `[test/repo:test] branch deleted by user1`, pl.(*MatrixPayload).FormattedBody)
+ assert.Equal(t, "[[test/repo](http://localhost:3000/test/repo):test] branch deleted by user1", pl.Body)
+ assert.Equal(t, `[test/repo:test] branch deleted by user1`, pl.FormattedBody)
})
t.Run("Fork", func(t *testing.T) {
p := forkTestPayload()
- d := new(MatrixPayload)
- pl, err := d.Fork(p)
+ pl, err := mc.Fork(p)
require.NoError(t, err)
require.NotNil(t, pl)
- require.IsType(t, &MatrixPayload{}, pl)
- assert.Equal(t, "[test/repo2](http://localhost:3000/test/repo2) is forked to [test/repo](http://localhost:3000/test/repo)", pl.(*MatrixPayload).Body)
- assert.Equal(t, `test/repo2 is forked to test/repo`, pl.(*MatrixPayload).FormattedBody)
+ assert.Equal(t, "[test/repo2](http://localhost:3000/test/repo2) is forked to [test/repo](http://localhost:3000/test/repo)", pl.Body)
+ assert.Equal(t, `test/repo2 is forked to test/repo`, pl.FormattedBody)
})
t.Run("Push", func(t *testing.T) {
p := pushTestPayload()
- d := new(MatrixPayload)
- pl, err := d.Push(p)
+ pl, err := mc.Push(p)
require.NoError(t, err)
require.NotNil(t, pl)
- require.IsType(t, &MatrixPayload{}, pl)
- assert.Equal(t, "[[test/repo](http://localhost:3000/test/repo)] user1 pushed 2 commits to [test](http://localhost:3000/test/repo/src/branch/test):\n[2020558](http://localhost:3000/test/repo/commit/2020558fe2e34debb818a514715839cabd25e778): commit message - user1\n[2020558](http://localhost:3000/test/repo/commit/2020558fe2e34debb818a514715839cabd25e778): commit message - user1", pl.(*MatrixPayload).Body)
- assert.Equal(t, `[test/repo] user1 pushed 2 commits to test:
2020558: commit message - user1
2020558: commit message - user1`, pl.(*MatrixPayload).FormattedBody)
+ assert.Equal(t, "[[test/repo](http://localhost:3000/test/repo)] user1 pushed 2 commits to [test](http://localhost:3000/test/repo/src/branch/test):\n[2020558](http://localhost:3000/test/repo/commit/2020558fe2e34debb818a514715839cabd25e778): commit message - user1\n[2020558](http://localhost:3000/test/repo/commit/2020558fe2e34debb818a514715839cabd25e778): commit message - user1", pl.Body)
+ assert.Equal(t, `[test/repo] user1 pushed 2 commits to test:
2020558: commit message - user1
2020558: commit message - user1`, pl.FormattedBody)
})
t.Run("Issue", func(t *testing.T) {
p := issueTestPayload()
- d := new(MatrixPayload)
p.Action = api.HookIssueOpened
- pl, err := d.Issue(p)
+ pl, err := mc.Issue(p)
require.NoError(t, err)
require.NotNil(t, pl)
- require.IsType(t, &MatrixPayload{}, pl)
- assert.Equal(t, "[[test/repo](http://localhost:3000/test/repo)] Issue opened: [#2 crash](http://localhost:3000/test/repo/issues/2) by [user1](https://try.gitea.io/user1)", pl.(*MatrixPayload).Body)
- assert.Equal(t, `[test/repo] Issue opened: #2 crash by user1`, pl.(*MatrixPayload).FormattedBody)
+ assert.Equal(t, "[[test/repo](http://localhost:3000/test/repo)] Issue opened: [#2 crash](http://localhost:3000/test/repo/issues/2) by [user1](https://try.gitea.io/user1)", pl.Body)
+ assert.Equal(t, `[test/repo] Issue opened: #2 crash by user1`, pl.FormattedBody)
p.Action = api.HookIssueClosed
- pl, err = d.Issue(p)
+ pl, err = mc.Issue(p)
require.NoError(t, err)
require.NotNil(t, pl)
- require.IsType(t, &MatrixPayload{}, pl)
- assert.Equal(t, "[[test/repo](http://localhost:3000/test/repo)] Issue closed: [#2 crash](http://localhost:3000/test/repo/issues/2) by [user1](https://try.gitea.io/user1)", pl.(*MatrixPayload).Body)
- assert.Equal(t, `[test/repo] Issue closed: #2 crash by user1`, pl.(*MatrixPayload).FormattedBody)
+ assert.Equal(t, "[[test/repo](http://localhost:3000/test/repo)] Issue closed: [#2 crash](http://localhost:3000/test/repo/issues/2) by [user1](https://try.gitea.io/user1)", pl.Body)
+ assert.Equal(t, `[test/repo] Issue closed: #2 crash by user1`, pl.FormattedBody)
})
t.Run("IssueComment", func(t *testing.T) {
p := issueCommentTestPayload()
- d := new(MatrixPayload)
- pl, err := d.IssueComment(p)
+ pl, err := mc.IssueComment(p)
require.NoError(t, err)
require.NotNil(t, pl)
- require.IsType(t, &MatrixPayload{}, pl)
- assert.Equal(t, "[[test/repo](http://localhost:3000/test/repo)] New comment on issue [#2 crash](http://localhost:3000/test/repo/issues/2) by [user1](https://try.gitea.io/user1)", pl.(*MatrixPayload).Body)
- assert.Equal(t, `[test/repo] New comment on issue #2 crash by user1`, pl.(*MatrixPayload).FormattedBody)
+ assert.Equal(t, "[[test/repo](http://localhost:3000/test/repo)] New comment on issue [#2 crash](http://localhost:3000/test/repo/issues/2) by [user1](https://try.gitea.io/user1)", pl.Body)
+ assert.Equal(t, `[test/repo] New comment on issue #2 crash by user1`, pl.FormattedBody)
})
t.Run("PullRequest", func(t *testing.T) {
p := pullRequestTestPayload()
- d := new(MatrixPayload)
- pl, err := d.PullRequest(p)
+ pl, err := mc.PullRequest(p)
require.NoError(t, err)
require.NotNil(t, pl)
- require.IsType(t, &MatrixPayload{}, pl)
- assert.Equal(t, "[[test/repo](http://localhost:3000/test/repo)] Pull request opened: [#12 Fix bug](http://localhost:3000/test/repo/pulls/12) by [user1](https://try.gitea.io/user1)", pl.(*MatrixPayload).Body)
- assert.Equal(t, `[test/repo] Pull request opened: #12 Fix bug by user1`, pl.(*MatrixPayload).FormattedBody)
+ assert.Equal(t, "[[test/repo](http://localhost:3000/test/repo)] Pull request opened: [#12 Fix bug](http://localhost:3000/test/repo/pulls/12) by [user1](https://try.gitea.io/user1)", pl.Body)
+ assert.Equal(t, `[test/repo] Pull request opened: #12 Fix bug by user1`, pl.FormattedBody)
})
t.Run("PullRequestComment", func(t *testing.T) {
p := pullRequestCommentTestPayload()
- d := new(MatrixPayload)
- pl, err := d.IssueComment(p)
+ pl, err := mc.IssueComment(p)
require.NoError(t, err)
require.NotNil(t, pl)
- require.IsType(t, &MatrixPayload{}, pl)
- assert.Equal(t, "[[test/repo](http://localhost:3000/test/repo)] New comment on pull request [#12 Fix bug](http://localhost:3000/test/repo/pulls/12) by [user1](https://try.gitea.io/user1)", pl.(*MatrixPayload).Body)
- assert.Equal(t, `[test/repo] New comment on pull request #12 Fix bug by user1`, pl.(*MatrixPayload).FormattedBody)
+ assert.Equal(t, "[[test/repo](http://localhost:3000/test/repo)] New comment on pull request [#12 Fix bug](http://localhost:3000/test/repo/pulls/12) by [user1](https://try.gitea.io/user1)", pl.Body)
+ assert.Equal(t, `[test/repo] New comment on pull request #12 Fix bug by user1`, pl.FormattedBody)
})
t.Run("Review", func(t *testing.T) {
p := pullRequestTestPayload()
p.Action = api.HookIssueReviewed
- d := new(MatrixPayload)
- pl, err := d.Review(p, webhook_module.HookEventPullRequestReviewApproved)
+ pl, err := mc.Review(p, webhook_module.HookEventPullRequestReviewApproved)
require.NoError(t, err)
require.NotNil(t, pl)
- require.IsType(t, &MatrixPayload{}, pl)
- assert.Equal(t, "[[test/repo](http://localhost:3000/test/repo)] Pull request review approved: [#12 Fix bug](http://localhost:3000/test/repo/pulls/12) by [user1](https://try.gitea.io/user1)", pl.(*MatrixPayload).Body)
- assert.Equal(t, `[test/repo] Pull request review approved: #12 Fix bug by user1`, pl.(*MatrixPayload).FormattedBody)
+ assert.Equal(t, "[[test/repo](http://localhost:3000/test/repo)] Pull request review approved: [#12 Fix bug](http://localhost:3000/test/repo/pulls/12) by [user1](https://try.gitea.io/user1)", pl.Body)
+ assert.Equal(t, `[test/repo] Pull request review approved: #12 Fix bug by user1`, pl.FormattedBody)
})
t.Run("Repository", func(t *testing.T) {
p := repositoryTestPayload()
- d := new(MatrixPayload)
- pl, err := d.Repository(p)
+ pl, err := mc.Repository(p)
require.NoError(t, err)
require.NotNil(t, pl)
- require.IsType(t, &MatrixPayload{}, pl)
- assert.Equal(t, `[[test/repo](http://localhost:3000/test/repo)] Repository created by [user1](https://try.gitea.io/user1)`, pl.(*MatrixPayload).Body)
- assert.Equal(t, `[test/repo] Repository created by user1`, pl.(*MatrixPayload).FormattedBody)
+ assert.Equal(t, `[[test/repo](http://localhost:3000/test/repo)] Repository created by [user1](https://try.gitea.io/user1)`, pl.Body)
+ assert.Equal(t, `[test/repo] Repository created by user1`, pl.FormattedBody)
})
t.Run("Package", func(t *testing.T) {
p := packageTestPayload()
- d := new(MatrixPayload)
- pl, err := d.Package(p)
+ pl, err := mc.Package(p)
require.NoError(t, err)
require.NotNil(t, pl)
- require.IsType(t, &MatrixPayload{}, pl)
- assert.Equal(t, `[[GiteaContainer](http://localhost:3000/user1/-/packages/container/GiteaContainer/latest)] Package published by [user1](https://try.gitea.io/user1)`, pl.(*MatrixPayload).Body)
- assert.Equal(t, `[GiteaContainer] Package published by user1`, pl.(*MatrixPayload).FormattedBody)
+ assert.Equal(t, `[[GiteaContainer](http://localhost:3000/user1/-/packages/container/GiteaContainer/latest)] Package published by [user1](https://try.gitea.io/user1)`, pl.Body)
+ assert.Equal(t, `[GiteaContainer] Package published by user1`, pl.FormattedBody)
})
t.Run("Wiki", func(t *testing.T) {
p := wikiTestPayload()
- d := new(MatrixPayload)
p.Action = api.HookWikiCreated
- pl, err := d.Wiki(p)
+ pl, err := mc.Wiki(p)
require.NoError(t, err)
require.NotNil(t, pl)
- require.IsType(t, &MatrixPayload{}, pl)
- assert.Equal(t, "[[test/repo](http://localhost:3000/test/repo)] New wiki page '[index](http://localhost:3000/test/repo/wiki/index)' (Wiki change comment) by [user1](https://try.gitea.io/user1)", pl.(*MatrixPayload).Body)
- assert.Equal(t, `[test/repo] New wiki page 'index' (Wiki change comment) by user1`, pl.(*MatrixPayload).FormattedBody)
+ assert.Equal(t, "[[test/repo](http://localhost:3000/test/repo)] New wiki page '[index](http://localhost:3000/test/repo/wiki/index)' (Wiki change comment) by [user1](https://try.gitea.io/user1)", pl.Body)
+ assert.Equal(t, `[test/repo] New wiki page 'index' (Wiki change comment) by user1`, pl.FormattedBody)
p.Action = api.HookWikiEdited
- pl, err = d.Wiki(p)
+ pl, err = mc.Wiki(p)
require.NoError(t, err)
require.NotNil(t, pl)
- require.IsType(t, &MatrixPayload{}, pl)
- assert.Equal(t, "[[test/repo](http://localhost:3000/test/repo)] Wiki page '[index](http://localhost:3000/test/repo/wiki/index)' edited (Wiki change comment) by [user1](https://try.gitea.io/user1)", pl.(*MatrixPayload).Body)
- assert.Equal(t, `[test/repo] Wiki page 'index' edited (Wiki change comment) by user1`, pl.(*MatrixPayload).FormattedBody)
+ assert.Equal(t, "[[test/repo](http://localhost:3000/test/repo)] Wiki page '[index](http://localhost:3000/test/repo/wiki/index)' edited (Wiki change comment) by [user1](https://try.gitea.io/user1)", pl.Body)
+ assert.Equal(t, `[test/repo] Wiki page 'index' edited (Wiki change comment) by user1`, pl.FormattedBody)
p.Action = api.HookWikiDeleted
- pl, err = d.Wiki(p)
+ pl, err = mc.Wiki(p)
require.NoError(t, err)
require.NotNil(t, pl)
- require.IsType(t, &MatrixPayload{}, pl)
- assert.Equal(t, "[[test/repo](http://localhost:3000/test/repo)] Wiki page '[index](http://localhost:3000/test/repo/wiki/index)' deleted by [user1](https://try.gitea.io/user1)", pl.(*MatrixPayload).Body)
- assert.Equal(t, `[test/repo] Wiki page 'index' deleted by user1`, pl.(*MatrixPayload).FormattedBody)
+ assert.Equal(t, "[[test/repo](http://localhost:3000/test/repo)] Wiki page '[index](http://localhost:3000/test/repo/wiki/index)' deleted by [user1](https://try.gitea.io/user1)", pl.Body)
+ assert.Equal(t, `[test/repo] Wiki page 'index' deleted by user1`, pl.FormattedBody)
})
t.Run("Release", func(t *testing.T) {
p := pullReleaseTestPayload()
- d := new(MatrixPayload)
- pl, err := d.Release(p)
+ pl, err := mc.Release(p)
require.NoError(t, err)
require.NotNil(t, pl)
- require.IsType(t, &MatrixPayload{}, pl)
- assert.Equal(t, "[[test/repo](http://localhost:3000/test/repo)] Release created: [v1.0](http://localhost:3000/test/repo/releases/tag/v1.0) by [user1](https://try.gitea.io/user1)", pl.(*MatrixPayload).Body)
- assert.Equal(t, `[test/repo] Release created: v1.0 by user1`, pl.(*MatrixPayload).FormattedBody)
+ assert.Equal(t, "[[test/repo](http://localhost:3000/test/repo)] Release created: [v1.0](http://localhost:3000/test/repo/releases/tag/v1.0) by [user1](https://try.gitea.io/user1)", pl.Body)
+ assert.Equal(t, `[test/repo] Release created: v1.0 by user1`, pl.FormattedBody)
})
}
func TestMatrixJSONPayload(t *testing.T) {
p := pushTestPayload()
-
- pl, err := new(MatrixPayload).Push(p)
+ data, err := p.JSONPayload()
require.NoError(t, err)
- require.NotNil(t, pl)
- require.IsType(t, &MatrixPayload{}, pl)
- json, err := pl.JSONPayload()
+ hook := &webhook_model.Webhook{
+ RepoID: 3,
+ IsActive: true,
+ Type: webhook_module.MATRIX,
+ URL: "https://matrix.example.com/_matrix/client/r0/rooms/ROOM_ID/send/m.room.message",
+ Meta: `{"message_type":0}`, // text
+ }
+ task := &webhook_model.HookTask{
+ HookID: hook.ID,
+ EventType: webhook_module.HookEventPush,
+ PayloadContent: string(data),
+ PayloadVersion: 2,
+ }
+
+ req, reqBody, err := newMatrixRequest(context.Background(), hook, task)
+ require.NotNil(t, req)
+ require.NotNil(t, reqBody)
require.NoError(t, err)
- assert.NotEmpty(t, json)
+
+ assert.Equal(t, "PUT", req.Method)
+ assert.Equal(t, "/_matrix/client/r0/rooms/ROOM_ID/send/m.room.message/6db5dc1e282529a8c162c7fe93dd2667494eeb51", req.URL.Path)
+ assert.Equal(t, "sha256=", req.Header.Get("X-Hub-Signature-256"))
+ assert.Equal(t, "application/json", req.Header.Get("Content-Type"))
+ var body MatrixPayload
+ err = json.NewDecoder(req.Body).Decode(&body)
+ assert.NoError(t, err)
+ assert.Equal(t, "[[test/repo](http://localhost:3000/test/repo)] user1 pushed 2 commits to [test](http://localhost:3000/test/repo/src/branch/test):\n[2020558](http://localhost:3000/test/repo/commit/2020558fe2e34debb818a514715839cabd25e778): commit message - user1\n[2020558](http://localhost:3000/test/repo/commit/2020558fe2e34debb818a514715839cabd25e778): commit message - user1", body.Body)
}
func Test_getTxnID(t *testing.T) {
diff --git a/services/webhook/msteams.go b/services/webhook/msteams.go
index 37810b4cd3..99d0106184 100644
--- a/services/webhook/msteams.go
+++ b/services/webhook/msteams.go
@@ -4,12 +4,14 @@
package webhook
import (
+ "context"
"fmt"
+ "net/http"
"net/url"
"strings"
+ webhook_model "code.gitea.io/gitea/models/webhook"
"code.gitea.io/gitea/modules/git"
- "code.gitea.io/gitea/modules/json"
api "code.gitea.io/gitea/modules/structs"
"code.gitea.io/gitea/modules/util"
webhook_module "code.gitea.io/gitea/modules/webhook"
@@ -56,19 +58,8 @@ type (
}
)
-// JSONPayload Marshals the MSTeamsPayload to json
-func (m *MSTeamsPayload) JSONPayload() ([]byte, error) {
- data, err := json.MarshalIndent(m, "", " ")
- if err != nil {
- return []byte{}, err
- }
- return data, nil
-}
-
-var _ PayloadConvertor = &MSTeamsPayload{}
-
// Create implements PayloadConvertor Create method
-func (m *MSTeamsPayload) Create(p *api.CreatePayload) (api.Payloader, error) {
+func (m msteamsConvertor) Create(p *api.CreatePayload) (MSTeamsPayload, error) {
// created tag/branch
refName := git.RefName(p.Ref).ShortName()
title := fmt.Sprintf("[%s] %s %s created", p.Repo.FullName, p.RefType, refName)
@@ -85,7 +76,7 @@ func (m *MSTeamsPayload) Create(p *api.CreatePayload) (api.Payloader, error) {
}
// Delete implements PayloadConvertor Delete method
-func (m *MSTeamsPayload) Delete(p *api.DeletePayload) (api.Payloader, error) {
+func (m msteamsConvertor) Delete(p *api.DeletePayload) (MSTeamsPayload, error) {
// deleted tag/branch
refName := git.RefName(p.Ref).ShortName()
title := fmt.Sprintf("[%s] %s %s deleted", p.Repo.FullName, p.RefType, refName)
@@ -102,7 +93,7 @@ func (m *MSTeamsPayload) Delete(p *api.DeletePayload) (api.Payloader, error) {
}
// Fork implements PayloadConvertor Fork method
-func (m *MSTeamsPayload) Fork(p *api.ForkPayload) (api.Payloader, error) {
+func (m msteamsConvertor) Fork(p *api.ForkPayload) (MSTeamsPayload, error) {
title := fmt.Sprintf("%s is forked to %s", p.Forkee.FullName, p.Repo.FullName)
return createMSTeamsPayload(
@@ -117,7 +108,7 @@ func (m *MSTeamsPayload) Fork(p *api.ForkPayload) (api.Payloader, error) {
}
// Push implements PayloadConvertor Push method
-func (m *MSTeamsPayload) Push(p *api.PushPayload) (api.Payloader, error) {
+func (m msteamsConvertor) Push(p *api.PushPayload) (MSTeamsPayload, error) {
var (
branchName = git.RefName(p.Ref).ShortName()
commitDesc string
@@ -160,7 +151,7 @@ func (m *MSTeamsPayload) Push(p *api.PushPayload) (api.Payloader, error) {
}
// Issue implements PayloadConvertor Issue method
-func (m *MSTeamsPayload) Issue(p *api.IssuePayload) (api.Payloader, error) {
+func (m msteamsConvertor) Issue(p *api.IssuePayload) (MSTeamsPayload, error) {
title, _, attachmentText, color := getIssuesPayloadInfo(p, noneLinkFormatter, false)
return createMSTeamsPayload(
@@ -175,7 +166,7 @@ func (m *MSTeamsPayload) Issue(p *api.IssuePayload) (api.Payloader, error) {
}
// IssueComment implements PayloadConvertor IssueComment method
-func (m *MSTeamsPayload) IssueComment(p *api.IssueCommentPayload) (api.Payloader, error) {
+func (m msteamsConvertor) IssueComment(p *api.IssueCommentPayload) (MSTeamsPayload, error) {
title, _, color := getIssueCommentPayloadInfo(p, noneLinkFormatter, false)
return createMSTeamsPayload(
@@ -190,7 +181,7 @@ func (m *MSTeamsPayload) IssueComment(p *api.IssueCommentPayload) (api.Payloader
}
// PullRequest implements PayloadConvertor PullRequest method
-func (m *MSTeamsPayload) PullRequest(p *api.PullRequestPayload) (api.Payloader, error) {
+func (m msteamsConvertor) PullRequest(p *api.PullRequestPayload) (MSTeamsPayload, error) {
title, _, attachmentText, color := getPullRequestPayloadInfo(p, noneLinkFormatter, false)
return createMSTeamsPayload(
@@ -205,14 +196,14 @@ func (m *MSTeamsPayload) PullRequest(p *api.PullRequestPayload) (api.Payloader,
}
// Review implements PayloadConvertor Review method
-func (m *MSTeamsPayload) Review(p *api.PullRequestPayload, event webhook_module.HookEventType) (api.Payloader, error) {
+func (m msteamsConvertor) Review(p *api.PullRequestPayload, event webhook_module.HookEventType) (MSTeamsPayload, error) {
var text, title string
var color int
switch p.Action {
case api.HookIssueReviewed:
action, err := parseHookPullRequestEventType(event)
if err != nil {
- return nil, err
+ return MSTeamsPayload{}, err
}
title = fmt.Sprintf("[%s] Pull request review %s: #%d %s", p.Repository.FullName, action, p.Index, p.PullRequest.Title)
@@ -242,7 +233,7 @@ func (m *MSTeamsPayload) Review(p *api.PullRequestPayload, event webhook_module.
}
// Repository implements PayloadConvertor Repository method
-func (m *MSTeamsPayload) Repository(p *api.RepositoryPayload) (api.Payloader, error) {
+func (m msteamsConvertor) Repository(p *api.RepositoryPayload) (MSTeamsPayload, error) {
var title, url string
var color int
switch p.Action {
@@ -267,7 +258,7 @@ func (m *MSTeamsPayload) Repository(p *api.RepositoryPayload) (api.Payloader, er
}
// Wiki implements PayloadConvertor Wiki method
-func (m *MSTeamsPayload) Wiki(p *api.WikiPayload) (api.Payloader, error) {
+func (m msteamsConvertor) Wiki(p *api.WikiPayload) (MSTeamsPayload, error) {
title, color, _ := getWikiPayloadInfo(p, noneLinkFormatter, false)
return createMSTeamsPayload(
@@ -282,7 +273,7 @@ func (m *MSTeamsPayload) Wiki(p *api.WikiPayload) (api.Payloader, error) {
}
// Release implements PayloadConvertor Release method
-func (m *MSTeamsPayload) Release(p *api.ReleasePayload) (api.Payloader, error) {
+func (m msteamsConvertor) Release(p *api.ReleasePayload) (MSTeamsPayload, error) {
title, color := getReleasePayloadInfo(p, noneLinkFormatter, false)
return createMSTeamsPayload(
@@ -296,7 +287,7 @@ func (m *MSTeamsPayload) Release(p *api.ReleasePayload) (api.Payloader, error) {
), nil
}
-func (m *MSTeamsPayload) Package(p *api.PackagePayload) (api.Payloader, error) {
+func (m msteamsConvertor) Package(p *api.PackagePayload) (MSTeamsPayload, error) {
title, color := getPackagePayloadInfo(p, noneLinkFormatter, false)
return createMSTeamsPayload(
@@ -310,12 +301,7 @@ func (m *MSTeamsPayload) Package(p *api.PackagePayload) (api.Payloader, error) {
), nil
}
-// GetMSTeamsPayload converts a MSTeams webhook into a MSTeamsPayload
-func GetMSTeamsPayload(p api.Payloader, event webhook_module.HookEventType, _ string) (api.Payloader, error) {
- return convertPayloader(new(MSTeamsPayload), p, event)
-}
-
-func createMSTeamsPayload(r *api.Repository, s *api.User, title, text, actionTarget string, color int, fact *MSTeamsFact) *MSTeamsPayload {
+func createMSTeamsPayload(r *api.Repository, s *api.User, title, text, actionTarget string, color int, fact *MSTeamsFact) MSTeamsPayload {
facts := make([]MSTeamsFact, 0, 2)
if r != nil {
facts = append(facts, MSTeamsFact{
@@ -327,7 +313,7 @@ func createMSTeamsPayload(r *api.Repository, s *api.User, title, text, actionTar
facts = append(facts, *fact)
}
- return &MSTeamsPayload{
+ return MSTeamsPayload{
Type: "MessageCard",
Context: "https://schema.org/extensions",
ThemeColor: fmt.Sprintf("%x", color),
@@ -356,3 +342,11 @@ func createMSTeamsPayload(r *api.Repository, s *api.User, title, text, actionTar
},
}
}
+
+type msteamsConvertor struct{}
+
+var _ payloadConvertor[MSTeamsPayload] = msteamsConvertor{}
+
+func newMSTeamsRequest(ctx context.Context, w *webhook_model.Webhook, t *webhook_model.HookTask) (*http.Request, []byte, error) {
+ return newJSONRequest(msteamsConvertor{}, w, t, true)
+}
diff --git a/services/webhook/msteams_test.go b/services/webhook/msteams_test.go
index 8d1aed6040..01e08b918e 100644
--- a/services/webhook/msteams_test.go
+++ b/services/webhook/msteams_test.go
@@ -4,8 +4,11 @@
package webhook
import (
+ "context"
"testing"
+ webhook_model "code.gitea.io/gitea/models/webhook"
+ "code.gitea.io/gitea/modules/json"
api "code.gitea.io/gitea/modules/structs"
webhook_module "code.gitea.io/gitea/modules/webhook"
@@ -14,22 +17,20 @@ import (
)
func TestMSTeamsPayload(t *testing.T) {
+ mc := msteamsConvertor{}
t.Run("Create", func(t *testing.T) {
p := createTestPayload()
- d := new(MSTeamsPayload)
- pl, err := d.Create(p)
+ pl, err := mc.Create(p)
require.NoError(t, err)
- require.NotNil(t, pl)
- require.IsType(t, &MSTeamsPayload{}, pl)
- assert.Equal(t, "[test/repo] branch test created", pl.(*MSTeamsPayload).Title)
- assert.Equal(t, "[test/repo] branch test created", pl.(*MSTeamsPayload).Summary)
- assert.Len(t, pl.(*MSTeamsPayload).Sections, 1)
- assert.Equal(t, "user1", pl.(*MSTeamsPayload).Sections[0].ActivitySubtitle)
- assert.Empty(t, pl.(*MSTeamsPayload).Sections[0].Text)
- assert.Len(t, pl.(*MSTeamsPayload).Sections[0].Facts, 2)
- for _, fact := range pl.(*MSTeamsPayload).Sections[0].Facts {
+ assert.Equal(t, "[test/repo] branch test created", pl.Title)
+ assert.Equal(t, "[test/repo] branch test created", pl.Summary)
+ assert.Len(t, pl.Sections, 1)
+ assert.Equal(t, "user1", pl.Sections[0].ActivitySubtitle)
+ assert.Empty(t, pl.Sections[0].Text)
+ assert.Len(t, pl.Sections[0].Facts, 2)
+ for _, fact := range pl.Sections[0].Facts {
if fact.Name == "Repository:" {
assert.Equal(t, p.Repo.FullName, fact.Value)
} else if fact.Name == "branch:" {
@@ -38,27 +39,24 @@ func TestMSTeamsPayload(t *testing.T) {
t.Fail()
}
}
- assert.Len(t, pl.(*MSTeamsPayload).PotentialAction, 1)
- assert.Len(t, pl.(*MSTeamsPayload).PotentialAction[0].Targets, 1)
- assert.Equal(t, "http://localhost:3000/test/repo/src/test", pl.(*MSTeamsPayload).PotentialAction[0].Targets[0].URI)
+ assert.Len(t, pl.PotentialAction, 1)
+ assert.Len(t, pl.PotentialAction[0].Targets, 1)
+ assert.Equal(t, "http://localhost:3000/test/repo/src/test", pl.PotentialAction[0].Targets[0].URI)
})
t.Run("Delete", func(t *testing.T) {
p := deleteTestPayload()
- d := new(MSTeamsPayload)
- pl, err := d.Delete(p)
+ pl, err := mc.Delete(p)
require.NoError(t, err)
- require.NotNil(t, pl)
- require.IsType(t, &MSTeamsPayload{}, pl)
- assert.Equal(t, "[test/repo] branch test deleted", pl.(*MSTeamsPayload).Title)
- assert.Equal(t, "[test/repo] branch test deleted", pl.(*MSTeamsPayload).Summary)
- assert.Len(t, pl.(*MSTeamsPayload).Sections, 1)
- assert.Equal(t, "user1", pl.(*MSTeamsPayload).Sections[0].ActivitySubtitle)
- assert.Empty(t, pl.(*MSTeamsPayload).Sections[0].Text)
- assert.Len(t, pl.(*MSTeamsPayload).Sections[0].Facts, 2)
- for _, fact := range pl.(*MSTeamsPayload).Sections[0].Facts {
+ assert.Equal(t, "[test/repo] branch test deleted", pl.Title)
+ assert.Equal(t, "[test/repo] branch test deleted", pl.Summary)
+ assert.Len(t, pl.Sections, 1)
+ assert.Equal(t, "user1", pl.Sections[0].ActivitySubtitle)
+ assert.Empty(t, pl.Sections[0].Text)
+ assert.Len(t, pl.Sections[0].Facts, 2)
+ for _, fact := range pl.Sections[0].Facts {
if fact.Name == "Repository:" {
assert.Equal(t, p.Repo.FullName, fact.Value)
} else if fact.Name == "branch:" {
@@ -67,27 +65,24 @@ func TestMSTeamsPayload(t *testing.T) {
t.Fail()
}
}
- assert.Len(t, pl.(*MSTeamsPayload).PotentialAction, 1)
- assert.Len(t, pl.(*MSTeamsPayload).PotentialAction[0].Targets, 1)
- assert.Equal(t, "http://localhost:3000/test/repo/src/test", pl.(*MSTeamsPayload).PotentialAction[0].Targets[0].URI)
+ assert.Len(t, pl.PotentialAction, 1)
+ assert.Len(t, pl.PotentialAction[0].Targets, 1)
+ assert.Equal(t, "http://localhost:3000/test/repo/src/test", pl.PotentialAction[0].Targets[0].URI)
})
t.Run("Fork", func(t *testing.T) {
p := forkTestPayload()
- d := new(MSTeamsPayload)
- pl, err := d.Fork(p)
+ pl, err := mc.Fork(p)
require.NoError(t, err)
- require.NotNil(t, pl)
- require.IsType(t, &MSTeamsPayload{}, pl)
- assert.Equal(t, "test/repo2 is forked to test/repo", pl.(*MSTeamsPayload).Title)
- assert.Equal(t, "test/repo2 is forked to test/repo", pl.(*MSTeamsPayload).Summary)
- assert.Len(t, pl.(*MSTeamsPayload).Sections, 1)
- assert.Equal(t, "user1", pl.(*MSTeamsPayload).Sections[0].ActivitySubtitle)
- assert.Empty(t, pl.(*MSTeamsPayload).Sections[0].Text)
- assert.Len(t, pl.(*MSTeamsPayload).Sections[0].Facts, 2)
- for _, fact := range pl.(*MSTeamsPayload).Sections[0].Facts {
+ assert.Equal(t, "test/repo2 is forked to test/repo", pl.Title)
+ assert.Equal(t, "test/repo2 is forked to test/repo", pl.Summary)
+ assert.Len(t, pl.Sections, 1)
+ assert.Equal(t, "user1", pl.Sections[0].ActivitySubtitle)
+ assert.Empty(t, pl.Sections[0].Text)
+ assert.Len(t, pl.Sections[0].Facts, 2)
+ for _, fact := range pl.Sections[0].Facts {
if fact.Name == "Repository:" {
assert.Equal(t, p.Repo.FullName, fact.Value)
} else if fact.Name == "Forkee:" {
@@ -96,27 +91,24 @@ func TestMSTeamsPayload(t *testing.T) {
t.Fail()
}
}
- assert.Len(t, pl.(*MSTeamsPayload).PotentialAction, 1)
- assert.Len(t, pl.(*MSTeamsPayload).PotentialAction[0].Targets, 1)
- assert.Equal(t, "http://localhost:3000/test/repo", pl.(*MSTeamsPayload).PotentialAction[0].Targets[0].URI)
+ assert.Len(t, pl.PotentialAction, 1)
+ assert.Len(t, pl.PotentialAction[0].Targets, 1)
+ assert.Equal(t, "http://localhost:3000/test/repo", pl.PotentialAction[0].Targets[0].URI)
})
t.Run("Push", func(t *testing.T) {
p := pushTestPayload()
- d := new(MSTeamsPayload)
- pl, err := d.Push(p)
+ pl, err := mc.Push(p)
require.NoError(t, err)
- require.NotNil(t, pl)
- require.IsType(t, &MSTeamsPayload{}, pl)
- assert.Equal(t, "[test/repo:test] 2 new commits", pl.(*MSTeamsPayload).Title)
- assert.Equal(t, "[test/repo:test] 2 new commits", pl.(*MSTeamsPayload).Summary)
- assert.Len(t, pl.(*MSTeamsPayload).Sections, 1)
- assert.Equal(t, "user1", pl.(*MSTeamsPayload).Sections[0].ActivitySubtitle)
- assert.Equal(t, "[2020558](http://localhost:3000/test/repo/commit/2020558fe2e34debb818a514715839cabd25e778) commit message - user1\n\n[2020558](http://localhost:3000/test/repo/commit/2020558fe2e34debb818a514715839cabd25e778) commit message - user1", pl.(*MSTeamsPayload).Sections[0].Text)
- assert.Len(t, pl.(*MSTeamsPayload).Sections[0].Facts, 2)
- for _, fact := range pl.(*MSTeamsPayload).Sections[0].Facts {
+ assert.Equal(t, "[test/repo:test] 2 new commits", pl.Title)
+ assert.Equal(t, "[test/repo:test] 2 new commits", pl.Summary)
+ assert.Len(t, pl.Sections, 1)
+ assert.Equal(t, "user1", pl.Sections[0].ActivitySubtitle)
+ assert.Equal(t, "[2020558](http://localhost:3000/test/repo/commit/2020558fe2e34debb818a514715839cabd25e778) commit message - user1\n\n[2020558](http://localhost:3000/test/repo/commit/2020558fe2e34debb818a514715839cabd25e778) commit message - user1", pl.Sections[0].Text)
+ assert.Len(t, pl.Sections[0].Facts, 2)
+ for _, fact := range pl.Sections[0].Facts {
if fact.Name == "Repository:" {
assert.Equal(t, p.Repo.FullName, fact.Value)
} else if fact.Name == "Commit count:" {
@@ -125,28 +117,25 @@ func TestMSTeamsPayload(t *testing.T) {
t.Fail()
}
}
- assert.Len(t, pl.(*MSTeamsPayload).PotentialAction, 1)
- assert.Len(t, pl.(*MSTeamsPayload).PotentialAction[0].Targets, 1)
- assert.Equal(t, "http://localhost:3000/test/repo/src/test", pl.(*MSTeamsPayload).PotentialAction[0].Targets[0].URI)
+ assert.Len(t, pl.PotentialAction, 1)
+ assert.Len(t, pl.PotentialAction[0].Targets, 1)
+ assert.Equal(t, "http://localhost:3000/test/repo/src/test", pl.PotentialAction[0].Targets[0].URI)
})
t.Run("Issue", func(t *testing.T) {
p := issueTestPayload()
- d := new(MSTeamsPayload)
p.Action = api.HookIssueOpened
- pl, err := d.Issue(p)
+ pl, err := mc.Issue(p)
require.NoError(t, err)
- require.NotNil(t, pl)
- require.IsType(t, &MSTeamsPayload{}, pl)
- assert.Equal(t, "[test/repo] Issue opened: #2 crash", pl.(*MSTeamsPayload).Title)
- assert.Equal(t, "[test/repo] Issue opened: #2 crash", pl.(*MSTeamsPayload).Summary)
- assert.Len(t, pl.(*MSTeamsPayload).Sections, 1)
- assert.Equal(t, "user1", pl.(*MSTeamsPayload).Sections[0].ActivitySubtitle)
- assert.Equal(t, "issue body", pl.(*MSTeamsPayload).Sections[0].Text)
- assert.Len(t, pl.(*MSTeamsPayload).Sections[0].Facts, 2)
- for _, fact := range pl.(*MSTeamsPayload).Sections[0].Facts {
+ assert.Equal(t, "[test/repo] Issue opened: #2 crash", pl.Title)
+ assert.Equal(t, "[test/repo] Issue opened: #2 crash", pl.Summary)
+ assert.Len(t, pl.Sections, 1)
+ assert.Equal(t, "user1", pl.Sections[0].ActivitySubtitle)
+ assert.Equal(t, "issue body", pl.Sections[0].Text)
+ assert.Len(t, pl.Sections[0].Facts, 2)
+ for _, fact := range pl.Sections[0].Facts {
if fact.Name == "Repository:" {
assert.Equal(t, p.Repository.FullName, fact.Value)
} else if fact.Name == "Issue #:" {
@@ -155,23 +144,21 @@ func TestMSTeamsPayload(t *testing.T) {
t.Fail()
}
}
- assert.Len(t, pl.(*MSTeamsPayload).PotentialAction, 1)
- assert.Len(t, pl.(*MSTeamsPayload).PotentialAction[0].Targets, 1)
- assert.Equal(t, "http://localhost:3000/test/repo/issues/2", pl.(*MSTeamsPayload).PotentialAction[0].Targets[0].URI)
+ assert.Len(t, pl.PotentialAction, 1)
+ assert.Len(t, pl.PotentialAction[0].Targets, 1)
+ assert.Equal(t, "http://localhost:3000/test/repo/issues/2", pl.PotentialAction[0].Targets[0].URI)
p.Action = api.HookIssueClosed
- pl, err = d.Issue(p)
+ pl, err = mc.Issue(p)
require.NoError(t, err)
- require.NotNil(t, pl)
- require.IsType(t, &MSTeamsPayload{}, pl)
- assert.Equal(t, "[test/repo] Issue closed: #2 crash", pl.(*MSTeamsPayload).Title)
- assert.Equal(t, "[test/repo] Issue closed: #2 crash", pl.(*MSTeamsPayload).Summary)
- assert.Len(t, pl.(*MSTeamsPayload).Sections, 1)
- assert.Equal(t, "user1", pl.(*MSTeamsPayload).Sections[0].ActivitySubtitle)
- assert.Empty(t, pl.(*MSTeamsPayload).Sections[0].Text)
- assert.Len(t, pl.(*MSTeamsPayload).Sections[0].Facts, 2)
- for _, fact := range pl.(*MSTeamsPayload).Sections[0].Facts {
+ assert.Equal(t, "[test/repo] Issue closed: #2 crash", pl.Title)
+ assert.Equal(t, "[test/repo] Issue closed: #2 crash", pl.Summary)
+ assert.Len(t, pl.Sections, 1)
+ assert.Equal(t, "user1", pl.Sections[0].ActivitySubtitle)
+ assert.Empty(t, pl.Sections[0].Text)
+ assert.Len(t, pl.Sections[0].Facts, 2)
+ for _, fact := range pl.Sections[0].Facts {
if fact.Name == "Repository:" {
assert.Equal(t, p.Repository.FullName, fact.Value)
} else if fact.Name == "Issue #:" {
@@ -180,27 +167,24 @@ func TestMSTeamsPayload(t *testing.T) {
t.Fail()
}
}
- assert.Len(t, pl.(*MSTeamsPayload).PotentialAction, 1)
- assert.Len(t, pl.(*MSTeamsPayload).PotentialAction[0].Targets, 1)
- assert.Equal(t, "http://localhost:3000/test/repo/issues/2", pl.(*MSTeamsPayload).PotentialAction[0].Targets[0].URI)
+ assert.Len(t, pl.PotentialAction, 1)
+ assert.Len(t, pl.PotentialAction[0].Targets, 1)
+ assert.Equal(t, "http://localhost:3000/test/repo/issues/2", pl.PotentialAction[0].Targets[0].URI)
})
t.Run("IssueComment", func(t *testing.T) {
p := issueCommentTestPayload()
- d := new(MSTeamsPayload)
- pl, err := d.IssueComment(p)
+ pl, err := mc.IssueComment(p)
require.NoError(t, err)
- require.NotNil(t, pl)
- require.IsType(t, &MSTeamsPayload{}, pl)
- assert.Equal(t, "[test/repo] New comment on issue #2 crash", pl.(*MSTeamsPayload).Title)
- assert.Equal(t, "[test/repo] New comment on issue #2 crash", pl.(*MSTeamsPayload).Summary)
- assert.Len(t, pl.(*MSTeamsPayload).Sections, 1)
- assert.Equal(t, "user1", pl.(*MSTeamsPayload).Sections[0].ActivitySubtitle)
- assert.Equal(t, "more info needed", pl.(*MSTeamsPayload).Sections[0].Text)
- assert.Len(t, pl.(*MSTeamsPayload).Sections[0].Facts, 2)
- for _, fact := range pl.(*MSTeamsPayload).Sections[0].Facts {
+ assert.Equal(t, "[test/repo] New comment on issue #2 crash", pl.Title)
+ assert.Equal(t, "[test/repo] New comment on issue #2 crash", pl.Summary)
+ assert.Len(t, pl.Sections, 1)
+ assert.Equal(t, "user1", pl.Sections[0].ActivitySubtitle)
+ assert.Equal(t, "more info needed", pl.Sections[0].Text)
+ assert.Len(t, pl.Sections[0].Facts, 2)
+ for _, fact := range pl.Sections[0].Facts {
if fact.Name == "Repository:" {
assert.Equal(t, p.Repository.FullName, fact.Value)
} else if fact.Name == "Issue #:" {
@@ -209,27 +193,24 @@ func TestMSTeamsPayload(t *testing.T) {
t.Fail()
}
}
- assert.Len(t, pl.(*MSTeamsPayload).PotentialAction, 1)
- assert.Len(t, pl.(*MSTeamsPayload).PotentialAction[0].Targets, 1)
- assert.Equal(t, "http://localhost:3000/test/repo/issues/2#issuecomment-4", pl.(*MSTeamsPayload).PotentialAction[0].Targets[0].URI)
+ assert.Len(t, pl.PotentialAction, 1)
+ assert.Len(t, pl.PotentialAction[0].Targets, 1)
+ assert.Equal(t, "http://localhost:3000/test/repo/issues/2#issuecomment-4", pl.PotentialAction[0].Targets[0].URI)
})
t.Run("PullRequest", func(t *testing.T) {
p := pullRequestTestPayload()
- d := new(MSTeamsPayload)
- pl, err := d.PullRequest(p)
+ pl, err := mc.PullRequest(p)
require.NoError(t, err)
- require.NotNil(t, pl)
- require.IsType(t, &MSTeamsPayload{}, pl)
- assert.Equal(t, "[test/repo] Pull request opened: #12 Fix bug", pl.(*MSTeamsPayload).Title)
- assert.Equal(t, "[test/repo] Pull request opened: #12 Fix bug", pl.(*MSTeamsPayload).Summary)
- assert.Len(t, pl.(*MSTeamsPayload).Sections, 1)
- assert.Equal(t, "user1", pl.(*MSTeamsPayload).Sections[0].ActivitySubtitle)
- assert.Equal(t, "fixes bug #2", pl.(*MSTeamsPayload).Sections[0].Text)
- assert.Len(t, pl.(*MSTeamsPayload).Sections[0].Facts, 2)
- for _, fact := range pl.(*MSTeamsPayload).Sections[0].Facts {
+ assert.Equal(t, "[test/repo] Pull request opened: #12 Fix bug", pl.Title)
+ assert.Equal(t, "[test/repo] Pull request opened: #12 Fix bug", pl.Summary)
+ assert.Len(t, pl.Sections, 1)
+ assert.Equal(t, "user1", pl.Sections[0].ActivitySubtitle)
+ assert.Equal(t, "fixes bug #2", pl.Sections[0].Text)
+ assert.Len(t, pl.Sections[0].Facts, 2)
+ for _, fact := range pl.Sections[0].Facts {
if fact.Name == "Repository:" {
assert.Equal(t, p.Repository.FullName, fact.Value)
} else if fact.Name == "Pull request #:" {
@@ -238,27 +219,24 @@ func TestMSTeamsPayload(t *testing.T) {
t.Fail()
}
}
- assert.Len(t, pl.(*MSTeamsPayload).PotentialAction, 1)
- assert.Len(t, pl.(*MSTeamsPayload).PotentialAction[0].Targets, 1)
- assert.Equal(t, "http://localhost:3000/test/repo/pulls/12", pl.(*MSTeamsPayload).PotentialAction[0].Targets[0].URI)
+ assert.Len(t, pl.PotentialAction, 1)
+ assert.Len(t, pl.PotentialAction[0].Targets, 1)
+ assert.Equal(t, "http://localhost:3000/test/repo/pulls/12", pl.PotentialAction[0].Targets[0].URI)
})
t.Run("PullRequestComment", func(t *testing.T) {
p := pullRequestCommentTestPayload()
- d := new(MSTeamsPayload)
- pl, err := d.IssueComment(p)
+ pl, err := mc.IssueComment(p)
require.NoError(t, err)
- require.NotNil(t, pl)
- require.IsType(t, &MSTeamsPayload{}, pl)
- assert.Equal(t, "[test/repo] New comment on pull request #12 Fix bug", pl.(*MSTeamsPayload).Title)
- assert.Equal(t, "[test/repo] New comment on pull request #12 Fix bug", pl.(*MSTeamsPayload).Summary)
- assert.Len(t, pl.(*MSTeamsPayload).Sections, 1)
- assert.Equal(t, "user1", pl.(*MSTeamsPayload).Sections[0].ActivitySubtitle)
- assert.Equal(t, "changes requested", pl.(*MSTeamsPayload).Sections[0].Text)
- assert.Len(t, pl.(*MSTeamsPayload).Sections[0].Facts, 2)
- for _, fact := range pl.(*MSTeamsPayload).Sections[0].Facts {
+ assert.Equal(t, "[test/repo] New comment on pull request #12 Fix bug", pl.Title)
+ assert.Equal(t, "[test/repo] New comment on pull request #12 Fix bug", pl.Summary)
+ assert.Len(t, pl.Sections, 1)
+ assert.Equal(t, "user1", pl.Sections[0].ActivitySubtitle)
+ assert.Equal(t, "changes requested", pl.Sections[0].Text)
+ assert.Len(t, pl.Sections[0].Facts, 2)
+ for _, fact := range pl.Sections[0].Facts {
if fact.Name == "Repository:" {
assert.Equal(t, p.Repository.FullName, fact.Value)
} else if fact.Name == "Issue #:" {
@@ -267,28 +245,25 @@ func TestMSTeamsPayload(t *testing.T) {
t.Fail()
}
}
- assert.Len(t, pl.(*MSTeamsPayload).PotentialAction, 1)
- assert.Len(t, pl.(*MSTeamsPayload).PotentialAction[0].Targets, 1)
- assert.Equal(t, "http://localhost:3000/test/repo/pulls/12#issuecomment-4", pl.(*MSTeamsPayload).PotentialAction[0].Targets[0].URI)
+ assert.Len(t, pl.PotentialAction, 1)
+ assert.Len(t, pl.PotentialAction[0].Targets, 1)
+ assert.Equal(t, "http://localhost:3000/test/repo/pulls/12#issuecomment-4", pl.PotentialAction[0].Targets[0].URI)
})
t.Run("Review", func(t *testing.T) {
p := pullRequestTestPayload()
p.Action = api.HookIssueReviewed
- d := new(MSTeamsPayload)
- pl, err := d.Review(p, webhook_module.HookEventPullRequestReviewApproved)
+ pl, err := mc.Review(p, webhook_module.HookEventPullRequestReviewApproved)
require.NoError(t, err)
- require.NotNil(t, pl)
- require.IsType(t, &MSTeamsPayload{}, pl)
- assert.Equal(t, "[test/repo] Pull request review approved: #12 Fix bug", pl.(*MSTeamsPayload).Title)
- assert.Equal(t, "[test/repo] Pull request review approved: #12 Fix bug", pl.(*MSTeamsPayload).Summary)
- assert.Len(t, pl.(*MSTeamsPayload).Sections, 1)
- assert.Equal(t, "user1", pl.(*MSTeamsPayload).Sections[0].ActivitySubtitle)
- assert.Equal(t, "good job", pl.(*MSTeamsPayload).Sections[0].Text)
- assert.Len(t, pl.(*MSTeamsPayload).Sections[0].Facts, 2)
- for _, fact := range pl.(*MSTeamsPayload).Sections[0].Facts {
+ assert.Equal(t, "[test/repo] Pull request review approved: #12 Fix bug", pl.Title)
+ assert.Equal(t, "[test/repo] Pull request review approved: #12 Fix bug", pl.Summary)
+ assert.Len(t, pl.Sections, 1)
+ assert.Equal(t, "user1", pl.Sections[0].ActivitySubtitle)
+ assert.Equal(t, "good job", pl.Sections[0].Text)
+ assert.Len(t, pl.Sections[0].Facts, 2)
+ for _, fact := range pl.Sections[0].Facts {
if fact.Name == "Repository:" {
assert.Equal(t, p.Repository.FullName, fact.Value)
} else if fact.Name == "Pull request #:" {
@@ -297,155 +272,139 @@ func TestMSTeamsPayload(t *testing.T) {
t.Fail()
}
}
- assert.Len(t, pl.(*MSTeamsPayload).PotentialAction, 1)
- assert.Len(t, pl.(*MSTeamsPayload).PotentialAction[0].Targets, 1)
- assert.Equal(t, "http://localhost:3000/test/repo/pulls/12", pl.(*MSTeamsPayload).PotentialAction[0].Targets[0].URI)
+ assert.Len(t, pl.PotentialAction, 1)
+ assert.Len(t, pl.PotentialAction[0].Targets, 1)
+ assert.Equal(t, "http://localhost:3000/test/repo/pulls/12", pl.PotentialAction[0].Targets[0].URI)
})
t.Run("Repository", func(t *testing.T) {
p := repositoryTestPayload()
- d := new(MSTeamsPayload)
- pl, err := d.Repository(p)
+ pl, err := mc.Repository(p)
require.NoError(t, err)
- require.NotNil(t, pl)
- require.IsType(t, &MSTeamsPayload{}, pl)
- assert.Equal(t, "[test/repo] Repository created", pl.(*MSTeamsPayload).Title)
- assert.Equal(t, "[test/repo] Repository created", pl.(*MSTeamsPayload).Summary)
- assert.Len(t, pl.(*MSTeamsPayload).Sections, 1)
- assert.Equal(t, "user1", pl.(*MSTeamsPayload).Sections[0].ActivitySubtitle)
- assert.Empty(t, pl.(*MSTeamsPayload).Sections[0].Text)
- assert.Len(t, pl.(*MSTeamsPayload).Sections[0].Facts, 1)
- for _, fact := range pl.(*MSTeamsPayload).Sections[0].Facts {
+ assert.Equal(t, "[test/repo] Repository created", pl.Title)
+ assert.Equal(t, "[test/repo] Repository created", pl.Summary)
+ assert.Len(t, pl.Sections, 1)
+ assert.Equal(t, "user1", pl.Sections[0].ActivitySubtitle)
+ assert.Empty(t, pl.Sections[0].Text)
+ assert.Len(t, pl.Sections[0].Facts, 1)
+ for _, fact := range pl.Sections[0].Facts {
if fact.Name == "Repository:" {
assert.Equal(t, p.Repository.FullName, fact.Value)
} else {
t.Fail()
}
}
- assert.Len(t, pl.(*MSTeamsPayload).PotentialAction, 1)
- assert.Len(t, pl.(*MSTeamsPayload).PotentialAction[0].Targets, 1)
- assert.Equal(t, "http://localhost:3000/test/repo", pl.(*MSTeamsPayload).PotentialAction[0].Targets[0].URI)
+ assert.Len(t, pl.PotentialAction, 1)
+ assert.Len(t, pl.PotentialAction[0].Targets, 1)
+ assert.Equal(t, "http://localhost:3000/test/repo", pl.PotentialAction[0].Targets[0].URI)
})
t.Run("Package", func(t *testing.T) {
p := packageTestPayload()
- d := new(MSTeamsPayload)
- pl, err := d.Package(p)
+ pl, err := mc.Package(p)
require.NoError(t, err)
- require.NotNil(t, pl)
- require.IsType(t, &MSTeamsPayload{}, pl)
- assert.Equal(t, "Package created: GiteaContainer:latest", pl.(*MSTeamsPayload).Title)
- assert.Equal(t, "Package created: GiteaContainer:latest", pl.(*MSTeamsPayload).Summary)
- assert.Len(t, pl.(*MSTeamsPayload).Sections, 1)
- assert.Equal(t, "user1", pl.(*MSTeamsPayload).Sections[0].ActivitySubtitle)
- assert.Empty(t, pl.(*MSTeamsPayload).Sections[0].Text)
- assert.Len(t, pl.(*MSTeamsPayload).Sections[0].Facts, 1)
- for _, fact := range pl.(*MSTeamsPayload).Sections[0].Facts {
+ assert.Equal(t, "Package created: GiteaContainer:latest", pl.Title)
+ assert.Equal(t, "Package created: GiteaContainer:latest", pl.Summary)
+ assert.Len(t, pl.Sections, 1)
+ assert.Equal(t, "user1", pl.Sections[0].ActivitySubtitle)
+ assert.Empty(t, pl.Sections[0].Text)
+ assert.Len(t, pl.Sections[0].Facts, 1)
+ for _, fact := range pl.Sections[0].Facts {
if fact.Name == "Package:" {
assert.Equal(t, p.Package.Name, fact.Value)
} else {
t.Fail()
}
}
- assert.Len(t, pl.(*MSTeamsPayload).PotentialAction, 1)
- assert.Len(t, pl.(*MSTeamsPayload).PotentialAction[0].Targets, 1)
- assert.Equal(t, "http://localhost:3000/user1/-/packages/container/GiteaContainer/latest", pl.(*MSTeamsPayload).PotentialAction[0].Targets[0].URI)
+ assert.Len(t, pl.PotentialAction, 1)
+ assert.Len(t, pl.PotentialAction[0].Targets, 1)
+ assert.Equal(t, "http://localhost:3000/user1/-/packages/container/GiteaContainer/latest", pl.PotentialAction[0].Targets[0].URI)
})
t.Run("Wiki", func(t *testing.T) {
p := wikiTestPayload()
- d := new(MSTeamsPayload)
p.Action = api.HookWikiCreated
- pl, err := d.Wiki(p)
+ pl, err := mc.Wiki(p)
require.NoError(t, err)
- require.NotNil(t, pl)
- require.IsType(t, &MSTeamsPayload{}, pl)
- assert.Equal(t, "[test/repo] New wiki page 'index' (Wiki change comment)", pl.(*MSTeamsPayload).Title)
- assert.Equal(t, "[test/repo] New wiki page 'index' (Wiki change comment)", pl.(*MSTeamsPayload).Summary)
- assert.Len(t, pl.(*MSTeamsPayload).Sections, 1)
- assert.Equal(t, "user1", pl.(*MSTeamsPayload).Sections[0].ActivitySubtitle)
- assert.Equal(t, "", pl.(*MSTeamsPayload).Sections[0].Text)
- assert.Len(t, pl.(*MSTeamsPayload).Sections[0].Facts, 2)
- for _, fact := range pl.(*MSTeamsPayload).Sections[0].Facts {
+ assert.Equal(t, "[test/repo] New wiki page 'index' (Wiki change comment)", pl.Title)
+ assert.Equal(t, "[test/repo] New wiki page 'index' (Wiki change comment)", pl.Summary)
+ assert.Len(t, pl.Sections, 1)
+ assert.Equal(t, "user1", pl.Sections[0].ActivitySubtitle)
+ assert.Equal(t, "", pl.Sections[0].Text)
+ assert.Len(t, pl.Sections[0].Facts, 2)
+ for _, fact := range pl.Sections[0].Facts {
if fact.Name == "Repository:" {
assert.Equal(t, p.Repository.FullName, fact.Value)
} else {
t.Fail()
}
}
- assert.Len(t, pl.(*MSTeamsPayload).PotentialAction, 1)
- assert.Len(t, pl.(*MSTeamsPayload).PotentialAction[0].Targets, 1)
- assert.Equal(t, "http://localhost:3000/test/repo/wiki/index", pl.(*MSTeamsPayload).PotentialAction[0].Targets[0].URI)
+ assert.Len(t, pl.PotentialAction, 1)
+ assert.Len(t, pl.PotentialAction[0].Targets, 1)
+ assert.Equal(t, "http://localhost:3000/test/repo/wiki/index", pl.PotentialAction[0].Targets[0].URI)
p.Action = api.HookWikiEdited
- pl, err = d.Wiki(p)
+ pl, err = mc.Wiki(p)
require.NoError(t, err)
- require.NotNil(t, pl)
- require.IsType(t, &MSTeamsPayload{}, pl)
- assert.Equal(t, "[test/repo] Wiki page 'index' edited (Wiki change comment)", pl.(*MSTeamsPayload).Title)
- assert.Equal(t, "[test/repo] Wiki page 'index' edited (Wiki change comment)", pl.(*MSTeamsPayload).Summary)
- assert.Len(t, pl.(*MSTeamsPayload).Sections, 1)
- assert.Equal(t, "user1", pl.(*MSTeamsPayload).Sections[0].ActivitySubtitle)
- assert.Equal(t, "", pl.(*MSTeamsPayload).Sections[0].Text)
- assert.Len(t, pl.(*MSTeamsPayload).Sections[0].Facts, 2)
- for _, fact := range pl.(*MSTeamsPayload).Sections[0].Facts {
+ assert.Equal(t, "[test/repo] Wiki page 'index' edited (Wiki change comment)", pl.Title)
+ assert.Equal(t, "[test/repo] Wiki page 'index' edited (Wiki change comment)", pl.Summary)
+ assert.Len(t, pl.Sections, 1)
+ assert.Equal(t, "user1", pl.Sections[0].ActivitySubtitle)
+ assert.Equal(t, "", pl.Sections[0].Text)
+ assert.Len(t, pl.Sections[0].Facts, 2)
+ for _, fact := range pl.Sections[0].Facts {
if fact.Name == "Repository:" {
assert.Equal(t, p.Repository.FullName, fact.Value)
} else {
t.Fail()
}
}
- assert.Len(t, pl.(*MSTeamsPayload).PotentialAction, 1)
- assert.Len(t, pl.(*MSTeamsPayload).PotentialAction[0].Targets, 1)
- assert.Equal(t, "http://localhost:3000/test/repo/wiki/index", pl.(*MSTeamsPayload).PotentialAction[0].Targets[0].URI)
+ assert.Len(t, pl.PotentialAction, 1)
+ assert.Len(t, pl.PotentialAction[0].Targets, 1)
+ assert.Equal(t, "http://localhost:3000/test/repo/wiki/index", pl.PotentialAction[0].Targets[0].URI)
p.Action = api.HookWikiDeleted
- pl, err = d.Wiki(p)
+ pl, err = mc.Wiki(p)
require.NoError(t, err)
- require.NotNil(t, pl)
- require.IsType(t, &MSTeamsPayload{}, pl)
- assert.Equal(t, "[test/repo] Wiki page 'index' deleted", pl.(*MSTeamsPayload).Title)
- assert.Equal(t, "[test/repo] Wiki page 'index' deleted", pl.(*MSTeamsPayload).Summary)
- assert.Len(t, pl.(*MSTeamsPayload).Sections, 1)
- assert.Equal(t, "user1", pl.(*MSTeamsPayload).Sections[0].ActivitySubtitle)
- assert.Empty(t, pl.(*MSTeamsPayload).Sections[0].Text)
- assert.Len(t, pl.(*MSTeamsPayload).Sections[0].Facts, 2)
- for _, fact := range pl.(*MSTeamsPayload).Sections[0].Facts {
+ assert.Equal(t, "[test/repo] Wiki page 'index' deleted", pl.Title)
+ assert.Equal(t, "[test/repo] Wiki page 'index' deleted", pl.Summary)
+ assert.Len(t, pl.Sections, 1)
+ assert.Equal(t, "user1", pl.Sections[0].ActivitySubtitle)
+ assert.Empty(t, pl.Sections[0].Text)
+ assert.Len(t, pl.Sections[0].Facts, 2)
+ for _, fact := range pl.Sections[0].Facts {
if fact.Name == "Repository:" {
assert.Equal(t, p.Repository.FullName, fact.Value)
} else {
t.Fail()
}
}
- assert.Len(t, pl.(*MSTeamsPayload).PotentialAction, 1)
- assert.Len(t, pl.(*MSTeamsPayload).PotentialAction[0].Targets, 1)
- assert.Equal(t, "http://localhost:3000/test/repo/wiki/index", pl.(*MSTeamsPayload).PotentialAction[0].Targets[0].URI)
+ assert.Len(t, pl.PotentialAction, 1)
+ assert.Len(t, pl.PotentialAction[0].Targets, 1)
+ assert.Equal(t, "http://localhost:3000/test/repo/wiki/index", pl.PotentialAction[0].Targets[0].URI)
})
t.Run("Release", func(t *testing.T) {
p := pullReleaseTestPayload()
- d := new(MSTeamsPayload)
- pl, err := d.Release(p)
+ pl, err := mc.Release(p)
require.NoError(t, err)
- require.NotNil(t, pl)
- require.IsType(t, &MSTeamsPayload{}, pl)
- assert.Equal(t, "[test/repo] Release created: v1.0", pl.(*MSTeamsPayload).Title)
- assert.Equal(t, "[test/repo] Release created: v1.0", pl.(*MSTeamsPayload).Summary)
- assert.Len(t, pl.(*MSTeamsPayload).Sections, 1)
- assert.Equal(t, "user1", pl.(*MSTeamsPayload).Sections[0].ActivitySubtitle)
- assert.Empty(t, pl.(*MSTeamsPayload).Sections[0].Text)
- assert.Len(t, pl.(*MSTeamsPayload).Sections[0].Facts, 2)
- for _, fact := range pl.(*MSTeamsPayload).Sections[0].Facts {
+ assert.Equal(t, "[test/repo] Release created: v1.0", pl.Title)
+ assert.Equal(t, "[test/repo] Release created: v1.0", pl.Summary)
+ assert.Len(t, pl.Sections, 1)
+ assert.Equal(t, "user1", pl.Sections[0].ActivitySubtitle)
+ assert.Empty(t, pl.Sections[0].Text)
+ assert.Len(t, pl.Sections[0].Facts, 2)
+ for _, fact := range pl.Sections[0].Facts {
if fact.Name == "Repository:" {
assert.Equal(t, p.Repository.FullName, fact.Value)
} else if fact.Name == "Tag:" {
@@ -454,21 +413,43 @@ func TestMSTeamsPayload(t *testing.T) {
t.Fail()
}
}
- assert.Len(t, pl.(*MSTeamsPayload).PotentialAction, 1)
- assert.Len(t, pl.(*MSTeamsPayload).PotentialAction[0].Targets, 1)
- assert.Equal(t, "http://localhost:3000/test/repo/releases/tag/v1.0", pl.(*MSTeamsPayload).PotentialAction[0].Targets[0].URI)
+ assert.Len(t, pl.PotentialAction, 1)
+ assert.Len(t, pl.PotentialAction[0].Targets, 1)
+ assert.Equal(t, "http://localhost:3000/test/repo/releases/tag/v1.0", pl.PotentialAction[0].Targets[0].URI)
})
}
func TestMSTeamsJSONPayload(t *testing.T) {
p := pushTestPayload()
-
- pl, err := new(MSTeamsPayload).Push(p)
+ data, err := p.JSONPayload()
require.NoError(t, err)
- require.NotNil(t, pl)
- require.IsType(t, &MSTeamsPayload{}, pl)
- json, err := pl.JSONPayload()
+ hook := &webhook_model.Webhook{
+ RepoID: 3,
+ IsActive: true,
+ Type: webhook_module.MSTEAMS,
+ URL: "https://msteams.example.com/",
+ Meta: ``,
+ HTTPMethod: "POST",
+ }
+ task := &webhook_model.HookTask{
+ HookID: hook.ID,
+ EventType: webhook_module.HookEventPush,
+ PayloadContent: string(data),
+ PayloadVersion: 2,
+ }
+
+ req, reqBody, err := newMSTeamsRequest(context.Background(), hook, task)
+ require.NotNil(t, req)
+ require.NotNil(t, reqBody)
require.NoError(t, err)
- assert.NotEmpty(t, json)
+
+ assert.Equal(t, "POST", req.Method)
+ assert.Equal(t, "https://msteams.example.com/", req.URL.String())
+ assert.Equal(t, "sha256=", req.Header.Get("X-Hub-Signature-256"))
+ assert.Equal(t, "application/json", req.Header.Get("Content-Type"))
+ var body MSTeamsPayload
+ err = json.NewDecoder(req.Body).Decode(&body)
+ assert.NoError(t, err)
+ assert.Equal(t, "[test/repo:test] 2 new commits", body.Summary)
}
diff --git a/services/webhook/packagist.go b/services/webhook/packagist.go
index 714a4c076e..0a2b62c89a 100644
--- a/services/webhook/packagist.go
+++ b/services/webhook/packagist.go
@@ -4,17 +4,18 @@
package webhook
import (
- "errors"
+ "context"
+ "fmt"
+ "net/http"
webhook_model "code.gitea.io/gitea/models/webhook"
"code.gitea.io/gitea/modules/json"
"code.gitea.io/gitea/modules/log"
- api "code.gitea.io/gitea/modules/structs"
- webhook_module "code.gitea.io/gitea/modules/webhook"
)
type (
- // PackagistPayload represents
+ // PackagistPayload represents a packagist payload
+ // as expected by https://packagist.org/about
PackagistPayload struct {
PackagistRepository struct {
URL string `json:"url"`
@@ -38,84 +39,19 @@ func GetPackagistHook(w *webhook_model.Webhook) *PackagistMeta {
return s
}
-// JSONPayload Marshals the PackagistPayload to json
-func (f *PackagistPayload) JSONPayload() ([]byte, error) {
- data, err := json.MarshalIndent(f, "", " ")
- if err != nil {
- return []byte{}, err
+// newPackagistRequest creates a request with the [PackagistPayload] for packagist (same payload for all events).
+func newPackagistRequest(ctx context.Context, w *webhook_model.Webhook, t *webhook_model.HookTask) (*http.Request, []byte, error) {
+ meta := &PackagistMeta{}
+ if err := json.Unmarshal([]byte(w.Meta), meta); err != nil {
+ return nil, nil, fmt.Errorf("newpackagistRequest meta json: %w", err)
}
- return data, nil
-}
-var _ PayloadConvertor = &PackagistPayload{}
-
-// Create implements PayloadConvertor Create method
-func (f *PackagistPayload) Create(_ *api.CreatePayload) (api.Payloader, error) {
- return nil, nil
-}
-
-// Delete implements PayloadConvertor Delete method
-func (f *PackagistPayload) Delete(_ *api.DeletePayload) (api.Payloader, error) {
- return nil, nil
-}
-
-// Fork implements PayloadConvertor Fork method
-func (f *PackagistPayload) Fork(_ *api.ForkPayload) (api.Payloader, error) {
- return nil, nil
-}
-
-// Push implements PayloadConvertor Push method
-func (f *PackagistPayload) Push(_ *api.PushPayload) (api.Payloader, error) {
- return f, nil
-}
-
-// Issue implements PayloadConvertor Issue method
-func (f *PackagistPayload) Issue(_ *api.IssuePayload) (api.Payloader, error) {
- return nil, nil
-}
-
-// IssueComment implements PayloadConvertor IssueComment method
-func (f *PackagistPayload) IssueComment(_ *api.IssueCommentPayload) (api.Payloader, error) {
- return nil, nil
-}
-
-// PullRequest implements PayloadConvertor PullRequest method
-func (f *PackagistPayload) PullRequest(_ *api.PullRequestPayload) (api.Payloader, error) {
- return nil, nil
-}
-
-// Review implements PayloadConvertor Review method
-func (f *PackagistPayload) Review(_ *api.PullRequestPayload, _ webhook_module.HookEventType) (api.Payloader, error) {
- return nil, nil
-}
-
-// Repository implements PayloadConvertor Repository method
-func (f *PackagistPayload) Repository(_ *api.RepositoryPayload) (api.Payloader, error) {
- return nil, nil
-}
-
-// Wiki implements PayloadConvertor Wiki method
-func (f *PackagistPayload) Wiki(_ *api.WikiPayload) (api.Payloader, error) {
- return nil, nil
-}
-
-// Release implements PayloadConvertor Release method
-func (f *PackagistPayload) Release(_ *api.ReleasePayload) (api.Payloader, error) {
- return nil, nil
-}
-
-func (f *PackagistPayload) Package(_ *api.PackagePayload) (api.Payloader, error) {
- return nil, nil
-}
-
-// GetPackagistPayload converts a packagist webhook into a PackagistPayload
-func GetPackagistPayload(p api.Payloader, event webhook_module.HookEventType, meta string) (api.Payloader, error) {
- s := new(PackagistPayload)
-
- packagist := &PackagistMeta{}
- if err := json.Unmarshal([]byte(meta), &packagist); err != nil {
- return s, errors.New("GetPackagistPayload meta json:" + err.Error())
+ payload := PackagistPayload{
+ PackagistRepository: struct {
+ URL string `json:"url"`
+ }{
+ URL: meta.PackageURL,
+ },
}
- s.PackagistRepository.URL = packagist.PackageURL
- return convertPayloader(s, p, event)
+ return newJSONRequestWithPayload(payload, w, t, false)
}
diff --git a/services/webhook/packagist_test.go b/services/webhook/packagist_test.go
index 26d01b0555..e6a963a9dd 100644
--- a/services/webhook/packagist_test.go
+++ b/services/webhook/packagist_test.go
@@ -4,8 +4,12 @@
package webhook
import (
+ "context"
+ "fmt"
"testing"
+ webhook_model "code.gitea.io/gitea/models/webhook"
+ "code.gitea.io/gitea/modules/json"
api "code.gitea.io/gitea/modules/structs"
webhook_module "code.gitea.io/gitea/modules/webhook"
@@ -14,155 +18,53 @@ import (
)
func TestPackagistPayload(t *testing.T) {
- t.Run("Create", func(t *testing.T) {
- p := createTestPayload()
+ payloads := []api.Payloader{
+ createTestPayload(),
+ deleteTestPayload(),
+ forkTestPayload(),
+ pushTestPayload(),
+ issueTestPayload(),
+ issueCommentTestPayload(),
+ pullRequestCommentTestPayload(),
+ pullRequestTestPayload(),
+ repositoryTestPayload(),
+ packageTestPayload(),
+ wikiTestPayload(),
+ pullReleaseTestPayload(),
+ }
- d := new(PackagistPayload)
- pl, err := d.Create(p)
- require.NoError(t, err)
- require.Nil(t, pl)
- })
+ for _, payloader := range payloads {
+ t.Run(fmt.Sprintf("%T", payloader), func(t *testing.T) {
+ data, err := payloader.JSONPayload()
+ require.NoError(t, err)
- t.Run("Delete", func(t *testing.T) {
- p := deleteTestPayload()
+ hook := &webhook_model.Webhook{
+ RepoID: 3,
+ IsActive: true,
+ Type: webhook_module.PACKAGIST,
+ URL: "https://packagist.org/api/update-package?username=THEUSERNAME&apiToken=TOPSECRETAPITOKEN",
+ Meta: `{"package_url":"https://packagist.org/packages/example"}`,
+ HTTPMethod: "POST",
+ }
+ task := &webhook_model.HookTask{
+ HookID: hook.ID,
+ EventType: webhook_module.HookEventPush,
+ PayloadContent: string(data),
+ PayloadVersion: 2,
+ }
- d := new(PackagistPayload)
- pl, err := d.Delete(p)
- require.NoError(t, err)
- require.Nil(t, pl)
- })
+ req, reqBody, err := newPackagistRequest(context.Background(), hook, task)
+ require.NotNil(t, req)
+ require.NotNil(t, reqBody)
+ require.NoError(t, err)
- t.Run("Fork", func(t *testing.T) {
- p := forkTestPayload()
-
- d := new(PackagistPayload)
- pl, err := d.Fork(p)
- require.NoError(t, err)
- require.Nil(t, pl)
- })
-
- t.Run("Push", func(t *testing.T) {
- p := pushTestPayload()
-
- d := new(PackagistPayload)
- d.PackagistRepository.URL = "https://packagist.org/api/update-package?username=THEUSERNAME&apiToken=TOPSECRETAPITOKEN"
- pl, err := d.Push(p)
- require.NoError(t, err)
- require.NotNil(t, pl)
- require.IsType(t, &PackagistPayload{}, pl)
-
- assert.Equal(t, "https://packagist.org/api/update-package?username=THEUSERNAME&apiToken=TOPSECRETAPITOKEN", pl.(*PackagistPayload).PackagistRepository.URL)
- })
-
- t.Run("Issue", func(t *testing.T) {
- p := issueTestPayload()
-
- d := new(PackagistPayload)
- p.Action = api.HookIssueOpened
- pl, err := d.Issue(p)
- require.NoError(t, err)
- require.Nil(t, pl)
-
- p.Action = api.HookIssueClosed
- pl, err = d.Issue(p)
- require.NoError(t, err)
- require.Nil(t, pl)
- })
-
- t.Run("IssueComment", func(t *testing.T) {
- p := issueCommentTestPayload()
-
- d := new(PackagistPayload)
- pl, err := d.IssueComment(p)
- require.NoError(t, err)
- require.Nil(t, pl)
- })
-
- t.Run("PullRequest", func(t *testing.T) {
- p := pullRequestTestPayload()
-
- d := new(PackagistPayload)
- pl, err := d.PullRequest(p)
- require.NoError(t, err)
- require.Nil(t, pl)
- })
-
- t.Run("PullRequestComment", func(t *testing.T) {
- p := pullRequestCommentTestPayload()
-
- d := new(PackagistPayload)
- pl, err := d.IssueComment(p)
- require.NoError(t, err)
- require.Nil(t, pl)
- })
-
- t.Run("Review", func(t *testing.T) {
- p := pullRequestTestPayload()
- p.Action = api.HookIssueReviewed
-
- d := new(PackagistPayload)
- pl, err := d.Review(p, webhook_module.HookEventPullRequestReviewApproved)
- require.NoError(t, err)
- require.Nil(t, pl)
- })
-
- t.Run("Repository", func(t *testing.T) {
- p := repositoryTestPayload()
-
- d := new(PackagistPayload)
- pl, err := d.Repository(p)
- require.NoError(t, err)
- require.Nil(t, pl)
- })
-
- t.Run("Package", func(t *testing.T) {
- p := packageTestPayload()
-
- d := new(PackagistPayload)
- pl, err := d.Package(p)
- require.NoError(t, err)
- require.Nil(t, pl)
- })
-
- t.Run("Wiki", func(t *testing.T) {
- p := wikiTestPayload()
-
- d := new(PackagistPayload)
- p.Action = api.HookWikiCreated
- pl, err := d.Wiki(p)
- require.NoError(t, err)
- require.Nil(t, pl)
-
- p.Action = api.HookWikiEdited
- pl, err = d.Wiki(p)
- require.NoError(t, err)
- require.Nil(t, pl)
-
- p.Action = api.HookWikiDeleted
- pl, err = d.Wiki(p)
- require.NoError(t, err)
- require.Nil(t, pl)
- })
-
- t.Run("Release", func(t *testing.T) {
- p := pullReleaseTestPayload()
-
- d := new(PackagistPayload)
- pl, err := d.Release(p)
- require.NoError(t, err)
- require.Nil(t, pl)
- })
-}
-
-func TestPackagistJSONPayload(t *testing.T) {
- p := pushTestPayload()
-
- pl, err := new(PackagistPayload).Push(p)
- require.NoError(t, err)
- require.NotNil(t, pl)
- require.IsType(t, &PackagistPayload{}, pl)
-
- json, err := pl.JSONPayload()
- require.NoError(t, err)
- assert.NotEmpty(t, json)
+ assert.Equal(t, "POST", req.Method)
+ assert.Equal(t, "https://packagist.org/api/update-package?username=THEUSERNAME&apiToken=TOPSECRETAPITOKEN", req.URL.String())
+ assert.Equal(t, "application/json", req.Header.Get("Content-Type"))
+ var body PackagistPayload
+ err = json.NewDecoder(req.Body).Decode(&body)
+ assert.NoError(t, err)
+ assert.Equal(t, "https://packagist.org/packages/example", body.PackagistRepository.URL)
+ })
+ }
}
diff --git a/services/webhook/payloader.go b/services/webhook/payloader.go
index bd482c04ea..f87e6e4eec 100644
--- a/services/webhook/payloader.go
+++ b/services/webhook/payloader.go
@@ -4,58 +4,112 @@
package webhook
import (
+ "bytes"
+ "fmt"
+ "net/http"
+
+ webhook_model "code.gitea.io/gitea/models/webhook"
+ "code.gitea.io/gitea/modules/json"
api "code.gitea.io/gitea/modules/structs"
webhook_module "code.gitea.io/gitea/modules/webhook"
)
-// PayloadConvertor defines the interface to convert system webhook payload to external payload
-type PayloadConvertor interface {
- api.Payloader
- Create(*api.CreatePayload) (api.Payloader, error)
- Delete(*api.DeletePayload) (api.Payloader, error)
- Fork(*api.ForkPayload) (api.Payloader, error)
- Issue(*api.IssuePayload) (api.Payloader, error)
- IssueComment(*api.IssueCommentPayload) (api.Payloader, error)
- Push(*api.PushPayload) (api.Payloader, error)
- PullRequest(*api.PullRequestPayload) (api.Payloader, error)
- Review(*api.PullRequestPayload, webhook_module.HookEventType) (api.Payloader, error)
- Repository(*api.RepositoryPayload) (api.Payloader, error)
- Release(*api.ReleasePayload) (api.Payloader, error)
- Wiki(*api.WikiPayload) (api.Payloader, error)
- Package(*api.PackagePayload) (api.Payloader, error)
+// payloadConvertor defines the interface to convert system payload to webhook payload
+type payloadConvertor[T any] interface {
+ Create(*api.CreatePayload) (T, error)
+ Delete(*api.DeletePayload) (T, error)
+ Fork(*api.ForkPayload) (T, error)
+ Issue(*api.IssuePayload) (T, error)
+ IssueComment(*api.IssueCommentPayload) (T, error)
+ Push(*api.PushPayload) (T, error)
+ PullRequest(*api.PullRequestPayload) (T, error)
+ Review(*api.PullRequestPayload, webhook_module.HookEventType) (T, error)
+ Repository(*api.RepositoryPayload) (T, error)
+ Release(*api.ReleasePayload) (T, error)
+ Wiki(*api.WikiPayload) (T, error)
+ Package(*api.PackagePayload) (T, error)
}
-func convertPayloader(s PayloadConvertor, p api.Payloader, event webhook_module.HookEventType) (api.Payloader, error) {
+func convertUnmarshalledJSON[T, P any](convert func(P) (T, error), data []byte) (T, error) {
+ var p P
+ if err := json.Unmarshal(data, &p); err != nil {
+ var t T
+ return t, fmt.Errorf("could not unmarshal payload: %w", err)
+ }
+ return convert(p)
+}
+
+func newPayload[T any](rc payloadConvertor[T], data []byte, event webhook_module.HookEventType) (T, error) {
switch event {
case webhook_module.HookEventCreate:
- return s.Create(p.(*api.CreatePayload))
+ return convertUnmarshalledJSON(rc.Create, data)
case webhook_module.HookEventDelete:
- return s.Delete(p.(*api.DeletePayload))
+ return convertUnmarshalledJSON(rc.Delete, data)
case webhook_module.HookEventFork:
- return s.Fork(p.(*api.ForkPayload))
+ return convertUnmarshalledJSON(rc.Fork, data)
case webhook_module.HookEventIssues, webhook_module.HookEventIssueAssign, webhook_module.HookEventIssueLabel, webhook_module.HookEventIssueMilestone:
- return s.Issue(p.(*api.IssuePayload))
+ return convertUnmarshalledJSON(rc.Issue, data)
case webhook_module.HookEventIssueComment, webhook_module.HookEventPullRequestComment:
- pl, ok := p.(*api.IssueCommentPayload)
- if ok {
- return s.IssueComment(pl)
- }
- return s.PullRequest(p.(*api.PullRequestPayload))
+ // previous code sometimes sent s.PullRequest(p.(*api.PullRequestPayload))
+ // however I couldn't find in notifier.go such a payload with an HookEvent***Comment event
+
+ // History (most recent first):
+ // - refactored in https://github.com/go-gitea/gitea/pull/12310
+ // - assertion added in https://github.com/go-gitea/gitea/pull/12046
+ // - issue raised in https://github.com/go-gitea/gitea/issues/11940#issuecomment-645713996
+ // > That's because for HookEventPullRequestComment event, some places use IssueCommentPayload and others use PullRequestPayload
+
+ // In modules/actions/workflows.go:183 the type assertion is always payload.(*api.IssueCommentPayload)
+ return convertUnmarshalledJSON(rc.IssueComment, data)
case webhook_module.HookEventPush:
- return s.Push(p.(*api.PushPayload))
+ return convertUnmarshalledJSON(rc.Push, data)
case webhook_module.HookEventPullRequest, webhook_module.HookEventPullRequestAssign, webhook_module.HookEventPullRequestLabel,
webhook_module.HookEventPullRequestMilestone, webhook_module.HookEventPullRequestSync, webhook_module.HookEventPullRequestReviewRequest:
- return s.PullRequest(p.(*api.PullRequestPayload))
+ return convertUnmarshalledJSON(rc.PullRequest, data)
case webhook_module.HookEventPullRequestReviewApproved, webhook_module.HookEventPullRequestReviewRejected, webhook_module.HookEventPullRequestReviewComment:
- return s.Review(p.(*api.PullRequestPayload), event)
+ return convertUnmarshalledJSON(func(p *api.PullRequestPayload) (T, error) {
+ return rc.Review(p, event)
+ }, data)
case webhook_module.HookEventRepository:
- return s.Repository(p.(*api.RepositoryPayload))
+ return convertUnmarshalledJSON(rc.Repository, data)
case webhook_module.HookEventRelease:
- return s.Release(p.(*api.ReleasePayload))
+ return convertUnmarshalledJSON(rc.Release, data)
case webhook_module.HookEventWiki:
- return s.Wiki(p.(*api.WikiPayload))
+ return convertUnmarshalledJSON(rc.Wiki, data)
case webhook_module.HookEventPackage:
- return s.Package(p.(*api.PackagePayload))
+ return convertUnmarshalledJSON(rc.Package, data)
}
- return s, nil
+ var t T
+ return t, fmt.Errorf("newPayload unsupported event: %s", event)
+}
+
+func newJSONRequest[T any](pc payloadConvertor[T], w *webhook_model.Webhook, t *webhook_model.HookTask, withDefaultHeaders bool) (*http.Request, []byte, error) {
+ payload, err := newPayload(pc, []byte(t.PayloadContent), t.EventType)
+ if err != nil {
+ return nil, nil, err
+ }
+ return newJSONRequestWithPayload(payload, w, t, withDefaultHeaders)
+}
+
+func newJSONRequestWithPayload(payload any, w *webhook_model.Webhook, t *webhook_model.HookTask, withDefaultHeaders bool) (*http.Request, []byte, error) {
+ body, err := json.MarshalIndent(payload, "", " ")
+ if err != nil {
+ return nil, nil, err
+ }
+
+ method := w.HTTPMethod
+ if method == "" {
+ method = http.MethodPost
+ }
+
+ req, err := http.NewRequest(method, w.URL, bytes.NewReader(body))
+ if err != nil {
+ return nil, nil, err
+ }
+ req.Header.Set("Content-Type", "application/json")
+
+ if withDefaultHeaders {
+ return req, body, addDefaultHeaders(req, []byte(w.Secret), t, body)
+ }
+ return req, body, nil
}
diff --git a/services/webhook/slack.go b/services/webhook/slack.go
index 945b0662d8..ba8bac27d9 100644
--- a/services/webhook/slack.go
+++ b/services/webhook/slack.go
@@ -4,8 +4,9 @@
package webhook
import (
- "errors"
+ "context"
"fmt"
+ "net/http"
"regexp"
"strings"
@@ -39,7 +40,6 @@ func GetSlackHook(w *webhook_model.Webhook) *SlackMeta {
type SlackPayload struct {
Channel string `json:"channel"`
Text string `json:"text"`
- Color string `json:"-"`
Username string `json:"username"`
IconURL string `json:"icon_url"`
UnfurlLinks int `json:"unfurl_links"`
@@ -56,15 +56,6 @@ type SlackAttachment struct {
Text string `json:"text"`
}
-// JSONPayload Marshals the SlackPayload to json
-func (s *SlackPayload) JSONPayload() ([]byte, error) {
- data, err := json.MarshalIndent(s, "", " ")
- if err != nil {
- return []byte{}, err
- }
- return data, nil
-}
-
// SlackTextFormatter replaces &, <, > with HTML characters
// see: https://api.slack.com/docs/formatting
func SlackTextFormatter(s string) string {
@@ -98,10 +89,8 @@ func SlackLinkToRef(repoURL, ref string) string {
return SlackLinkFormatter(url, refName)
}
-var _ PayloadConvertor = &SlackPayload{}
-
-// Create implements PayloadConvertor Create method
-func (s *SlackPayload) Create(p *api.CreatePayload) (api.Payloader, error) {
+// Create implements payloadConvertor Create method
+func (s slackConvertor) Create(p *api.CreatePayload) (SlackPayload, error) {
repoLink := SlackLinkFormatter(p.Repo.HTMLURL, p.Repo.FullName)
refLink := SlackLinkToRef(p.Repo.HTMLURL, p.Ref)
text := fmt.Sprintf("[%s:%s] %s created by %s", repoLink, refLink, p.RefType, p.Sender.UserName)
@@ -110,7 +99,7 @@ func (s *SlackPayload) Create(p *api.CreatePayload) (api.Payloader, error) {
}
// Delete composes Slack payload for delete a branch or tag.
-func (s *SlackPayload) Delete(p *api.DeletePayload) (api.Payloader, error) {
+func (s slackConvertor) Delete(p *api.DeletePayload) (SlackPayload, error) {
refName := git.RefName(p.Ref).ShortName()
repoLink := SlackLinkFormatter(p.Repo.HTMLURL, p.Repo.FullName)
text := fmt.Sprintf("[%s:%s] %s deleted by %s", repoLink, refName, p.RefType, p.Sender.UserName)
@@ -119,7 +108,7 @@ func (s *SlackPayload) Delete(p *api.DeletePayload) (api.Payloader, error) {
}
// Fork composes Slack payload for forked by a repository.
-func (s *SlackPayload) Fork(p *api.ForkPayload) (api.Payloader, error) {
+func (s slackConvertor) Fork(p *api.ForkPayload) (SlackPayload, error) {
baseLink := SlackLinkFormatter(p.Forkee.HTMLURL, p.Forkee.FullName)
forkLink := SlackLinkFormatter(p.Repo.HTMLURL, p.Repo.FullName)
text := fmt.Sprintf("%s is forked to %s", baseLink, forkLink)
@@ -127,8 +116,8 @@ func (s *SlackPayload) Fork(p *api.ForkPayload) (api.Payloader, error) {
return s.createPayload(text, nil), nil
}
-// Issue implements PayloadConvertor Issue method
-func (s *SlackPayload) Issue(p *api.IssuePayload) (api.Payloader, error) {
+// Issue implements payloadConvertor Issue method
+func (s slackConvertor) Issue(p *api.IssuePayload) (SlackPayload, error) {
text, issueTitle, attachmentText, color := getIssuesPayloadInfo(p, SlackLinkFormatter, true)
var attachments []SlackAttachment
@@ -146,8 +135,8 @@ func (s *SlackPayload) Issue(p *api.IssuePayload) (api.Payloader, error) {
return s.createPayload(text, attachments), nil
}
-// IssueComment implements PayloadConvertor IssueComment method
-func (s *SlackPayload) IssueComment(p *api.IssueCommentPayload) (api.Payloader, error) {
+// IssueComment implements payloadConvertor IssueComment method
+func (s slackConvertor) IssueComment(p *api.IssueCommentPayload) (SlackPayload, error) {
text, issueTitle, color := getIssueCommentPayloadInfo(p, SlackLinkFormatter, true)
return s.createPayload(text, []SlackAttachment{{
@@ -158,28 +147,28 @@ func (s *SlackPayload) IssueComment(p *api.IssueCommentPayload) (api.Payloader,
}}), nil
}
-// Wiki implements PayloadConvertor Wiki method
-func (s *SlackPayload) Wiki(p *api.WikiPayload) (api.Payloader, error) {
+// Wiki implements payloadConvertor Wiki method
+func (s slackConvertor) Wiki(p *api.WikiPayload) (SlackPayload, error) {
text, _, _ := getWikiPayloadInfo(p, SlackLinkFormatter, true)
return s.createPayload(text, nil), nil
}
-// Release implements PayloadConvertor Release method
-func (s *SlackPayload) Release(p *api.ReleasePayload) (api.Payloader, error) {
+// Release implements payloadConvertor Release method
+func (s slackConvertor) Release(p *api.ReleasePayload) (SlackPayload, error) {
text, _ := getReleasePayloadInfo(p, SlackLinkFormatter, true)
return s.createPayload(text, nil), nil
}
-func (s *SlackPayload) Package(p *api.PackagePayload) (api.Payloader, error) {
+func (s slackConvertor) Package(p *api.PackagePayload) (SlackPayload, error) {
text, _ := getPackagePayloadInfo(p, SlackLinkFormatter, true)
return s.createPayload(text, nil), nil
}
-// Push implements PayloadConvertor Push method
-func (s *SlackPayload) Push(p *api.PushPayload) (api.Payloader, error) {
+// Push implements payloadConvertor Push method
+func (s slackConvertor) Push(p *api.PushPayload) (SlackPayload, error) {
// n new commits
var (
commitDesc string
@@ -219,8 +208,8 @@ func (s *SlackPayload) Push(p *api.PushPayload) (api.Payloader, error) {
}}), nil
}
-// PullRequest implements PayloadConvertor PullRequest method
-func (s *SlackPayload) PullRequest(p *api.PullRequestPayload) (api.Payloader, error) {
+// PullRequest implements payloadConvertor PullRequest method
+func (s slackConvertor) PullRequest(p *api.PullRequestPayload) (SlackPayload, error) {
text, issueTitle, attachmentText, color := getPullRequestPayloadInfo(p, SlackLinkFormatter, true)
var attachments []SlackAttachment
@@ -238,8 +227,8 @@ func (s *SlackPayload) PullRequest(p *api.PullRequestPayload) (api.Payloader, er
return s.createPayload(text, attachments), nil
}
-// Review implements PayloadConvertor Review method
-func (s *SlackPayload) Review(p *api.PullRequestPayload, event webhook_module.HookEventType) (api.Payloader, error) {
+// Review implements payloadConvertor Review method
+func (s slackConvertor) Review(p *api.PullRequestPayload, event webhook_module.HookEventType) (SlackPayload, error) {
senderLink := SlackLinkFormatter(setting.AppURL+p.Sender.UserName, p.Sender.UserName)
title := fmt.Sprintf("#%d %s", p.Index, p.PullRequest.Title)
titleLink := fmt.Sprintf("%s/pulls/%d", p.Repository.HTMLURL, p.Index)
@@ -250,7 +239,7 @@ func (s *SlackPayload) Review(p *api.PullRequestPayload, event webhook_module.Ho
case api.HookIssueReviewed:
action, err := parseHookPullRequestEventType(event)
if err != nil {
- return nil, err
+ return SlackPayload{}, err
}
text = fmt.Sprintf("[%s] Pull request review %s: [%s](%s) by %s", repoLink, action, title, titleLink, senderLink)
@@ -259,8 +248,8 @@ func (s *SlackPayload) Review(p *api.PullRequestPayload, event webhook_module.Ho
return s.createPayload(text, nil), nil
}
-// Repository implements PayloadConvertor Repository method
-func (s *SlackPayload) Repository(p *api.RepositoryPayload) (api.Payloader, error) {
+// Repository implements payloadConvertor Repository method
+func (s slackConvertor) Repository(p *api.RepositoryPayload) (SlackPayload, error) {
senderLink := SlackLinkFormatter(setting.AppURL+p.Sender.UserName, p.Sender.UserName)
repoLink := SlackLinkFormatter(p.Repository.HTMLURL, p.Repository.FullName)
var text string
@@ -275,8 +264,8 @@ func (s *SlackPayload) Repository(p *api.RepositoryPayload) (api.Payloader, erro
return s.createPayload(text, nil), nil
}
-func (s *SlackPayload) createPayload(text string, attachments []SlackAttachment) *SlackPayload {
- return &SlackPayload{
+func (s slackConvertor) createPayload(text string, attachments []SlackAttachment) SlackPayload {
+ return SlackPayload{
Channel: s.Channel,
Text: text,
Username: s.Username,
@@ -285,21 +274,27 @@ func (s *SlackPayload) createPayload(text string, attachments []SlackAttachment)
}
}
-// GetSlackPayload converts a slack webhook into a SlackPayload
-func GetSlackPayload(p api.Payloader, event webhook_module.HookEventType, meta string) (api.Payloader, error) {
- s := new(SlackPayload)
+type slackConvertor struct {
+ Channel string
+ Username string
+ IconURL string
+ Color string
+}
- slack := &SlackMeta{}
- if err := json.Unmarshal([]byte(meta), &slack); err != nil {
- return s, errors.New("GetSlackPayload meta json:" + err.Error())
+var _ payloadConvertor[SlackPayload] = slackConvertor{}
+
+func newSlackRequest(ctx context.Context, w *webhook_model.Webhook, t *webhook_model.HookTask) (*http.Request, []byte, error) {
+ meta := &SlackMeta{}
+ if err := json.Unmarshal([]byte(w.Meta), meta); err != nil {
+ return nil, nil, fmt.Errorf("newSlackRequest meta json: %w", err)
}
-
- s.Channel = slack.Channel
- s.Username = slack.Username
- s.IconURL = slack.IconURL
- s.Color = slack.Color
-
- return convertPayloader(s, p, event)
+ sc := slackConvertor{
+ Channel: meta.Channel,
+ Username: meta.Username,
+ IconURL: meta.IconURL,
+ Color: meta.Color,
+ }
+ return newJSONRequest(sc, w, t, true)
}
var slackChannel = regexp.MustCompile(`^#?[a-z0-9_-]{1,80}$`)
diff --git a/services/webhook/slack_test.go b/services/webhook/slack_test.go
index b1340963e2..7ebf16aba2 100644
--- a/services/webhook/slack_test.go
+++ b/services/webhook/slack_test.go
@@ -4,8 +4,11 @@
package webhook
import (
+ "context"
"testing"
+ webhook_model "code.gitea.io/gitea/models/webhook"
+ "code.gitea.io/gitea/modules/json"
api "code.gitea.io/gitea/modules/structs"
webhook_module "code.gitea.io/gitea/modules/webhook"
@@ -14,201 +17,180 @@ import (
)
func TestSlackPayload(t *testing.T) {
+ sc := slackConvertor{}
+
t.Run("Create", func(t *testing.T) {
p := createTestPayload()
- d := new(SlackPayload)
- pl, err := d.Create(p)
+ pl, err := sc.Create(p)
require.NoError(t, err)
- require.NotNil(t, pl)
- require.IsType(t, &SlackPayload{}, pl)
- assert.Equal(t, "[:] branch created by user1", pl.(*SlackPayload).Text)
+ assert.Equal(t, "[:] branch created by user1", pl.Text)
})
t.Run("Delete", func(t *testing.T) {
p := deleteTestPayload()
- d := new(SlackPayload)
- pl, err := d.Delete(p)
+ pl, err := sc.Delete(p)
require.NoError(t, err)
- require.NotNil(t, pl)
- require.IsType(t, &SlackPayload{}, pl)
- assert.Equal(t, "[:test] branch deleted by user1", pl.(*SlackPayload).Text)
+ assert.Equal(t, "[:test] branch deleted by user1", pl.Text)
})
t.Run("Fork", func(t *testing.T) {
p := forkTestPayload()
- d := new(SlackPayload)
- pl, err := d.Fork(p)
+ pl, err := sc.Fork(p)
require.NoError(t, err)
- require.NotNil(t, pl)
- require.IsType(t, &SlackPayload{}, pl)
- assert.Equal(t, " is forked to ", pl.(*SlackPayload).Text)
+ assert.Equal(t, " is forked to ", pl.Text)
})
t.Run("Push", func(t *testing.T) {
p := pushTestPayload()
- d := new(SlackPayload)
- pl, err := d.Push(p)
+ pl, err := sc.Push(p)
require.NoError(t, err)
- require.NotNil(t, pl)
- require.IsType(t, &SlackPayload{}, pl)
- assert.Equal(t, "[:] 2 new commits pushed by user1", pl.(*SlackPayload).Text)
+ assert.Equal(t, "[:] 2 new commits pushed by user1", pl.Text)
})
t.Run("Issue", func(t *testing.T) {
p := issueTestPayload()
- d := new(SlackPayload)
p.Action = api.HookIssueOpened
- pl, err := d.Issue(p)
+ pl, err := sc.Issue(p)
require.NoError(t, err)
- require.NotNil(t, pl)
- require.IsType(t, &SlackPayload{}, pl)
- assert.Equal(t, "[] Issue opened: by ", pl.(*SlackPayload).Text)
+ assert.Equal(t, "[] Issue opened: by ", pl.Text)
p.Action = api.HookIssueClosed
- pl, err = d.Issue(p)
+ pl, err = sc.Issue(p)
require.NoError(t, err)
- require.NotNil(t, pl)
- require.IsType(t, &SlackPayload{}, pl)
- assert.Equal(t, "[] Issue closed: by ", pl.(*SlackPayload).Text)
+ assert.Equal(t, "[] Issue closed: by ", pl.Text)
})
t.Run("IssueComment", func(t *testing.T) {
p := issueCommentTestPayload()
- d := new(SlackPayload)
- pl, err := d.IssueComment(p)
+ pl, err := sc.IssueComment(p)
require.NoError(t, err)
- require.NotNil(t, pl)
- require.IsType(t, &SlackPayload{}, pl)
- assert.Equal(t, "[] New comment on issue by ", pl.(*SlackPayload).Text)
+ assert.Equal(t, "[] New comment on issue by ", pl.Text)
})
t.Run("PullRequest", func(t *testing.T) {
p := pullRequestTestPayload()
- d := new(SlackPayload)
- pl, err := d.PullRequest(p)
+ pl, err := sc.PullRequest(p)
require.NoError(t, err)
- require.NotNil(t, pl)
- require.IsType(t, &SlackPayload{}, pl)
- assert.Equal(t, "[] Pull request opened: by ", pl.(*SlackPayload).Text)
+ assert.Equal(t, "[] Pull request opened: by ", pl.Text)
})
t.Run("PullRequestComment", func(t *testing.T) {
p := pullRequestCommentTestPayload()
- d := new(SlackPayload)
- pl, err := d.IssueComment(p)
+ pl, err := sc.IssueComment(p)
require.NoError(t, err)
- require.NotNil(t, pl)
- require.IsType(t, &SlackPayload{}, pl)
- assert.Equal(t, "[] New comment on pull request by ", pl.(*SlackPayload).Text)
+ assert.Equal(t, "[] New comment on pull request by ", pl.Text)
})
t.Run("Review", func(t *testing.T) {
p := pullRequestTestPayload()
p.Action = api.HookIssueReviewed
- d := new(SlackPayload)
- pl, err := d.Review(p, webhook_module.HookEventPullRequestReviewApproved)
+ pl, err := sc.Review(p, webhook_module.HookEventPullRequestReviewApproved)
require.NoError(t, err)
- require.NotNil(t, pl)
- require.IsType(t, &SlackPayload{}, pl)
- assert.Equal(t, "[] Pull request review approved: [#12 Fix bug](http://localhost:3000/test/repo/pulls/12) by ", pl.(*SlackPayload).Text)
+ assert.Equal(t, "[] Pull request review approved: [#12 Fix bug](http://localhost:3000/test/repo/pulls/12) by ", pl.Text)
})
t.Run("Repository", func(t *testing.T) {
p := repositoryTestPayload()
- d := new(SlackPayload)
- pl, err := d.Repository(p)
+ pl, err := sc.Repository(p)
require.NoError(t, err)
- require.NotNil(t, pl)
- require.IsType(t, &SlackPayload{}, pl)
- assert.Equal(t, "[] Repository created by ", pl.(*SlackPayload).Text)
+ assert.Equal(t, "[] Repository created by ", pl.Text)
})
t.Run("Package", func(t *testing.T) {
p := packageTestPayload()
- d := new(SlackPayload)
- pl, err := d.Package(p)
+ pl, err := sc.Package(p)
require.NoError(t, err)
- require.NotNil(t, pl)
- require.IsType(t, &SlackPayload{}, pl)
- assert.Equal(t, "Package created: by ", pl.(*SlackPayload).Text)
+ assert.Equal(t, "Package created: by ", pl.Text)
})
t.Run("Wiki", func(t *testing.T) {
p := wikiTestPayload()
- d := new(SlackPayload)
p.Action = api.HookWikiCreated
- pl, err := d.Wiki(p)
+ pl, err := sc.Wiki(p)
require.NoError(t, err)
- require.NotNil(t, pl)
- require.IsType(t, &SlackPayload{}, pl)
- assert.Equal(t, "[] New wiki page '' (Wiki change comment) by ", pl.(*SlackPayload).Text)
+ assert.Equal(t, "[] New wiki page '' (Wiki change comment) by ", pl.Text)
p.Action = api.HookWikiEdited
- pl, err = d.Wiki(p)
+ pl, err = sc.Wiki(p)
require.NoError(t, err)
- require.NotNil(t, pl)
- require.IsType(t, &SlackPayload{}, pl)
- assert.Equal(t, "[] Wiki page '' edited (Wiki change comment) by ", pl.(*SlackPayload).Text)
+ assert.Equal(t, "[] Wiki page '' edited (Wiki change comment) by ", pl.Text)
p.Action = api.HookWikiDeleted
- pl, err = d.Wiki(p)
+ pl, err = sc.Wiki(p)
require.NoError(t, err)
- require.NotNil(t, pl)
- require.IsType(t, &SlackPayload{}, pl)
- assert.Equal(t, "[] Wiki page '' deleted by ", pl.(*SlackPayload).Text)
+ assert.Equal(t, "[] Wiki page '' deleted by ", pl.Text)
})
t.Run("Release", func(t *testing.T) {
p := pullReleaseTestPayload()
- d := new(SlackPayload)
- pl, err := d.Release(p)
+ pl, err := sc.Release(p)
require.NoError(t, err)
- require.NotNil(t, pl)
- require.IsType(t, &SlackPayload{}, pl)
- assert.Equal(t, "[] Release created: by ", pl.(*SlackPayload).Text)
+ assert.Equal(t, "[] Release created: by ", pl.Text)
})
}
func TestSlackJSONPayload(t *testing.T) {
p := pushTestPayload()
-
- pl, err := new(SlackPayload).Push(p)
+ data, err := p.JSONPayload()
require.NoError(t, err)
- require.NotNil(t, pl)
- require.IsType(t, &SlackPayload{}, pl)
- json, err := pl.JSONPayload()
+ hook := &webhook_model.Webhook{
+ RepoID: 3,
+ IsActive: true,
+ Type: webhook_module.SLACK,
+ URL: "https://slack.example.com/",
+ Meta: `{}`,
+ HTTPMethod: "POST",
+ }
+ task := &webhook_model.HookTask{
+ HookID: hook.ID,
+ EventType: webhook_module.HookEventPush,
+ PayloadContent: string(data),
+ PayloadVersion: 2,
+ }
+
+ req, reqBody, err := newSlackRequest(context.Background(), hook, task)
+ require.NotNil(t, req)
+ require.NotNil(t, reqBody)
require.NoError(t, err)
- assert.NotEmpty(t, json)
+
+ assert.Equal(t, "POST", req.Method)
+ assert.Equal(t, "https://slack.example.com/", req.URL.String())
+ assert.Equal(t, "sha256=", req.Header.Get("X-Hub-Signature-256"))
+ assert.Equal(t, "application/json", req.Header.Get("Content-Type"))
+ var body SlackPayload
+ err = json.NewDecoder(req.Body).Decode(&body)
+ assert.NoError(t, err)
+ assert.Equal(t, "[:] 2 new commits pushed by user1", body.Text)
}
func TestIsValidSlackChannel(t *testing.T) {
diff --git a/services/webhook/telegram.go b/services/webhook/telegram.go
index 1bdc74e183..e4a5b5a424 100644
--- a/services/webhook/telegram.go
+++ b/services/webhook/telegram.go
@@ -4,14 +4,15 @@
package webhook
import (
+ "context"
"fmt"
+ "net/http"
"strings"
webhook_model "code.gitea.io/gitea/models/webhook"
"code.gitea.io/gitea/modules/git"
"code.gitea.io/gitea/modules/json"
"code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/markup"
api "code.gitea.io/gitea/modules/structs"
webhook_module "code.gitea.io/gitea/modules/webhook"
)
@@ -41,22 +42,8 @@ func GetTelegramHook(w *webhook_model.Webhook) *TelegramMeta {
return s
}
-var _ PayloadConvertor = &TelegramPayload{}
-
-// JSONPayload Marshals the TelegramPayload to json
-func (t *TelegramPayload) JSONPayload() ([]byte, error) {
- t.ParseMode = "HTML"
- t.DisableWebPreview = true
- t.Message = markup.Sanitize(t.Message)
- data, err := json.MarshalIndent(t, "", " ")
- if err != nil {
- return []byte{}, err
- }
- return data, nil
-}
-
// Create implements PayloadConvertor Create method
-func (t *TelegramPayload) Create(p *api.CreatePayload) (api.Payloader, error) {
+func (t telegramConvertor) Create(p *api.CreatePayload) (TelegramPayload, error) {
// created tag/branch
refName := git.RefName(p.Ref).ShortName()
title := fmt.Sprintf(`[%s] %s %s created`, p.Repo.HTMLURL, p.Repo.FullName, p.RefType,
@@ -66,7 +53,7 @@ func (t *TelegramPayload) Create(p *api.CreatePayload) (api.Payloader, error) {
}
// Delete implements PayloadConvertor Delete method
-func (t *TelegramPayload) Delete(p *api.DeletePayload) (api.Payloader, error) {
+func (t telegramConvertor) Delete(p *api.DeletePayload) (TelegramPayload, error) {
// created tag/branch
refName := git.RefName(p.Ref).ShortName()
title := fmt.Sprintf(`[%s] %s %s deleted`, p.Repo.HTMLURL, p.Repo.FullName, p.RefType,
@@ -76,14 +63,14 @@ func (t *TelegramPayload) Delete(p *api.DeletePayload) (api.Payloader, error) {
}
// Fork implements PayloadConvertor Fork method
-func (t *TelegramPayload) Fork(p *api.ForkPayload) (api.Payloader, error) {
+func (t telegramConvertor) Fork(p *api.ForkPayload) (TelegramPayload, error) {
title := fmt.Sprintf(`%s is forked to %s`, p.Forkee.FullName, p.Repo.HTMLURL, p.Repo.FullName)
return createTelegramPayload(title), nil
}
// Push implements PayloadConvertor Push method
-func (t *TelegramPayload) Push(p *api.PushPayload) (api.Payloader, error) {
+func (t telegramConvertor) Push(p *api.PushPayload) (TelegramPayload, error) {
var (
branchName = git.RefName(p.Ref).ShortName()
commitDesc string
@@ -121,34 +108,34 @@ func (t *TelegramPayload) Push(p *api.PushPayload) (api.Payloader, error) {
}
// Issue implements PayloadConvertor Issue method
-func (t *TelegramPayload) Issue(p *api.IssuePayload) (api.Payloader, error) {
+func (t telegramConvertor) Issue(p *api.IssuePayload) (TelegramPayload, error) {
text, _, attachmentText, _ := getIssuesPayloadInfo(p, htmlLinkFormatter, true)
return createTelegramPayload(text + "\n\n" + attachmentText), nil
}
// IssueComment implements PayloadConvertor IssueComment method
-func (t *TelegramPayload) IssueComment(p *api.IssueCommentPayload) (api.Payloader, error) {
+func (t telegramConvertor) IssueComment(p *api.IssueCommentPayload) (TelegramPayload, error) {
text, _, _ := getIssueCommentPayloadInfo(p, htmlLinkFormatter, true)
return createTelegramPayload(text + "\n" + p.Comment.Body), nil
}
// PullRequest implements PayloadConvertor PullRequest method
-func (t *TelegramPayload) PullRequest(p *api.PullRequestPayload) (api.Payloader, error) {
+func (t telegramConvertor) PullRequest(p *api.PullRequestPayload) (TelegramPayload, error) {
text, _, attachmentText, _ := getPullRequestPayloadInfo(p, htmlLinkFormatter, true)
return createTelegramPayload(text + "\n" + attachmentText), nil
}
// Review implements PayloadConvertor Review method
-func (t *TelegramPayload) Review(p *api.PullRequestPayload, event webhook_module.HookEventType) (api.Payloader, error) {
+func (t telegramConvertor) Review(p *api.PullRequestPayload, event webhook_module.HookEventType) (TelegramPayload, error) {
var text, attachmentText string
switch p.Action {
case api.HookIssueReviewed:
action, err := parseHookPullRequestEventType(event)
if err != nil {
- return nil, err
+ return TelegramPayload{}, err
}
text = fmt.Sprintf("[%s] Pull request review %s: #%d %s", p.Repository.FullName, action, p.Index, p.PullRequest.Title)
@@ -159,7 +146,7 @@ func (t *TelegramPayload) Review(p *api.PullRequestPayload, event webhook_module
}
// Repository implements PayloadConvertor Repository method
-func (t *TelegramPayload) Repository(p *api.RepositoryPayload) (api.Payloader, error) {
+func (t telegramConvertor) Repository(p *api.RepositoryPayload) (TelegramPayload, error) {
var title string
switch p.Action {
case api.HookRepoCreated:
@@ -169,36 +156,39 @@ func (t *TelegramPayload) Repository(p *api.RepositoryPayload) (api.Payloader, e
title = fmt.Sprintf("[%s] Repository deleted", p.Repository.FullName)
return createTelegramPayload(title), nil
}
- return nil, nil
+ return TelegramPayload{}, nil
}
// Wiki implements PayloadConvertor Wiki method
-func (t *TelegramPayload) Wiki(p *api.WikiPayload) (api.Payloader, error) {
+func (t telegramConvertor) Wiki(p *api.WikiPayload) (TelegramPayload, error) {
text, _, _ := getWikiPayloadInfo(p, htmlLinkFormatter, true)
return createTelegramPayload(text), nil
}
// Release implements PayloadConvertor Release method
-func (t *TelegramPayload) Release(p *api.ReleasePayload) (api.Payloader, error) {
+func (t telegramConvertor) Release(p *api.ReleasePayload) (TelegramPayload, error) {
text, _ := getReleasePayloadInfo(p, htmlLinkFormatter, true)
return createTelegramPayload(text), nil
}
-func (t *TelegramPayload) Package(p *api.PackagePayload) (api.Payloader, error) {
+func (t telegramConvertor) Package(p *api.PackagePayload) (TelegramPayload, error) {
text, _ := getPackagePayloadInfo(p, htmlLinkFormatter, true)
return createTelegramPayload(text), nil
}
-// GetTelegramPayload converts a telegram webhook into a TelegramPayload
-func GetTelegramPayload(p api.Payloader, event webhook_module.HookEventType, _ string) (api.Payloader, error) {
- return convertPayloader(new(TelegramPayload), p, event)
-}
-
-func createTelegramPayload(message string) *TelegramPayload {
- return &TelegramPayload{
+func createTelegramPayload(message string) TelegramPayload {
+ return TelegramPayload{
Message: strings.TrimSpace(message),
}
}
+
+type telegramConvertor struct{}
+
+var _ payloadConvertor[TelegramPayload] = telegramConvertor{}
+
+func newTelegramRequest(ctx context.Context, w *webhook_model.Webhook, t *webhook_model.HookTask) (*http.Request, []byte, error) {
+ return newJSONRequest(telegramConvertor{}, w, t, true)
+}
diff --git a/services/webhook/telegram_test.go b/services/webhook/telegram_test.go
index 5b9927d057..27ab96cd09 100644
--- a/services/webhook/telegram_test.go
+++ b/services/webhook/telegram_test.go
@@ -4,8 +4,11 @@
package webhook
import (
+ "context"
"testing"
+ webhook_model "code.gitea.io/gitea/models/webhook"
+ "code.gitea.io/gitea/modules/json"
api "code.gitea.io/gitea/modules/structs"
webhook_module "code.gitea.io/gitea/modules/webhook"
@@ -14,199 +17,177 @@ import (
)
func TestTelegramPayload(t *testing.T) {
+ tc := telegramConvertor{}
t.Run("Create", func(t *testing.T) {
p := createTestPayload()
- d := new(TelegramPayload)
- pl, err := d.Create(p)
+ pl, err := tc.Create(p)
require.NoError(t, err)
- require.NotNil(t, pl)
- require.IsType(t, &TelegramPayload{}, pl)
- assert.Equal(t, `[test/repo] branch test created`, pl.(*TelegramPayload).Message)
+ assert.Equal(t, `[test/repo] branch test created`, pl.Message)
})
t.Run("Delete", func(t *testing.T) {
p := deleteTestPayload()
- d := new(TelegramPayload)
- pl, err := d.Delete(p)
+ pl, err := tc.Delete(p)
require.NoError(t, err)
- require.NotNil(t, pl)
- require.IsType(t, &TelegramPayload{}, pl)
- assert.Equal(t, `[test/repo] branch test deleted`, pl.(*TelegramPayload).Message)
+ assert.Equal(t, `[test/repo] branch test deleted`, pl.Message)
})
t.Run("Fork", func(t *testing.T) {
p := forkTestPayload()
- d := new(TelegramPayload)
- pl, err := d.Fork(p)
+ pl, err := tc.Fork(p)
require.NoError(t, err)
- require.NotNil(t, pl)
- require.IsType(t, &TelegramPayload{}, pl)
- assert.Equal(t, `test/repo2 is forked to test/repo`, pl.(*TelegramPayload).Message)
+ assert.Equal(t, `test/repo2 is forked to test/repo`, pl.Message)
})
t.Run("Push", func(t *testing.T) {
p := pushTestPayload()
- d := new(TelegramPayload)
- pl, err := d.Push(p)
+ pl, err := tc.Push(p)
require.NoError(t, err)
- require.NotNil(t, pl)
- require.IsType(t, &TelegramPayload{}, pl)
- assert.Equal(t, "[test/repo:test] 2 new commits\n[2020558] commit message - user1\n[2020558] commit message - user1", pl.(*TelegramPayload).Message)
+ assert.Equal(t, "[test/repo:test] 2 new commits\n[2020558] commit message - user1\n[2020558] commit message - user1", pl.Message)
})
t.Run("Issue", func(t *testing.T) {
p := issueTestPayload()
- d := new(TelegramPayload)
p.Action = api.HookIssueOpened
- pl, err := d.Issue(p)
+ pl, err := tc.Issue(p)
require.NoError(t, err)
- require.NotNil(t, pl)
- require.IsType(t, &TelegramPayload{}, pl)
- assert.Equal(t, "[test/repo] Issue opened: #2 crash by user1\n\nissue body", pl.(*TelegramPayload).Message)
+ assert.Equal(t, "[test/repo] Issue opened: #2 crash by user1\n\nissue body", pl.Message)
p.Action = api.HookIssueClosed
- pl, err = d.Issue(p)
+ pl, err = tc.Issue(p)
require.NoError(t, err)
- require.NotNil(t, pl)
- require.IsType(t, &TelegramPayload{}, pl)
- assert.Equal(t, `[test/repo] Issue closed: #2 crash by user1`, pl.(*TelegramPayload).Message)
+ assert.Equal(t, `[test/repo] Issue closed: #2 crash by user1`, pl.Message)
})
t.Run("IssueComment", func(t *testing.T) {
p := issueCommentTestPayload()
- d := new(TelegramPayload)
- pl, err := d.IssueComment(p)
+ pl, err := tc.IssueComment(p)
require.NoError(t, err)
- require.NotNil(t, pl)
- require.IsType(t, &TelegramPayload{}, pl)
- assert.Equal(t, "[test/repo] New comment on issue #2 crash by user1\nmore info needed", pl.(*TelegramPayload).Message)
+ assert.Equal(t, "[test/repo] New comment on issue #2 crash by user1\nmore info needed", pl.Message)
})
t.Run("PullRequest", func(t *testing.T) {
p := pullRequestTestPayload()
- d := new(TelegramPayload)
- pl, err := d.PullRequest(p)
+ pl, err := tc.PullRequest(p)
require.NoError(t, err)
- require.NotNil(t, pl)
- require.IsType(t, &TelegramPayload{}, pl)
- assert.Equal(t, "[test/repo] Pull request opened: #12 Fix bug by user1\nfixes bug #2", pl.(*TelegramPayload).Message)
+ assert.Equal(t, "[test/repo] Pull request opened: #12 Fix bug by user1\nfixes bug #2", pl.Message)
})
t.Run("PullRequestComment", func(t *testing.T) {
p := pullRequestCommentTestPayload()
- d := new(TelegramPayload)
- pl, err := d.IssueComment(p)
+ pl, err := tc.IssueComment(p)
require.NoError(t, err)
- require.NotNil(t, pl)
- require.IsType(t, &TelegramPayload{}, pl)
- assert.Equal(t, "[test/repo] New comment on pull request #12 Fix bug by user1\nchanges requested", pl.(*TelegramPayload).Message)
+ assert.Equal(t, "[test/repo] New comment on pull request #12 Fix bug by user1\nchanges requested", pl.Message)
})
t.Run("Review", func(t *testing.T) {
p := pullRequestTestPayload()
p.Action = api.HookIssueReviewed
- d := new(TelegramPayload)
- pl, err := d.Review(p, webhook_module.HookEventPullRequestReviewApproved)
+ pl, err := tc.Review(p, webhook_module.HookEventPullRequestReviewApproved)
require.NoError(t, err)
- require.NotNil(t, pl)
- require.IsType(t, &TelegramPayload{}, pl)
- assert.Equal(t, "[test/repo] Pull request review approved: #12 Fix bug\ngood job", pl.(*TelegramPayload).Message)
+ assert.Equal(t, "[test/repo] Pull request review approved: #12 Fix bug\ngood job", pl.Message)
})
t.Run("Repository", func(t *testing.T) {
p := repositoryTestPayload()
- d := new(TelegramPayload)
- pl, err := d.Repository(p)
+ pl, err := tc.Repository(p)
require.NoError(t, err)
- require.NotNil(t, pl)
- require.IsType(t, &TelegramPayload{}, pl)
- assert.Equal(t, `[test/repo] Repository created`, pl.(*TelegramPayload).Message)
+ assert.Equal(t, `[test/repo] Repository created`, pl.Message)
})
t.Run("Package", func(t *testing.T) {
p := packageTestPayload()
- d := new(TelegramPayload)
- pl, err := d.Package(p)
+ pl, err := tc.Package(p)
require.NoError(t, err)
- require.NotNil(t, pl)
- require.IsType(t, &TelegramPayload{}, pl)
- assert.Equal(t, `Package created: GiteaContainer:latest by user1`, pl.(*TelegramPayload).Message)
+ assert.Equal(t, `Package created: GiteaContainer:latest by user1`, pl.Message)
})
t.Run("Wiki", func(t *testing.T) {
p := wikiTestPayload()
- d := new(TelegramPayload)
p.Action = api.HookWikiCreated
- pl, err := d.Wiki(p)
+ pl, err := tc.Wiki(p)
require.NoError(t, err)
- require.NotNil(t, pl)
- require.IsType(t, &TelegramPayload{}, pl)
- assert.Equal(t, `[test/repo] New wiki page 'index' (Wiki change comment) by user1`, pl.(*TelegramPayload).Message)
+ assert.Equal(t, `[test/repo] New wiki page 'index' (Wiki change comment) by user1`, pl.Message)
p.Action = api.HookWikiEdited
- pl, err = d.Wiki(p)
+ pl, err = tc.Wiki(p)
require.NoError(t, err)
- require.NotNil(t, pl)
- require.IsType(t, &TelegramPayload{}, pl)
- assert.Equal(t, `[test/repo] Wiki page 'index' edited (Wiki change comment) by user1`, pl.(*TelegramPayload).Message)
+ assert.Equal(t, `[test/repo] Wiki page 'index' edited (Wiki change comment) by user1`, pl.Message)
p.Action = api.HookWikiDeleted
- pl, err = d.Wiki(p)
+ pl, err = tc.Wiki(p)
require.NoError(t, err)
- require.NotNil(t, pl)
- require.IsType(t, &TelegramPayload{}, pl)
- assert.Equal(t, `[test/repo] Wiki page 'index' deleted by user1`, pl.(*TelegramPayload).Message)
+ assert.Equal(t, `[test/repo] Wiki page 'index' deleted by user1`, pl.Message)
})
t.Run("Release", func(t *testing.T) {
p := pullReleaseTestPayload()
- d := new(TelegramPayload)
- pl, err := d.Release(p)
+ pl, err := tc.Release(p)
require.NoError(t, err)
- require.NotNil(t, pl)
- require.IsType(t, &TelegramPayload{}, pl)
- assert.Equal(t, `[test/repo] Release created: v1.0 by user1`, pl.(*TelegramPayload).Message)
+ assert.Equal(t, `[test/repo] Release created: v1.0 by user1`, pl.Message)
})
}
func TestTelegramJSONPayload(t *testing.T) {
p := pushTestPayload()
-
- pl, err := new(TelegramPayload).Push(p)
+ data, err := p.JSONPayload()
require.NoError(t, err)
- require.NotNil(t, pl)
- require.IsType(t, &TelegramPayload{}, pl)
- json, err := pl.JSONPayload()
+ hook := &webhook_model.Webhook{
+ RepoID: 3,
+ IsActive: true,
+ Type: webhook_module.TELEGRAM,
+ URL: "https://telegram.example.com/",
+ Meta: ``,
+ HTTPMethod: "POST",
+ }
+ task := &webhook_model.HookTask{
+ HookID: hook.ID,
+ EventType: webhook_module.HookEventPush,
+ PayloadContent: string(data),
+ PayloadVersion: 2,
+ }
+
+ req, reqBody, err := newTelegramRequest(context.Background(), hook, task)
+ require.NotNil(t, req)
+ require.NotNil(t, reqBody)
require.NoError(t, err)
- assert.NotEmpty(t, json)
+
+ assert.Equal(t, "POST", req.Method)
+ assert.Equal(t, "https://telegram.example.com/", req.URL.String())
+ assert.Equal(t, "sha256=", req.Header.Get("X-Hub-Signature-256"))
+ assert.Equal(t, "application/json", req.Header.Get("Content-Type"))
+ var body TelegramPayload
+ err = json.NewDecoder(req.Body).Decode(&body)
+ assert.NoError(t, err)
+ assert.Equal(t, "[test/repo:test] 2 new commits\n[2020558] commit message - user1\n[2020558] commit message - user1", body.Message)
}
diff --git a/services/webhook/webhook.go b/services/webhook/webhook.go
index 996942d1e5..e6646501da 100644
--- a/services/webhook/webhook.go
+++ b/services/webhook/webhook.go
@@ -7,6 +7,7 @@ import (
"context"
"errors"
"fmt"
+ "net/http"
"strings"
"code.gitea.io/gitea/models/db"
@@ -26,48 +27,16 @@ import (
"github.com/gobwas/glob"
)
-type webhook struct {
- name webhook_module.HookType
- payloadCreator func(p api.Payloader, event webhook_module.HookEventType, meta string) (api.Payloader, error)
-}
-
-var webhooks = map[webhook_module.HookType]*webhook{
- webhook_module.SLACK: {
- name: webhook_module.SLACK,
- payloadCreator: GetSlackPayload,
- },
- webhook_module.DISCORD: {
- name: webhook_module.DISCORD,
- payloadCreator: GetDiscordPayload,
- },
- webhook_module.DINGTALK: {
- name: webhook_module.DINGTALK,
- payloadCreator: GetDingtalkPayload,
- },
- webhook_module.TELEGRAM: {
- name: webhook_module.TELEGRAM,
- payloadCreator: GetTelegramPayload,
- },
- webhook_module.MSTEAMS: {
- name: webhook_module.MSTEAMS,
- payloadCreator: GetMSTeamsPayload,
- },
- webhook_module.FEISHU: {
- name: webhook_module.FEISHU,
- payloadCreator: GetFeishuPayload,
- },
- webhook_module.MATRIX: {
- name: webhook_module.MATRIX,
- payloadCreator: GetMatrixPayload,
- },
- webhook_module.WECHATWORK: {
- name: webhook_module.WECHATWORK,
- payloadCreator: GetWechatworkPayload,
- },
- webhook_module.PACKAGIST: {
- name: webhook_module.PACKAGIST,
- payloadCreator: GetPackagistPayload,
- },
+var webhookRequesters = map[webhook_module.HookType]func(context.Context, *webhook_model.Webhook, *webhook_model.HookTask) (req *http.Request, body []byte, err error){
+ webhook_module.SLACK: newSlackRequest,
+ webhook_module.DISCORD: newDiscordRequest,
+ webhook_module.DINGTALK: newDingtalkRequest,
+ webhook_module.TELEGRAM: newTelegramRequest,
+ webhook_module.MSTEAMS: newMSTeamsRequest,
+ webhook_module.FEISHU: newFeishuRequest,
+ webhook_module.MATRIX: newMatrixRequest,
+ webhook_module.WECHATWORK: newWechatworkRequest,
+ webhook_module.PACKAGIST: newPackagistRequest,
}
// IsValidHookTaskType returns true if a webhook registered
@@ -75,7 +44,7 @@ func IsValidHookTaskType(name string) bool {
if name == webhook_module.FORGEJO || name == webhook_module.GITEA || name == webhook_module.GOGS {
return true
}
- _, ok := webhooks[name]
+ _, ok := webhookRequesters[name]
return ok
}
@@ -159,7 +128,9 @@ func checkBranch(w *webhook_model.Webhook, branch string) bool {
return g.Match(branch)
}
-// PrepareWebhook creates a hook task and enqueues it for processing
+// PrepareWebhook creates a hook task and enqueues it for processing.
+// The payload is saved as-is. The adjustments depending on the webhook type happen
+// right before delivery, in the [Deliver] method.
func PrepareWebhook(ctx context.Context, w *webhook_model.Webhook, event webhook_module.HookEventType, p api.Payloader) error {
// Skip sending if webhooks are disabled.
if setting.DisableWebhooks {
@@ -193,25 +164,19 @@ func PrepareWebhook(ctx context.Context, w *webhook_model.Webhook, event webhook
}
}
- var payloader api.Payloader
- var err error
- webhook, ok := webhooks[w.Type]
- if ok {
- payloader, err = webhook.payloadCreator(p, event, w.Meta)
- if err != nil {
- return fmt.Errorf("create payload for %s[%s]: %w", w.Type, event, err)
- }
- } else {
- payloader = p
+ payload, err := p.JSONPayload()
+ if err != nil {
+ return fmt.Errorf("JSONPayload for %s: %w", event, err)
}
task, err := webhook_model.CreateHookTask(ctx, &webhook_model.HookTask{
- HookID: w.ID,
- Payloader: payloader,
- EventType: event,
+ HookID: w.ID,
+ PayloadContent: string(payload),
+ EventType: event,
+ PayloadVersion: 2,
})
if err != nil {
- return fmt.Errorf("CreateHookTask: %w", err)
+ return fmt.Errorf("CreateHookTask for %s: %w", event, err)
}
return enqueueHookTask(task.ID)
diff --git a/services/webhook/webhook_test.go b/services/webhook/webhook_test.go
index 338b94360b..5f5c146232 100644
--- a/services/webhook/webhook_test.go
+++ b/services/webhook/webhook_test.go
@@ -77,7 +77,3 @@ func TestPrepareWebhooksBranchFilterNoMatch(t *testing.T) {
unittest.AssertNotExistsBean(t, hookTask)
}
}
-
-// TODO TestHookTask_deliver
-
-// TODO TestDeliverHooks
diff --git a/services/webhook/wechatwork.go b/services/webhook/wechatwork.go
index 80245c7e77..46e7856ecf 100644
--- a/services/webhook/wechatwork.go
+++ b/services/webhook/wechatwork.go
@@ -4,11 +4,13 @@
package webhook
import (
+ "context"
"fmt"
+ "net/http"
"strings"
+ webhook_model "code.gitea.io/gitea/models/webhook"
"code.gitea.io/gitea/modules/git"
- "code.gitea.io/gitea/modules/json"
api "code.gitea.io/gitea/modules/structs"
webhook_module "code.gitea.io/gitea/modules/webhook"
)
@@ -28,20 +30,8 @@ type (
}
)
-// SetSecret sets the Wechatwork secret
-func (f *WechatworkPayload) SetSecret(_ string) {}
-
-// JSONPayload Marshals the WechatworkPayload to json
-func (f *WechatworkPayload) JSONPayload() ([]byte, error) {
- data, err := json.MarshalIndent(f, "", " ")
- if err != nil {
- return []byte{}, err
- }
- return data, nil
-}
-
-func newWechatworkMarkdownPayload(title string) *WechatworkPayload {
- return &WechatworkPayload{
+func newWechatworkMarkdownPayload(title string) WechatworkPayload {
+ return WechatworkPayload{
Msgtype: "markdown",
Markdown: struct {
Content string `json:"content"`
@@ -51,10 +41,8 @@ func newWechatworkMarkdownPayload(title string) *WechatworkPayload {
}
}
-var _ PayloadConvertor = &WechatworkPayload{}
-
// Create implements PayloadConvertor Create method
-func (f *WechatworkPayload) Create(p *api.CreatePayload) (api.Payloader, error) {
+func (wc wechatworkConvertor) Create(p *api.CreatePayload) (WechatworkPayload, error) {
// created tag/branch
refName := git.RefName(p.Ref).ShortName()
title := fmt.Sprintf("[%s] %s %s created", p.Repo.FullName, p.RefType, refName)
@@ -63,7 +51,7 @@ func (f *WechatworkPayload) Create(p *api.CreatePayload) (api.Payloader, error)
}
// Delete implements PayloadConvertor Delete method
-func (f *WechatworkPayload) Delete(p *api.DeletePayload) (api.Payloader, error) {
+func (wc wechatworkConvertor) Delete(p *api.DeletePayload) (WechatworkPayload, error) {
// created tag/branch
refName := git.RefName(p.Ref).ShortName()
title := fmt.Sprintf("[%s] %s %s deleted", p.Repo.FullName, p.RefType, refName)
@@ -72,14 +60,14 @@ func (f *WechatworkPayload) Delete(p *api.DeletePayload) (api.Payloader, error)
}
// Fork implements PayloadConvertor Fork method
-func (f *WechatworkPayload) Fork(p *api.ForkPayload) (api.Payloader, error) {
+func (wc wechatworkConvertor) Fork(p *api.ForkPayload) (WechatworkPayload, error) {
title := fmt.Sprintf("%s is forked to %s", p.Forkee.FullName, p.Repo.FullName)
return newWechatworkMarkdownPayload(title), nil
}
// Push implements PayloadConvertor Push method
-func (f *WechatworkPayload) Push(p *api.PushPayload) (api.Payloader, error) {
+func (wc wechatworkConvertor) Push(p *api.PushPayload) (WechatworkPayload, error) {
var (
branchName = git.RefName(p.Ref).ShortName()
commitDesc string
@@ -108,7 +96,7 @@ func (f *WechatworkPayload) Push(p *api.PushPayload) (api.Payloader, error) {
}
// Issue implements PayloadConvertor Issue method
-func (f *WechatworkPayload) Issue(p *api.IssuePayload) (api.Payloader, error) {
+func (wc wechatworkConvertor) Issue(p *api.IssuePayload) (WechatworkPayload, error) {
text, issueTitle, attachmentText, _ := getIssuesPayloadInfo(p, noneLinkFormatter, true)
var content string
content += fmt.Sprintf(" >%s\n >%s \n > %s \n [%s](%s)", text, attachmentText, issueTitle, p.Issue.HTMLURL, p.Issue.HTMLURL)
@@ -117,7 +105,7 @@ func (f *WechatworkPayload) Issue(p *api.IssuePayload) (api.Payloader, error) {
}
// IssueComment implements PayloadConvertor IssueComment method
-func (f *WechatworkPayload) IssueComment(p *api.IssueCommentPayload) (api.Payloader, error) {
+func (wc wechatworkConvertor) IssueComment(p *api.IssueCommentPayload) (WechatworkPayload, error) {
text, issueTitle, _ := getIssueCommentPayloadInfo(p, noneLinkFormatter, true)
var content string
content += fmt.Sprintf(" >%s\n >%s \n >%s \n [%s](%s)", text, p.Comment.Body, issueTitle, p.Comment.HTMLURL, p.Comment.HTMLURL)
@@ -126,7 +114,7 @@ func (f *WechatworkPayload) IssueComment(p *api.IssueCommentPayload) (api.Payloa
}
// PullRequest implements PayloadConvertor PullRequest method
-func (f *WechatworkPayload) PullRequest(p *api.PullRequestPayload) (api.Payloader, error) {
+func (wc wechatworkConvertor) PullRequest(p *api.PullRequestPayload) (WechatworkPayload, error) {
text, issueTitle, attachmentText, _ := getPullRequestPayloadInfo(p, noneLinkFormatter, true)
pr := fmt.Sprintf("> %s \r\n > %s \r\n > %s \r\n",
text, issueTitle, attachmentText)
@@ -135,13 +123,13 @@ func (f *WechatworkPayload) PullRequest(p *api.PullRequestPayload) (api.Payloade
}
// Review implements PayloadConvertor Review method
-func (f *WechatworkPayload) Review(p *api.PullRequestPayload, event webhook_module.HookEventType) (api.Payloader, error) {
+func (wc wechatworkConvertor) Review(p *api.PullRequestPayload, event webhook_module.HookEventType) (WechatworkPayload, error) {
var text, title string
switch p.Action {
case api.HookIssueReviewed:
action, err := parseHookPullRequestEventType(event)
if err != nil {
- return nil, err
+ return WechatworkPayload{}, err
}
title = fmt.Sprintf("[%s] Pull request review %s : #%d %s", p.Repository.FullName, action, p.Index, p.PullRequest.Title)
text = p.Review.Content
@@ -151,7 +139,7 @@ func (f *WechatworkPayload) Review(p *api.PullRequestPayload, event webhook_modu
}
// Repository implements PayloadConvertor Repository method
-func (f *WechatworkPayload) Repository(p *api.RepositoryPayload) (api.Payloader, error) {
+func (wc wechatworkConvertor) Repository(p *api.RepositoryPayload) (WechatworkPayload, error) {
var title string
switch p.Action {
case api.HookRepoCreated:
@@ -162,30 +150,33 @@ func (f *WechatworkPayload) Repository(p *api.RepositoryPayload) (api.Payloader,
return newWechatworkMarkdownPayload(title), nil
}
- return nil, nil
+ return WechatworkPayload{}, nil
}
// Wiki implements PayloadConvertor Wiki method
-func (f *WechatworkPayload) Wiki(p *api.WikiPayload) (api.Payloader, error) {
+func (wc wechatworkConvertor) Wiki(p *api.WikiPayload) (WechatworkPayload, error) {
text, _, _ := getWikiPayloadInfo(p, noneLinkFormatter, true)
return newWechatworkMarkdownPayload(text), nil
}
// Release implements PayloadConvertor Release method
-func (f *WechatworkPayload) Release(p *api.ReleasePayload) (api.Payloader, error) {
+func (wc wechatworkConvertor) Release(p *api.ReleasePayload) (WechatworkPayload, error) {
text, _ := getReleasePayloadInfo(p, noneLinkFormatter, true)
return newWechatworkMarkdownPayload(text), nil
}
-func (f *WechatworkPayload) Package(p *api.PackagePayload) (api.Payloader, error) {
+func (wc wechatworkConvertor) Package(p *api.PackagePayload) (WechatworkPayload, error) {
text, _ := getPackagePayloadInfo(p, noneLinkFormatter, true)
return newWechatworkMarkdownPayload(text), nil
}
-// GetWechatworkPayload GetWechatworkPayload converts a ding talk webhook into a WechatworkPayload
-func GetWechatworkPayload(p api.Payloader, event webhook_module.HookEventType, _ string) (api.Payloader, error) {
- return convertPayloader(new(WechatworkPayload), p, event)
+type wechatworkConvertor struct{}
+
+var _ payloadConvertor[WechatworkPayload] = wechatworkConvertor{}
+
+func newWechatworkRequest(ctx context.Context, w *webhook_model.Webhook, t *webhook_model.HookTask) (*http.Request, []byte, error) {
+ return newJSONRequest(wechatworkConvertor{}, w, t, true)
}
diff --git a/services/wiki/wiki.go b/services/wiki/wiki.go
index 81e0b84ea8..01c8cf987f 100644
--- a/services/wiki/wiki.go
+++ b/services/wiki/wiki.go
@@ -16,6 +16,7 @@ import (
"code.gitea.io/gitea/models/unit"
user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/modules/git"
+ "code.gitea.io/gitea/modules/gitrepo"
"code.gitea.io/gitea/modules/log"
repo_module "code.gitea.io/gitea/modules/repository"
"code.gitea.io/gitea/modules/sync"
@@ -87,7 +88,7 @@ func NormalizeWikiBranch(ctx context.Context, repo *repo_model.Repository, to st
return err
}
- if err := gitRepo.SetDefaultBranch(to); err != nil {
+ if err := gitrepo.SetDefaultBranch(ctx, repo, to); err != nil {
return err
}
diff --git a/snap/snapcraft.yaml b/snap/snapcraft.yaml
deleted file mode 100644
index 7c10074bc5..0000000000
--- a/snap/snapcraft.yaml
+++ /dev/null
@@ -1,86 +0,0 @@
-name: gitea
-summary: Gitea - A painless self-hosted Git service
-description: |
- The goal of this project is to make the easiest, fastest, and most painless
- way of setting up a self-hosted Git service. With Go, this can be done with
- an independent binary distribution across ALL platforms that Go supports,
- including Linux, Mac OS X, Windows and ARM.
-
-icon: public/assets/img/logo.png
-confinement: strict
-base: core22
-adopt-info: gitea
-
-architectures:
- - build-on: armhf
- - build-on: amd64
- - build-on: arm64
-
-environment:
- GITEA_CUSTOM: "$SNAP_COMMON"
- GITEA_WORK_DIR: "$SNAP_COMMON"
- GIT_TEMPLATE_DIR: "$SNAP/usr/share/git-core/templates"
- GIT_EXEC_PATH: "$SNAP/usr/lib/git-core"
-
-apps:
- gitea:
- command: gitea
- plugs: [network, network-bind, removable-media]
- web:
- command: gitea web
- daemon: simple
- plugs: [network, network-bind, removable-media]
- dump:
- command: gitea dump
- plugs: [home, removable-media]
- version:
- command: gitea --version
- sqlite:
- command: usr/bin/sqlite3
-
-parts:
- gitea:
- plugin: make
- source: .
- stage-packages: [ git, sqlite3, openssh-client ]
- build-packages: [ git, libpam0g-dev, libsqlite3-dev, build-essential]
- build-snaps: [ go/1.21/stable, node/18/stable ]
- build-environment:
- - LDFLAGS: ""
- override-pull: |
- craftctl default
-
- git config --global --add safe.directory /root/parts/gitea/src
- last_committed_tag="$(git for-each-ref --sort=taggerdate --format '%(tag)' refs/tags | tail -n 1)"
- last_released_tag="$(snap info gitea | awk '$1 == "latest/candidate:" { print $2 }')"
- # If the latest tag from the upstream project has not been released to
- # stable, build that tag instead of master.
- if [ "${last_committed_tag}" != "${last_released_tag}" ]; then
- git fetch
- git checkout "${last_committed_tag}"
- fi
-
- version="$(git describe --always | sed -e 's/-/+git/;y/-/./')"
- [ -n "$(echo $version | grep "+git")" ] && grade=devel || grade=stable
- craftctl set version="$version"
- craftctl set grade="$grade"
-
- override-build: |
- set -x
- sed -i 's/os.Getuid()/1/g' modules/setting/setting.go
- TAGS="bindata sqlite sqlite_unlock_notify pam cert" make build
- install -D gitea "${SNAPCRAFT_PART_INSTALL}/gitea"
- cp -r options "${SNAPCRAFT_PART_INSTALL}/"
-
- prime:
- - -etc
- - -usr/lib/systemd
- - -usr/lib/gcc
- - -usr/lib/sasl2
- - -usr/lib/x86_64-linux-gnu/krb5
- - -usr/share/apport
- - -usr/share/bash-completion
- - -usr/share/git-core/contrib
- - -usr/share/man
- - -usr/share/upstart
- - -var
diff --git a/tailwind.config.js b/tailwind.config.js
index 7f36822001..d783268bd7 100644
--- a/tailwind.config.js
+++ b/tailwind.config.js
@@ -1,17 +1,41 @@
import {readFileSync} from 'node:fs';
import {env} from 'node:process';
-import {parse} from 'css-variables-parser';
+import {parse} from 'postcss';
const isProduction = env.NODE_ENV !== 'development';
+function extractRootVars(css) {
+ const root = parse(css);
+ const vars = new Set();
+ root.walkRules((rule) => {
+ if (rule.selector !== ':root') return;
+ rule.each((decl) => {
+ if (decl.value && decl.prop.startsWith('--')) {
+ vars.add(decl.prop.substring(2));
+ }
+ });
+ });
+ return Array.from(vars);
+}
+
+const vars = extractRootVars([
+ readFileSync(new URL('web_src/css/themes/theme-gitea-light.css', import.meta.url), 'utf8'),
+ readFileSync(new URL('web_src/css/themes/theme-gitea-dark.css', import.meta.url), 'utf8'),
+].join('\n'));
+
export default {
prefix: 'tw-',
important: true, // the frameworks are mixed together, so tailwind needs to override other framework's styles
content: [
isProduction && '!./templates/devtest/**/*',
isProduction && '!./web_src/js/standalone/devtest.js',
+ '!./templates/swagger/v1_json.tmpl',
+ '!./templates/user/auth/oidc_wellknown.tmpl',
+ '!**/*_test.go',
+ '!./modules/{public,options,templates}/bindata.go',
+ './{build,models,modules,routers,services}/**/*.go',
'./templates/**/*.tmpl',
- './web_src/**/*.{js,vue}',
+ './web_src/js/**/*.{js,vue}',
].filter(Boolean),
blocklist: [
// classes that don't work without CSS variables from "@tailwind base" which we don't use
@@ -23,15 +47,10 @@ export default {
theme: {
colors: {
// make `tw-bg-red` etc work with our CSS variables
- ...Object.fromEntries(
- Object.keys(parse([
- readFileSync(new URL('web_src/css/themes/theme-gitea-light.css', import.meta.url), 'utf8'),
- readFileSync(new URL('web_src/css/themes/theme-gitea-dark.css', import.meta.url), 'utf8'),
- ].join('\n'), {})).filter((prop) => prop.startsWith('color-')).map((prop) => {
- const color = prop.substring(6);
- return [color, `var(--color-${color})`];
- })
- ),
+ ...Object.fromEntries(vars.filter((prop) => prop.startsWith('color-')).map((prop) => {
+ const color = prop.substring(6);
+ return [color, `var(--color-${color})`];
+ })),
inherit: 'inherit',
current: 'currentcolor',
transparent: 'transparent',
diff --git a/templates/admin/auth/edit.tmpl b/templates/admin/auth/edit.tmpl
index 65e82ba26f..2187761828 100644
--- a/templates/admin/auth/edit.tmpl
+++ b/templates/admin/auth/edit.tmpl
@@ -438,7 +438,7 @@
{{ctx.Locale.Tr "admin.auths.tips"}}
- GMail Settings:
+ {{ctx.Locale.Tr "admin.auths.tips.gmail_settings"}}
Host: smtp.gmail.com, Port: 587, Enable TLS Encryption: true
{{ctx.Locale.Tr "admin.auths.tips.oauth2.general"}}:
diff --git a/templates/admin/auth/new.tmpl b/templates/admin/auth/new.tmpl
index f32f77d5dc..d8935341f4 100644
--- a/templates/admin/auth/new.tmpl
+++ b/templates/admin/auth/new.tmpl
@@ -82,7 +82,7 @@
{{ctx.Locale.Tr "admin.auths.tips"}}
- GMail Settings:
+ {{ctx.Locale.Tr "admin.auths.tips.gmail_settings"}}
Host: smtp.gmail.com, Port: 587, Enable TLS Encryption: true
{{ctx.Locale.Tr "admin.auths.tips.oauth2.general"}}:
diff --git a/templates/admin/config.tmpl b/templates/admin/config.tmpl
index ce6edf8a97..0c944fcb8f 100644
--- a/templates/admin/config.tmpl
+++ b/templates/admin/config.tmpl
@@ -285,27 +285,6 @@
-
- {{ctx.Locale.Tr "admin.config.picture_config"}}
-
-
-
- - {{ctx.Locale.Tr "admin.config.disable_gravatar"}}
- -
-
-
-
-
-
- - {{ctx.Locale.Tr "admin.config.enable_federated_avatar"}}
- -
-
-
-
-
-
-
-
{{ctx.Locale.Tr "admin.config.git_config"}}
diff --git a/templates/admin/config_settings.tmpl b/templates/admin/config_settings.tmpl
new file mode 100644
index 0000000000..22ad5c24ac
--- /dev/null
+++ b/templates/admin/config_settings.tmpl
@@ -0,0 +1,42 @@
+{{template "admin/layout_head" (dict "ctxData" . "pageClass" "admin config")}}
+
+ {{ctx.Locale.Tr "admin.config.picture_config"}}
+
+
+
+ - {{ctx.Locale.Tr "admin.config.disable_gravatar"}}
+ -
+
+
+
+
+
+ - {{ctx.Locale.Tr "admin.config.enable_federated_avatar"}}
+ -
+
+
+
+
+
+
+
+
+ {{ctx.Locale.Tr "repository"}}
+
+
+
+
+{{template "admin/layout_footer" .}}
diff --git a/templates/admin/dashboard.tmpl b/templates/admin/dashboard.tmpl
index 53a12cbe27..cc7d338589 100644
--- a/templates/admin/dashboard.tmpl
+++ b/templates/admin/dashboard.tmpl
@@ -2,7 +2,7 @@
{{if .NeedUpdate}}
diff --git a/templates/admin/emails/list.tmpl b/templates/admin/emails/list.tmpl
index bcd80368e6..29fbb5f039 100644
--- a/templates/admin/emails/list.tmpl
+++ b/templates/admin/emails/list.tmpl
@@ -47,8 +47,8 @@
{{range .Emails}}
{{.Name}}
- {{.FullName}}
- {{.Email}}
+ {{.FullName}}
+ {{.Email}}
{{if .IsPrimary}}{{svg "octicon-check"}}{{else}}{{svg "octicon-x"}}{{end}}
{{if .CanChange}}
diff --git a/templates/admin/layout_head.tmpl b/templates/admin/layout_head.tmpl
index 0067f336e0..b326c82a6c 100644
--- a/templates/admin/layout_head.tmpl
+++ b/templates/admin/layout_head.tmpl
@@ -3,7 +3,7 @@
{{template "base/alert" .ctxData}}
-
+
{{template "admin/navbar" .ctxData}}
{{/* block: admin-setting-content */}}
diff --git a/templates/admin/navbar.tmpl b/templates/admin/navbar.tmpl
index f23bdee124..16ec1b4b5b 100644
--- a/templates/admin/navbar.tmpl
+++ b/templates/admin/navbar.tmpl
@@ -77,9 +77,17 @@
{{end}}
-
- {{ctx.Locale.Tr "admin.config"}}
-
+
+ {{ctx.Locale.Tr "admin.config"}}
+
+
{{ctx.Locale.Tr "admin.notices"}}
diff --git a/templates/admin/notice.tmpl b/templates/admin/notice.tmpl
index ed410425b5..e0abe4f8c0 100644
--- a/templates/admin/notice.tmpl
+++ b/templates/admin/notice.tmpl
@@ -31,7 +31,7 @@
-
diff --git a/templates/admin/packages/list.tmpl b/templates/admin/packages/list.tmpl
index cf860dab2a..aef4815424 100644
--- a/templates/admin/packages/list.tmpl
+++ b/templates/admin/packages/list.tmpl
@@ -62,8 +62,8 @@
{{end}}
{{.Package.Type.Name}}
- {{.Package.Name}}
- {{.Version.Version}}
+ {{.Package.Name}}
+ {{.Version.Version}}
{{.Creator.Name}}
{{if .Repository}}
diff --git a/templates/admin/user/list.tmpl b/templates/admin/user/list.tmpl
index 8fdc80fc70..e9ce17ac90 100644
--- a/templates/admin/user/list.tmpl
+++ b/templates/admin/user/list.tmpl
@@ -96,7 +96,7 @@
{{ctx.Locale.Tr "admin.users.remote"}}
{{end}}
- {{.Email}}
+ {{.Email}}
{{if .IsActive}}{{svg "octicon-check"}}{{else}}{{svg "octicon-x"}}{{end}}
{{if .IsRestricted}}{{svg "octicon-check"}}{{else}}{{svg "octicon-x"}}{{end}}
{{if index $.UsersTwoFaStatus .ID}}{{svg "octicon-check"}}{{else}}{{svg "octicon-x"}}{{end}}
diff --git a/templates/base/head_navbar.tmpl b/templates/base/head_navbar.tmpl
index 06fc5913d0..e755775985 100644
--- a/templates/base/head_navbar.tmpl
+++ b/templates/base/head_navbar.tmpl
@@ -14,7 +14,7 @@
@@ -35,7 +35,7 @@
{{svg "octicon-rocket"}} {{ctx.Locale.Tr "startpage.lightweight"}}
- {{ctx.Locale.Tr "startpage.lightweight_desc" | SanitizeHTML}}
+ {{ctx.Locale.Tr "startpage.lightweight_desc"}}
@@ -43,7 +43,7 @@
{{svg "octicon-code"}} {{ctx.Locale.Tr "startpage.license"}}
- {{ctx.Locale.Tr "startpage.license_desc" | SanitizeHTML}}
+ {{ctx.Locale.Tr "startpage.license_desc"}}
diff --git a/templates/install.tmpl b/templates/install.tmpl
index c18f25f79c..b3aea39ee5 100644
--- a/templates/install.tmpl
+++ b/templates/install.tmpl
@@ -336,7 +336,7 @@
- These configuration options will be written into: {{.CustomConfFile}}
+ {{ctx.Locale.Tr "install.config_location_hint"}} {{.CustomConfFile}}
diff --git a/templates/mail/auth/activate.tmpl b/templates/mail/auth/activate.tmpl
index c50717d315..b1bb4cb463 100644
--- a/templates/mail/auth/activate.tmpl
+++ b/templates/mail/auth/activate.tmpl
@@ -8,8 +8,8 @@
{{$activate_url := printf "%suser/activate?code=%s" AppUrl (QueryEscape .Code)}}
- {{.locale.Tr "mail.activate_account.text_1" (.DisplayName|DotEscape) AppName | SanitizeHTML}}
- {{.locale.Tr "mail.activate_account.text_2" .ActiveCodeLives | SanitizeHTML}}
+ {{.locale.Tr "mail.activate_account.text_1" (.DisplayName|DotEscape) AppName}}
+ {{.locale.Tr "mail.activate_account.text_2" .ActiveCodeLives}}
{{.locale.Tr "mail.link_not_working_do_paste"}}
diff --git a/templates/mail/auth/activate_email.tmpl b/templates/mail/auth/activate_email.tmpl
index 30fcb99ab8..3d32f80a4e 100644
--- a/templates/mail/auth/activate_email.tmpl
+++ b/templates/mail/auth/activate_email.tmpl
@@ -8,8 +8,8 @@
{{$activate_url := printf "%suser/activate_email?code=%s&email=%s" AppUrl (QueryEscape .Code) (QueryEscape .Email)}}
- {{.locale.Tr "mail.hi_user_x" (.DisplayName|DotEscape) | SanitizeHTML}}
- {{.locale.Tr "mail.activate_email.text" .ActiveCodeLives | SanitizeHTML}}
+ {{.locale.Tr "mail.hi_user_x" (.DisplayName|DotEscape)}}
+ {{.locale.Tr "mail.activate_email.text" .ActiveCodeLives}}
{{.locale.Tr "mail.link_not_working_do_paste"}}
diff --git a/templates/mail/auth/register_notify.tmpl b/templates/mail/auth/register_notify.tmpl
index 27c685e58f..62dbf7d927 100644
--- a/templates/mail/auth/register_notify.tmpl
+++ b/templates/mail/auth/register_notify.tmpl
@@ -8,7 +8,7 @@
{{$set_pwd_url := printf "%[1]suser/forgot_password" AppUrl}}
- {{.locale.Tr "mail.hi_user_x" (.DisplayName|DotEscape) | SanitizeHTML}}
+ {{.locale.Tr "mail.hi_user_x" (.DisplayName|DotEscape)}}
{{.locale.Tr "mail.register_notify.text_1" AppName}}
{{.locale.Tr "mail.register_notify.text_2" .Username}}
{{.locale.Tr "mail.register_notify.text_3" $set_pwd_url}}
diff --git a/templates/mail/auth/reset_passwd.tmpl b/templates/mail/auth/reset_passwd.tmpl
index e1af5b483c..55b1ecec3f 100644
--- a/templates/mail/auth/reset_passwd.tmpl
+++ b/templates/mail/auth/reset_passwd.tmpl
@@ -8,8 +8,8 @@
{{$recover_url := printf "%suser/recover_account?code=%s" AppUrl (QueryEscape .Code)}}
- {{.locale.Tr "mail.hi_user_x" (.DisplayName|DotEscape) | SanitizeHTML}}
- {{.locale.Tr "mail.reset_password.text" .ResetPwdCodeLives | SanitizeHTML}}
+ {{.locale.Tr "mail.hi_user_x" (.DisplayName|DotEscape)}}
+ {{.locale.Tr "mail.reset_password.text" .ResetPwdCodeLives}}
{{.locale.Tr "mail.link_not_working_do_paste"}}
diff --git a/templates/mail/issue/default.tmpl b/templates/mail/issue/default.tmpl
index 796dc403b7..4e83dbcfdb 100644
--- a/templates/mail/issue/default.tmpl
+++ b/templates/mail/issue/default.tmpl
@@ -16,7 +16,7 @@
- {{if .IsMention}}{{.locale.Tr "mail.issue.x_mentioned_you" .Doer.Name | SanitizeHTML}}
{{end}}
+ {{if .IsMention}}{{.locale.Tr "mail.issue.x_mentioned_you" .Doer.Name}}
{{end}}
{{if eq .ActionName "push"}}
{{if .Comment.IsForcePush}}
@@ -58,7 +58,7 @@
{{.locale.Tr "mail.issue.action.new" .Doer.Name .Issue.Index}}
{{end}}
{{else}}
- {{.Body | SanitizeHTML}}
+ {{.Body}}
{{end -}}
{{- range .ReviewComments}}
diff --git a/templates/mail/notify/admin_new_user.tmpl b/templates/mail/notify/admin_new_user.tmpl
index 04f90b61ab..613c58194a 100644
--- a/templates/mail/notify/admin_new_user.tmpl
+++ b/templates/mail/notify/admin_new_user.tmpl
@@ -13,8 +13,8 @@
- {{.Locale.Tr "mail.admin.new_user.user_info" | SanitizeHTML}}: @{{.NewUser.Name}}
- - {{.Locale.Tr "admin.users.created" | SanitizeHTML}}: {{DateTime "full" .NewUser.CreatedUnix}}
+ {{.Locale.Tr "mail.admin.new_user.user_info"}}: @{{.NewUser.Name}}
+ - {{.Locale.Tr "admin.users.created"}}: {{DateTime "full" .NewUser.CreatedUnix}}
{{.Body | SanitizeHTML}}
diff --git a/templates/mail/team_invite.tmpl b/templates/mail/team_invite.tmpl
index 67b368f348..cb0c0c0a50 100644
--- a/templates/mail/team_invite.tmpl
+++ b/templates/mail/team_invite.tmpl
@@ -5,7 +5,7 @@
- {{.locale.Tr "mail.team_invite.text_1" (DotEscape .Inviter.DisplayName) (DotEscape .Team.Name) (DotEscape .Organization.DisplayName) | SanitizeHTML}}
+ {{.locale.Tr "mail.team_invite.text_1" (DotEscape .Inviter.DisplayName) (DotEscape .Team.Name) (DotEscape .Organization.DisplayName)}}
{{.locale.Tr "mail.team_invite.text_2"}}
{{.locale.Tr "mail.link_not_working_do_paste"}}
{{.locale.Tr "mail.team_invite.text_3" .Invite.Email}}
diff --git a/templates/org/header.tmpl b/templates/org/header.tmpl
index efbbc43b1d..943557b1ca 100644
--- a/templates/org/header.tmpl
+++ b/templates/org/header.tmpl
@@ -7,7 +7,7 @@
{{if .Org.Visibility.IsLimited}}{{ctx.Locale.Tr "org.settings.visibility.limited_shortname"}}{{end}}
{{if .Org.Visibility.IsPrivate}}{{ctx.Locale.Tr "org.settings.visibility.private_shortname"}}{{end}}
-
+
{{if .EnableFeed}}
{{svg "octicon-rss" 24}}
diff --git a/templates/org/menu.tmpl b/templates/org/menu.tmpl
index f07b26865a..8eacc17e82 100644
--- a/templates/org/menu.tmpl
+++ b/templates/org/menu.tmpl
@@ -1,50 +1,49 @@
-
diff --git a/templates/org/settings/delete.tmpl b/templates/org/settings/delete.tmpl
index 8c93e7548d..e1ef471e34 100644
--- a/templates/org/settings/delete.tmpl
+++ b/templates/org/settings/delete.tmpl
@@ -6,7 +6,7 @@
+
- {{ctx.Locale.Tr "org.teams.all_repositories_helper" | SanitizeHTML}}
+ {{ctx.Locale.Tr "org.teams.all_repositories_helper"}}
diff --git a/templates/org/team/sidebar.tmpl b/templates/org/team/sidebar.tmpl
index e59c0e5613..9311a46e38 100644
--- a/templates/org/team/sidebar.tmpl
+++ b/templates/org/team/sidebar.tmpl
@@ -27,16 +27,16 @@
{{if eq .Team.LowerName "owners"}}
- {{ctx.Locale.Tr "org.teams.owners_permission_desc" | SanitizeHTML}}
+ {{ctx.Locale.Tr "org.teams.owners_permission_desc"}}
{{else}}
{{ctx.Locale.Tr "org.team_access_desc"}}
{{if .Team.IncludesAllRepositories}}
- - {{ctx.Locale.Tr "org.teams.all_repositories" | SanitizeHTML}}
+ - {{ctx.Locale.Tr "org.teams.all_repositories"}}
{{else}}
- - {{ctx.Locale.Tr "org.teams.specific_repositories" | SanitizeHTML}}
+ - {{ctx.Locale.Tr "org.teams.specific_repositories"}}
{{end}}
{{if .Team.CanCreateOrgRepo}}
- {{ctx.Locale.Tr "org.teams.can_create_org_repo"}}
@@ -44,10 +44,10 @@
{{if (eq .Team.AccessMode 2)}}
{{ctx.Locale.Tr "org.settings.permission"}}
- {{ctx.Locale.Tr "org.teams.write_permission_desc" | SanitizeHTML}}
+ {{ctx.Locale.Tr "org.teams.write_permission_desc"}}
{{else if (eq .Team.AccessMode 3)}}
{{ctx.Locale.Tr "org.settings.permission"}}
- {{ctx.Locale.Tr "org.teams.admin_permission_desc" | SanitizeHTML}}
+ {{ctx.Locale.Tr "org.teams.admin_permission_desc"}}
{{else}}
diff --git a/templates/package/content/alpine.tmpl b/templates/package/content/alpine.tmpl
index 496ffbc7b5..8914006ff0 100644
--- a/templates/package/content/alpine.tmpl
+++ b/templates/package/content/alpine.tmpl
@@ -4,12 +4,12 @@
- /$branch/$repository
+ /$branch/$repository
{{ctx.Locale.Tr "packages.alpine.registry.info"}}
- curl -JO
+ curl -JO
diff --git a/templates/package/content/cargo.tmpl b/templates/package/content/cargo.tmpl
index 53b2ef1152..2f14945d1e 100644
--- a/templates/package/content/cargo.tmpl
+++ b/templates/package/content/cargo.tmpl
@@ -8,8 +8,8 @@
default = "forgejo"
[registries.forgejo]
-index = "sparse+ " # Sparse index
-# index = " " # Git
+index = "sparse+ " # Sparse index
+# index = " " # Git
[net]
git-fetch-with-cli = true
diff --git a/templates/package/content/chef.tmpl b/templates/package/content/chef.tmpl
index 0f7694edc8..d39164b90b 100644
--- a/templates/package/content/chef.tmpl
+++ b/templates/package/content/chef.tmpl
@@ -4,7 +4,7 @@
- knife[:supermarket_site] = ' '
+ knife[:supermarket_site] = ' '
diff --git a/templates/package/content/composer.tmpl b/templates/package/content/composer.tmpl
index 7da94095dd..bcc6d3099f 100644
--- a/templates/package/content/composer.tmpl
+++ b/templates/package/content/composer.tmpl
@@ -7,7 +7,7 @@
{
"repositories": [{
"type": "composer",
- "url": " "
+ "url": " "
}
]
}
diff --git a/templates/package/content/conan.tmpl b/templates/package/content/conan.tmpl
index 0a9f508dcc..13a7723fe4 100644
--- a/templates/package/content/conan.tmpl
+++ b/templates/package/content/conan.tmpl
@@ -4,7 +4,7 @@
- conan remote add gitea
+ conan remote add gitea
diff --git a/templates/package/content/conda.tmpl b/templates/package/content/conda.tmpl
index 313b05ffe9..5ff79445fe 100644
--- a/templates/package/content/conda.tmpl
+++ b/templates/package/content/conda.tmpl
@@ -4,11 +4,11 @@
- channel_alias:
+ channel_alias:
channels:
- -
+ -
default_channels:
- -
+ -
diff --git a/templates/package/content/cran.tmpl b/templates/package/content/cran.tmpl
index 766dd43a4c..df7a48c3d6 100644
--- a/templates/package/content/cran.tmpl
+++ b/templates/package/content/cran.tmpl
@@ -4,7 +4,7 @@
- options("repos" = c(getOption("repos"), c(forgejo=" ")))
+ options("repos" = c(getOption("repos"), c(forgejo=" ")))
diff --git a/templates/package/content/debian.tmpl b/templates/package/content/debian.tmpl
index 3c03eec396..782ac1c8b3 100644
--- a/templates/package/content/debian.tmpl
+++ b/templates/package/content/debian.tmpl
@@ -4,8 +4,8 @@
- sudo curl -o /etc/apt/keyrings/forgejo-{{$.PackageDescriptor.Owner.Name}}.asc
-echo "deb [signed-by=/etc/apt/keyrings/forgejo-{{$.PackageDescriptor.Owner.Name}}.asc] $distribution $component" | sudo tee -a /etc/apt/sources.list.d/forgejo.list
+ sudo curl -o /etc/apt/keyrings/forgejo-{{$.PackageDescriptor.Owner.Name}}.asc
+echo "deb [signed-by=/etc/apt/keyrings/forgejo-{{$.PackageDescriptor.Owner.Name}}.asc] $distribution $component" | sudo tee -a /etc/apt/sources.list.d/forgejo.list
sudo apt update
{{ctx.Locale.Tr "packages.debian.registry.info"}}
diff --git a/templates/package/content/generic.tmpl b/templates/package/content/generic.tmpl
index aec8eb314e..4ebfb9103f 100644
--- a/templates/package/content/generic.tmpl
+++ b/templates/package/content/generic.tmpl
@@ -6,7 +6,7 @@
{{- range .PackageDescriptor.Files -}}
-curl -OJ
+curl -OJ
{{end -}}
diff --git a/templates/package/content/go.tmpl b/templates/package/content/go.tmpl
index 853218e51c..5e32ea7f87 100644
--- a/templates/package/content/go.tmpl
+++ b/templates/package/content/go.tmpl
@@ -4,7 +4,7 @@
- GOPROXY= go install {{$.PackageDescriptor.Package.Name}}@{{$.PackageDescriptor.Version.Version}}
+ GOPROXY= go install {{$.PackageDescriptor.Package.Name}}@{{$.PackageDescriptor.Version.Version}}
diff --git a/templates/package/content/helm.tmpl b/templates/package/content/helm.tmpl
index 59f89be637..9d8555597e 100644
--- a/templates/package/content/helm.tmpl
+++ b/templates/package/content/helm.tmpl
@@ -4,7 +4,7 @@
- helm repo add {{AppDomain}}
+ helm repo add {{AppDomain}}
helm repo update
diff --git a/templates/package/content/maven.tmpl b/templates/package/content/maven.tmpl
index e764684595..49ada6a3a3 100644
--- a/templates/package/content/maven.tmpl
+++ b/templates/package/content/maven.tmpl
@@ -7,19 +7,19 @@
<repositories>
<repository>
<id>gitea</id>
- <url> </url>
+ <url> </url>
</repository>
</repositories>
<distributionManagement>
<repository>
<id>gitea</id>
- <url> </url>
+ <url> </url>
</repository>
<snapshotRepository>
<id>gitea</id>
- <url> </url>
+ <url> </url>
</snapshotRepository>
</distributionManagement>
@@ -37,7 +37,7 @@
- mvn dependency:get -DremoteRepositories= -Dartifact={{.PackageDescriptor.Metadata.GroupID}}:{{.PackageDescriptor.Metadata.ArtifactID}}:{{.PackageDescriptor.Version.Version}}
+ mvn dependency:get -DremoteRepositories= -Dartifact={{.PackageDescriptor.Metadata.GroupID}}:{{.PackageDescriptor.Metadata.ArtifactID}}:{{.PackageDescriptor.Version.Version}}
diff --git a/templates/package/content/npm.tmpl b/templates/package/content/npm.tmpl
index cfd7595bfc..c5d9b3f428 100644
--- a/templates/package/content/npm.tmpl
+++ b/templates/package/content/npm.tmpl
@@ -4,7 +4,7 @@
- {{if .PackageDescriptor.Metadata.Scope}}{{.PackageDescriptor.Metadata.Scope}}:{{end}}registry=
+ {{if .PackageDescriptor.Metadata.Scope}}{{.PackageDescriptor.Metadata.Scope}}:{{end}}registry=
diff --git a/templates/package/content/nuget.tmpl b/templates/package/content/nuget.tmpl
index d56f50cb22..fadeaffe10 100644
--- a/templates/package/content/nuget.tmpl
+++ b/templates/package/content/nuget.tmpl
@@ -4,7 +4,7 @@
- dotnet nuget add source --name {{.PackageDescriptor.Owner.Name}} --username your_username --password your_token
+ dotnet nuget add source --name {{.PackageDescriptor.Owner.Name}} --username your_username --password your_token
diff --git a/templates/package/content/pub.tmpl b/templates/package/content/pub.tmpl
index e83b0d3570..8448b97466 100644
--- a/templates/package/content/pub.tmpl
+++ b/templates/package/content/pub.tmpl
@@ -4,7 +4,7 @@
- dart pub add {{.PackageDescriptor.Package.Name}}:{{.PackageDescriptor.Version.Version}} --hosted-url=
+ dart pub add {{.PackageDescriptor.Package.Name}}:{{.PackageDescriptor.Version.Version}} --hosted-url=
diff --git a/templates/package/content/pypi.tmpl b/templates/package/content/pypi.tmpl
index e0353c91c6..6addac3f8e 100644
--- a/templates/package/content/pypi.tmpl
+++ b/templates/package/content/pypi.tmpl
@@ -4,7 +4,7 @@
- pip install --index-url {{.PackageDescriptor.Package.Name}}
+ pip install --index-url {{.PackageDescriptor.Package.Name}}
diff --git a/templates/package/content/rpm.tmpl b/templates/package/content/rpm.tmpl
index a7e2141ccd..f5d56623ac 100644
--- a/templates/package/content/rpm.tmpl
+++ b/templates/package/content/rpm.tmpl
@@ -11,13 +11,13 @@
# {{ctx.Locale.Tr "packages.rpm.distros.redhat"}}
{{- range $group := .Groups}}
{{- if $group}}{{$group = print "/" $group}}{{end}}
-dnf config-manager --add-repo
+dnf config-manager --add-repo
{{- end}}
# {{ctx.Locale.Tr "packages.rpm.distros.suse"}}
{{- range $group := .Groups}}
{{- if $group}}{{$group = print "/" $group}}{{end}}
-zypper addrepo
+zypper addrepo
{{- end}}
diff --git a/templates/package/content/rubygems.tmpl b/templates/package/content/rubygems.tmpl
index 412c3a2954..009fd703e0 100644
--- a/templates/package/content/rubygems.tmpl
+++ b/templates/package/content/rubygems.tmpl
@@ -4,11 +4,11 @@
- gem install {{.PackageDescriptor.Package.Name}} --version "{{.PackageDescriptor.Version.Version}}" --source " "
+ gem install {{.PackageDescriptor.Package.Name}} --version "{{.PackageDescriptor.Version.Version}}" --source " "
- source " " do
+ source " " do
gem "{{.PackageDescriptor.Package.Name}}", "{{.PackageDescriptor.Version.Version}}"
end
diff --git a/templates/package/content/swift.tmpl b/templates/package/content/swift.tmpl
index 471f5b5457..68db444883 100644
--- a/templates/package/content/swift.tmpl
+++ b/templates/package/content/swift.tmpl
@@ -4,7 +4,7 @@
- swift package-registry set
+ swift package-registry set
diff --git a/templates/package/content/vagrant.tmpl b/templates/package/content/vagrant.tmpl
index 79b4d2f054..4dc3e62a06 100644
--- a/templates/package/content/vagrant.tmpl
+++ b/templates/package/content/vagrant.tmpl
@@ -4,7 +4,7 @@
- vagrant box add --box-version {{.PackageDescriptor.Version.Version}} " "
+ vagrant box add --box-version {{.PackageDescriptor.Version.Version}} " "
diff --git a/templates/package/settings.tmpl b/templates/package/settings.tmpl
index 10e26c7010..9424baf493 100644
--- a/templates/package/settings.tmpl
+++ b/templates/package/settings.tmpl
@@ -10,7 +10,7 @@
{{template "user/overview/header" .}}
{{end}}
{{template "base/alert" .}}
- {{.PackageDescriptor.Package.Name}} ({{.PackageDescriptor.Version.Version}}) / {{ctx.Locale.Tr "repo.settings"}}
+ {{.PackageDescriptor.Package.Name}} ({{.PackageDescriptor.Version.Version}}) / {{ctx.Locale.Tr "repo.settings"}}
{{ctx.Locale.Tr "packages.settings.link"}}
diff --git a/templates/package/shared/cargo.tmpl b/templates/package/shared/cargo.tmpl
index 401d909002..5b0f63965d 100644
--- a/templates/package/shared/cargo.tmpl
+++ b/templates/package/shared/cargo.tmpl
@@ -3,13 +3,7 @@
-
-
-
-
+ {{if .CargoIndexExists}}
@@ -17,6 +11,15 @@
{{.CsrfTokenHtml}}
+ {{else}}
+
+
+
+
+ {{end}}
diff --git a/templates/package/shared/cleanup_rules/preview.tmpl b/templates/package/shared/cleanup_rules/preview.tmpl
index 7a50d5ccca..cff8e8249f 100644
--- a/templates/package/shared/cleanup_rules/preview.tmpl
+++ b/templates/package/shared/cleanup_rules/preview.tmpl
@@ -19,7 +19,7 @@
{{.Package.Type.Name}}
{{.Package.Name}}
- {{.Version.Version}}
+ {{.Version.Version}}
{{.Creator.Name}}
{{FileSize .CalculateBlobSize}}
{{DateTime "short" .Version.CreatedUnix}}
diff --git a/templates/package/shared/list.tmpl b/templates/package/shared/list.tmpl
index 67c686675c..7b10e52ff7 100644
--- a/templates/package/shared/list.tmpl
+++ b/templates/package/shared/list.tmpl
@@ -20,7 +20,7 @@
diff --git a/templates/package/shared/versionlist.tmpl b/templates/package/shared/versionlist.tmpl
index eee952c096..59d6d89b53 100644
--- a/templates/package/shared/versionlist.tmpl
+++ b/templates/package/shared/versionlist.tmpl
@@ -23,7 +23,7 @@
- {{.Version.LowerVersion}}
+ {{.Version.LowerVersion}}
{{ctx.Locale.Tr "packages.published_by" (TimeSinceUnix .Version.CreatedUnix ctx.Locale) .Creator.HomeLink .Creator.GetDisplayName}}
diff --git a/templates/package/view.tmpl b/templates/package/view.tmpl
index 0fa23d67fd..54af71126f 100644
--- a/templates/package/view.tmpl
+++ b/templates/package/view.tmpl
@@ -87,7 +87,7 @@
{{end}}
{{ctx.Locale.Tr "packages.versions"}} ({{.TotalVersionCount}})
- {{ctx.Locale.Tr "packages.versions.view_all"}}
+ {{ctx.Locale.Tr "packages.versions.view_all"}}
{{range .LatestVersions}}
diff --git a/templates/projects/list.tmpl b/templates/projects/list.tmpl
index 30fbd498a4..54a41221bf 100644
--- a/templates/projects/list.tmpl
+++ b/templates/projects/list.tmpl
@@ -10,7 +10,7 @@
{{ctx.Locale.PrettyNumber .ClosedCount}} {{ctx.Locale.Tr "repo.issues.closed_title"}}
-
diff --git a/templates/projects/new.tmpl b/templates/projects/new.tmpl
index 711dbe842a..92ee36c1c4 100644
--- a/templates/projects/new.tmpl
+++ b/templates/projects/new.tmpl
@@ -55,7 +55,7 @@
-
+
{{ctx.Locale.Tr "repo.milestones.cancel"}}
diff --git a/templates/projects/view.tmpl b/templates/projects/view.tmpl
index 3792ccca0e..a6e84024bc 100644
--- a/templates/projects/view.tmpl
+++ b/templates/projects/view.tmpl
@@ -41,7 +41,7 @@
-
+
{{template "repo/issue/label_precolors"}}
@@ -165,9 +165,9 @@
-
+
{{range (index $.IssuesMap .ID)}}
-
+
{{template "repo/issue/card" (dict "Issue" . "Page" $)}}
{{end}}
diff --git a/templates/repo/blame.tmpl b/templates/repo/blame.tmpl
index 75104cdcd2..6e0d0d1a5e 100644
--- a/templates/repo/blame.tmpl
+++ b/templates/repo/blame.tmpl
@@ -2,11 +2,11 @@
{{$revsFileLink := URLJoin .RepoLink "src" .BranchNameSubURL "/.git-blame-ignore-revs"}}
{{if .UsesIgnoreRevs}}
{{else}}
{{end}}
{{end}}
diff --git a/templates/repo/branch/list.tmpl b/templates/repo/branch/list.tmpl
index 4aa0e22b78..916111faca 100644
--- a/templates/repo/branch/list.tmpl
+++ b/templates/repo/branch/list.tmpl
@@ -72,7 +72,7 @@
{{ctx.Locale.Tr "repo.branches"}}
-
+
diff --git a/templates/repo/cite/cite_buttons.tmpl b/templates/repo/cite/cite_buttons.tmpl
index 9953c92c8a..426ca3858e 100644
--- a/templates/repo/cite/cite_buttons.tmpl
+++ b/templates/repo/cite/cite_buttons.tmpl
@@ -6,6 +6,6 @@ BibTeX
-
{{end}}