Compare commits
183 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 43c8d014e8 | |||
| c2a0fe8c51 | |||
| 379da5c828 | |||
| 5772454b31 | |||
| 4c47020d37 | |||
| c95a092b4c | |||
| bfac06111e | |||
| a02e97d52b | |||
| fe0ccc2806 | |||
| 792d0dd224 | |||
| 28a8361033 | |||
| fca2db6c11 | |||
| e91a744803 | |||
| e929533398 | |||
| f278b9697b | |||
| 0b4e05fcb3 | |||
| b67937faf1 | |||
| f10391597d | |||
| 9264ef61d4 | |||
| 4ab92b3365 | |||
| 4de459603c | |||
| 80ba739abe | |||
| e8e6177e8a | |||
| 62933b0eda | |||
| bef4b822cd | |||
| 84bcea290c | |||
| 9242cd6655 | |||
| bff70ba3de | |||
| 63b691c29e | |||
| a1052dbf96 | |||
| 70e1e99ff7 | |||
| 32c9ac12e6 | |||
| bbcc540c0a | |||
| 17ebac5c3c | |||
| 699803d1d7 | |||
| e97842d0a0 | |||
| 579558f74a | |||
| a3c50ac2cd | |||
| 3f8775bce5 | |||
| 1f0d9b3471 | |||
| 3b2bf52e62 | |||
| 7131424da1 | |||
| 171850b8f9 | |||
| 4991e019a5 | |||
| 70ec5f9976 | |||
| dae225ec3a | |||
| 729d063f3d | |||
| b46aa97fff | |||
| c401ffb2c4 | |||
| 12474983f1 | |||
| e38d9eca83 | |||
| d1845fa0b3 | |||
| f93d28f277 | |||
| 78f8fb8307 | |||
| 512ecb175f | |||
| edc292d12c | |||
| 400928623b | |||
| 249fc8bf0b | |||
| f608948bf7 | |||
| e77ede6a9f | |||
| 52ce12c13f | |||
| 7070660554 | |||
| b36fd283af | |||
| 9bf972379b | |||
| 981d9d0d9b | |||
| 23cff646b5 | |||
| 223d2f3f58 | |||
| 53a6ca83a5 | |||
| 03898ed70d | |||
| 57a91789c5 | |||
| 4a2c81d044 | |||
| 5866b9de18 | |||
| f5e38807f0 | |||
| 8d9ce66c91 | |||
| e215adbc70 | |||
| 76ec1d4552 | |||
| 93d2710d8e | |||
| 23a76e0cc0 | |||
| 5786d40338 | |||
| c1cc5cf8fd | |||
| eb595cd684 | |||
| ffc1c0931c | |||
| 5319872a75 | |||
| 1679a81f34 | |||
| 8a2b349a66 | |||
| 86a695b2d1 | |||
| 41908de091 | |||
| ac42a80034 | |||
| 2abc050929 | |||
| 60f48b91ad | |||
| d5c8a106ec | |||
| 33cb73228e | |||
| 319ecf0bec | |||
| 201a4c3f69 | |||
| 4bf723f382 | |||
| 9b81fbf2ce | |||
| 85149bde8d | |||
| 19d0586b47 | |||
| 95a23e426a | |||
| 35dc5df4d9 | |||
| 741f4c0413 | |||
| 15bf8de3a1 | |||
| 21e0121676 | |||
| ab299063b1 | |||
| 57ee21d53e | |||
| ad36689444 | |||
| 37ada5c0d9 | |||
| 6c16930c07 | |||
| e20cd8a329 | |||
| b82c82ee57 | |||
| 529a6603db | |||
| 659abcfd5f | |||
| c06bed2dce | |||
| 38fef3bcd7 | |||
| 1c133b3454 | |||
| 1bf070ae1d | |||
| 38a1b1dffe | |||
| b10c956c1e | |||
| a2cf18e98e | |||
| ae7eeaafbb | |||
| dcac42161e | |||
| e71c56d8a2 | |||
| 35a7f9184c | |||
| 25c22c5c93 | |||
| 6be878abca | |||
| 97121edd6b | |||
| 4c60b2bf00 | |||
| 44276e2eba | |||
| b40d828934 | |||
| e3e8edc143 | |||
| ab0f52ea51 | |||
| 4b7b647c30 | |||
| 089863052d | |||
| 6484fc06ef | |||
| 344ef1fad6 | |||
| 63b93a7048 | |||
| c7d6f61d9e | |||
| 384fba3fc3 | |||
| f2fae6095b | |||
| cab2a9371f | |||
| b588b3d2b2 | |||
| e40acbea0b | |||
| 05318e0933 | |||
| 30f9ff7478 | |||
| 61f9e3bf06 | |||
| 3fbd617767 | |||
| caff3a8315 | |||
| b50134da2f | |||
| 35e79a8393 | |||
| d3b5d47e76 | |||
| e2a750824d | |||
| 2e2756c16a | |||
| 137243c988 | |||
| 12e140bf68 | |||
| 8557aeca72 | |||
| fb23ea28bc | |||
| a25837d735 | |||
| 6e9ea05a4f | |||
| 296c2a1689 | |||
| cfb6f32204 | |||
| e0e7f0c4ed | |||
| b79074aeb1 | |||
| 64f52201b1 | |||
| af15978c31 | |||
| 511f9bfd20 | |||
| 8d921a67ff | |||
| b56db2ff18 | |||
| 367a72ce11 | |||
| 4957f351d0 | |||
| 43197a9efd | |||
| e334806d4e | |||
| 3759793fa8 | |||
| 7e79b87136 | |||
| 09d8f9bc47 | |||
| 469daf5924 | |||
| 7ae0c597f1 | |||
| 9da2215095 | |||
| f9131d4261 | |||
| 5acdf62b9a | |||
| 0c3f3b85e8 | |||
| fdb233150a | |||
| ffb13c1136 | |||
| 0716d3fa15 |
@@ -0,0 +1,358 @@
|
||||
.
|
||||
./types.d.ts
|
||||
./docker
|
||||
./docker/manifest.rootless.tmpl
|
||||
./docker/root
|
||||
./docker/manifest.tmpl
|
||||
./docker/README.md
|
||||
./docker/rootless
|
||||
./BSDmakefile
|
||||
./tests
|
||||
./tests/integration
|
||||
./tests/gitea-lfs-meta
|
||||
./tests/mysql.ini.tmpl
|
||||
./tests/e2e
|
||||
./tests/testdata
|
||||
./tests/fuzz
|
||||
./tests/test_utils.go
|
||||
./tests/sqlite.ini.tmpl
|
||||
./tests/gitea-repositories-meta
|
||||
./tests/pgsql.ini.tmpl
|
||||
./tests/mssql.ini.tmpl
|
||||
./eslint.json.config.ts
|
||||
./LICENSE
|
||||
./models
|
||||
./models/repo.go
|
||||
./models/avatars
|
||||
./models/system
|
||||
./models/auth
|
||||
./models/migrations
|
||||
./models/pull
|
||||
./models/main_test.go
|
||||
./models/fixtures
|
||||
./models/asymkey
|
||||
./models/packages
|
||||
./models/unittest
|
||||
./models/admin
|
||||
./models/repo
|
||||
./models/activities
|
||||
./models/unit
|
||||
./models/db
|
||||
./models/dbfs
|
||||
./models/shared
|
||||
./models/webhook
|
||||
./models/secret
|
||||
./models/perm
|
||||
./models/user
|
||||
./models/renderhelper
|
||||
./models/actions
|
||||
./models/git
|
||||
./models/organization
|
||||
./models/issues
|
||||
./models/repo_test.go
|
||||
./models/project
|
||||
./eslint.config.ts
|
||||
./flake.lock
|
||||
./tools
|
||||
./tools/generate-svg-vscode-extensions.json
|
||||
./tools/test-e2e.sh
|
||||
./tools/code-batch-process.go
|
||||
./tools/gocovmerge.go
|
||||
./tools/lint-templates-svg.ts
|
||||
./tools/generate-images.ts
|
||||
./tools/codeformat
|
||||
./tools/generate-svg.ts
|
||||
./tools/test-echo.go
|
||||
./tools/watch.sh
|
||||
./vitest.config.ts
|
||||
./CHANGELOG.md
|
||||
./+x
|
||||
./CODE_OF_CONDUCT.md
|
||||
./CLAUDE.md
|
||||
./README.zh-tw.md
|
||||
./web_src
|
||||
./web_src/svg
|
||||
./web_src/fomantic
|
||||
./web_src/js
|
||||
./web_src/css
|
||||
./CHANGELOG-archived.md
|
||||
./custom
|
||||
./custom/conf
|
||||
./contrib
|
||||
./contrib/systemd
|
||||
./contrib/init
|
||||
./contrib/update_dependencies.sh
|
||||
./contrib/fhs-compliant-script
|
||||
./contrib/launchd
|
||||
./contrib/backport
|
||||
./contrib/README
|
||||
./contrib/legal
|
||||
./contrib/supervisor
|
||||
./contrib/options
|
||||
./contrib/upgrade.sh
|
||||
./contrib/ide
|
||||
./contrib/gitea-monitoring-mixin
|
||||
./templates
|
||||
./templates/package
|
||||
./templates/post-install.tmpl
|
||||
./templates/status
|
||||
./templates/devtest
|
||||
./templates/projects
|
||||
./templates/base
|
||||
./templates/org
|
||||
./templates/swagger
|
||||
./templates/custom
|
||||
./templates/admin
|
||||
./templates/repo
|
||||
./templates/shared
|
||||
./templates/webhook
|
||||
./templates/api
|
||||
./templates/home.tmpl
|
||||
./templates/install.tmpl
|
||||
./templates/user
|
||||
./templates/explore
|
||||
./templates/mail
|
||||
./update-gitea.sh
|
||||
./flake.nix
|
||||
./DCO
|
||||
./MAINTAINERS
|
||||
./routers
|
||||
./routers/common
|
||||
./routers/install
|
||||
./routers/web
|
||||
./routers/private
|
||||
./routers/init.go
|
||||
./routers/api
|
||||
./routers/utils
|
||||
./pnpm
|
||||
./package.json
|
||||
./snap
|
||||
./snap/snapcraft.yaml
|
||||
./services
|
||||
./services/uinotification
|
||||
./services/convert
|
||||
./services/secrets
|
||||
./services/wiki
|
||||
./services/auth
|
||||
./services/migrations
|
||||
./services/pull
|
||||
./services/projects
|
||||
./services/repository
|
||||
./services/markup
|
||||
./services/oauth2_provider
|
||||
./services/asymkey
|
||||
./services/org
|
||||
./services/task
|
||||
./services/packages
|
||||
./services/mailer
|
||||
./services/forms
|
||||
./services/issue
|
||||
./services/webtheme
|
||||
./services/attachment
|
||||
./services/mirror
|
||||
./services/versioned_migration
|
||||
./services/agit
|
||||
./services/context
|
||||
./services/release
|
||||
./services/doctor
|
||||
./services/gitdiff
|
||||
./services/webhook
|
||||
./services/automerge
|
||||
./services/contexttest
|
||||
./services/cron
|
||||
./services/user
|
||||
./services/automergequeue
|
||||
./services/feed
|
||||
./services/actions
|
||||
./services/git
|
||||
./services/lfs
|
||||
./services/notify
|
||||
./services/indexer
|
||||
./services/externalaccount
|
||||
./go.mod
|
||||
./assets
|
||||
./assets/misspellings.csv
|
||||
./assets/logo.svg
|
||||
./assets/emoji.json
|
||||
./assets/go-licenses.json
|
||||
./assets/favicon.svg
|
||||
./smart-build.sh
|
||||
./Dockerfile.rootless
|
||||
./build
|
||||
./build/generate-go-licenses.go
|
||||
./build/update-locales.sh
|
||||
./build/generate-emoji.go
|
||||
./build/generate-bindata.go
|
||||
./build/generate-gitignores.go
|
||||
./build/test-env-check.sh
|
||||
./build/test-env-prepare.sh
|
||||
./pyproject.toml
|
||||
./updates.config.ts
|
||||
./tsconfig.json
|
||||
./pnpm-lock.yaml
|
||||
./crowdin.yml
|
||||
./SECURITY.md
|
||||
./options
|
||||
./options/locale
|
||||
./options/gitignore
|
||||
./options/fileicon
|
||||
./options/label
|
||||
./options/license
|
||||
./options/readme
|
||||
./docs
|
||||
./docs/guideline-frontend.md
|
||||
./docs/release-management.md
|
||||
./docs/guideline-backend.md
|
||||
./docs/community-governance.md
|
||||
./playwright.config.ts
|
||||
./cmd
|
||||
./cmd/manager_logging.go
|
||||
./cmd/admin_auth_ldap_test.go
|
||||
./cmd/web_acme.go
|
||||
./cmd/admin_user_delete.go
|
||||
./cmd/admin_user_must_change_password_test.go
|
||||
./cmd/admin_user_create.go
|
||||
./cmd/admin_regenerate.go
|
||||
./cmd/generate.go
|
||||
./cmd/admin_auth.go
|
||||
./cmd/dump.go
|
||||
./cmd/admin_user_must_change_password.go
|
||||
./cmd/doctor_test.go
|
||||
./cmd/migrate.go
|
||||
./cmd/admin_auth_oauth.go
|
||||
./cmd/main_test.go
|
||||
./cmd/actions.go
|
||||
./cmd/cmd_test.go
|
||||
./cmd/cert_test.go
|
||||
./cmd/migrate_storage_test.go
|
||||
./cmd/web_graceful.go
|
||||
./cmd/doctor.go
|
||||
./cmd/admin_user_delete_test.go
|
||||
./cmd/embedded.go
|
||||
./cmd/manager.go
|
||||
./cmd/config.go
|
||||
./cmd/admin_user_change_password.go
|
||||
./cmd/cert.go
|
||||
./cmd/hook_test.go
|
||||
./cmd/web.go
|
||||
./cmd/hook.go
|
||||
./cmd/admin_auth_ldap.go
|
||||
./cmd/admin_user_list.go
|
||||
./cmd/admin_user_change_password_test.go
|
||||
./cmd/admin_auth_smtp_test.go
|
||||
./cmd/web_https.go
|
||||
./cmd/docs.go
|
||||
./cmd/admin_user_create_test.go
|
||||
./cmd/migrate_storage.go
|
||||
./cmd/admin_auth_oauth_test.go
|
||||
./cmd/serv.go
|
||||
./cmd/admin_user_generate_access_token.go
|
||||
./cmd/admin.go
|
||||
./cmd/config_test.go
|
||||
./cmd/doctor_convert.go
|
||||
./cmd/main.go
|
||||
./cmd/dump_repo.go
|
||||
./cmd/keys.go
|
||||
./cmd/admin_user.go
|
||||
./cmd/admin_auth_smtp.go
|
||||
./cmd/restore_repo.go
|
||||
./cmd/mailer.go
|
||||
./cmd/cmd.go
|
||||
./AGENTS.md
|
||||
./README.zh-cn.md
|
||||
./Dockerfile
|
||||
./tailwind.config.ts
|
||||
./Makefile
|
||||
./README.md
|
||||
./main.go
|
||||
./go.sum
|
||||
./uv.lock
|
||||
./stylelint.config.js
|
||||
./CONTRIBUTING.md
|
||||
./modules
|
||||
./modules/reqctx
|
||||
./modules/public
|
||||
./modules/references
|
||||
./modules/httplib
|
||||
./modules/hcaptcha
|
||||
./modules/generate
|
||||
./modules/tailmsg
|
||||
./modules/turnstile
|
||||
./modules/system
|
||||
./modules/badge
|
||||
./modules/eventsource
|
||||
./modules/htmlutil
|
||||
./modules/setting
|
||||
./modules/fileicon
|
||||
./modules/auth
|
||||
./modules/migration
|
||||
./modules/svg
|
||||
./modules/repository
|
||||
./modules/markup
|
||||
./modules/typesniffer
|
||||
./modules/test
|
||||
./modules/web
|
||||
./modules/pprof
|
||||
./modules/validation
|
||||
./modules/base
|
||||
./modules/tempdir
|
||||
./modules/zstd
|
||||
./modules/gitrepo
|
||||
./modules/packages
|
||||
./modules/testlogger
|
||||
./modules/process
|
||||
./modules/templates
|
||||
./modules/label
|
||||
./modules/issue
|
||||
./modules/dump
|
||||
./modules/metrics
|
||||
./modules/assetfs
|
||||
./modules/nosql
|
||||
./modules/avatar
|
||||
./modules/updatechecker
|
||||
./modules/private
|
||||
./modules/cache
|
||||
./modules/regexplru
|
||||
./modules/gtprof
|
||||
./modules/log
|
||||
./modules/commitstatus
|
||||
./modules/session
|
||||
./modules/highlight
|
||||
./modules/csv
|
||||
./modules/proxy
|
||||
./modules/queue
|
||||
./modules/uri
|
||||
./modules/httpcache
|
||||
./modules/lfstransfer
|
||||
./modules/options
|
||||
./modules/webhook
|
||||
./modules/secret
|
||||
./modules/json
|
||||
./modules/globallock
|
||||
./modules/emoji
|
||||
./modules/charset
|
||||
./modules/recaptcha
|
||||
./modules/user
|
||||
./modules/paginator
|
||||
./modules/proxyprotocol
|
||||
./modules/actions
|
||||
./modules/optional
|
||||
./modules/structs
|
||||
./modules/ssh
|
||||
./modules/timeutil
|
||||
./modules/glob
|
||||
./modules/git
|
||||
./modules/lfs
|
||||
./modules/mcaptcha
|
||||
./modules/util
|
||||
./modules/sitemap
|
||||
./modules/graceful
|
||||
./modules/storage
|
||||
./modules/cachegroup
|
||||
./modules/hostmatcher
|
||||
./modules/container
|
||||
./modules/translation
|
||||
./modules/indexer
|
||||
./modules/analyze
|
||||
./vite.config.ts
|
||||
./main_timezones.go
|
||||
@@ -0,0 +1,64 @@
|
||||
# Gitea Codex Context
|
||||
|
||||
This file is Codex's persistent operating context for this repository.
|
||||
|
||||
Related orientation documents:
|
||||
- Full project change log: `./.codex-history.md`
|
||||
- Persistent implementation map: `./.codex-project-map.md`
|
||||
- Raw structural baseline: `./.ai-structure.md`
|
||||
|
||||
## Recommended Read Order
|
||||
|
||||
1. `./.codex-context.md`
|
||||
2. `./.codex-project-map.md`
|
||||
3. The concrete files involved in the current task
|
||||
4. `./.codex-history.md` only through targeted search, tags, or the latest relevant entries
|
||||
|
||||
## High-Value Project Anchors
|
||||
|
||||
- App entry point and default version wiring: `main.go`
|
||||
- Web command and server startup: `cmd/web.go`
|
||||
- Installed-instance initialization and route mounting: `routers/init.go`
|
||||
- Main web router: `routers/web/web.go`
|
||||
- Authentication handlers: `routers/web/auth/`
|
||||
- Request context, session, template data, and response helpers: `services/context/`
|
||||
- Domain business logic: `services/`
|
||||
- Persistence, DB infrastructure, and migrations: `models/`, `models/db/`, `models/migrations/`
|
||||
- Server-side UI templates: `templates/`
|
||||
- Browser-side JS/CSS/frontend: `web_src/`
|
||||
|
||||
For detailed request flow, auth flow, extension points, and task-oriented entry points, use `./.codex-project-map.md` instead of duplicating them here.
|
||||
|
||||
## Persistent Workflow Rules
|
||||
|
||||
- Update `./.codex-history.md` after real project code changes.
|
||||
- Do not add Codex-only preference or memory edits to `./.codex-history.md`.
|
||||
- Do not reread unchanged context files within the same session unless the current task explicitly depends on them.
|
||||
- Prefer targeted search in `./.codex-history.md` by keyword, tag, or subsystem before reading larger ranges.
|
||||
- When the user asks for `revert`:
|
||||
- first show the latest 10 commits as a numbered list with short descriptions;
|
||||
- wait for the user's numeric choice before doing anything;
|
||||
- if the target change is not committed, explain that the safe path is `git restore`, not `git revert`.
|
||||
- Revert flows must stay non-destructive by default; prefer `git revert` for committed changes and avoid destructive reset-style actions unless the user explicitly asks for them.
|
||||
|
||||
## Persistent `.codex-history.md` Rules
|
||||
|
||||
- Numeric IDs are reserved only for real project code changes.
|
||||
- IDs start at `0` and increase sequentially by `1`.
|
||||
- Use the format `N - [YYYY-MM-DD HH:MM:SS]`.
|
||||
- Store the real repository-derived application version, without a `Version:` label.
|
||||
- Keep only the final consolidated result of a task; do not keep intermediate attempts or failed correction steps.
|
||||
- Append to the same task only while the changes are consecutive follow-ups to the same problem.
|
||||
- If unrelated tasks happened in between, record the new work as a new task even if it returns to the same area.
|
||||
|
||||
## Persistent Communication Preferences
|
||||
|
||||
- After finishing a task, respond briefly and directly unless there are blockers or problems.
|
||||
- Re-check the rules in this file before and after making changes.
|
||||
|
||||
## Current Working Notes
|
||||
|
||||
- `main.go` defaults `setting.AppVer` to `development`; derive the real build/version string from the repository when writing `./.codex-history.md`.
|
||||
- The repository is predictably split across `cmd/`, `routers/`, `services/`, `models/`, `templates/`, and `web_src/`, so changes should normally stay localized to one or two layers plus their tests.
|
||||
- For custom release maintenance and repo-sync tasks, consult `./.codex-script-notes.md` before reanalyzing the large helper scripts.
|
||||
- New UI-visible functionality in this fork often also requires locale updates, so UI tasks and related history searches should usually consider `options/locale/`, especially `locale_en-US.json` and any actively maintained translated locale files.
|
||||
@@ -0,0 +1,812 @@
|
||||
Project Change ID[date-time] - application-version - Type - Summary:
|
||||
|
||||
History search guidance:
|
||||
- Prefer targeted search by task tag, subsystem keyword, or file/path before reading long ranges.
|
||||
- Entries are tagged inline as `[tag] [tag]` to support targeted search and filtering.
|
||||
|
||||
|
||||
0 - [2026-04-16 02:46:18] - v.1.27.0-dev-38-g4b334df6d4 - Type: Modified - [repo-ui] [visibility] [badges] Added explicit repository visibility badges to match the requested GitHub-style presentation more closely.
|
||||
- 1 - I modified `templates/repo/header.tmpl` so the repository page header now always shows a visibility badge on the right side: `Private`, `Internal`, or `Public`.
|
||||
- 2 - I modified `templates/shared/repo/list.tmpl` so each repository entry in shared repository lists also shows an explicit visibility badge for `Private`, `Internal`, or `Public`.
|
||||
- 3 - I added the `Public` label for repositories that previously had no explicit visibility badge, while preserving the existing archived, template, and sha256 labels.
|
||||
- 4 - I reused existing translation keys and existing badge styling so the change stays visually consistent with the current Gitea UI.
|
||||
|
||||
|
||||
1 - [2026-04-16 03:31:29] - v.1.27.0-dev-38-g4b334df6d4 - Type: Modified - [repo-ui] [visibility] [badges] [repo-settings] Refined repository visibility badges with semantic colors, owner-aware navigation, and broader coverage in repository settings views.
|
||||
- 1 - I modified `templates/shared/repo/list.tmpl` so `Public` now uses a basic green badge and `Private` now uses a basic red badge, while `Internal` remains neutral.
|
||||
- 2 - I modified `templates/repo/header.tmpl` so the repository header uses the same color-coded visibility badges and keeps the mobile icon behavior unchanged.
|
||||
- 3 - I added owner-aware navigation for the `Public` and `Private` badges so they link to the repository `Settings` page only when the signed-in user is the repository owner.
|
||||
- 4 - I modified `templates/user/settings/repos.tmpl` so the same visibility badge now appears next to repository names in `/user/settings/repos`, in both list variants rendered by that page.
|
||||
- 5 - I preserved the existing archived, template, fork, mirror, and object-format indicators so only the requested visibility presentation changed.
|
||||
|
||||
|
||||
2 - [2026-04-16 03:45:08] - v.1.27.0-dev-38-g4b334df6d4 - Type: Fixed - [user-settings] Corrected a template rendering error in /user/settings/repos caused by dereferencing a missing Owner object.
|
||||
- 1 - I fixed `templates/user/settings/repos.tmpl` so the internal-visibility check now guards against a nil `Owner` before accessing `Owner.Visibility`.
|
||||
- 2 - I applied the null-safe visibility guard in both repository list variants rendered by `/user/settings/repos`.
|
||||
- 3 - I preserved the new green/red visibility badge styling and owner-aware settings links while removing the nil-pointer render failure.
|
||||
|
||||
|
||||
3 - [2026-04-16 04:53:24] - v.1.27.0-dev-38-g4b334df6d4 - Type: Modified - [admin-users] Hid the admin privilege toggle when an administrator edits their own account from the admin user edit page.
|
||||
- 1 - I modified `templates/admin/user/edit.tmpl` so the `Is Administrator` checkbox is no longer rendered when the edited user ID matches the signed-in admin ID.
|
||||
- 2 - I preserved the existing checkbox behavior for editing other users, so administrators can still grant or revoke admin rights for other accounts.
|
||||
- 3 - I kept the change limited to the admin edit UI without altering unrelated fields or backend update logic.
|
||||
|
||||
4 - [2026-04-16 03:11:08] - v.1.27.0-dev-38-g4b334df6d4 - Type: Modified - [admin-users] [account-deletion] Disabled the self-account deletion option only for the last administrator and aligned the backend rule with that behavior.
|
||||
- 1 - I modified `templates/user/settings/account.tmpl` so the `Delete Your Account` action is disabled and shows the last-admin warning when the signed-in user is the only remaining admin.
|
||||
- 2 - I modified `routers/web/user/setting/account.go` so the account settings page now receives an `IsLastAdminUser` flag used by the template.
|
||||
- 3 - I updated the self-delete backend flow so it blocks account deletion only when the signed-in user is the last admin, instead of blocking every admin unconditionally.
|
||||
|
||||
5 - [2026-04-16 03:26:40] - v.1.27.0-dev-38-g4b334df6d4 - Type: Fixed - [admin-users] [account-deletion] Adjusted the shared last-admin detection to count only active administrators so account deletion and admin demotion rules behave correctly in real instances.
|
||||
- 1 - I modified `models/user/user.go` so `IsLastAdminUser` now treats only active admins as candidates when deciding whether a user is the last admin.
|
||||
- 2 - This aligns the shared last-admin protection used by account deletion and admin privilege update flows with practical instance behavior.
|
||||
- 3 - The existing `/user/settings/account` UI and backend guards now work against the refined active-admin definition without additional template changes.
|
||||
|
||||
6 - [2026-04-16 03:43:20] - v.1.27.0-dev-38-g4b334df6d4 - Type: Modified - [user-settings] [admin-users] [account-deletion] [ui] Updated the Delete Your Account panel for the last-admin case so it shows a direct warning message and hides the deletion controls.
|
||||
- 1 - I modified `templates/user/settings/account.tmpl` so the panel now shows `You cannot remove the last admin. There must be at least one admin.` while keeping the existing alert icon.
|
||||
- 2 - I hid the `Password` field for the last-admin case.
|
||||
- 3 - I hid the `Confirm Deletion` button for the last-admin case while preserving the normal delete flow for other users.
|
||||
|
||||
7 - [2026-04-16 17:37:53] - v.1.27.0-dev-40-gc3b9d21472 - Type: Added - [auth] [account-requests] [mailer] [locale] [en] Added administrator notifications for pending account requests and delayed the user activation email until manual approval.
|
||||
- 1 - I added a new `email_notification.new_account_requests` user setting in `models/user/setting_options.go`, with an admin-default enabled preference and helper functions to read the preference consistently.
|
||||
- 2 - I modified `routers/web/user/setting/notifications.go`, `routers/web/web.go`, and `templates/user/settings/notifications.tmpl` so administrators now get a `New account request notifications` checkbox in `/user/settings/notifications`, and the last active admin cannot disable it.
|
||||
- 3 - I modified `routers/web/auth/auth.go`, `services/mailer/mail_user.go`, `templates/mail/user/auth/new_account_request.tmpl`, and `options/locale/locale_en-US.json` so manual account requests now send notification emails to opted-in active admins with a direct review link.
|
||||
- 4 - I modified `routers/web/admin/users.go` so when an administrator activates a manually approved account while registration email confirmation is disabled, the applicant receives the standard account activation email at that approval moment.
|
||||
|
||||
8 - [2026-04-16 18:59:58] - v.1.27.0-dev-41-g97eee0a9a8 - Type: Fixed - [account-requests] [locale] [en] Corrected the new account request notification rule so at least one active administrator must remain subscribed.
|
||||
- 1 - I modified `models/user/setting_options.go` to count active administrators who still have new account request notifications enabled and to detect when the current admin is the last enabled recipient.
|
||||
- 2 - I modified `routers/web/user/setting/notifications.go` so the backend now blocks disabling the preference only when the signed-in admin is the last enabled notification recipient, instead of checking whether they are merely the last admin user.
|
||||
- 3 - I modified `templates/user/settings/notifications.tmpl` so the checkbox and submit button are disabled only for the last enabled notification recipient.
|
||||
- 4 - I updated `options/locale/locale_en-US.json` so the warning message now states the real rule clearly: at least one admin must keep these notifications enabled.
|
||||
|
||||
9 - [2026-04-16 20:53:32] - v.1.27.0-dev-41-g97eee0a9a8 - Type: Added - [account-requests] Added automatic notification fallback when deleting the only admin who still receives new account request notifications.
|
||||
- 1 - I added `ShouldEnableNewAccountRequestNotificationsFallback` in `models/user/setting_options.go` so the code can detect when the deleted user is the last active admin with this notification enabled and the acting admin is currently unsubscribed.
|
||||
- 2 - I modified `routers/web/admin/users.go` so, after a successful admin-driven user deletion, the acting admin is automatically subscribed to new account request notifications when they deleted the last subscribed admin.
|
||||
- 3 - I modified `routers/api/v1/admin/user.go` so the same automatic fallback also applies to admin deletions performed through the API, keeping the behavior consistent across both deletion entry points.
|
||||
|
||||
10 - [2026-04-16 23:02:55] - v.1.27.0-dev-42-g81727dd3e9 - Type: Added - [account-requests] [mailer] [locale] [en] Implemented a staged new account request workflow with email validation, admin review, request statuses, and automatic expiry cleanup.
|
||||
- 1 - I added `models/user/account_request.go` to store and manage account request states, validation expiry, retry counting, approval or rejection metadata, validation code generation, and expired pending-request cleanup.
|
||||
- 2 - I modified `routers/web/auth/auth.go`, added `routers/web/auth/account_request.go`, and updated `templates/user/auth/signup_inner.tmpl` so registration now creates pending account requests, resends validation mail when appropriate, blocks repeated unconfirmed attempts after five tries, and moves validated requests into administrator review instead of activating them immediately.
|
||||
- 3 - I modified `routers/web/admin/users.go`, added `routers/web/admin/account_request.go`, updated `routers/web/web.go`, and updated `templates/admin/user/edit.tmpl` so administrators can see the account request status for a user and explicitly activate, reject, or unblock requests from the admin user edit page.
|
||||
- 4 - I modified `services/mailer/mail_user.go`, added the new account request mail templates, updated `options/locale/locale_en-US.json`, and modified `services/user/user.go` with `services/cron/tasks_extended.go` so the workflow now sends dedicated validation, approval, and rejection emails, preserves rejected or blocked accounts from inactive-user cleanup, and automatically deletes only expired requests that never completed email validation.
|
||||
|
||||
11 - [2026-04-16 23:18:45] - v.1.27.0-dev-43-gb2b024d0b6 - Type: Fixed - [account-requests] [locale] [en] Added the missing admin dashboard translation entries for the expired account request cleanup cron task.
|
||||
- 1 - I modified `options/locale/locale_en-US.json` to add `admin.dashboard.delete_expired_account_requests` so the new cron task can be rendered correctly in the admin dashboard task list.
|
||||
- 2 - I added `admin.dashboard.delete_expired_account_requests.started` alongside it so the matching task start message is also available and the cron task follows the same translation pattern as the existing dashboard tasks.
|
||||
- 3 - I verified the locale file remains valid JSON after the change.
|
||||
|
||||
12 - [2026-04-17 00:05:29] - v.1.27.0-dev-43-gb2b024d0b6 - Type: Fixed - [account-requests] [mailer] [signup] Hardened the account request validation email flow so manual approval registrations do not silently skip or hide validation mail failures.
|
||||
- 1 - I modified `routers/web/auth/auth.go` so the `RegisterManualConfirm` path now runs before the generic activation shortcut for normal self-registrations, while still preserving the first-user bootstrap exception.
|
||||
- 2 - I modified `services/mailer/mail_user.go` so account request validation, approval, and rejection emails now return explicit errors when their templates cannot be rendered instead of failing silently.
|
||||
- 3 - I modified `routers/web/auth/account_request.go` and `routers/web/admin/account_request.go` so resend and unblock flows now surface validation-email rendering failures immediately, while approval and rejection actions log mail errors without rolling back the already completed admin decision.
|
||||
- 4 - I verified the updated flow builds cleanly after formatting with compile-only Go tests on the touched packages.
|
||||
|
||||
13 - [2026-04-17 00:53:04] - v.1.27.0-dev-43-gb2b024d0b6 - Type: Fixed - [account-requests] [mailer] Reworked the first-user bootstrap path so manual confirmation sends the validation email instead of bypassing the new account request flow.
|
||||
- 1 - I modified `routers/web/auth/auth.go` so the automatic first-user admin bootstrap now only bypasses email handling when manual confirmation is disabled, while manual-confirm registrations still go through the validation email path.
|
||||
- 2 - I modified `routers/web/auth/account_request.go` so when the validated account is the only user in the instance, the system activates it directly and grants admin rights immediately instead of sending it into an impossible admin-review deadlock.
|
||||
- 3 - I preserved the normal staged workflow for all non-bootstrap registrations, so other users still go from email validation to pending admin review as before.
|
||||
- 4 - I formatted the code and verified the touched packages with compile-only Go tests after the bootstrap flow change.
|
||||
|
||||
14 - [2026-04-17 01:14:35] - v.1.27.0-dev-43-gb2b024d0b6 - Type: Added - [account-requests] [admin-users] [mailer] [locale] [en] Added an admin-side validation email send indicator with success or failure icon and attempt timestamp.
|
||||
- 1 - I modified `models/user/account_request.go` to persist the last validation email attempt status and timestamp for each account request.
|
||||
- 2 - I modified `routers/web/auth/auth.go`, `routers/web/auth/account_request.go`, and `routers/web/admin/account_request.go` so initial send, resend, and unblock flows now record whether the validation email send function returned success or error.
|
||||
- 3 - I modified `routers/web/admin/account_request.go` and `templates/admin/user/edit.tmpl` so the account request panel in the admin user edit page now shows a `✔` or `❌` together with the last validation email attempt timestamp.
|
||||
- 4 - I updated `options/locale/locale_en-US.json`, validated the JSON file, formatted the code, and verified the touched packages with compile-only Go tests.
|
||||
|
||||
15 - [2026-04-17 06:26:17] - v.1.27.0-dev-43-gb2b024d0b6 - Type: Modified - [account-requests] [mailer] [ui] [signup] Extended the validation email attempt indicator so it is visible in the user-facing registration flow as well as in the admin account request panel.
|
||||
- 1 - I modified `routers/web/auth/account_request.go` and `routers/web/auth/auth.go` so the last validation email attempt status and timestamp are loaded into the user-facing signup retry and activation prompt pages.
|
||||
- 2 - I modified `templates/user/auth/signup_inner.tmpl` so the `✔` or `❌` indicator and timestamp now appear next to the pending request message and beside the `Resend` button area.
|
||||
- 3 - I modified `templates/user/auth/activate_prompt.tmpl` so the same indicator and timestamp now appear after the initial validation email attempt triggered by account creation.
|
||||
- 4 - I adjusted `templates/admin/user/edit.tmpl` so the admin panel also shows the indicator when there is mail-attempt data even if the current account request status line is otherwise absent.
|
||||
|
||||
16 - [2026-04-17 07:05:39] - v.1.27.0-dev-43-gb2b024d0b6 - Type: Fixed - [account-requests] [mailer] Switched the account request validation email to a real synchronous send path and added logging for silent mail queue enqueue failures.
|
||||
- 1 - I modified `services/mailer/mail_user.go` so `SendAccountRequestValidationMail` now uses a synchronous sender path instead of only enqueueing the message asynchronously.
|
||||
- 2 - I modified `services/mailer/mailer.go` to add `SendImmediately`, which uses the initialized configured sender directly and returns the real SMTP or sendmail error back to the caller.
|
||||
- 3 - I modified `services/mailer/mailer.go` so `SendAsync` now logs queue initialization and enqueue failures instead of silently discarding them.
|
||||
- 4 - This makes the new-user validation mail behave much closer to `SendTestMail`, which was already using direct sending and was one likely reason test emails succeeded while queued validation emails still appeared to disappear.
|
||||
|
||||
17 - [2026-04-17 08:20:46] - v.1.27.0-dev-43-gb2b024d0b6 - Type: Fixed - [auth] [mailer] Switched the remaining user-facing activation emails to synchronous delivery and stopped showing success when the actual send fails.
|
||||
- 1 - I modified `services/mailer/mail_user.go` so `SendActivateAccountMail` and `SendActivateEmailMail` now return real errors and use direct synchronous sending instead of only queueing the message.
|
||||
- 2 - I modified `services/mailer/mail_user.go` so account request approval and rejection emails sent to the user now use the same synchronous delivery path for consistent behavior.
|
||||
- 3 - I modified `routers/web/auth/auth.go` and `routers/web/user/setting/account.go` so signup and email-confirmation flows stop reporting success when the mail send to the user fails.
|
||||
- 4 - I modified `routers/web/admin/users.go` so administrator-triggered account activation now logs and warns when the activation email to the user could not be sent.
|
||||
|
||||
18 - [2026-04-17 18:54:53] - v.1.27.0-dev-43-gb2b024d0b6 - Type: Modified - [auth] [account-requests] [signup] [locale] [en] Refined the account request resend UX so pending users can retry from both activation and signup pages without losing their entered registration data.
|
||||
- 1 - I modified `templates/user/auth/activate_prompt.tmpl` so the activation page now shows a separate `Did not receive the email?` prompt, a standalone `Resend` button under the mail status indicator, and a Spam/Junk reminder.
|
||||
- 2 - I modified `templates/user/auth/signup_inner.tmpl` so the pending-registration panel now uses plain prompt text plus a dedicated `Resend` button instead of the combined button label, while also preserving the signup form values through the resend action.
|
||||
- 3 - I modified `models/user/account_request.go` and `routers/web/auth/account_request.go` so account request validation emails now track up to five resend actions and automatically hide the resend button after that limit is reached.
|
||||
- 4 - I modified `routers/web/auth/auth.go` and `options/locale/locale_en-US.json` so the activation prompt receives the same resend controls immediately after registration and the new texts are available consistently across both user-facing flows.
|
||||
|
||||
19 - [2026-04-17 22:10:39] - v.1.27.0-dev-43-gb2b024d0b6 - Type: Fixed - [auth] [account-requests] [mailer] [signup] Prevented invalid signup email input from triggering an internal server error in the account request pre-check flow.
|
||||
- 1 - I modified `models/user/account_request.go` so `GetUserByAnyEmail` now trims and validates the email address before querying, reusing the normal email validation behavior instead of treating malformed input like a server-side lookup problem.
|
||||
- 2 - I modified `routers/web/auth/account_request.go` so the signup pre-check now treats invalid or unsupported email formats as normal invalid input and lets the standard registration validation flow handle the user-facing error message.
|
||||
- 3 - I modified `routers/web/auth/account_request.go` so the resend endpoint also treats malformed email input as unavailable instead of escalating it into a 500 error.
|
||||
|
||||
20 - [2026-04-17 23:13:17] - v.1.27.0-dev-43-gb2b024d0b6 - Type: Fixed - [mailer] [signup] [locale] [en] Rolled back newly created self-registration accounts when the initial confirmation email cannot actually be sent.
|
||||
- 1 - I modified `routers/web/auth/auth.go` so `createAndHandleCreatedUser` now passes the template and form context into the post-create flow, allowing failed registration emails to return a normal form error instead of a 500 page.
|
||||
- 2 - I modified `routers/web/auth/auth.go` so the initial account-request validation mail and the initial standard activation mail both delete the newly created user if sending fails, preventing orphaned accounts from being left in the database.
|
||||
- 3 - I added a dedicated `auth.confirmation_mail_failed` user-facing message in `options/locale/locale_en-US.json` so registration now tells the user that the account was not created because the confirmation email could not be sent.
|
||||
- 4 - I preserved the existing resend behavior for already created inactive users, so the rollback applies only to the first mail send during new self-registration.
|
||||
|
||||
21 - [2026-04-26 22:55:56] - v.1.27.0-dev-43-gb2b024d0b6 - Type: Fixed - [scripts] [smart-build] Updated the smart build script for PNPM 10 and the repository frontend build flow.
|
||||
- 1 - I modified `smart-build.sh` to remove the unsupported `--ignore-engines` PNPM option from dependency installation.
|
||||
- 2 - I changed the frontend rebuild step to call `make frontend`, matching the Gitea Makefile target instead of calling a missing `pnpm run build` script.
|
||||
- 3 - I fixed the architecture menu echo line so `Initialization checks` is no longer appended as stray shell text.
|
||||
|
||||
22 - [2026-04-26 23:01:28] - v.1.27.0-dev-43-gb2b024d0b6 - Type: Fixed - [scripts] [smart-build] Made the smart build script find the local Go toolchain before running backend builds.
|
||||
- 1 - I modified `smart-build.sh` to prepend `/usr/local/go/bin` to `PATH` when the local Go binary exists.
|
||||
- 2 - I added an early Go availability check so the script stops with a clear message before invoking `make build` if Go is not installed or visible.
|
||||
- 3 - I added explicit failure handling for dependency installation and frontend asset builds so the script does not continue after a failed prerequisite step.
|
||||
|
||||
23 - [2026-04-26 23:20:08] - v.1.27.0-dev-43-gb2b024d0b6 - Type: Modified - [scripts] [smart-build] [bindata] Added a smart build menu option for SQLite-enabled bindata builds.
|
||||
- 1 - I modified `smart-build.sh` to add a build-tag selection menu with the existing `bindata` build and a new `bindata sqlite sqlite_unlock_notify` option.
|
||||
- 2 - I changed the backend build command to use the selected tag set instead of always passing `TAGS="bindata"`.
|
||||
- 3 - I made SQLite builds enable CGO and write artifacts with a `-sqlite` suffix so they are distinguishable from default bindata builds.
|
||||
|
||||
24 - [2026-04-27 00:18:15] - v.1.27.0-dev-43-gb2b024d0b6 - Type: Fixed - [account-requests] [auth] Made account request validation links robust after account data changes.
|
||||
- 1 - I modified `models/user/account_request.go` so account request validation codes can be stored as hashes and later accepted as a fallback when the stateless code can no longer be recalculated from current user data.
|
||||
- 2 - I modified the registration, resend, and admin unblock flows to generate one validation code, send that exact code by email, and store its hash only after the email send succeeds.
|
||||
- 3 - I cleared stored validation-code hashes when account requests are reset, validated, or approved so old validation links cannot keep working after the request leaves email validation.
|
||||
- 4 - I added focused tests for account request code verification and `/user/activate` handling, including the case where user data changes after the validation email is sent.
|
||||
|
||||
25 - [2026-04-27 00:49:34] - v.1.27.0-dev-43-gb2b024d0b6 - Type: Fixed - [account-requests] [signup] [auth] Corrected pending account request detection for validation links and repeated registration attempts.
|
||||
- 1 - I modified account request status detection so inactive users with validation markers are treated as pending email validation even if `account_request.status` is missing.
|
||||
- 2 - I added a dedicated account-request time-limit code purpose while keeping compatibility with older account-request links, preventing normal activation links from being intercepted by the account request path.
|
||||
- 3 - I moved the pending account request pre-check before generic signup form errors so repeated registration attempts show the pending-request message and resend option instead of `The username is already taken`.
|
||||
- 4 - I updated the pending signup message to include the email address that received the validation email and added focused tests for missing-status validation, classic activation separation, and repeated registration.
|
||||
|
||||
26 - [2026-04-27 01:10:03] - v.1.27.0-dev-43-gb2b024d0b6 - Type: Fixed - [account-requests] Restored the admin account request review flow link to the page with approval controls.
|
||||
- 1 - I modified `services/mailer/mail_user.go` so new account request notification emails now link directly to `/-/admin/users/{id}/edit`, where the `Activate Request` and `Reject` controls are rendered.
|
||||
- 2 - I added a focused mailer test to ensure future account request notifications keep pointing to the admin edit page instead of the read-only user view page.
|
||||
|
||||
27 - [2026-04-27 01:47:34] - v.1.27.0-dev-43-gb2b024d0b6 - Type: Modified - [admin-users] [account-deletion] Hid admin-side account deletion controls for the last active administrator.
|
||||
- 1 - I modified `routers/web/admin/users.go` so the admin user edit page receives `IsLastAdminUser` for the edited user.
|
||||
- 2 - I modified `templates/admin/user/edit.tmpl` so `Delete User Account` is replaced by the existing last-admin warning when the edited user is the only active admin.
|
||||
- 3 - I hid the admin delete confirmation modal for the last-admin case while preserving the backend `DeleteUser` last-admin guard as the final protection.
|
||||
|
||||
28 - [2026-04-27 02:06:06] - v.1.27.0-dev-43-gb2b024d0b6 - Type: Modified - [admin-users] [account-deletion] Kept last-admin account deletion actions visible but disabled.
|
||||
- 1 - I modified `templates/admin/user/edit.tmpl` so `Delete User Account` remains visible as a disabled button for the last active admin while showing the existing last-admin warning.
|
||||
- 2 - I modified `templates/user/settings/account.tmpl` so the self-delete confirmation button remains visible as disabled for the last active admin while showing the same warning.
|
||||
- 3 - I kept delete confirmation modals unavailable for the disabled last-admin actions so blocked actions cannot be submitted from the UI.
|
||||
|
||||
29 - [2026-04-27 09:12:11] - v.1.27.0-dev-43-gb2b024d0b6 - Type: Modified - [admin-users] Adjusted last-admin delete warning placement and spacing.
|
||||
- 1 - I modified `templates/admin/user/edit.tmpl` so the last-admin warning appears above the disabled `Delete User Account` button with vertical spacing.
|
||||
- 2 - I modified `templates/user/settings/account.tmpl` so the disabled self-delete confirmation button has spacing below the warning message.
|
||||
|
||||
30 - [2026-04-27 09:28:16] - v.1.27.0-dev-43-gb2b024d0b6 - Type: Modified - [admin-users] [ui] Restored admin edit action button alignment while keeping the last-admin warning above them.
|
||||
- 1 - I modified `templates/admin/user/edit.tmpl` so the last-admin warning appears above the action button row.
|
||||
- 2 - I kept `Update Profile` and the disabled `Delete User Account` button in the same button row and original order.
|
||||
|
||||
31 - [2026-04-27 10:07:15] - v.1.27.0-dev-43-gb2b024d0b6 - Type: Modified - [account-requests] Adjusted account request resend button sizing and delivery-state feedback.
|
||||
- 1 - I modified the pending signup and activation prompt templates so the resend button is smaller, blue by default, and spaced away from the spam-folder hint.
|
||||
- 2 - I added resend result state rendering so successful sends turn the button green for five seconds and failed sends keep it red.
|
||||
- 3 - I changed the resend handler to re-render the current account-request page with a failed send message instead of showing a server-error page when email delivery fails.
|
||||
|
||||
32 - [2026-04-27 14:41:33] - v.1.27.0-dev-43-gb2b024d0b6 - Type: Added - [scripts] [build-env] Added a build environment configuration script.
|
||||
- 1 - I added `configure.sh` to install and verify the system packages, Go version, Node version, pnpm version, and frontend dependencies required by this Gitea tree.
|
||||
- 2 - I made the script read the required Go, Node, and pnpm versions from `go.mod` and `package.json`, while still allowing environment overrides.
|
||||
- 3 - I added an optional `--with-cross-cgo` mode that installs/configures the heavier cross-CGO toolchains needed for SQLite builds targeting linux/armv7 and windows/amd64.
|
||||
|
||||
33 - [2026-04-27 14:51:16] - v.1.27.0-dev-43-gb2b024d0b6 - Type: Modified - [scripts] [build-env] Added an interactive run menu to the build environment configuration script.
|
||||
- 1 - I modified `configure.sh` so running it without arguments in an interactive terminal shows a description of what the script installs and verifies.
|
||||
- 2 - I added a run menu with Normal, With cross cgo, Verify only, and Quit options.
|
||||
- 3 - I added a `--menu` flag so the same interactive menu can be requested explicitly while keeping the existing command-line options for automated runs.
|
||||
|
||||
34 - [2026-04-27 14:59:01] - v.1.27.0-dev-43-gb2b024d0b6 - Type: Modified - [scripts] [build-env] Made interactive environment verification report missing requirements without failing the menu run.
|
||||
- 1 - I modified `configure.sh` so the interactive `Verify only` menu option lists all detected missing commands and configuration issues instead of stopping at the first missing requirement.
|
||||
- 2 - I kept the direct `./configure.sh --verify-only` mode strict for automated checks, returning a failure when requirements are missing.
|
||||
- 3 - I adjusted the final interactive verification message so it recommends rerunning the menu with Normal or With cross cgo instead of suggesting a build when requirements are still missing.
|
||||
|
||||
35 - [2026-04-27 15:20:01] - v.1.27.0-dev-43-gb2b024d0b6 - Type: Modified - [scripts] [build-env] Translated the build environment configuration script text to English.
|
||||
- 1 - I modified `configure.sh` so the interactive description is written in English.
|
||||
- 2 - I translated the interactive menu option descriptions to English while keeping the existing script behavior unchanged.
|
||||
|
||||
36 - [2026-04-27 19:28:55] - v.1.27.0-dev-43-gb2b024d0b6 - Type: Modified - [mailer] [mailer-ui] Moved test email feedback inline and aligned mail action button states.
|
||||
- 1 - I modified `routers/web/admin/config.go` so the test email result redirects back to the config page with local test-mail state instead of using the global flash alert.
|
||||
- 2 - I modified `templates/admin/config.tmpl` so the test email result appears beside the `Send` button, with the button using primary, green, or red state colors.
|
||||
- 3 - I changed the account request `Resend` button default state from `blue` to `primary` so it uses the same visible blue styling as the rest of the Gitea UI.
|
||||
|
||||
37 - [2026-04-27 19:56:31] - v.1.27.0-dev-43-gb2b024d0b6 - Type: Fixed - [mailer] [mailer-ui] [scripts] [bindata] Forced mail action button colors and refreshed local template bindata.
|
||||
- 1 - I modified the admin test mail and account request resend templates so their default, success, and failure colors are set directly with Gitea theme variables.
|
||||
- 2 - I updated the success timeout scripts to restore the direct primary-color styling after five seconds.
|
||||
- 3 - I regenerated the local ignored `modules/templates/bindata.dat` file so local bindata builds can include the updated templates.
|
||||
|
||||
38 - [2026-04-27 20:05:18] - v.1.27.0-dev-43-gb2b024d0b6 - Type: Modified - [scripts] [smart-build] [bindata] Added bindata freshness checks to the smart build script.
|
||||
- 1 - I modified `smart-build.sh` so bindata builds check the generated templates, options, public, and migration schema bindata files before compilation.
|
||||
- 2 - I made the script regenerate any missing or stale bindata file with `go generate -tags bindata` before running `make build`.
|
||||
- 3 - I kept the regeneration step neutral from cross-build environment variables by clearing `GOOS`, `GOARCH`, `CGO_ENABLED`, and `CC` for the go generate command.
|
||||
|
||||
39 - [2026-04-27 20:35:07] - v.1.27.0-dev-43-gb2b024d0b6 - Type: Fixed - [mailer] [mailer-ui] [admin-config] [ui] [sticky-layout] Preserved scroll position after sending a test email from the admin config page.
|
||||
- 1 - I modified `templates/admin/config.tmpl` so the test email form records the current scroll position before submit.
|
||||
- 2 - I modified `routers/web/admin/config.go` so the test email redirect carries the saved scroll position and returns to the local test-email anchor.
|
||||
- 3 - I regenerated the local ignored `modules/templates/bindata.dat` file so bindata builds can include the scroll-preserving template update.
|
||||
|
||||
40 - [2026-04-27 21:03:25] - v.1.27.0-dev-43-gb2b024d0b6 - Type: Fixed - [mailer] [mailer-ui] [admin-config] [ui] Removed page reload and scroll movement from the admin test email action.
|
||||
- 1 - I modified `templates/admin/config.tmpl` so the `Send Testing Email` form submits through `fetch` and updates the inline message without changing the page URL or scroll position.
|
||||
- 2 - I modified `routers/web/admin/config.go` so inline test email requests return JSON state and message data instead of redirecting.
|
||||
- 3 - I regenerated the local ignored `modules/templates/bindata.dat` file so bindata builds can include the no-jump test email behavior.
|
||||
|
||||
41 - [2026-04-27 21:14:20] - v.1.27.0-dev-43-gb2b024d0b6 - Type: Modified - [mailer] [mailer-ui] [admin-config] Shortened admin test email delivery error messages.
|
||||
- 1 - I modified `routers/web/admin/config.go` so `Send Testing Email` displays a concise SMTP failure reason instead of the full command chain.
|
||||
- 2 - I added normalization for common mail errors such as user unknown, mailbox unavailable, relay access denied, and authentication failure.
|
||||
- 3 - I added a focused unit test for the short test mail error formatter.
|
||||
|
||||
42 - [2026-04-27 21:47:26] - v.1.27.0-dev-43-gb2b024d0b6 - Type: Added - [admin-users] [account-deletion] Added an admin user-list delete account action.
|
||||
- 1 - I modified `templates/admin/user/list.tmpl` so each user row now shows a red trash icon beside the existing User Details and Edit actions.
|
||||
- 2 - I added a shared delete-account confirmation modal on the user management list, including the existing purge option and delete-account warning text.
|
||||
- 3 - I regenerated the local ignored `modules/templates/bindata.dat` file so bindata builds can include the new list action.
|
||||
|
||||
43 - [2026-04-27 22:17:13] - v.1.27.0-dev-43-gb2b024d0b6 - Type: Modified - [admin-users] Matched the admin user-list delete action to the edit-page delete state.
|
||||
- 1 - I modified `routers/web/explore/user.go` so user search pages can receive optional per-user extra data before rendering.
|
||||
- 2 - I modified `routers/web/admin/users.go` so the admin user list marks rows where the user is the last active administrator using the same condition as the edit page.
|
||||
- 3 - I modified `templates/admin/user/list.tmpl` so the trash icon is disabled with the existing last-admin warning tooltip whenever the edit-page `Delete User Account` button would be disabled.
|
||||
|
||||
44 - [2026-04-28 09:12:49] - v.1.27.0-dev-43-gb2b024d0b6 - Type: Fixed - [auth] [account-requests] Blocked inactive account-request users from getting a signed-in session.
|
||||
- 1 - I modified the password sign-in flow so inactive account-request users are stopped before session, 2FA, or remember-cookie creation and are shown the activation prompt instead.
|
||||
- 2 - I added account-request login prompts for pending email validation, pending admin review, rejected, and blocked states, while keeping the resend button available only for pending email validation.
|
||||
- 3 - I modified existing inactive signed sessions on web pages to be signed out before rendering the activation/account-request prompt so the account menu and Sign Out action are not shown.
|
||||
- 4 - I added targeted auth tests for pending email validation and pending admin review login attempts, including username and email login for the validation case.
|
||||
- 5 - I regenerated the local ignored `modules/options/bindata.dat` file so bindata builds can include the new login prompt locale string.
|
||||
|
||||
45 - [2026-04-28 16:01:28] - v1.27.0-dev-47-gf21b6b7a3b - Type: Modified - [auth] [recovery] Added password confirmation to account recovery.
|
||||
- 1 - I modified `templates/user/auth/reset_passwd.tmpl` so the account recovery reset form includes a required `Confirm Password` field.
|
||||
- 2 - I modified `routers/web/auth/password.go` so reset submissions reject mismatched passwords before two-factor checks or password updates.
|
||||
- 3 - I added a focused auth test for mismatched recovery password confirmation and regenerated the local ignored `modules/templates/bindata.dat` file for bindata builds.
|
||||
|
||||
46 - [2026-04-28 19:05:06] - v1.27.0-dev-48-g25a1d84c2e - Type: Fixed - [auth] [recovery] Used the reset-password lifetime for account recovery codes.
|
||||
- 1 - I modified `models/user/user.go` so reset-password time-limit codes are generated and verified with `RESET_PASSWD_CODE_LIVE_MINUTES` instead of `ACTIVE_CODE_LIVE_MINUTES`.
|
||||
- 2 - I kept activation, email activation, and account-request time-limit codes on the existing active-code lifetime.
|
||||
- 3 - I added a focused user-model test that proves reset-password codes remain valid when only `RESET_PASSWD_CODE_LIVE_MINUTES` allows them.
|
||||
|
||||
47 - [2026-04-28 20:31:34] - v1.27.0-dev-48-g25a1d84c2e - Type: Added - [admin-invite] [admin-created-user] [signup] Added admin-created account invitation flow when registration is disabled.
|
||||
- 1 - I modified admin user creation so `DISABLE_REGISTRATION = true` creates inactive, sign-in-prohibited accounts and checks `Send User Registration Notification` by default when mail is configured.
|
||||
- 2 - I added a 24-hour admin invitation token and email template that lets the invited user accept the account, activate the email, and clear `Disable Sign-In`.
|
||||
- 3 - I added targeted tests for invitation token lifetime, invitation acceptance, and disabled-registration admin account creation defaults, then regenerated local ignored template and options bindata.
|
||||
|
||||
48 - [2026-04-28 21:56:08] - v1.27.0-dev-48-g25a1d84c2e - Type: Modified - [scripts] [smart-build] Added smart-build load profile options.
|
||||
- 1 - I modified `smart-build.sh` so it asks for a build load profile before dependency checks, frontend build, bindata generation, and Go compilation.
|
||||
- 2 - I added Moderate and Low Resource profiles that set `GOMAXPROCS`, `MAKEFLAGS=-j1`, and a conservative Node memory limit to reduce CPU and RAM pressure.
|
||||
- 3 - I kept the Normal profile available for the existing unrestricted build behavior.
|
||||
|
||||
49 - [2026-04-28 23:00:25] - v1.27.0-dev-49-g20405fe5e7 - Type: Added - [admin-invite] Notified inviting admins when admin-created invitations are accepted.
|
||||
- 1 - I stored the creator admin ID on disabled-registration admin-created invitation accounts so the invitation acceptance flow knows who to notify.
|
||||
- 2 - I added an invitation-accepted email template and mailer function that sends the accepting user's details back to the admin who created the account.
|
||||
- 3 - I updated targeted admin/auth tests and regenerated local ignored template and options bindata for the new email template and locale strings.
|
||||
|
||||
50 - [2026-04-28 23:52:04] - v1.27.0-dev-50-g8147f7a798 - Type: Modified - [admin-created-user] [admin-users] [badges] Added creator-admin badges to the admin users list.
|
||||
- 1 - I modified the admin user list data loader so users created through the disabled-registration invitation flow include the admin creator name.
|
||||
- 2 - I modified `templates/admin/user/list.tmpl` so the Created column shows a `by <admin>` mini badge next to the creation date when creator data exists.
|
||||
- 3 - I added a focused admin list test for the creator-admin mapping and regenerated local ignored template bindata.
|
||||
|
||||
51 - [2026-04-29 01:55:04] - v1.27.0-dev-51-gcfd7cfa1dc - Type: Fixed - [admin-invite] [admin-created-user] [badges] Kept creator-admin badges permanently attached to invited accounts.
|
||||
- 1 - I modified the admin invitation acceptance notification flow so it no longer deletes the stored creator-admin ID.
|
||||
- 2 - I updated the invitation acceptance test to assert the creator-admin marker remains after the user accepts the invitation.
|
||||
|
||||
52 - [2026-04-29 02:04:41] - v1.27.0-dev-52-gcd96c721e0 - Type: Modified - [admin-created-user] [badges] [mailer] Added persistent admin email tooltip to creator badges.
|
||||
- 1 - I modified admin-created invitation account storage so it permanently saves the creator admin ID, username, and email address.
|
||||
- 2 - I modified the admin users list creator badge so it shows `by <admin>` and exposes the stored admin email as a hover tooltip.
|
||||
- 3 - I updated the focused admin list tests to prove the badge data still renders from stored name/email even without looking up the admin account, then regenerated local ignored template bindata.
|
||||
|
||||
53 - [2026-04-29 02:30:55] - v1.27.0-dev-52-gcd96c721e0 - Type: Modified - [auth] [admin-created-user] [badges] Added admin activation badges and first-admin GOD badge.
|
||||
- 1 - I modified the admin users list so the Activated column can show a `by <admin>` badge with the stored admin email as a hover tooltip.
|
||||
- 2 - I stored admin activation ID, username, and email address when account requests are approved or inactive users are manually activated by an admin.
|
||||
- 3 - I added the special `by GOD` Created-column badge for the first admin account, updated focused admin list tests, and regenerated local ignored template bindata.
|
||||
|
||||
54 - [2026-04-29 08:25:36] - v1.27.0-dev-53-ga3e09bb819 - Type: Fixed - [admin-users] [badges] Prevented empty `by` badges in the admin users list.
|
||||
- 1 - I changed the admin users list badge maps to use pointer values so missing entries render as empty instead of truthy zero-value structs.
|
||||
- 2 - I guarded the Created and Activated badge rendering so badges only appear when a display name exists.
|
||||
- 3 - I reran the focused admin badge tests and regenerated local ignored template bindata.
|
||||
|
||||
55 - [2026-04-29 09:02:42] - v1.27.0-dev-53-ga3e09bb819 - Type: Modified - [account-requests] [admin-users] [ui] Moved account request review controls to the top of the admin user edit panel.
|
||||
- 1 - I moved the account request status message to the top of the admin user edit segment, immediately under the panel header.
|
||||
- 2 - I moved the Activate/Reject/Unblock request controls above the profile edit form so admins can review pending accounts without scrolling down.
|
||||
- 3 - I regenerated local ignored template bindata for the updated admin user edit template.
|
||||
|
||||
56 - [2026-04-29 09:32:09] - v1.27.0-dev-54-gc7c7af77a1 - Type: Modified - [admin-users] Defaulted admin user purge checkboxes to enabled.
|
||||
- 1 - I set the Purge User checkbox to checked by default in the admin user edit delete modal.
|
||||
- 2 - I set the Purge User checkbox to checked by default in the admin users list delete modal.
|
||||
- 3 - I regenerated local ignored template bindata for the updated admin templates.
|
||||
|
||||
57 - [2026-04-29 09:53:08] - v1.27.0-dev-55-ga8d9e5e659 - Type: Added - [auth] [admin-users] [account-status] Added Disable Sign-In metadata to the admin users list.
|
||||
- 1 - I added persistent admin metadata for Disable Sign-In actions, including timestamp, admin ID, admin name, and admin email.
|
||||
- 2 - I added a Disable Sign-In column to the admin users list that displays the block date and `by <admin>` badge with email tooltip.
|
||||
- 3 - I stored the same metadata when admin-created invitation accounts start disabled, when an admin disables sign-in from the edit form, and when an account request is rejected.
|
||||
|
||||
58 - [2026-04-29 10:09:41] - v1.27.0-dev-55-ga8d9e5e659 - Type: Modified - [auth] [admin-users] [account-status] Added inactive marker to the Disable Sign-In admin users column.
|
||||
- 1 - I changed the Disable Sign-In column so users without sign-in disabled show the same `octicon-x` marker style as the other status columns.
|
||||
- 2 - I kept the block date and `by <admin>` badge for users that do have Disable Sign-In metadata.
|
||||
- 3 - I regenerated local ignored template bindata for the updated admin users list template.
|
||||
|
||||
59 - [2026-04-29 14:49:39] - v1.27.0-dev-56-g1dcd81b420 - Type: Added - [admin-users] [account-status] [mailer] Added admin status-change reasons and user email notifications.
|
||||
- 1 - I added reason fields under the admin edit checkboxes for account activation, Disable Sign-In, and restricted status.
|
||||
- 2 - I require a reason when an admin newly deactivates an account, enables Disable Sign-In, or enables restricted mode, then email the user with the action, admin name, and reason.
|
||||
- 3 - I added the status-change email template, locale strings, regenerated local ignored template/options bindata, and reran the focused admin tests.
|
||||
|
||||
60 - [2026-04-29 19:01:39] - v1.27.0-dev-57-g210955465e - Type: Fixed - [auth] [account-status] [mailer] Corrected admin status reason behavior and reactivation emails.
|
||||
- 1 - I changed the admin edit form so reason fields belong to the existing checkboxes and only appear for the restrictive state of each checkbox.
|
||||
- 2 - I persisted the deactivation, Disable Sign-In, and restricted reasons in user settings so later administrators can see the saved reason.
|
||||
- 3 - I changed status-change emails to describe the actual account effect, added notifications when restrictions are lifted, and stopped sending the old activation email on admin reactivation.
|
||||
|
||||
61 - [2026-04-29 19:56:22] - v1.27.0-dev-59-gb3204f3db6 - Type: Added - [admin-users] [badges] Added restricted-admin badges and reason actor badges.
|
||||
- 1 - I added persistent admin metadata for Restricted actions, including timestamp, admin ID, admin name, and admin email.
|
||||
- 2 - I changed the admin users list Restricted column so newly restricted users show the restriction date and `by <admin>` badge with email tooltip.
|
||||
- 3 - I added `by <admin>` badges next to the saved Reason labels in the admin user edit panel for deactivation, Disable Sign-In, and Restricted reasons.
|
||||
|
||||
62 - [2026-04-29 21:00:30] - v1.27.0-dev-60-g396b15372d - Type: Added - [admin-users] [badges] Added Is Administrator reason and admin-grant badges.
|
||||
- 1 - I added persistent metadata for granting administrator privileges, including timestamp, admin ID, admin name, admin email, and reason.
|
||||
- 2 - I changed the admin users list so administrator accounts with grant metadata show an `Admin by <admin>` badge with email tooltip.
|
||||
- 3 - I added the Is Administrator reason field, reason actor badge, grant/revoke email notifications, regenerated local ignored bindata, and added focused admin grant tests.
|
||||
|
||||
63 - [2026-04-29 21:30:55] - v1.27.0-dev-60-g396b15372d - Type: Fixed - [admin-users] Made Is Administrator reasons apply only when admin rights are revoked.
|
||||
- 1 - I changed the Is Administrator reason field so it appears only when the checkbox is unchecked.
|
||||
- 2 - I stopped requiring or sending a reason when administrator privileges are granted and changed that email to a congratulatory promotion message.
|
||||
- 3 - I kept the reason on administrator privilege removal, regenerated template/options bindata, and reran the focused admin grant tests.
|
||||
|
||||
64 - [2026-04-29 22:03:18] - v1.27.0-dev-61-g067a09c2ac - Type: Fixed - [admin-users] Disabled critical self-edit account state checkboxes.
|
||||
- 1 - I disabled User Account Is Activated and Is Restricted when an administrator edits their own account, matching the existing self-edit protection for Disable Sign-In.
|
||||
- 2 - I hardened the admin user update handler so manually submitted self-edit forms cannot change the current admin's active, restricted, or prohibit-login state.
|
||||
- 3 - I regenerated local ignored template bindata and verified the admin package compilation with reduced build pressure.
|
||||
|
||||
65 - [2026-04-29 22:37:56] - v1.27.0-dev-62-g3afb4e8afa - Type: Added - [auth] [scripts] Added Codex ChatGPT login helper script.
|
||||
- 1 - I added `.codex_gpt_login`, an interactive helper for completing the local Codex ChatGPT auth callback in code-server environments.
|
||||
- 2 - The script accepts either a raw received code or a full URL/query containing `code=...`, calls the local callback endpoint, extracts `id_token`, and completes the `/success` request.
|
||||
- 3 - I made the script executable and verified its shell syntax with `bash -n`.
|
||||
|
||||
66 - [2026-04-29 22:55:08] - v1.27.0-dev-62-g3afb4e8afa - Type: Modified - [admin-users] [badges] Added admin actor badge beside the Is Administrator option.
|
||||
- 1 - I updated the admin user edit panel so the Is Administrator checkbox label shows `by <admin>` when administrator grant metadata exists.
|
||||
- 2 - I reused the stored admin email as the badge hover tooltip and regenerated local ignored template bindata.
|
||||
|
||||
67 - [2026-04-30 00:30:40] - v1.27.0-dev-63-g4aacf3bd20 - Type: Fixed - [admin-users] Hid Is Administrator reason unless admin rights were revoked.
|
||||
- 1 - I changed the Is Administrator reason field so normal non-admin users do not see it just because the checkbox is unchecked.
|
||||
- 2 - The reason field now appears only when a saved admin-revocation reason exists or when an existing administrator is being unchecked during the current edit.
|
||||
- 3 - I regenerated local ignored template bindata and verified whitespace with `git diff --check`.
|
||||
|
||||
68 - [2026-04-30 01:44:17] - v1.27.0-dev-64-gcff1b46f50 - Type: Added - [admin-users] [super-admin] Added persistent super administrator protection.
|
||||
- 1 - I added `SUPER_ADMIN_ENABLED` and `ADMIN_MANAGEMENT_POLICY` configuration options for administrator permission management.
|
||||
- 2 - I stored the super administrator role and grant/revoke metadata in persistent user settings, with automatic `by GOD` bootstrap for the first active admin.
|
||||
- 3 - I protected administrator and super administrator changes so regular admins cannot alter existing admins unless the selected policy allows a regular-user promotion.
|
||||
- 4 - I added super administrator badges, reason tracking, and status-change emails, then regenerated template and options bindata.
|
||||
|
||||
69 - [2026-04-30 02:20:26] - v1.27.0-dev-64-gcff1b46f50 - Type: Fixed - [admin-users] [super-admin] Enabled super administrator bootstrap by default.
|
||||
- 1 - I changed `SUPER_ADMIN_ENABLED` to default to `true` so existing installations without the new app.ini key bootstrap the first active administrator automatically.
|
||||
- 2 - I updated the app.ini example to document the enabled default and kept `SUPER_ADMIN_ENABLED = false` available as the explicit opt-out.
|
||||
- 3 - I made the super administrator list badge fall back to `by GOD` for the bootstrapped first administrator and regenerated options bindata.
|
||||
|
||||
70 - [2026-04-30 04:08:23] - v1.27.0-dev-66-g35b9fa65d3 - Type: Fixed - [admin-users] [super-admin] Blocked regular administrators from editing super administrator accounts.
|
||||
- 1 - I modified `routers/web/admin/users.go` so non-super-admins are redirected away from super-admin edit actions, including profile edits and avatar changes.
|
||||
- 2 - I modified `routers/api/v1/admin/user.go` so the admin user edit API now returns forbidden when a regular admin targets a super admin.
|
||||
- 3 - I modified `templates/admin/user/list.tmpl` and `templates/admin/user/view.tmpl` so edit actions are hidden for super-admin accounts when the acting admin is not also a super admin.
|
||||
- 4 - I added `TestAdminCannotEditSuperAdminUser` in `tests/integration/admin_user_test.go` to cover the denied web-edit flow.
|
||||
|
||||
71 - [2026-04-30 04:19:14] - v1.27.0-dev-67-g0fc6f30a30 - Type: Modified - [admin-users] [super-admin] Kept super administrator Edit and Delete controls visible but disabled for regular admins.
|
||||
- 1 - I modified `templates/admin/user/list.tmpl` so super-admin rows still show the `Edit` and `Delete` icons for regular admins, but as disabled muted controls with the super-admin-required tooltip.
|
||||
- 2 - I modified `templates/admin/user/view.tmpl` so the `Edit` button remains visible on the super-admin user details page for regular admins, but in a disabled state.
|
||||
|
||||
72 - [2026-04-30 04:58:16] - v1.27.0-dev-68-g5da24d2c7b - Type: Modified - [admin-users] [admin-policy] Protected GOD-granted admin accounts and blocked deleting the direct grantor.
|
||||
- 1 - I added `models/user/admin_grant.go` with helpers to read admin and super-admin grantor metadata, detect `by GOD` bootstrap grants, and check whether a target user is the direct grantor of another admin.
|
||||
- 2 - I modified `routers/web/admin/users.go` so GOD-granted accounts cannot be edited or deleted through admin actions, and regular admins may delete other admin accounts except their direct grantor and protected super-admin cases.
|
||||
- 3 - I modified `routers/api/v1/admin/user.go` so the admin API now enforces the same GOD-protection and direct-grantor deletion rule.
|
||||
- 4 - I added locale messages for the new admin restrictions and added focused integration coverage for deleting another admin versus the direct grantor, plus GOD-protected admin API edits.
|
||||
|
||||
73 - [2026-04-30 16:51:42] - v1.27.0-dev-71-g80497e4194 - Type: Modified - [admin-users] Restored normal self-edit access for super admins and disabled only the admin actions that are truly forbidden.
|
||||
- 1 - I modified `routers/web/admin/users.go` so a GOD-granted or super-admin user can still edit their own ordinary account fields, while forbidden cross-user edits remain blocked and table action states are computed per target user.
|
||||
- 2 - I modified `routers/api/v1/admin/user.go` so GOD-protection no longer blocks a user from editing their own account through the admin API.
|
||||
- 3 - I modified `templates/admin/user/list.tmpl`, `templates/admin/user/view.tmpl`, and `templates/admin/user/edit.tmpl` so `Edit` stays enabled for allowed self-edits, while forbidden `Edit` and `Delete` actions are shown disabled with the specific reason tooltip or warning message.
|
||||
|
||||
74 - [2026-04-30 20:11:48] - v1.27.0-dev-72-g43161732e3 - Type: Modified - [installer] [locale] [en] Added install-time admin management policy choices with direct-grantor and inherited-grantor enforcement.
|
||||
- 1 - I modified `modules/setting/admin.go`, `services/forms/user_form.go`, `routers/install/install.go`, `templates/install.tmpl`, and `options/locale/locale_en-US.json` so installation now exposes three administrator-management policies: `super_admin_only`, `grantor_only`, and `grantor_inheritance`, while normalizing the old legacy policy names.
|
||||
- 2 - I modified `models/user/admin_grant.go` so the code can resolve the effective admin grantor by walking the admin-grant chain until it finds an active administrator who still has sign-in enabled.
|
||||
- 3 - I modified `routers/web/admin/users.go` so regular admins can edit or delete only the administrator accounts allowed by the selected policy, while keeping super-admin protections, GOD protections, self-edit exceptions, and disabled forbidden actions intact in the admin UI.
|
||||
- 4 - I modified `routers/api/v1/admin/user.go` so the admin API now applies the same grantor-based restrictions for editing and deleting administrator accounts.
|
||||
- 5 - I added focused integration coverage in `tests/integration/admin_user_test.go` and `tests/integration/api_admin_test.go` for direct-grantor edits, inherited-grantor edits, and API denial for unrelated admins.
|
||||
|
||||
75 - [2026-04-30 20:37:01] - v1.27.0-dev-72-g43161732e3 - Type: Modified - [installer] [app-ini-import] [admin-policy] Updated the example app.ini documentation for the new administrator management policies.
|
||||
- 1 - I modified `custom/conf/app.example.ini` so the `ADMIN_MANAGEMENT_POLICY` comments now document `super_admin_only`, `grantor_only`, and `grantor_inheritance`, and changed the documented default to `grantor_only`.
|
||||
|
||||
76 - [2026-04-30 22:03:50] - v1.27.0-dev-73-g1e13af4d6e - Type: Modified - [admin-users] [super-admin] [installer] [locale] [en] Updated install-page administrator labels to super administrator wording.
|
||||
- 1 - I modified `options/locale/locale_en-US.json` so the install-page administrator account title, description, and username label now refer to the super administrator role.
|
||||
- 2 - I renamed the install-page policy label from `Administrator Management Policy` to `Administration Management Policy`.
|
||||
|
||||
77 - [2026-04-30 23:05:46] - v1.27.0-dev-75-gd4a1b88385 - Type: Modified - [mailer] [installer] [locale] [en] Added install-page testing email verification using the entered SMTP settings.
|
||||
- 1 - I modified `routers/install/routes.go`, `routers/install/install.go`, and `templates/install.tmpl` so the install page now has an inline `Send Testing Email` action that posts the current SMTP form values to a dedicated install endpoint.
|
||||
- 2 - I modified `services/mailer/mail.go` and `routers/web/admin/config.go` so compact test-mail error formatting is shared and install can send a test message with a temporary mailer configuration instead of relying on saved global settings.
|
||||
- 3 - I modified `options/locale/locale_en-US.json` for the install-page test-mail labels and regenerated template and options bindata after verifying the affected Go packages compile.
|
||||
|
||||
78 - [2026-04-30 23:25:10] - v1.27.0-dev-75-gd4a1b88385 - Type: Modified - [mailer] [mailer-ui] [installer] Repositioned install-page Send Testing Email under SMTP Password.
|
||||
- 1 - I modified `templates/install.tmpl` so the `Send Testing Email` row now appears immediately below the `SMTP Password` field inside `Email Settings`.
|
||||
- 2 - I kept the existing selectors, inline message area, and button behavior unchanged while preserving the remaining field order.
|
||||
- 3 - I regenerated template bindata and rechecked the install package compile path after the layout-only change.
|
||||
|
||||
79 - [2026-04-30 23:48:41] - v1.27.0-dev-75-gd4a1b88385 - Type: Fixed - [mailer] [mailer-ui] [installer] Aligned install-page Send Testing Email with the standard inline form grid.
|
||||
- 1 - I modified `templates/install.tmpl` so the `Send Testing Email` input, button, and message now render inside the same `right-content` column used by the other install-page inline fields.
|
||||
- 2 - I kept the existing selectors and behavior unchanged and only corrected the layout alignment relative to `SMTP Password`.
|
||||
|
||||
80 - [2026-05-01 00:36:35] - v1.27.0-dev-75-gd4a1b88385 - Type: Fixed - [mailer] [mailer-ui] [installer] [ui] Matched install-page Send Testing Email row to the target inline layout.
|
||||
- 1 - I modified `templates/install.tmpl` so the `Send Testing Email` controls now use an inline wrapper with the same 60 percent content width as the standard install-form inputs instead of the block-style `right-content` helper.
|
||||
- 2 - I kept the existing selectors and behavior unchanged and only corrected the horizontal alignment to match the target SMTP Password row layout.
|
||||
|
||||
81 - [2026-05-01 00:56:45] - v1.27.0-dev-75-gd4a1b88385 - Type: Modified - [mailer] [mailer-ui] [installer] [ui] Brightened install-page Send Testing Email status message colors.
|
||||
- 1 - I modified `templates/install.tmpl` so the inline status message now uses `var(--color-green)` for success and `var(--color-red)` for failure instead of the softer Tailwind utility classes.
|
||||
- 2 - I kept the existing button behavior unchanged and only adjusted the message text color handling in the install-page JavaScript.
|
||||
|
||||
82 - [2026-05-01 13:09:43] - v1.27.0-dev-76-g362d01abbc - Type: Modified - [installer] [signup] [locale] [en] Added install-page Registration Management with coherent mode-driven registration settings.
|
||||
- 1 - I modified `templates/install.tmpl`, `services/forms/user_form.go`, and `routers/install/install.go` so the install page now exposes a dedicated `Registration Management` section with radio-button registration modes plus dependent local and external sub-options.
|
||||
- 2 - I mapped the new UI to the existing service settings by deriving `DISABLE_REGISTRATION`, `ALLOW_ONLY_INTERNAL_REGISTRATION`, `ALLOW_ONLY_EXTERNAL_REGISTRATION`, `REGISTER_EMAIL_CONFIRM`, and `REGISTER_MANUAL_CONFIRM` consistently from the selected mode and sub-options.
|
||||
- 3 - I updated `web_src/js/features/install.ts` and `options/locale/locale_en-US.json` so contradictory options are hidden or disabled in the browser, added the new English labels and descriptions, and regenerated template and options bindata.
|
||||
|
||||
83 - [2026-05-01 18:14:40] - v1.27.0-dev-77-g19fb194db6 - Type: Modified - [installer] [locale] [en] Completed install-page admin-managed account modes and aligned locale install sections.
|
||||
- 1 - I modified `modules/setting/service.go`, `custom/conf/app.example.ini`, `services/forms/user_form.go`, `routers/install/install.go`, `templates/install.tmpl`, and `web_src/js/features/install.ts` so `Registration Management` now includes administrator-managed local versus invitation-based account provisioning, plus a helper for `Enable Email Notifications`.
|
||||
- 2 - I updated `routers/web/admin/users.go` and `routers/api/v1/admin/user.go` so disabled-registration account creation follows the configured administrator-created account mode, stores creator metadata for admin-created users, and sends either invitation mail or standard registration notification accordingly.
|
||||
- 3 - I aligned every `options/locale/locale_*.json` install section to the new key set and en-US fallback order, regenerated template and options bindata, and verified the affected install, admin web, and admin API packages.
|
||||
|
||||
84 - [2026-05-02 00:16:23] - v1.27.0-dev-78-gad0ab4be60 - Type: Modified - [admin-created-user] [admin-users] [installer] [locale] [en] Moved admin-created account delivery mode selection from install to the admin new-user form.
|
||||
- 1 - I updated `templates/install.tmpl` and `web_src/js/features/install.ts` to remove the install-page `Administrator-managed accounts only` sub-mode choice so registration mode no longer decides how `/admin/users/new` delivers newly created accounts.
|
||||
- 2 - I extended `services/forms/admin.go`, `templates/admin/user/new.tmpl`, `web_src/js/features/admin/common.ts`, and `routers/web/admin/users.go` so `/admin/users/new` now offers mutually exclusive `Send User Registration Notification` and `Send User Registration Invitation` checkboxes, defaults the invitation checkbox when mail is available, preserves checkbox state on form re-render, and sends the matching email flow.
|
||||
- 3 - I adjusted `routers/web/admin/users_test.go`, added the new `admin.users.send_register_invite` locale key across `options/locale/locale_*.json`, regenerated template and options bindata, and re-verified the focused admin user flow.
|
||||
|
||||
85 - [2026-05-02 01:52:40] - v1.27.0-dev-79-ga6695a6e73 - Type: Modified - [auth] [mailer] [signup] [locale] [en] Unified classic email-confirmation signup with the resend-based pending validation flow.
|
||||
- 1 - I updated `routers/web/auth/auth.go` and `routers/web/auth/account_request.go` so classic `REGISTER_EMAIL_CONFIRM` signups now render the same resend-capable activation prompt after account creation, redirect repeated signups with the same unconfirmed email to the resend-capable pending state instead of `The username is already taken`, and show the same resend-capable prompt when an unconfirmed user attempts to sign in.
|
||||
- 2 - I added classic activation resend state tracking in `models/user/account_request.go`, re-used the existing resend UI data contract for both signup and activation prompts, and extended `/user/sign_up/resend` to handle classic email-confirmation accounts with a five-resend limit.
|
||||
- 3 - I added focused auth tests in `routers/web/auth/auth_test.go`, aligned all `options/locale/locale_*.json` files with the new confirmation-mail keys, regenerated options bindata, and re-verified the affected auth package.
|
||||
|
||||
86 - [2026-05-02 02:20:53] - v1.27.0-dev-80-g4ab8063966 - Type: Modified - [installer] [locale] [en] Added default language selection to the install page initial configuration.
|
||||
- 1 - I extended `services/forms/user_form.go`, `routers/install/install.go`, and `templates/install.tmpl` so `General Settings` now includes a `Default Language` selector backed by the existing `AllLangs` list and validated against configured locales.
|
||||
- 2 - I wired install submission to persist the selection by reordering `[i18n] LANGS` so the chosen language becomes the first fallback/default locale, while keeping the remaining languages available.
|
||||
- 3 - I added focused install tests in `routers/install/routes_test.go`, aligned all `options/locale/locale_*.json` files with the new install language keys, regenerated template and options bindata, and re-verified the install package.
|
||||
|
||||
87 - [2026-05-02 02:36:07] - v1.27.0-dev-80-g4ab8063966 - Type: Modified - [mailer] Disabled forbidden email deletion actions in the admin email list.
|
||||
- 1 - I extended `routers/web/admin/emails.go` so each listed email now carries explicit delete permission state and, for primary addresses, the existing `admin.emails.delete_primary_email_error` reason for the disabled UI.
|
||||
- 2 - I updated `templates/admin/emails/list.tmpl` so the trash icon remains clickable only for deletable addresses and renders as a muted disabled control with a tooltip when deletion is forbidden, such as for a primary email address.
|
||||
- 3 - I kept the existing backend deletion guard in place, regenerated template bindata, and re-verified the affected admin package plus whitespace consistency.
|
||||
|
||||
88 - [2026-05-02 03:12:25] - v1.27.0-dev-82-gf8f988e85e - Type: Modified - [admin-invite] [installer] [sticky-layout] [locale] [en] Added a dedicated pending-invitation flow for admin-created invite accounts and pinned the install footer.
|
||||
- 1 - I updated `templates/admin/user/new.tmpl`, `routers/web/admin/users.go`, `routers/api/v1/admin/user.go`, `models/user/account_request.go`, and `services/mailer/mail_user.go` so admin-created invitation accounts remain inactive without forcing `Disable Sign-In`, carry explicit pending-invitation state, and show helper text for the notification versus invitation options.
|
||||
- 2 - I added the dedicated invitation prompt and resend flow through `templates/user/auth/invite_prompt.tmpl`, `routers/web/auth/auth.go`, `routers/web/auth/account_request.go`, and `routers/web/web.go`, including sign-in redirection for pending invitations, backward-compatible handling for legacy prohibited invite accounts, and resend tracking for invitation emails.
|
||||
- 3 - I updated `templates/base/footer_content.tmpl`, `web_src/css/install.css`, and all `options/locale/locale_*.json` files so the install footer stays continuously visible on the install page, the new invitation strings are available across locales, template and option bindata were regenerated, and the affected auth/admin/API packages were re-verified.
|
||||
|
||||
89 - [2026-05-02 04:05:54] - v1.27.0-dev-83-gf7bc24d4e8 - Type: Modified - [admin-invite] [installer] [ui] Aligned the admin new-user invitation help text with the install-page help layout.
|
||||
- 1 - I updated `templates/admin/user/new.tmpl` so the `Send User Registration Notification` and `Send User Registration Invitation` rows now use a dedicated right-side content wrapper instead of rendering the help text directly under the checkbox.
|
||||
- 2 - I extended `web_src/css/admin.css` with scoped layout rules for `.admin-user-mail-option` so the help text sits under the checkbox content in the same visual column style used on the install page, including responsive behavior for narrow screens.
|
||||
- 3 - I regenerated template bindata after the markup change and re-verified whitespace consistency for the affected files.
|
||||
|
||||
90 - [2026-05-02 12:11:50] - v1.27.0-dev-84-gf60b2af5a6 - Type: Modified - [installer] [locale] [en] [ui] [sticky-layout] Added an install-page language hint balloon anchored to the footer language selector.
|
||||
- 1 - I updated `templates/base/footer_content.tmpl` and `templates/install.tmpl` so the install page now renders a green `Choose a language` hint balloon tied to the footer language selector and dismisses it on the first page click.
|
||||
- 2 - I extended `web_src/css/install.css` with fixed-position balloon styling and responsive placement above the install footer so the hint remains visible without overlapping the footer controls.
|
||||
- 3 - I added the new `install.language_balloon` locale key to `options/locale/locale_en-US.json`, aligned all `options/locale/locale_*.json` files to include it, and re-generated the template and options bindata assets.
|
||||
|
||||
91 - [2026-05-02 12:28:12] - v1.27.0-dev-84-gf60b2af5a6 - Type: Fixed - [installer] [locale] [ui] [sticky-layout] Delayed the install-page language hint balloon initialization until the footer exists in the DOM.
|
||||
- 1 - I updated `templates/install.tmpl` so the `Choose a language` balloon now initializes on `DOMContentLoaded` instead of running before the footer language selector has been parsed.
|
||||
- 2 - I kept the existing dismiss-on-first-click behavior unchanged and only fixed the timing issue that prevented the balloon from appearing at first page load.
|
||||
- 3 - I regenerated the template bindata assets and re-verified whitespace consistency after the template-only fix.
|
||||
|
||||
92 - [2026-05-02 13:31:45] - v1.27.0-dev-85-g4eaa42bccd - Type: Modified - [locale] [en] [ro] Added official bootstrap support for the Romanian locale.
|
||||
- 1 - I updated `modules/setting/i18n.go` so `ro-RO` is now part of the built-in language list with the display name `Română`.
|
||||
- 2 - I updated `custom/conf/app.example.ini` so the example `[i18n] LANGS` and `NAMES` lists now include `ro-RO` and `Română`.
|
||||
- 3 - I added `options/locale/locale_ro-RO.json` as an initial bootstrap locale copied from `locale_en-US.json`, so the Romanian locale can be selected and loaded cleanly before the dedicated translation pass.
|
||||
|
||||
93 - [2026-05-02 14:41:58] - v1.27.0-dev-86-g414c77278b - Type: Modified - [locale] [en] [ro] Added a first complete Romanian translation pass for `locale_ro-RO.json`.
|
||||
- 1 - I translated `options/locale/locale_ro-RO.json` from the current `locale_en-US.json` structure, preserving placeholders and HTML fragments, then applied targeted manual overrides for the install, auth, mail, and admin account-management flows customized in this fork.
|
||||
- 2 - I normalized key Git and administration terms in Romanian and fixed token-protection artifacts that surfaced during the automated translation pass, including the affected `WebAuthn`, `OpenID`, `CAPTCHA`, `Gitea`, milestone completeness, delete-warning, and GPG warning strings.
|
||||
- 3 - I regenerated `modules/options/bindata.dat` so the updated Romanian locale is embedded in the build output.
|
||||
|
||||
94 - [2026-05-05 02:30:50] - v1.27.0-dev-86-g414c77278b - Type: Modified - [locale] [ro] Refined Romanian UI wording in `locale_ro-RO.json`.
|
||||
- 1 - I adjusted Romanian phrasing across the translated locale to improve readability and consistency in general UI strings.
|
||||
- 2 - I normalized terminology for navigation, repository, authentication, and administration labels to better match the existing Gitea interface.
|
||||
- 3 - I kept placeholders, HTML fragments, and technical tokens intact while polishing the translated text.
|
||||
|
||||
95 - [2026-05-06 03:15:10] - v1.27.0-dev-86-g414c77278b - Type: Modified - [locale] [ro] Corrected Romanian wording and grammar in `locale_ro-RO.json`.
|
||||
- 1 - I fixed a small set of Romanian phrasing and grammar issues identified after the previous translation polish pass.
|
||||
- 2 - I kept the scope limited to wording corrections without changing the locale structure or translation coverage.
|
||||
- 3 - I preserved existing placeholders, HTML fragments, and technical tokens while applying the text fixes.
|
||||
|
||||
96 - [2026-05-06 00:47:16] - v1.27.0-dev-90-g75a9dbf7d7 - Type: Modified - [org-ui] [ui] Restyled the organization creation panel and added a cancel action.
|
||||
- 1 - I updated `templates/org/create.tmpl` so `/org/create` now renders inside a settings-style attached header and segment panel instead of the older standalone form block.
|
||||
- 2 - I kept the existing organization creation fields intact, but changed the action row to a right-aligned button group with a new `Cancel` button beside `Create Organization`.
|
||||
- 3 - I updated `routers/web/org/org.go` to provide a `CancelLink` back to `/user/settings/organization`, regenerated template bindata, and re-verified the `routers/web/org` package.
|
||||
|
||||
97 - [2026-05-06 01:08:23] - v1.27.0-dev-90-g75a9dbf7d7 - Type: Modified - [org-ui] [modal] Converted the organization creation page to a modal-style dialog and preserved the caller page for cancel.
|
||||
- 1 - I updated `templates/org/create.tmpl` so `/org/create` now renders as a visible `ui small modal` dialog with header, content, and actions matching the visual structure used by the Actions secrets and variables modals.
|
||||
- 2 - I extended `web_src/css/org.css` with page-scoped layout rules that center the active modal on the standalone page while keeping the styling limited to `page-content.organization.new.org`.
|
||||
- 3 - I updated `routers/web/org/org.go` so `Cancel` now returns to a safe current-site `redirect_to` target or same-site referrer instead of always forcing `/user/settings/organization`, regenerated template bindata, and re-verified the `routers/web/org` package.
|
||||
|
||||
98 - [2026-05-06 02:02:33] - v1.27.0-dev-91-gba0da47957 - Type: Added - [codex-docs] Added persistent Codex project-orientation documents for fast task handoff and recovery.
|
||||
- 1 - I added `.codex-project-map.md` as a durable project guide that captures the web request flow, authentication architecture, practical extension points, and a restart procedure for new tasks.
|
||||
- 2 - I modified `.codex-context.md` so it now points explicitly to `.codex-project-map.md` and documents the recommended read order for resuming work after a blocked session.
|
||||
- 3 - I refreshed the repository-derived version reference in `.codex-context.md` so future history updates can use the current application version format consistently.
|
||||
|
||||
99 - [2026-05-06 02:18:58] - v1.27.0-dev-91-gba0da47957 - Type: Modified - [org-ui] [modal] [ui] Reworked organization creation into a real overlay modal on top of the organization settings page and made outside clicks close it.
|
||||
- 1 - I modified `templates/user/settings/organization.tmpl` so the `New Organization` action now opens the create dialog with the standard `show-modal` flow while keeping the organization settings page visible in the background.
|
||||
- 2 - I converted `templates/org/create.tmpl` into a reusable modal partial and updated `routers/web/org/org.go` so `/org/create` now renders the same organization settings page with that modal auto-opened, preserving `CancelLink` for close and validation-error flows.
|
||||
- 3 - I simplified `web_src/css/org.css` to keep only the create-modal helper text styling and removed the previous fake standalone modal layout that replaced the background page.
|
||||
|
||||
100 - [2026-05-06 10:13:49] - v1.27.0-dev-91-gba0da47957 - Type: Fixed - [org-ui] [ui] Corrected the organization settings cancel-link build regression.
|
||||
- 1 - I fixed `routers/web/user/setting/profile.go` so it uses the `ctx.Req.RequestURI` field instead of calling it like a function.
|
||||
- 2 - This removes the compile error in `code.gitea.io/gitea/routers/web/user/setting` that was blocking the Windows build after the organization-create modal refactor.
|
||||
|
||||
101 - [2026-05-06 10:54:10] - v1.27.0-dev-91-gba0da47957 - Type: Modified - [org-ui] [modal] Made the new-organization modal open in place from the UI and reset its default values consistently.
|
||||
- 1 - I moved the reusable `create-org-modal` inclusion to `templates/base/footer.tmpl` so signed-in users who can create organizations have the modal available on normal pages without navigating away first.
|
||||
- 2 - I updated the `New Organization` triggers in `templates/base/head_navbar.tmpl`, `templates/user/dashboard/navbar.tmpl`, `templates/admin/org/list.tmpl`, and `templates/user/settings/organization.tmpl` to use `show-modal` with `/org/create` as a non-JavaScript fallback, preserving the current page and scroll position when JavaScript is enabled.
|
||||
- 3 - I added explicit reset attributes for organization name, `redirect_to`, visibility radios, and the `repo_admin_change_team_access` checkbox so the modal opened from `/user/settings/organization` now uses the same defaults as the one opened from the global create menu.
|
||||
|
||||
102 - [2026-05-06 10:55:13] - v1.27.0-dev-91-gba0da47957 - Type: Modified - [org-ui] [modal] Extended the in-place new-organization modal behavior to the dashboard organization list component.
|
||||
- 1 - I modified `web_src/js/components/DashboardRepoList.vue` so the `New Organization` trigger in the organizations dashboard tab now also uses the shared `show-modal` flow instead of forcing navigation when JavaScript is enabled.
|
||||
- 2 - I kept `/org/create` as the fallback `href` in the component so the non-JavaScript path remains available.
|
||||
|
||||
103 - [2026-05-06 18:03:33] - v1.27.0-dev-91-gba0da47957 - Type: Modified - [locale] [ro] Somes correction Romanian wording and grammar in `locale_ro-RO.json`.
|
||||
104 - [2026-05-06 18:19:21] - v1.27.0-dev-91-gba0da47957 - Type: Modified - [ui] Fix align new-user check-boxes help text.
|
||||
105 - [2026-05-06 18:47:44] - v1.27.0-dev-91-gba0da47957 - Type: Modified - [locale] [ro] Some new correction Romanian wording and grammar in `locale_ro-RO.json`.
|
||||
106 - [2026-05-06 15:54:50] - v1.27.0-dev-96-g7c7357f314 - Type: Modified - [admin-invite] [auth] Reduced the resend button size on the invitation acceptance prompt.
|
||||
- 1 - I modified `templates/user/auth/invite_prompt.tmpl` so the `Resend` button on `/user/invitation?email=...` now uses the smaller `ui mini button` size instead of `ui tiny button`.
|
||||
- 2 - I kept the existing inline resend states, colors, and success reset behavior unchanged.
|
||||
|
||||
107 - [2026-05-06 18:57:49] - v1.27.0-dev-98-g5f0f52d04f - Type: Fixed - [org-ui] [modal] Prevented the new-organization modal from inheriting unrelated global success flashes from the underlying page.
|
||||
- 1 - I modified `templates/org/create.tmpl` so the modal now renders only its local error flash instead of the full `base/alert` block.
|
||||
- 2 - This keeps `/org/create` validation errors visible in the modal while preventing inherited success, info, or warning flash messages from the background page from appearing inside it.
|
||||
|
||||
108 - [2026-05-06 21:07:26] - v1.27.0-dev-99-gfc43980a5c - Type: Fixed - [admin-invite] [admin-created-user] [mailer] [locale] Made admin-created user notification and invitation emails use the current page locale.
|
||||
- 1 - I modified `services/mailer/mail_user.go` to add locale-aware variants for registration-notify and admin-invite emails, while preserving the existing user-language fallback helpers for other call sites.
|
||||
- 2 - I modified `routers/web/admin/users.go` and `routers/api/v1/admin/user.go` so admin-created account emails now use `ctx.Locale` from the current request instead of always rendering in the new account's empty or default language.
|
||||
|
||||
109 - [2026-05-06 22:11:33] - v1.27.0-dev-100-g70ef46362e - Type: Modified - [admin-created-user] [mailer] [locale] [en] [ro] Personalized the admin-created account notification email with the creator name and a direct set-password link.
|
||||
- 1 - I modified `services/mailer/mail_user.go` so the registration notification email now accepts the admin user, generates a time-limited `reset_password` token URL for the new account, and passes both values into the mail template.
|
||||
- 2 - I modified `routers/web/admin/users.go` and `routers/api/v1/admin/user.go` so the admin-created account notification now includes `ctx.Doer` when sending the non-invite email variant.
|
||||
- 3 - I modified `templates/mail/user/auth/register_notify.tmpl`, `options/locale/locale_en-US.json`, and `options/locale/locale_ro-RO.json` so the email explicitly states that the administrator created the account and instructs the recipient to use a personal password-setup link before signing in.
|
||||
|
||||
110 - [2026-05-06 22:11:33] - v1.27.0-dev-100-g70ef46362e - Type: Fixed - [admin-created-user] [mailer] Corrected the admin-created account password-setup email link to use the public recovery route.
|
||||
- 1 - I modified `services/mailer/mail_user.go` so the personalized password-setup link now targets `/user/recover_account?code=...`, which is the actual public route mounted for password reset token handling.
|
||||
- 2 - This fixes the 404 triggered by the previous `/user/reset_password?code=...` link, because the router exposes `auth.ResetPasswd` on `/user/recover_account` instead.
|
||||
|
||||
111 - [2026-05-06 23:43:34] - v1.27.0-dev-102-g146013827c - Type: Modified - [admin-invite] [admin-created-user] Made the admin-created account notification link behave like an invitation by signing the user in through `/user/activate`.
|
||||
- 1 - I modified `models/user/user.go` to add a dedicated `TimeLimitCodeAdminAccess` purpose that reuses the password-reset lifetime but remains separate from reset-password and invite tokens.
|
||||
- 2 - I modified `services/mailer/mail_user.go` so the `Send User Registration Notification` email now points to `/user/activate?code=...` with the new admin-access token instead of sending the recipient through the recovery form flow.
|
||||
- 3 - I modified `routers/web/auth/auth.go` so `auth.Activate` and `auth.ActivatePost` can consume the new token, rotate `Rands`, create the session, refresh locale, update last-login metadata, and then rely on the existing `MustChangePassword` redirect to land the user on `/user/settings/change_password`.
|
||||
- 4 - I added `TestActivateAdminAccessSignsInAndInvalidatesCode` in `routers/web/auth/auth_test.go` to cover the new direct-access flow and confirm the token is invalidated after first use.
|
||||
|
||||
112 - [2026-05-06 23:43:34] - v1.27.0-dev-102-g146013827c - Type: Modified - [auth] [admin-created-user] [mailer] Simplified the admin-created account notification email to show only the personalized activation link.
|
||||
- 1 - I modified `templates/mail/user/auth/register_notify.tmpl` so the mail no longer shows the generic `/user/login` URL and instead displays the personalized admin-access link directly under the username.
|
||||
- 2 - I removed the trailing explanatory paragraph below that link to avoid repeating the same password-setup action twice in the same email.
|
||||
|
||||
113 - [2026-05-07 01:01:44] - v1.27.0-dev-104-g10495b7cd1 - Type: Modified - [user-settings] [sticky-layout] [appearance] [locale] [en] [ro] Reverted the global fixed-footer behavior and replaced it with a persistent per-user footer preference in `/user/settings/appearance`.
|
||||
- 1 - I modified `templates/user/settings/appearance.tmpl`, `routers/web/user/setting/profile.go`, and `routers/web/web.go` to add a new footer section with a checkbox that saves whether the footer should stay visible at the bottom of the viewport for the current user.
|
||||
- 2 - I modified `models/user/setting_options.go`, `routers/common/pagetmpl.go`, `templates/base/head.tmpl`, `modules/web/middleware/cookie.go`, `web_src/css/base.css`, and `web_src/css/home.css` so the preference is stored in `user_settings`, propagated into the page layout, and applied only when the `show-persistent-footer` body class is enabled.
|
||||
- 3 - I modified `options/locale/locale_en-US.json`, `options/locale/locale_ro-RO.json`, and `models/user/setting_test.go` to add the new UI strings and a focused test covering the new persisted setting key.
|
||||
|
||||
114 - [2026-05-07 09:30:56] - v1.27.0-dev-105-gb3a7692ce9 - Type: Modified - [ui] [sticky-layout] Moved the persistent footer outside the page scroll area.
|
||||
- 1 - I modified `web_src/css/base.css` so pages with `show-persistent-footer` stop scrolling the whole `body` and instead scroll the `.full.height` content container, keeping the footer in its own fixed viewport slot.
|
||||
- 2 - I modified `web_src/css/home.css` so the persistent footer no longer overlays the page with `position: fixed`, but stays permanently visible as a non-scrolling sibling below the main content area.
|
||||
|
||||
115 - [2026-05-07 09:54:43] - v1.27.0-dev-106-g61a9e4bd06 - Type: Modified - [user-settings] [sticky-layout] [locale] [en] [ro] Added the persistent sticky side-menu preference and the finalized sidebar behavior for `/user/settings` and `/-/admin`.
|
||||
- 1 - I modified `models/user/setting_options.go`, `routers/common/pagetmpl.go`, `templates/base/head.tmpl`, `routers/web/user/setting/profile.go`, `routers/web/web.go`, `templates/user/settings/appearance.tmpl`, `options/locale/locale_en-US.json`, `options/locale/locale_ro-RO.json`, and `models/user/setting_test.go` to add the persisted `ui.sticky_side_menus` preference, expose it to templates as `ShowStickySideMenus`, save it from `/user/settings/appearance`, document it in the UI, and cover it with a focused test.
|
||||
- 2 - I modified `templates/user/settings/actions_general.tmpl` so `/user/settings/actions/general` passes the expected `pageClass` and participates in the same sticky-sidebar behavior as the other settings subpages.
|
||||
- 3 - I modified `web_src/css/modules/flexcontainer.css` so, when the preference is enabled, the shared left menus on `/user/settings` and `/-/admin` use the current sticky layout: sticky positioning on the inner menu, `top: var(--page-spacing)`, footer-aware `max-height` handling for both persistent and non-persistent footer modes, hidden desktop scrollbars, green overflow hints, local menu scrolling, and the current `/user/settings` item padding.
|
||||
- 4 - I modified `web_src/js/features/common-page.ts` so the sticky side menus update their overflow-hint classes dynamically as their scroll position, size, or expanded sections change.
|
||||
|
||||
116 - [2026-05-07 20:41:28] - v1.27.0-dev-106-g61a9e4bd06 - Type: Modified - [user-settings] [sticky-layout] [appearance] [locale] [en] [ro] Added a persistent navigation-bar preference in `/user/settings/appearance`.
|
||||
- 1 - I modified `models/user/setting_options.go`, `models/user/setting_test.go`, `routers/common/pagetmpl.go`, `routers/web/user/setting/profile.go`, `routers/web/web.go`, `templates/base/head.tmpl`, `templates/user/settings/appearance.tmpl`, `options/locale/locale_en-US.json`, and `options/locale/locale_ro-RO.json` to add the persisted `ui.persistent_navbar` preference, expose it to templates as `ShowPersistentNavbar`, save it from `/user/settings/appearance`, and document it in the UI.
|
||||
- 2 - I modified `web_src/css/modules/navbar.css` so the main `#navbar` becomes sticky at the top of the viewport when the new preference is enabled.
|
||||
- 3 - I modified `web_src/css/modules/flexcontainer.css` so sticky side menus take the persistent navbar height into account on desktop, preventing the left menus from sliding underneath the navbar when both preferences are enabled.
|
||||
|
||||
117 - [2026-05-07 20:49:16] - v1.27.0-dev-106-g61a9e4bd06 - Type: Modified - [user-settings] [ui] [sticky-layout] Preserved the `/user/settings` left-menu scroll position across settings-page navigation.
|
||||
- 1 - I modified `web_src/js/features/common-page.ts` so the sticky `/user/settings` menu saves its current `scrollTop` to `sessionStorage` while scrolling and immediately before clicking a menu link.
|
||||
- 2 - I also made the same code restore that saved scroll position after the next settings page renders, keeping the left menu at the same viewport position when navigating between items and subitems.
|
||||
|
||||
118 - [2026-05-07 20:57:42] - v1.27.0-dev-106-g61a9e4bd06 - Type: Modified - [ui] [sticky-layout] Made the footer `Licenses` and `API` links open in a new browser tab and finalized the sticky `User Settings` header plus its top green scroll indicator.
|
||||
- 1 - I modified `templates/base/footer_content.tmpl` so both footer links now use `target="_blank"` with `rel="noreferrer"`.
|
||||
- 2 - I modified `web_src/css/modules/flexcontainer.css` so the `.header.item` at the top of the `/user/settings` sticky side menu now uses `position: sticky` inside the menu itself, with its own background and bottom separator.
|
||||
- 3 - I modified `web_src/css/modules/flexcontainer.css` so, after making the `User Settings` header sticky, the top overflow hint is rendered on the bottom edge of that header and its gradient is drawn by a dedicated `::after` element extending into the scrollable area, while the menu container keeps only the bottom hint when both are active.
|
||||
|
||||
119 - [2026-05-07 21:14:11] - v1.27.0-dev-106-g61a9e4bd06 - Type: Modified - [ui] [sticky-layout] Made the `Admin Settings` menu header sticky while the admin left-menu options scroll.
|
||||
- 1 - I modified `web_src/css/modules/flexcontainer.css` so the `.header.item` at the top of the `/-/admin` sticky side menu now uses the same sticky header treatment as `/user/settings`, with its own background and bottom separator.
|
||||
- 2 - I modified `web_src/css/modules/flexcontainer.css` so the top green overflow indicator for `/-/admin` is also rendered on the bottom edge of the sticky header, with the gradient drawn by the same dedicated `::after` element used in `/user/settings`.
|
||||
|
||||
120 - [2026-05-07 21:31:18] - v1.27.0-dev-106-g61a9e4bd06 - Type: Modified - [user-settings] [ui] [sticky-layout] Preserved the `/user/settings` left-menu scroll position without the visible reset flicker during navigation.
|
||||
- 1 - I modified `templates/user/settings/navbar.tmpl` to add a small inline restore hook around the menu markup, so a saved `scrollTop` is applied from `sessionStorage` before the menu becomes visible on the next settings page.
|
||||
- 2 - I modified `web_src/css/modules/flexcontainer.css` so, while that inline restore is in progress, only the `/user/settings` left menu is temporarily hidden, preventing the brief flash of the menu reset at the top.
|
||||
- 3 - I kept `web_src/js/features/common-page.ts` focused on saving the menu scroll position and refreshing the scroll indicators, removing the now-redundant late restore path from the global initializer.
|
||||
|
||||
121 - [2026-05-07 21:41:44] - v1.27.0-dev-106-g61a9e4bd06 - Type: Modified - [user-settings] [sticky-layout] Restored the agreed `/user/settings` sticky-menu item padding behavior.
|
||||
- 1 - I also updated the same CSS so the `/user/settings` menu padding is applied at the item level inside `.ui.vertical.menu`, using `0.9em 1.14285714em` instead of relying on a menu-level spacing adjustment.
|
||||
|
||||
122 - [2026-05-07 22:11:06] - v1.27.0-dev-106-g61a9e4bd06 - Type: Modified - [user-settings] [ui] [sticky-layout] Restored the pre-`122` `/user/settings` layout baseline while keeping the current sticky-menu behavior.
|
||||
- 1 - I modified `templates/user/settings/layout_head.tmpl` to return the settings page wrapper from `ui container fluid padded flex-container` to `ui container flex-container`.
|
||||
- 2 - I restored the `/user/settings` menu to the same single scroll container structure used before, removing the ineffective inner-body split and keeping the inline restore hook in `templates/user/settings/navbar.tmpl`.
|
||||
- 3 - I modified `web_src/css/modules/flexcontainer.css` so the `/user/settings` left menu remains temporarily hidden only during the inline scroll restore, keeps the `/user/settings`-only 24px non-persistent-footer bottom padding on the left navigation column, and supports the small `--sticky-side-menu-correction` transform without affecting admin pages.
|
||||
- 4 - I kept the matching logic in `web_src/js/features/common-page.ts`, so the `/user/settings` menu still restores its saved scroll position after navigation, refreshes the green overflow indicators, and applies the modest runtime correction only when the sticky menu drifts slightly above its configured top offset.
|
||||
|
||||
123 - [2026-05-09 12:47:10] - v1.27.0-dev-114-gbb77e80bf5 - Type: Modified - [sticky-layout] Finalized the sticky side-menu bottom-edge behavior by compacting menu items and increasing the viewport reserve.
|
||||
- 1 - I modified `web_src/css/modules/menu.css` so shared menu items now use `padding: 0.75em 1.14285714em`, reducing vertical item height across the sticky left menus.
|
||||
- 2 - I modified `web_src/css/modules/flexcontainer.css` so the sticky side menus in both `/user/settings` and `/-/admin` now reserve `40px` instead of `24px` at the bottom of their `max-height` calculation for the non-persistent-footer case.
|
||||
- 3 - This combination keeps the sticky menus from jumping upward at the bottom of the page scroll while preserving the current sticky headers, scroll hints, and `/user/settings` scroll-position restore behavior.
|
||||
|
||||
124 - [2026-05-09 15:31:52] - v1.27.0-dev-115-g06b7bd3ca1 - Type: Modified - [sticky-layout] Highlighted the active submenu entry with the standard active background color.
|
||||
- 1 - I modified `web_src/css/modules/menu.css` so `.ui.vertical.menu .item .menu .active.item` now uses `background-color: var(--color-active)` instead of `transparent`.
|
||||
- 2 - I kept the existing medium font weight and text color unchanged, so only the active submenu background treatment changed.
|
||||
|
||||
125 - [2026-05-09 15:56:47] - v1.27.0-dev-116-g8a0d319607 - Type: Added - [permissions-table] [locale] [en] [ro] Added column-wide Select all controls to the user access-token permissions table.
|
||||
- 1 - I modified `templates/user/settings/applications.tmpl` to add a `Select all` row above the token-scope category rows, with per-column `All` radio buttons for No access, Read, and Write.
|
||||
- 2 - I added `web_src/js/features/access-token-settings.ts` and registered it in `web_src/js/index.ts` so selecting one of those top-row radios automatically applies the matching permission choice to every category row in the same column.
|
||||
- 3 - I added the `settings.select_all` locale string in both `options/locale/locale_en-US.json` and `options/locale/locale_ro-RO.json` for the new control row label.
|
||||
- 4 - I extended the same `web_src/js/features/access-token-settings.ts` logic so each top-row `All` radio now becomes active only when every category row in its column is selected, becomes inactive when the column is no longer fully selected, and can still be reselected to apply that column choice to all rows again.
|
||||
- 5 - I corrected the select-all synchronization fallback so no top-row radio stays selected when no permission column is fully matched, instead of incorrectly defaulting back to the `No access` column.
|
||||
|
||||
126 - [2026-05-09 17:16:12] - v1.27.0-dev-117-gab1135d1c6 - Type: Added - [permissions-table] Added header-level Select all controls to the shared Actions maximum-permissions table.
|
||||
- 1 - I modified `templates/shared/actions/permissions_table.tmpl` to add a second header row with `Select all` on the left and per-column `All` radio controls for None, Read, and Write.
|
||||
- 2 - I extended `web_src/js/features/common-actions-permissions.ts` so those header radios apply the chosen permission to every row in the table and stay synchronized bidirectionally with the current per-row selections.
|
||||
- 3 - Because the change is implemented in the shared Actions permissions partial and its existing initializer, the same behavior now applies consistently to `/user/settings/actions/general` and the other pages that reuse that table.
|
||||
|
||||
127 - [2026-05-09 17:34:41] - v1.27.0-dev-118-g021f12509f - Type: Modified - [org-ui] [sticky-layout] Applied the shared sticky side-menu behavior to organization settings pages.
|
||||
- 1 - I modified `web_src/css/modules/flexcontainer.css` so the same sticky left-menu layout, hidden scrollbar styling, sticky header behavior, and green overflow indicators used by user settings and admin pages now also apply to `.page-content.organization.settings`.
|
||||
- 2 - I modified `web_src/js/features/common-page.ts` so organization settings menus participate in the shared sticky-menu overflow indicator logic.
|
||||
- 3 - I modified `templates/org/settings/actions_general.tmpl` to pass `pageClass: "organization settings actions"` into the shared organization settings layout, so the Actions General page also matches the shared organization settings selectors.
|
||||
|
||||
128 - [2026-05-09 18:46:07] - v1.27.0-dev-120-g01e3eb1306 - Type: Added - [auth] [password-ui] [signup] [locale] [en] [ro] Added password visibility toggles to the login and signup forms.
|
||||
- 1 - I modified `templates/user/auth/signin_inner.tmpl` to add an eye button beside the `/user/login` password field.
|
||||
- 2 - I modified `templates/user/auth/signup_inner.tmpl` to add the same eye button beside the `/user/sign_up` password field and marked the `Confirm Password` field for toggle-aware behavior.
|
||||
- 3 - I added `web_src/js/features/password-visibility.ts` and registered it in `web_src/js/index.ts` so the eye button toggles between hidden and visible password states.
|
||||
- 4 - In the signup form, when password visibility is enabled, the script now hides the `Confirm Password` field, removes its `required` state, and keeps its value synchronized with the main password field; when visibility is disabled again, the field is shown and required again.
|
||||
- 5 - I added `auth.show_password` and `auth.hide_password` locale strings in both `options/locale/locale_en-US.json` and `options/locale/locale_ro-RO.json` for the button tooltip and accessibility label.
|
||||
- 6 - I corrected the login and signup password-toggle button templates so their `data-hide-label` attributes close the Go template expression properly, removing the template parsing error that prevented startup.
|
||||
- 7 - I added `octicon-eye-closed` to `web_src/js/svg.ts`, fixing the runtime JavaScript error raised when the password toggle switched from the visible-eye icon to the hidden-eye icon.
|
||||
|
||||
129 - [2026-05-09 19:36:18] - v1.27.0-dev-121-gbfb584f161 - Type: Modified - [sticky-layout] [repo-settings] Applied the shared sticky side-menu behavior to repository settings pages.
|
||||
- 1 - I modified `web_src/css/modules/flexcontainer.css` so the same sticky left-menu layout, hidden scrollbar styling, sticky header behavior, and green overflow indicators used by user settings, organization settings, and admin pages now also apply to `.page-content.repository.settings`.
|
||||
- 2 - I modified `web_src/js/features/common-page.ts` so repository settings menus participate in the shared sticky-menu overflow indicator logic.
|
||||
|
||||
130 - [2026-05-09 20:07:36] - v1.27.0-dev-122-g652d3c20da - Type: Modified - [sticky-layout] [repo-actions] Applied the shared sticky side-menu behavior to repository Actions pages.
|
||||
- 1 - I modified `templates/repo/actions/list.tmpl` to mark the workflow sidebar menu with a dedicated hook class for the shared sticky-menu initializer.
|
||||
- 2 - I modified `web_src/css/modules/flexcontainer.css` so the same sticky left-menu layout, hidden scrollbar styling, and green overflow indicators now also apply to `.page-content.repository.actions`.
|
||||
- 3 - I modified `web_src/js/features/common-page.ts` so the repository Actions sidebar participates in the shared sticky-menu overflow indicator logic.
|
||||
- 4 - I refined the same CSS for repository Actions so the top green scroll hint is drawn directly on the menu container, because that sidebar has no `.header.item` for the shared header-based top-gradient treatment.
|
||||
- 5 - I extended `templates/repo/actions/list.tmpl` with the same inline `sessionStorage` restore hook pattern used by `/user/settings`, so the repository Actions sidebar can restore its scroll position before becoming visible.
|
||||
- 6 - I modified `web_src/css/modules/flexcontainer.css` so the repository Actions sidebar is temporarily hidden only during that inline restore step, preventing the visible reset flicker.
|
||||
- 7 - I extended `web_src/js/features/common-page.ts` so the repository Actions sidebar now saves its own scroll position on scroll and before navigation clicks, using the dedicated `sticky-side-menu-scroll:repo-actions` session key.
|
||||
|
||||
131 - [2026-05-09 20:54:41] - v1.27.0-dev-123-g0f3876c0b1 - Type: Added - [repo-actions] Added pilot partial navigation for the repository Actions sidebar.
|
||||
- 1 - I added `web_src/js/features/repo-actions-sidebar.ts` and registered it in `web_src/js/index.ts` to intercept plain left-click navigation on `/<user>/<repo>/actions` sidebar workflow links.
|
||||
- 2 - The new client-side flow fetches the target page, replaces only the Actions page `.ui.container` content, updates `document.title`, and pushes the new URL into browser history instead of reloading the full page.
|
||||
- 3 - The same logic also handles browser back/forward through `popstate`, keeping the pilot partial navigation limited to repository Actions pages.
|
||||
- 4 - I extended the same pilot so, after each partial `.ui.container` swap, the repository Actions sidebar re-runs the shared sticky-menu indicator initializer on the new DOM, restoring the green overflow hints that disappeared after the first in-page navigation.
|
||||
|
||||
132 - [2026-05-09 21:10:27] - v1.27.0-dev-123-g0f3876c0b1 - Type: Modified - [scripts] [smart-build] Added an audio bell for interactive prompts in `smart-build.sh`.
|
||||
- 1 - I added a small `notify_human_interaction()` helper to `smart-build.sh` that emits a terminal bell only when the script is running on an interactive terminal.
|
||||
- 2 - I call that helper immediately before the build-load, architecture, and build-tags interactive menus, so the user gets an audible prompt exactly when human input is needed.
|
||||
- 3 - I extended the same helper so VS Code and code-server terminals also get a high-visibility fallback banner when browser-controlled terminal bells do not produce an audible sound.
|
||||
- 4 - I extended the same helper again to send a Linux desktop notification through `notify-send` before each interactive menu, while keeping the existing audio and terminal fallbacks for environments where no notification daemon is available.
|
||||
|
||||
133 - [2026-05-09 22:32:57] - v1.27.0-dev-125-g1525c9c8ee - Type: Modified - [auth] [password-ui] [signup] Finalized the manual-only password visibility toggle behavior for login and signup.
|
||||
- 1 - I removed the static eye button from the login and signup templates and now create it from `web_src/js/features/password-visibility.ts` only when the current password value qualifies for manual reveal.
|
||||
- 2 - The final reveal rules are now strict: prefilled or browser-autofilled passwords never show the eye, appending characters to an already non-empty password still keeps it hidden, and the eye appears only after a trusted manual empty-to-non-empty entry or a full manual replacement of a selected existing value.
|
||||
- 3 - Once the eye has legitimately appeared, it stays visible through continued typing until the password is cleared again, preserves focus plus caret/selection on click, and keeps the signup confirm-password field synchronized while reveal mode is active.
|
||||
- 4 - I converted the toggle into an overlaid control inside the password field, hid the browser-native reveal buttons, and kept the final transparent eye-button background styling that was adjusted manually in `web_src/css/user.css`.
|
||||
|
||||
134 - [2026-05-09 23:58:22] - v1.27.0-dev-125-g1525c9c8ee - Type: Modified - [build-artifacts] Ignored the local frontend hash artifact.
|
||||
- 1 - I added `/.frontend.hash` to `.gitignore` so local frontend rebuild hash churn no longer appears in the repository working tree.
|
||||
- 2 - I removed `.frontend.hash` from Git tracking with `git rm --cached`, so the ignore rule now fully suppresses future local hash churn instead of only affecting newly untracked copies.
|
||||
|
||||
135 - [2026-05-10 00:06:54] - v1.27.0-dev-125-g1525c9c8ee - Type: Modified - [user-settings] [appearance] Unified the persistent appearance toggles into a single settings group.
|
||||
- 1 - I merged the top navigation bar, side menus, and footer persistence controls in `templates/user/settings/appearance.tmpl` into one shared `Persistent layout` section with a single Save button.
|
||||
- 2 - I added `UpdatePersistentLayout` in `routers/web/user/setting/profile.go` and routed `/user/settings/appearance/layout` to save all three preferences in one request while preserving the footer cookie update.
|
||||
- 3 - I added the `settings.persistent_layout` and `settings.persistent_layout_desc` locale strings and finalized the section markup so the shared description sits in its own `.field` container and each per-option help paragraph is separated with a `<br>` after the checkbox row.
|
||||
|
||||
136 - [2026-05-10 18:40:36] - v1.27.0-dev-125-g1525c9c8ee - Type: Added - [org-ui] [permissions-table] Added column-wide Select all controls to the organization team-units permissions table.
|
||||
- 1 - I extended `templates/org/team/new.tmpl` so the team-units permissions table in `org/<team_name>/teams/new` gets the same header-level Select row used by the Actions permissions table, with `All` radios for none, read, and write.
|
||||
- 2 - I extended `web_src/js/features/org-team.ts` to synchronize those header radios bidirectionally with the per-unit permission rows, while correctly ignoring globally disabled read/write cells when applying or computing a column-wide selection.
|
||||
|
||||
137 - [2026-05-10 19:02:14] - v1.27.0-dev-125-g1525c9c8ee - Type: Added - [installer] [password-ui] Added the password visibility toggle to the SMTP password field on the install page.
|
||||
- 1 - I wrapped the `smtp_passwd` input in `templates/install.tmpl` with the same `js-password-toggle-group` used by login and signup, reusing the existing password-visibility initializer and show/hide labels so the install-page SMTP password field gets the same eye toggle behavior.
|
||||
|
||||
138 - [2026-05-10 19:08:32] - v1.27.0-dev-125-g1525c9c8ee - Type: Modified - [mailer] [installer] Enabled install-page email notifications by default for fresh setups.
|
||||
- 1 - I updated `routers/install/install.go` so the install form defaults `mail_notify` to enabled when there is no existing mailer configuration and notify-mail was still unset, while preserving an explicit existing configuration during reinstall/edit scenarios.
|
||||
|
||||
139 - [2026-05-10 19:15:41] - v1.27.0-dev-125-g1525c9c8ee - Type: Added - [installer] [password-ui] Added the password visibility toggle and confirm-password behavior to the install-page super-admin password fields.
|
||||
- 1 - I wrapped the install-page `admin_passwd` field in the same `js-password-toggle-group` used by signup and login, so the super-admin password now gets the same eye toggle UI and manual-entry reveal behavior.
|
||||
- 2 - I wired the install-page `admin_confirm_passwd` field into the existing confirm-password flow, so revealing the admin password hides the confirm field and keeps it synchronized just like the signup form.
|
||||
- 3 - I refined `web_src/js/features/password-visibility.ts` so confirm-field synchronization is opt-in per toggle group via explicit selectors, preventing the install-page SMTP password toggle from accidentally targeting the super-admin confirm field in the same form.
|
||||
- 4 - I adjusted `web_src/css/install.css` so install-page password fields that use the overlaid eye wrapper keep the same 60% inline-field width as the original plain inputs instead of shrinking or stretching when the wrapper is present.
|
||||
|
||||
140 - [2026-05-10 19:22:04] - v1.27.0-dev-125-g1525c9c8ee - Type: Added - [installer] [password-ui] Added the password visibility toggle to the install-page database password field.
|
||||
- 1 - I wrapped `db_passwd` in `templates/install.tmpl` with the same `js-password-toggle-group` used by the other install-page password fields, so the database password now gets the same eye control without changing its inline width or reusing any confirm-password logic.
|
||||
|
||||
141 - [2026-05-10 19:27:48] - v1.27.0-dev-125-g1525c9c8ee - Type: Added - [user-settings] [password-ui] Added the password visibility toggle and confirm-password behavior to `/user/settings/account`.
|
||||
- 1 - I wrapped the `settings.new_password` field in `templates/user/settings/account.tmpl` with the shared `js-password-toggle-group`, reusing the existing eye-toggle logic and show/hide labels.
|
||||
- 2 - I wired the `settings.retype_new_password` field into the existing confirm-password flow through dedicated selectors, so revealing the new password hides the confirm field and keeps it synchronized the same way as signup and the install-page super-admin password form.
|
||||
|
||||
142 - [2026-05-10 19:43:11] - v1.27.0-dev-125-g1525c9c8ee - Type: Added - [installer] [branding] Added optional custom branding uploads to the install page.
|
||||
- 1 - I finalized the installer `Branding` section with optional uploads for `logo.svg`, `logo.png`, `loading.png`, `favicon.svg`, and `favicon.png`, including clear format/size guidance plus a shared-assets checkbox for using one SVG and one PNG upload for both logo and favicon.
|
||||
- 2 - I implemented backend validation and persistence for all branding uploads in `routers/install/install.go` (expected type checks, 1 MB limit, square PNG with minimum 64x64) and save accepted overrides under `custom/public/assets/img/`.
|
||||
- 3 - I completed the runtime behavior so uploaded branding files override built-in assets through layered serving, `logo.svg` is mirrored to `gitea.svg` for legacy lookups, post-install progress prefers a custom `loading.png`, and the shared-assets mode hides favicon fields while relabeling logo fields to `Logo & Favicon SVG/PNG`.
|
||||
- 4 - I manually updated Romanian locale wording for the final branding texts and labels.
|
||||
|
||||
143 - [2026-05-12 00:02:10] - v1.27.0-dev-125-g1525c9c8ee - Type: Modified - [auth] [signup] [admin-created-user] [locale] [en] [ro] Finalized Register behavior for admin-created notification accounts without altering the invitation flow.
|
||||
- 1 - I extended `POST /user/sign_up` in `routers/web/auth/auth.go` for existing active local accounts created by an admin when `username` and `email` match, while explicitly leaving pending admin invitations on their existing flow.
|
||||
- 2 - If password is correct, the user is now authenticated into that existing account; when `MustChangePassword` is enabled, the flow redirects directly to `/user/settings/change_password`, otherwise it follows the normal post-auth redirect.
|
||||
- 3 - If password is incorrect, the flow now redirects to `/user/forgot_password?email=<email>` and shows a warning to use account recovery plus check Spam/Junk.
|
||||
- 4 - I added the locale key `auth.admin_notify_recover_password_spam_hint` in both `options/locale/locale_en-US.json` and `options/locale/locale_ro-RO.json`.
|
||||
- 5 - I added regression tests in `routers/web/auth/auth_test.go` for normal sign-in, forced change-password redirect, wrong-password recovery redirect, and a guard that the admin-invitation flow still redirects to `/user/invitation`.
|
||||
|
||||
144 - [2026-05-12 00:47:20] - v1.27.0-dev-125-g1525c9c8ee - Type: Added - [user-settings] [password-ui] Added the password visibility toggle to `/user/settings/change_password`.
|
||||
- 1 - I wrapped the forced-change password field in `templates/user/auth/change_passwd_inner.tmpl` with the shared `js-password-toggle-group`, reusing the existing eye-toggle logic and show/hide labels.
|
||||
- 2 - I wired the confirm-password field into the existing toggle sync behavior so revealing the new password hides the confirm field and keeps it synchronized like the other password-update forms.
|
||||
|
||||
145 - [2026-05-12 01:16:50] - v1.27.0-dev-125-g1525c9c8ee - Type: Added - [installer] [app-ini-import] [locale] [en] [ro] Added installer support for importing an existing `app.ini`.
|
||||
- 1 - I added an `Import Existing Configuration` section at the top of `templates/install.tmpl` with an `app.ini` upload control that imports automatically as soon as a file is selected, without a separate `Load app.ini` button.
|
||||
- 2 - I kept the dedicated installer route `POST /import_app_ini` in `routers/install/routes.go`, but the page now posts to it via `fetch` and applies the imported values back into the existing form with `DOMParser`, so the browser is not visibly navigated to `/import_app_ini` and the page scripts are not re-executed.
|
||||
- 3 - In `routers/install/install.go`, I factored the installer defaults into reusable helpers, added `app.ini` upload parsing with size/error handling, and mapped the imported config into the existing install form fields for database, general server paths, mailer, registration, OpenID, security, and admin policy settings.
|
||||
- 4 - I added installer locale strings in both `options/locale/locale_en-US.json` and `options/locale/locale_ro-RO.json` for the new import UI, success message, and import errors, and the success flash now auto-dismisses after 5 seconds both on initial page load and after the AJAX import injects a new flash message.
|
||||
- 5 - I added regression coverage in `routers/install/routes_test.go` for the new upload control and the config-to-form mapping behavior.
|
||||
|
||||
146 - [2026-05-12 01:30:10] - v1.27.0-dev-125-g1525c9c8ee - Type: Modified - [installer] [branding] Enabled shared branding assets by default in the installer.
|
||||
- 1 - I updated `routers/install/install.go` so `BrandingUseSharedAssets` starts as enabled on the install form, making `Use the same logo files for favicon assets` checked by default.
|
||||
|
||||
147 - [2026-05-12 01:43:10] - v1.27.0-dev-125-g1525c9c8ee - Type: Added - [installer] [app-ini-import] [secrets] Added optional sensitive-secret import for installer `app.ini` uploads.
|
||||
- 1 - I added an explicit installer checkbox for importing sensitive secrets from `app.ini` in `templates/install.tmpl`.
|
||||
- 2 - I extended the installer form, submit pipeline, and final config writer so the optional import reuses `LFS_JWT_SECRET`, `INTERNAL_TOKEN`, and `oauth2.JWT_SECRET` from the uploaded `app.ini` instead of generating new values, including a submit-time fallback that re-reads the uploaded file if the checkbox was enabled after the first auto-import.
|
||||
- 3 - I finalized secret resolution for both direct values and `LFS_JWT_SECRET_URI` / `INTERNAL_TOKEN_URI` / `JWT_SECRET_URI` file-based references, and added regression coverage for direct imports, URI-based imports, the real `POST /import_app_ini` flow, and the persisted `app.ini` output.
|
||||
|
||||
148 - [2026-05-12 22:44:38] - v1.27.0-dev-143-g512e577c3f - Type: Added - [scripts] [repo-sync] [rollback] Finalized the safe upstream update helper script as `.update-gitea.sh`.
|
||||
- 1 - I renamed the updater to `.update-gitea.sh`, documented its purpose and ordered usage steps, including the explicit "dry-run has conflicts" path before any real sync, and added an interactive menu plus direct commands for `sync`, `dry-run`, `fetch`, `backup`, `status`, `list-backups`, `rollback`, `restore-stash`, `restore-snapshot`, and `clean-dry-run`.
|
||||
- 2 - I hardened real update actions so they verify repository state, create or offer safety backup branches, retain the original pre-sync stash for rollback, and record the active restore metadata inside `.git`.
|
||||
- 3 - I added exact worktree snapshots under `.git/.update-gitea-snapshots`, showed the latest/saved snapshot paths in `status`, and made `rollback` plus `restore-snapshot` restore the saved starting commit, the original local changes, and the exact worktree contents including untracked and ignored files while preserving a fresh safety snapshot of the state being replaced.
|
||||
- 4 - I implemented a reusable dry-run workspace under `.git/.update-gitea-dry-run`, added cleanup for both that workspace and legacy temporary dry-run directories, and made dry-run collect and report all detected rebase conflict steps without modifying the real repository.
|
||||
- 5 - I improved conflict reporting so package.json conflicts show the upstream scripts block, the conflicting commit side, and the current branch working-tree side, and the final dry-run summary now includes the total conflict-step count, the local commits that conflicted, and the unique conflicted files.
|
||||
|
||||
149 - [2026-05-13 00:05:18] - v1.27.0-dev-143-g512e577c3f - Type: Added - [scripts] [repo-sync] [cherry-pick] Added a dedicated safe upstream import helper based on `cherry-pick`.
|
||||
- 1 - I added [`.import-upstream-cherry-pick.sh`](/config/workspace/gitea-dev/gitea/.import-upstream-cherry-pick.sh) as a separate helper that fetches upstream, lists importable upstream-only commits, and imports either selected commits or an inclusive upstream range through `git cherry-pick -x` so the imported commits keep a visible reference to the original upstream hashes.
|
||||
- 2 - I gave the script the same safety model as the updater flow by creating a fresh backup branch, an exact worktree snapshot, and a saved tracked/untracked stash before every real import action, while recording the active restore metadata in `.git/.import-upstream-cherry-pick-state`.
|
||||
- 3 - I added safe recovery commands for `continue`, `rollback`, `restore-stash`, and `restore-snapshot`, so interrupted or unwanted imports can be resumed or reverted back to the saved starting commit and exact worktree state, including untracked and ignored files.
|
||||
- 4 - I added both command-line usage and an interactive menu for fetch, list, import, import-range, continue, backup, rollback, restore, and status workflows.
|
||||
|
||||
150 - [2026-05-13 00:18:42] - v1.27.0-dev-143-g512e577c3f - Type: Added - [scripts] [custom-release] [interactive] Added an interactive custom-release maintenance helper for stable patch lines.
|
||||
- 1 - I added [`.maintain-custom-release.sh`](/config/workspace/gitea-dev/gitea/.maintain-custom-release.sh) to maintain a persistent custom branch such as `release/v1.26-custom`, starting from a base tag like `v1.26.0-rc0`, importing the missing upstream commits from the real upstream minor release branch such as `release/v1.26`, and then importing only the custom commits from a chosen local source branch.
|
||||
- 2 - I made the helper interactive with a menu plus a guided `configure` step, so the base tag, upstream release branch, maintenance branch, custom source branch, upstream compare branch, and custom tag suffix can all be adjusted from prompts instead of only through environment variables, and I added automatic fallback from mistyped patch-style branch names like `release/v1.26.0` to the real upstream branch `release/v1.26` when it exists.
|
||||
- 3 - I gave the script the same safety model as the other local Git helpers by creating a fresh backup branch, an exact worktree snapshot, and a saved tracked/untracked stash before every real import action, while also storing pending cherry-pick state so interrupted sequences can be continued.
|
||||
- 4 - I added recovery commands for `continue`, `rollback`, `restore-stash`, and `restore-snapshot`, and a `tag` command that creates annotated custom release tags such as `v1.26.0-custom` on the maintained custom release branch.
|
||||
|
||||
151 - [2026-05-13 00:34:10] - v1.27.0-dev-143-g512e577c3f - Type: Modified - [scripts] [repo-sync] [fetch] Narrowed local upstream fetch scope and cleaned unused upstream tracking refs.
|
||||
- 1 - I updated [`.update-gitea.sh`](/config/workspace/gitea-dev/gitea/.update-gitea.sh) and [`.import-upstream-cherry-pick.sh`](/config/workspace/gitea-dev/gitea/.import-upstream-cherry-pick.sh) so they fetch only the explicitly requested upstream branch instead of all upstream branches.
|
||||
- 2 - I updated [`.maintain-custom-release.sh`](/config/workspace/gitea-dev/gitea/.maintain-custom-release.sh) so it fetches only the configured upstream release branch, the configured compare branch, and tags, while also normalizing mistaken patch-style release branch names like `release/v1.26.0` to the real upstream branch `release/v1.26`.
|
||||
- 3 - I narrowed the local `remote.upstream.fetch` refspec to `upstream/main` and `upstream/release/v1.26`, then removed the other local `upstream/*` remote-tracking refs so Git Graph no longer shows the unused upstream branches by default.
|
||||
|
||||
152 - [2026-05-13 20:23:40] - v1.27.0-dev-143-g512e577c3f - Type: Modified - [scripts] [custom-release] [restore-points] Extended the custom-release maintenance helper with manual restore points and corrected its fetch and interactive configuration behavior.
|
||||
- 1 - I updated [`.maintain-custom-release.sh`](/config/workspace/gitea-dev/gitea/.maintain-custom-release.sh) so it no longer auto-fetches upstream tags during release-branch synchronization, preventing patch tags like `v1.26.1` from being pulled in just because the release branch history was fetched.
|
||||
- 2 - I added manual restore-point management commands for `create-restore-point`, `list-restore-points`, `restore-point`, and `delete-restore-point`, each backed by an exact worktree snapshot plus an associated backup branch stored under `.git/.maintain-custom-release-restore-points`.
|
||||
- 3 - I integrated the new restore-point workflow into the interactive menu, the `help` text, and `status`, including support for restoring by full path or by the final restore-point directory name, automatically using the latest restore point for the current branch when no target is provided, recognizing the older manual restore points already stored under `.git/.manual-restore-points`, and fixing the interactive configuration prompts so they are shown correctly during `Edit configuration`.
|
||||
|
||||
153 - [2026-05-13 21:51:32] - v1.27.0-dev-143-g512e577c3f - Type: Modified - [scripts] [custom-release] [rollback] Finalized the custom-release maintenance helper workflow and recovery behavior.
|
||||
- 1 - I made `bootstrap` a clean branch-creation step from `BASE_TAG`, separated fetch and sync into explicit compare/release-target/custom actions, added `UPSTREAM_RELEASE_TARGET_REF`, and updated the built-in help so the recommended workflow matches the current menu structure.
|
||||
- 2 - I hardened recovery so rollback, restore-point, restore-snapshot, restore-stash, and restore-deletion correctly preserve or clean script-managed refs, maintenance branches, state files, backup branches, and snapshots, including rollback from the original entry branch after a bootstrap-created maintenance branch, cleanup of legacy restore-point leftovers, and removal of the correctly paired `backup/maint-*` Git Graph marker when a saved snapshot is deleted.
|
||||
- 3 - I finalized the interactive UX by keeping a self-updating runtime copy in `/tmp`, persisting the last-used settings in `/tmp/.maintain-custom-release.env`, and reorganizing the menu into `Manual Backups >`, `Fetch upstreams >`, `Sync >`, `Rollback >`, and `Restore >` submenus, including `Delete Restore >` with numbered stash and snapshot selection, with numbered selections, `b`/`B` or `Enter` for Back, correct return-to-parent behavior from every submenu, and `0` for Exit.
|
||||
|
||||
154 - [2026-05-17 00:18:43] - v1.26.0-rc0-154-gfc98a14014 - Type: Fixed - [admin-users] [terminology] [locale] [en] [ro] Corrected the bootstrap-admin label from `GOOD` to `GOD`.
|
||||
- 1 - I renamed the bootstrap admin actor label and the related immutable-account locale key from `good` to `god` in the admin grant helpers and admin users UI flow.
|
||||
- 2 - I updated the admin API and admin-panel restriction messages, tests, and both English and Romanian locale strings so bootstrap-protected accounts are consistently labeled as `GOD`-granted.
|
||||
- 3 - I updated the matching historical task descriptions in `.codex-history.md` so the earlier admin-policy entries now use the corrected `GOD` terminology.
|
||||
|
||||
155 - [2026-05-17 15:35:49] - v1.26.0-by-petru - Type: Fixed - [scripts] [custom-release] [release-target] Stopped release-target sync from requiring the remote release branch when an explicit target tag/ref is configured.
|
||||
- 1 - I updated [`.maintain-custom-release.sh`](/config/workspace/gitea-dev/gitea/.maintain-custom-release.sh) so `Sync upstream release target commits` validates only the configured `UPSTREAM_RELEASE_TARGET_REF` when one is set, instead of still failing on a missing local `upstream/release/...` remote-tracking branch after successfully fetching a target tag such as `v1.26.1`.
|
||||
|
||||
156 - [2026-05-17 18:14:08] - v1.26.0-by-petru-24-gadb90b3453 - Type: Modified - [scripts] [smart-build] [artifacts] Renamed smart-build outputs to include the tag/ref and generated per-file SHA-256 checksums.
|
||||
- 1 - I updated [`.smart-build.sh`](/config/workspace/gitea-dev/gitea/.smart-build.sh) so each build artifact is now written as `gitea-<tag-or-ref>-<os>-<platform><-sqlite>` with the original executable extension preserved, and each output also gets its own adjacent `.sha256` file generated with `sha256sum` or `shasum -a 256`.
|
||||
|
||||
157 - [2026-05-17 17:32:10] - v1.26.0-by-petru-23-g2d228475fc - Type: Fixed - [build] [versioning] Preserved custom tag names in `GITEA_VERSION` while keeping `git describe` build metadata.
|
||||
- 1 - I updated `Makefile` so `GITEA_VERSION` now strips the leading `v`, preserves exact custom tag names such as `1.26.0-by-petru`, and converts only the trailing `-N-gSHA` suffix from `git describe` into `+N-gSHA` for in-between builds like `1.26.0-by-petru+3-g...` and `1.27.0-dev+143-g...`.
|
||||
|
||||
158 - [2026-05-17 22:20:35] - v1.26.0-by-petru - Type: Fixed - [admin-users] [delete-user] [fetch-action] Made the admin user-table trash action return fetch-compatible delete responses.
|
||||
- 1 - I updated the `/-/admin/users` delete modal in the user table to submit an explicit inline fetch flag, and I changed the web admin `DeleteUser` handler so that this table-specific fetch flow now returns `JSONRedirect` on success and `JSONError` for expected validation failures, while the classic edit-page delete form keeps its normal redirect behavior; I also added integration coverage for the table delete path.
|
||||
|
||||
159 - [2026-05-17 00:21:37] - v1.26.0-by-petru - Type: Modified - [docs] [changelog] [github-links] Documented the custom `1.26.0-by petru & codex` release in `CHANGELOG.md`.
|
||||
- 1 - I added the custom release reference and the dedicated `CUSTOM by petru & codex` release-notes block in `CHANGELOG.md`, summarizing the project-specific features and behavior changes shipped on top of upstream `1.26.0`.
|
||||
- 2 - I updated `CHANGELOG.md` and `CHANGELOG-archived.md` so plain standalone references of the form `(#NNNNN)` and compound ampersand groups such as `(#NNNNN & #MMMMM)` now point directly to `https://github.com/
|
||||
|
||||
159 - [2026-05-17 17:13:47] - v1.26.0-by-petru - Type: Modified - [update] Added v1.26.1 original Gitea commits
|
||||
|
||||
160 - [2026-05-17 17:13:47] - v1.26.1-by-petru - Type: Modified - [docs] [changelog] [github-links] Added explicit GitHub links for the remaining bare PR references in `CHANGELOG.md` for the `v1.26.1-by-petru` release notes.
|
||||
- 1 - I updated the remaining bare `#NNNNN` pull-request references in `CHANGELOG.md` so they now point directly to `https://github.com/go-gitea/gitea/pull/...`, without folding this tag-specific changelog cleanup into the earlier generic changelog-link conversion entry.
|
||||
|
||||
161 - [2026-05-19 21:31:45] - v1.27.0-dev-172-g3a6684178a - Type: Modified - [scripts] [smart-build] [darwin] Added macOS amd64/arm64 smart-build support, including SQLite-aware Docker-host handling for containerized workspaces.
|
||||
- 1 - I updated `smart-build.sh` so its interactive architecture menu now offers `macos-amd64`, `macos-arm64`, and includes both Darwin targets in `All Arch`, while preserving the existing `darwin` artifact naming in `dist/`.
|
||||
- 2 - I added a dedicated Darwin SQLite build path in `smart-build.sh` that routes macOS `bindata sqlite sqlite_unlock_notify` builds through `make release-darwin`, and I updated `Makefile` to make `release-darwin` configurable through `DARWIN_ARCHS` so helper scripts can request only `darwin-10.12/amd64` or `darwin-10.12/arm64`.
|
||||
- 3 - I hardened the Darwin SQLite flow in `smart-build.sh` for `code-server`-style containerized workspaces by distinguishing between a missing Docker CLI and an unreachable Docker daemon, by validating that the host Docker daemon can see the same mounted repository `go.mod` path as the current workspace, and by moving the temporary release output under `dist/` instead of `/tmp`.
|
||||
- 4 - I added `SMART_BUILD_DARWIN_HOST_REPO_PATH` support to `smart-build.sh` so Darwin SQLite builds can be redirected to a host-visible repository mount path when the interactive workspace path inside the container differs from the real host path used by the Docker daemon.
|
||||
|
||||
161 - [2026-05-19 23:43:29] - v1.27.0-dev-172-g06e5bd7f46 - Type: Modified - [scripts] [configure] [git-lfs] Added conditional Git LFS setup to `configure.sh` when repository LFS hooks are installed.
|
||||
- 1 - I updated `.configure.sh` so repositories that already have Git LFS hook scripts in `.git/hooks` now treat `git-lfs` as a required dependency during verification, install the `git-lfs` system package on supported package managers, and run `git lfs install --local` during non-verify setup.
|
||||
@@ -0,0 +1,337 @@
|
||||
# Gitea Project Map for Codex
|
||||
|
||||
This file is the persistent implementation map for fast project orientation.
|
||||
|
||||
Use it after `./.codex-context.md` when a task needs architecture, flow, or extension-point context.
|
||||
|
||||
## 1. Fast Entry Points Index
|
||||
|
||||
- auth -> `routers/web/auth/`, `templates/user/auth/`, `services/auth/`
|
||||
- installer -> `routers/install/`, `templates/install.tmpl`, `options/locale/`
|
||||
- user settings UI -> `routers/web/user/setting/`, `templates/user/settings/`, `web_src/js/features/`, `web_src/css/modules/`
|
||||
- sticky menus / persistent layout UI -> `templates/*/navbar*.tmpl`, `web_src/css/modules/menu.css`, `web_src/css/modules/flexcontainer.css`, `web_src/js/features/common-page.ts`
|
||||
- repo settings / actions UI -> `routers/web/repo/`, `templates/repo/`, `templates/repo/settings/`
|
||||
- admin UI -> `routers/web/admin/`, `templates/admin/`
|
||||
- mail / notifications -> `services/mailer/`, `templates/mail/`, `routers/web/admin/`, `routers/web/auth/`
|
||||
- custom release maintenance and repo-sync helpers -> `./.maintain-custom-release.sh`, `./.update-gitea.sh`, `./.import-upstream-cherry-pick.sh`, `./.codex-script-notes.md`
|
||||
|
||||
## 2. Repository Map
|
||||
|
||||
- Executable entry point: `main.go`
|
||||
- CLI lifecycle and command startup: `cmd/`
|
||||
- Installed-instance initialization and route-tree mounting: `routers/init.go`
|
||||
- Web SSR routes: `routers/web/`
|
||||
- API routes: `routers/api/`
|
||||
- Request context, session, template data, response helpers: `services/context/`
|
||||
- Business logic: `services/`
|
||||
- Persistence and domain models: `models/`
|
||||
- Cross-cutting infrastructure: `modules/`
|
||||
- Server-side templates: `templates/`
|
||||
- Browser-side frontend: `web_src/`
|
||||
|
||||
## 3. Bootstrap and Request Flow
|
||||
|
||||
### 2.1 Application Bootstrap
|
||||
|
||||
1. `main.go`
|
||||
- Sets `setting.AppVer`, `setting.AppBuiltWith`, and `setting.AppStartTime`.
|
||||
- Starts the CLI app through `cmd.NewMainApp(...)` and `cmd.RunMainApp(...)`.
|
||||
|
||||
2. `cmd/web.go`
|
||||
- `newWebCommand()` defines the `web` command.
|
||||
- `runWeb(...)` prepares graceful shutdown.
|
||||
- `serveInstalled(...)` calls `routers.InitWebInstalled(...)` and then `routers.NormalRoutes()`.
|
||||
|
||||
3. `routers/init.go`
|
||||
- `InitWebInstalled(...)` initializes Git, settings, storage, cache, DB, models, auth, indexers, webhooks, SSH, Actions, and cron.
|
||||
- `NormalRoutes()` mounts:
|
||||
- `/` -> `routers/web.Routes()`
|
||||
- `/api/v1` -> public API
|
||||
- `/api/internal` -> private API
|
||||
- optional package and Actions API areas when enabled
|
||||
|
||||
### 2.2 Web Request Pipeline
|
||||
|
||||
1. `routers/web/web.go:Routes()`
|
||||
- Builds the main web router.
|
||||
- Exposes static assets, avatars, `robots.txt`, `metrics`, and `healthz`.
|
||||
|
||||
2. Core middleware
|
||||
- `common.MustInitSessioner()` prepares the session.
|
||||
- `context.Contexter()` builds the web context and template data.
|
||||
- `newWebAuthMiddleware()` resolves optional or required authentication.
|
||||
|
||||
3. `services/context/`
|
||||
- `NewBaseContext(...)` creates the base request context.
|
||||
- `NewWebContext(...)` attaches `Doer`, `Repo`, `Org`, `Session`, `Flash`, and `PageData`.
|
||||
- `Contexter()` injects global template and page data such as:
|
||||
- `Link`
|
||||
- `PageData`
|
||||
- flash cookie
|
||||
- `SystemConfig`
|
||||
- shared template state
|
||||
|
||||
4. Auth and access validation
|
||||
- `verifyAuthWithOptions(...)` enforces:
|
||||
- `SignInRequired`
|
||||
- `SignOutRequired`
|
||||
- `AdminRequired`
|
||||
- cross-origin rules
|
||||
- inactive-user and forced-password-change constraints
|
||||
|
||||
5. Domain handler
|
||||
- The request reaches `routers/web/...` or `routers/api/...`.
|
||||
- Handlers should stay thin and delegate to `services/...`.
|
||||
|
||||
6. Business logic and persistence
|
||||
- `services/...` orchestrate business rules.
|
||||
- `models/...` read or write the DB and represent domain state.
|
||||
- `modules/...` provide reusable infrastructure such as git, storage, cache, markup, logging, web helpers, SSH, and indexing.
|
||||
|
||||
7. Response
|
||||
- Web:
|
||||
- templates from `templates/...`
|
||||
- optional page JS data for `web_src/js/...`
|
||||
- API:
|
||||
- JSON or file responses through helpers in `services/context/`
|
||||
|
||||
## 4. Authentication Map
|
||||
|
||||
### 3.1 Where Auth Routes Live
|
||||
|
||||
Auth routes are mainly declared in `routers/web/web.go`, especially around:
|
||||
- `/user/login`
|
||||
- `/user/sign_up`
|
||||
- `/user/two_factor/...`
|
||||
- `/user/webauthn/...`
|
||||
- `/user/openid/...`
|
||||
- `/login/oauth/...`
|
||||
- `/user/settings/security/...`
|
||||
- `/user/settings/applications/oauth2/...`
|
||||
|
||||
### 3.2 Key Auth Files
|
||||
|
||||
- `routers/web/auth/auth.go`
|
||||
- classic login
|
||||
- signup
|
||||
- remember-cookie login
|
||||
- post-login redirect
|
||||
- branching toward 2FA or WebAuthn
|
||||
|
||||
- `routers/web/auth/password.go`
|
||||
- forgot password
|
||||
- reset password
|
||||
- forced password change
|
||||
|
||||
- `routers/web/auth/2fa.go`
|
||||
- TOTP
|
||||
- scratch codes
|
||||
|
||||
- `routers/web/auth/webauthn.go`
|
||||
- passkeys
|
||||
- WebAuthn challenge/assertion flow
|
||||
|
||||
- `routers/web/auth/openid.go`
|
||||
- OpenID sign-in
|
||||
- connect
|
||||
- register
|
||||
|
||||
- `routers/web/auth/oauth.go`
|
||||
- OAuth2 / OIDC provider login start and callback
|
||||
- link account
|
||||
- auto-registration
|
||||
- provider-data sync triggers
|
||||
|
||||
- `routers/web/auth/oauth_signin_sync.go`
|
||||
- post-login provider-data synchronization
|
||||
|
||||
- `routers/web/auth/oauth2_provider.go`
|
||||
- Gitea as an OAuth2 / OIDC provider
|
||||
- authorize, access token, userinfo, introspection, JWKS
|
||||
|
||||
- `routers/web/auth/linkaccount.go`
|
||||
- external-account linking to a local account
|
||||
|
||||
### 3.3 Classic Web Login Flow
|
||||
|
||||
1. Browser requests `/user/login`.
|
||||
2. `context.Contexter()` prepares context and page data.
|
||||
3. `newWebAuthMiddleware()` attempts authentication through available strategies:
|
||||
- OAuth2 header/bearer where allowed
|
||||
- Basic auth where allowed
|
||||
- reverse-proxy auth if enabled
|
||||
- session
|
||||
- SSPI on Windows if enabled
|
||||
4. `auth.SignIn` renders the page.
|
||||
5. `POST /user/login` enters `auth.SignInPost`.
|
||||
6. On success, the flow may:
|
||||
- branch to 2FA
|
||||
- branch to WebAuthn
|
||||
- create a remember cookie
|
||||
- redirect to `redirect_to` or the default target
|
||||
7. Inactive, blocked, or forced-password-change users are stopped by auth logic or `verifyAuthWithOptions(...)`.
|
||||
|
||||
### 3.4 Auth Services and UI
|
||||
|
||||
- `services/auth/` contains reusable auth strategies such as:
|
||||
- `Basic`
|
||||
- `OAuth2`
|
||||
- `Session`
|
||||
- `ReverseProxy`
|
||||
- `SSPI`
|
||||
|
||||
- Auth UI lives in `templates/user/auth/`
|
||||
- Relevant browser-side auth code includes:
|
||||
- `web_src/js/features/user-auth-webauthn.ts`
|
||||
- `web_src/js/features/captcha.ts`
|
||||
|
||||
### 3.5 Where to Extend Auth
|
||||
|
||||
- New auth UI step:
|
||||
- `routers/web/auth/...`
|
||||
- `templates/user/auth/...`
|
||||
- optional `web_src/js/features/...`
|
||||
|
||||
- New authentication rule or source:
|
||||
- `services/auth/...`
|
||||
- optionally `models/auth/...`
|
||||
- integrate through `newWebAuthMiddleware()`
|
||||
|
||||
- New OAuth2/OIDC provider endpoint:
|
||||
- `routers/web/auth/oauth2_provider.go`
|
||||
- `services/oauth2_provider/...`
|
||||
|
||||
## 5. Change Entry Points
|
||||
|
||||
### 4.1 New Web Route
|
||||
|
||||
- Add handler in `routers/web/<domain>/`
|
||||
- Register in `routers/web/web.go`
|
||||
- If it has UI:
|
||||
- template in `templates/...`
|
||||
- optional JS/CSS in `web_src/...`
|
||||
|
||||
### 4.2 New API Route
|
||||
|
||||
- Add handler in `routers/api/v1/...` or the proper API subtree
|
||||
- Mount through `routers/init.go` or the existing API router
|
||||
- Use `services/context/` helpers for validation and response consistency
|
||||
|
||||
### 4.3 New Business Rule
|
||||
|
||||
- Orchestration in `services/<domain>/`
|
||||
- Persistence in `models/<domain>/`
|
||||
- Keep routing logic thin
|
||||
|
||||
### 4.4 New Template Data
|
||||
|
||||
- Put page-specific data in handlers or domain middleware
|
||||
- Put global data there only if it is truly cross-cutting
|
||||
- For data consumed by page JS, use `ctx.PageData`
|
||||
|
||||
### 4.5 New SSR Screen or UI Change
|
||||
|
||||
- Template in `templates/...`
|
||||
- If client-side interaction is needed:
|
||||
- logic in `web_src/js/features/...`
|
||||
- styles in `web_src/css/...`
|
||||
|
||||
### 4.6 Global Navigation and Template Hooks
|
||||
|
||||
- Main top navigation:
|
||||
- `templates/base/head_navbar.tmpl`
|
||||
|
||||
- Extra global links without rewriting the standard navbar:
|
||||
- `templates/custom/`
|
||||
- `custom/extra_links` hook in `templates/base/head_navbar.tmpl`
|
||||
|
||||
- Repository header and main repo tabs:
|
||||
- `templates/repo/header.tmpl`
|
||||
|
||||
- Extra repo tabs without rewriting the standard header:
|
||||
- `custom/extra_tabs` hook in `templates/repo/header.tmpl`
|
||||
|
||||
- Repo submenu areas:
|
||||
- `templates/repo/navbar.tmpl`
|
||||
- `templates/repo/sub_menu.tmpl`
|
||||
|
||||
### 4.7 User, Org, Repo, and Admin Areas
|
||||
|
||||
- Repo:
|
||||
- `routers/web/repo/`
|
||||
- `services/repository/`, `services/pull/`, `services/issue/`, `services/git/`
|
||||
- `templates/repo/`
|
||||
|
||||
- User:
|
||||
- `routers/web/user/`
|
||||
- `routers/web/user/setting/`
|
||||
- `services/user/`
|
||||
- `templates/user/`
|
||||
- `templates/user/settings/`
|
||||
|
||||
- Org:
|
||||
- `routers/web/org/`
|
||||
- `services/org/`
|
||||
- `templates/org/`
|
||||
- `templates/org/settings/`
|
||||
|
||||
- Admin:
|
||||
- `routers/web/admin/`
|
||||
- support often spans `models/`, `services/`, and `modules/setting/`
|
||||
- `templates/admin/`
|
||||
|
||||
## 6. Frequent Task Shortcuts
|
||||
|
||||
- Login / signup / account recovery:
|
||||
- `routers/web/auth/`
|
||||
- `templates/user/auth/`
|
||||
- `services/auth/`
|
||||
- `models/auth/`
|
||||
- `models/user/`
|
||||
|
||||
- User settings / security / applications:
|
||||
- `routers/web/user/setting/`
|
||||
- `templates/user/settings/`
|
||||
|
||||
- Repository header / tabs / page chrome:
|
||||
- `templates/repo/header.tmpl`
|
||||
- `templates/repo/navbar.tmpl`
|
||||
- `templates/repo/sub_menu.tmpl`
|
||||
|
||||
- Top navigation / global links:
|
||||
- `templates/base/head_navbar.tmpl`
|
||||
- `templates/custom/`
|
||||
|
||||
- Packages:
|
||||
- `routers/api/packages/`
|
||||
- `services/packages/`
|
||||
- `models/packages/`
|
||||
|
||||
- Actions:
|
||||
- `routers/api/actions/`
|
||||
- `routers/web/repo/actions/`
|
||||
- `services/actions/`
|
||||
- `models/actions/`
|
||||
|
||||
## 7. Technology and Validation Notes
|
||||
|
||||
- Backend: Go
|
||||
- Server-side rendering: Go `.tmpl` templates
|
||||
- Frontend: TypeScript
|
||||
- Vue components exist in the repo
|
||||
- Styling: CSS, Tailwind CSS, Fomantic UI
|
||||
- Frontend verification tooling: Vitest, Playwright, ESLint, Stylelint
|
||||
|
||||
For area-specific validation:
|
||||
- Go:
|
||||
- `make fmt`
|
||||
- `make lint-go`
|
||||
- targeted Go tests
|
||||
- TypeScript / frontend:
|
||||
- `make lint-js`
|
||||
- `make test-frontend` or targeted frontend tests when needed
|
||||
- `go.mod` changes:
|
||||
- `make tidy`
|
||||
- targeted frontend tests when needed
|
||||
- `go.mod` changes:
|
||||
- `make tidy`
|
||||
@@ -0,0 +1,62 @@
|
||||
# Codex Script Notes
|
||||
|
||||
This file is a fast-reference companion for the large local helper scripts.
|
||||
|
||||
## `.maintain-custom-release.sh`
|
||||
|
||||
Purpose:
|
||||
- maintain a custom stable branch such as `release/v1.26-custom`
|
||||
- start from `BASE_TAG`
|
||||
- fetch and sync upstream compare / release-target refs explicitly
|
||||
- cherry-pick selected custom work from a local source branch
|
||||
|
||||
Current interaction model:
|
||||
- interactive menu with submenus:
|
||||
- `Manual Backups >`
|
||||
- `Fetch upstreams >`
|
||||
- `Sync >`
|
||||
- `Rollback >`
|
||||
- `Restore >`
|
||||
- submenu navigation:
|
||||
- `Enter` or `b` / `B` => Back
|
||||
- `0` => Exit
|
||||
|
||||
Persistent runtime state:
|
||||
- runtime copy: `/tmp/.maintain-custom-release.sh`
|
||||
- persisted settings: `/tmp/.maintain-custom-release.env`
|
||||
- restore points: `.git/.maintain-custom-release-restore-points/`
|
||||
- snapshots: `.git/.maintain-custom-release-snapshots/`
|
||||
- active state file: `.git/.maintain-custom-release-state`
|
||||
|
||||
Recommended order:
|
||||
1. `Bootstrap maintenance branch`
|
||||
2. `Fetch upstream/main compare ref`
|
||||
3. `Fetch upstream release target ref`
|
||||
4. `Show import plan`
|
||||
5. `Sync` actions as needed
|
||||
|
||||
Important behavior:
|
||||
- `bootstrap` should only create/switch the maintenance branch from `BASE_TAG`; it should not fetch automatically
|
||||
- `rollback` should remove bootstrap-created maintenance branches and clean script-managed refs/artifacts
|
||||
- deleting a saved exact snapshot should also remove its paired `backup/maint-*` Git Graph marker
|
||||
|
||||
## `.update-gitea.sh`
|
||||
|
||||
Purpose:
|
||||
- safe upstream sync helper for the working tree
|
||||
- create safety backups before real sync actions
|
||||
- provide `dry-run`, `rollback`, `restore-stash`, and `restore-snapshot`
|
||||
|
||||
Key safety expectations:
|
||||
- `dry-run` must not modify the real repository
|
||||
- real sync actions must preserve enough state for exact rollback
|
||||
|
||||
## `.import-upstream-cherry-pick.sh`
|
||||
|
||||
Purpose:
|
||||
- import upstream commits through `git cherry-pick -x`
|
||||
- support commit-by-commit or range-based import
|
||||
|
||||
Key safety expectations:
|
||||
- save backup branch, snapshot, and stash before real import actions
|
||||
- support `continue`, `rollback`, `restore-stash`, and `restore-snapshot`
|
||||
Executable
+61
@@ -0,0 +1,61 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
CALLBACK_URL="http://127.0.0.1:1455/auth/callback"
|
||||
SUCCESS_URL="http://localhost:1455/success"
|
||||
|
||||
die() {
|
||||
printf 'ERROR: %s\n' "$*" >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
extract_code() {
|
||||
local input="$1"
|
||||
|
||||
case "$input" in
|
||||
*code=*)
|
||||
input="${input#*code=}"
|
||||
input="${input%%&*}"
|
||||
input="${input%%#*}"
|
||||
;;
|
||||
esac
|
||||
|
||||
printf '%s' "$input"
|
||||
}
|
||||
|
||||
extract_id_token() {
|
||||
local response_file="$1"
|
||||
|
||||
sed -n 's/.*id_token=\([^&[:space:]"'"'"'<>]*\).*/\1/p' "$response_file" |
|
||||
tr -d '\r' |
|
||||
head -n 1
|
||||
}
|
||||
|
||||
printf 'Codex ChatGPT login helper\n'
|
||||
printf 'Paste the received code, full callback URL, or query string containing code=...\n'
|
||||
printf 'Received key: '
|
||||
IFS= read -r received_key
|
||||
|
||||
[ -n "$received_key" ] || die "empty received key"
|
||||
|
||||
code="$(extract_code "$received_key")"
|
||||
[ -n "$code" ] || die "could not extract code"
|
||||
|
||||
response_file="$(mktemp)"
|
||||
trap 'rm -f "$response_file"' EXIT
|
||||
|
||||
printf '\nCalling Codex auth callback...\n'
|
||||
curl -sv -H "Host: localhost" --get --data-urlencode "code=$code" "$CALLBACK_URL" >"$response_file" 2>&1 || {
|
||||
cat "$response_file" >&2
|
||||
die "callback request failed"
|
||||
}
|
||||
|
||||
id_token="$(extract_id_token "$response_file")"
|
||||
[ -n "$id_token" ] || {
|
||||
cat "$response_file" >&2
|
||||
die "could not find id_token in callback response"
|
||||
}
|
||||
|
||||
printf 'id_token received. Completing login...\n'
|
||||
curl -sv --get --data-urlencode "id_token=$id_token" "$SUCCESS_URL"
|
||||
printf '\nDone.\n'
|
||||
Executable
+722
@@ -0,0 +1,722 @@
|
||||
#!/usr/bin/env bash
|
||||
set -Eeuo pipefail
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
|
||||
repo_go_version() {
|
||||
sed -n 's/^go //p' "$SCRIPT_DIR/go.mod" 2>/dev/null | head -n 1
|
||||
}
|
||||
|
||||
repo_node_version() {
|
||||
sed -n 's/.*"node": ">= *\([^"]*\)".*/\1/p' "$SCRIPT_DIR/package.json" 2>/dev/null | head -n 1
|
||||
}
|
||||
|
||||
repo_pnpm_version() {
|
||||
sed -n 's/.*"packageManager": "pnpm@\([^"]*\)".*/\1/p' "$SCRIPT_DIR/package.json" 2>/dev/null | head -n 1
|
||||
}
|
||||
|
||||
GO_VERSION="${GO_VERSION:-$(repo_go_version)}"
|
||||
GO_VERSION="${GO_VERSION:-1.26.2}"
|
||||
NODE_VERSION="${NODE_VERSION:-$(repo_node_version)}"
|
||||
NODE_VERSION="${NODE_VERSION:-22.18.0}"
|
||||
PNPM_VERSION="${PNPM_VERSION:-$(repo_pnpm_version)}"
|
||||
PNPM_VERSION="${PNPM_VERSION:-10.33.0}"
|
||||
NVM_VERSION="${NVM_VERSION:-v0.40.3}"
|
||||
|
||||
INSTALL_SYSTEM=1
|
||||
INSTALL_GO=1
|
||||
INSTALL_NODE=1
|
||||
INSTALL_FRONTEND_DEPS=1
|
||||
VERIFY_ONLY=0
|
||||
WITH_CROSS_CGO=0
|
||||
SHOW_MENU=0
|
||||
VERIFY_REPORT_ONLY=0
|
||||
VERIFY_HAD_ISSUES=0
|
||||
|
||||
usage() {
|
||||
cat <<EOF
|
||||
Usage: ./configure.sh [options]
|
||||
|
||||
Installs and configures the local build requirements for this Gitea tree.
|
||||
|
||||
Options:
|
||||
--with-cross-cgo Also install/configure cross-CGO toolchains for
|
||||
sqlite builds targeting linux/armv7 and windows/amd64.
|
||||
This is useful for "All Arch" + sqlite builds, but it
|
||||
downloads noticeably larger packages.
|
||||
--skip-system Do not install system packages.
|
||||
--skip-go Do not install Go.
|
||||
--skip-node Do not install NVM/Node/pnpm.
|
||||
--skip-frontend-deps Do not run pnpm install --frozen-lockfile.
|
||||
--verify-only Only check the current environment.
|
||||
--menu Show the interactive run menu.
|
||||
-h, --help Show this help.
|
||||
|
||||
Environment overrides:
|
||||
GO_VERSION=$GO_VERSION
|
||||
NODE_VERSION=$NODE_VERSION
|
||||
PNPM_VERSION=$PNPM_VERSION
|
||||
NVM_VERSION=$NVM_VERSION
|
||||
EOF
|
||||
}
|
||||
|
||||
show_description() {
|
||||
cat <<EOF
|
||||
Gitea build environment setup
|
||||
|
||||
This script prepares the local machine for the Gitea build used in this tree.
|
||||
It can install or verify:
|
||||
- the required system build packages, including gcc, make, git, pkg-config,
|
||||
and the SQLite/PAM libraries;
|
||||
- git-lfs when this repository has Git LFS hooks installed;
|
||||
- Go $GO_VERSION, as required by go.mod;
|
||||
- Node $NODE_VERSION and pnpm $PNPM_VERSION, as required by package.json;
|
||||
- frontend dependencies with pnpm install --frozen-lockfile;
|
||||
- optional cross-CGO compilers for SQLite builds targeting linux/armv7
|
||||
and windows/amd64.
|
||||
|
||||
For automated runs, you can keep using CLI options, for example:
|
||||
./configure.sh --verify-only
|
||||
./configure.sh --with-cross-cgo
|
||||
|
||||
EOF
|
||||
}
|
||||
|
||||
interactive_menu() {
|
||||
show_description
|
||||
cat <<EOF
|
||||
Select install mode:
|
||||
1) Normal mode
|
||||
2) With cross cgo
|
||||
3) Verify only
|
||||
4) Quit
|
||||
|
||||
EOF
|
||||
# Install the standard requirements: system packages, Go, Node, pnpm, and frontend deps.
|
||||
# Normal mode plus cross-CGO toolchains for multi-arch SQLite builds.
|
||||
# Install nothing; only check the current environment.
|
||||
|
||||
while true; do
|
||||
printf 'Choose option [1-4]: '
|
||||
if ! read -r choice; then
|
||||
die "No menu option selected."
|
||||
fi
|
||||
|
||||
case "$choice" in
|
||||
1)
|
||||
printf 'Selected: Normal\n'
|
||||
return
|
||||
;;
|
||||
2)
|
||||
WITH_CROSS_CGO=1
|
||||
printf 'Selected: With cross cgo\n'
|
||||
return
|
||||
;;
|
||||
3)
|
||||
VERIFY_ONLY=1
|
||||
INSTALL_SYSTEM=0
|
||||
INSTALL_GO=0
|
||||
INSTALL_NODE=0
|
||||
INSTALL_FRONTEND_DEPS=0
|
||||
VERIFY_REPORT_ONLY=1
|
||||
printf 'Selected: Verify only\n'
|
||||
return
|
||||
;;
|
||||
4)
|
||||
printf 'Canceled.\n'
|
||||
exit 0
|
||||
;;
|
||||
*)
|
||||
printf 'Invalid option: %s\n' "$choice"
|
||||
;;
|
||||
esac
|
||||
done
|
||||
}
|
||||
|
||||
log() {
|
||||
printf '\n==> %s\n' "$*"
|
||||
}
|
||||
|
||||
warn() {
|
||||
printf 'WARNING: %s\n' "$*" >&2
|
||||
}
|
||||
|
||||
die() {
|
||||
printf 'ERROR: %s\n' "$*" >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
command_exists() {
|
||||
command -v "$1" >/dev/null 2>&1
|
||||
}
|
||||
|
||||
repo_has_git_lfs_hooks() {
|
||||
local hook
|
||||
for hook in pre-push post-checkout post-commit post-merge; do
|
||||
[ -f "$SCRIPT_DIR/.git/hooks/$hook" ] || continue
|
||||
if grep -q 'git-lfs' "$SCRIPT_DIR/.git/hooks/$hook"; then
|
||||
return 0
|
||||
fi
|
||||
done
|
||||
return 1
|
||||
}
|
||||
|
||||
repo_requires_git_lfs() {
|
||||
repo_has_git_lfs_hooks
|
||||
}
|
||||
|
||||
run_as_root() {
|
||||
if [ "$(id -u)" -eq 0 ]; then
|
||||
"$@"
|
||||
elif command_exists sudo; then
|
||||
sudo "$@"
|
||||
else
|
||||
die "This step needs root privileges. Install sudo or run the script as root."
|
||||
fi
|
||||
}
|
||||
|
||||
fetch_to() {
|
||||
local url="$1"
|
||||
local output="$2"
|
||||
|
||||
if command_exists curl; then
|
||||
curl -fL --retry 3 --retry-delay 2 -o "$output" "$url"
|
||||
elif command_exists wget; then
|
||||
wget -O "$output" "$url"
|
||||
else
|
||||
die "curl or wget is required to download $url"
|
||||
fi
|
||||
}
|
||||
|
||||
version_ge() {
|
||||
local actual="$1"
|
||||
local required="$2"
|
||||
[ "$(printf '%s\n%s\n' "$required" "$actual" | sort -V | head -n 1)" = "$required" ]
|
||||
}
|
||||
|
||||
append_profile_line() {
|
||||
local file="$1"
|
||||
local line="$2"
|
||||
|
||||
touch "$file"
|
||||
if ! grep -qxF "$line" "$file"; then
|
||||
printf '\n%s\n' "$line" >>"$file"
|
||||
fi
|
||||
}
|
||||
|
||||
ensure_go_path() {
|
||||
activate_go_path
|
||||
append_profile_line "$HOME/.profile" 'export PATH="/usr/local/go/bin:$HOME/go/bin:$PATH"'
|
||||
append_profile_line "$HOME/.bashrc" 'export PATH="/usr/local/go/bin:$HOME/go/bin:$PATH"'
|
||||
}
|
||||
|
||||
activate_go_path() {
|
||||
export PATH="/usr/local/go/bin:$HOME/go/bin:$PATH"
|
||||
}
|
||||
|
||||
install_system_packages() {
|
||||
log "Installing system packages"
|
||||
|
||||
if command_exists apt-get; then
|
||||
local -a packages=(
|
||||
bash
|
||||
build-essential
|
||||
ca-certificates
|
||||
coreutils
|
||||
curl
|
||||
findutils
|
||||
gawk
|
||||
git
|
||||
gzip
|
||||
libpam0g-dev
|
||||
libsqlite3-dev
|
||||
make
|
||||
openssh-client
|
||||
perl
|
||||
pkg-config
|
||||
python3
|
||||
sed
|
||||
sqlite3
|
||||
tar
|
||||
unzip
|
||||
wget
|
||||
xz-utils
|
||||
zip
|
||||
)
|
||||
repo_requires_git_lfs && packages+=(git-lfs)
|
||||
if [ "$WITH_CROSS_CGO" -eq 1 ]; then
|
||||
packages+=(
|
||||
gcc-arm-linux-gnueabihf
|
||||
g++-arm-linux-gnueabihf
|
||||
gcc-mingw-w64-x86-64
|
||||
g++-mingw-w64-x86-64
|
||||
)
|
||||
fi
|
||||
run_as_root apt-get update
|
||||
run_as_root env DEBIAN_FRONTEND=noninteractive apt-get install -y "${packages[@]}"
|
||||
return
|
||||
fi
|
||||
|
||||
if command_exists dnf; then
|
||||
local -a packages=(
|
||||
bash
|
||||
ca-certificates
|
||||
coreutils
|
||||
curl
|
||||
findutils
|
||||
gawk
|
||||
gcc
|
||||
gcc-c++
|
||||
git
|
||||
gzip
|
||||
make
|
||||
openssh-clients
|
||||
pam-devel
|
||||
perl-core
|
||||
pkgconf-pkg-config
|
||||
python3
|
||||
sed
|
||||
sqlite
|
||||
sqlite-devel
|
||||
tar
|
||||
unzip
|
||||
wget
|
||||
xz
|
||||
zip
|
||||
)
|
||||
repo_requires_git_lfs && packages+=(git-lfs)
|
||||
run_as_root dnf install -y "${packages[@]}"
|
||||
[ "$WITH_CROSS_CGO" -eq 0 ] || warn "Cross-CGO package setup is only automated for apt-based systems."
|
||||
return
|
||||
fi
|
||||
|
||||
if command_exists yum; then
|
||||
local -a packages=(
|
||||
bash
|
||||
ca-certificates
|
||||
coreutils
|
||||
curl
|
||||
findutils
|
||||
gawk
|
||||
gcc
|
||||
gcc-c++
|
||||
git
|
||||
gzip
|
||||
make
|
||||
openssh-clients
|
||||
pam-devel
|
||||
perl
|
||||
pkgconfig
|
||||
python3
|
||||
sed
|
||||
sqlite
|
||||
sqlite-devel
|
||||
tar
|
||||
unzip
|
||||
wget
|
||||
xz
|
||||
zip
|
||||
)
|
||||
repo_requires_git_lfs && packages+=(git-lfs)
|
||||
run_as_root yum install -y "${packages[@]}"
|
||||
[ "$WITH_CROSS_CGO" -eq 0 ] || warn "Cross-CGO package setup is only automated for apt-based systems."
|
||||
return
|
||||
fi
|
||||
|
||||
if command_exists pacman; then
|
||||
local -a packages=(
|
||||
base-devel
|
||||
bash
|
||||
ca-certificates
|
||||
coreutils
|
||||
curl
|
||||
findutils
|
||||
gawk
|
||||
git
|
||||
gzip
|
||||
make
|
||||
openssh
|
||||
pam
|
||||
perl
|
||||
pkgconf
|
||||
python
|
||||
sed
|
||||
sqlite
|
||||
tar
|
||||
unzip
|
||||
wget
|
||||
xz
|
||||
zip
|
||||
)
|
||||
repo_requires_git_lfs && packages+=(git-lfs)
|
||||
run_as_root pacman -Sy --needed --noconfirm "${packages[@]}"
|
||||
[ "$WITH_CROSS_CGO" -eq 0 ] || warn "Cross-CGO package setup is only automated for apt-based systems."
|
||||
return
|
||||
fi
|
||||
|
||||
if command_exists zypper; then
|
||||
local -a packages=(
|
||||
bash
|
||||
ca-certificates
|
||||
coreutils
|
||||
curl
|
||||
findutils
|
||||
gawk
|
||||
gcc
|
||||
gcc-c++
|
||||
git
|
||||
gzip
|
||||
make
|
||||
openssh
|
||||
pam-devel
|
||||
perl
|
||||
pkg-config
|
||||
python3
|
||||
sed
|
||||
sqlite3
|
||||
sqlite3-devel
|
||||
tar
|
||||
unzip
|
||||
wget
|
||||
xz
|
||||
zip
|
||||
)
|
||||
repo_requires_git_lfs && packages+=(git-lfs)
|
||||
run_as_root zypper install -y "${packages[@]}"
|
||||
[ "$WITH_CROSS_CGO" -eq 0 ] || warn "Cross-CGO package setup is only automated for apt-based systems."
|
||||
return
|
||||
fi
|
||||
|
||||
die "Unsupported package manager. Install git, make, gcc/g++, pkg-config, sqlite3 headers, curl/wget, tar, unzip, xz, python3, and then rerun with --skip-system."
|
||||
}
|
||||
|
||||
go_download_arch() {
|
||||
case "$(uname -m)" in
|
||||
x86_64 | amd64)
|
||||
printf 'amd64'
|
||||
;;
|
||||
aarch64 | arm64)
|
||||
printf 'arm64'
|
||||
;;
|
||||
i386 | i686)
|
||||
printf '386'
|
||||
;;
|
||||
armv6l | armv7l)
|
||||
printf 'armv6l'
|
||||
;;
|
||||
*)
|
||||
die "Unsupported CPU architecture for automatic Go install: $(uname -m)"
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
current_go_version() {
|
||||
if command_exists go; then
|
||||
go version | awk '{print $3}' | sed 's/^go//'
|
||||
fi
|
||||
}
|
||||
|
||||
install_go() {
|
||||
log "Configuring Go $GO_VERSION"
|
||||
ensure_go_path
|
||||
|
||||
if [ "$(current_go_version)" = "$GO_VERSION" ]; then
|
||||
printf 'Go %s is already installed.\n' "$GO_VERSION"
|
||||
return
|
||||
fi
|
||||
|
||||
local arch
|
||||
arch="$(go_download_arch)"
|
||||
local archive="/tmp/go${GO_VERSION}.linux-${arch}.tar.gz"
|
||||
local url="https://go.dev/dl/go${GO_VERSION}.linux-${arch}.tar.gz"
|
||||
|
||||
fetch_to "$url" "$archive"
|
||||
run_as_root rm -rf /usr/local/go
|
||||
run_as_root tar -C /usr/local -xzf "$archive"
|
||||
ensure_go_path
|
||||
|
||||
[ "$(current_go_version)" = "$GO_VERSION" ] || die "Go install finished, but go version is not $GO_VERSION."
|
||||
}
|
||||
|
||||
load_nvm() {
|
||||
export NVM_DIR="${NVM_DIR:-$HOME/.nvm}"
|
||||
# shellcheck disable=SC1091
|
||||
[ -s "$NVM_DIR/nvm.sh" ] && . "$NVM_DIR/nvm.sh"
|
||||
}
|
||||
|
||||
install_nvm() {
|
||||
export NVM_DIR="${NVM_DIR:-$HOME/.nvm}"
|
||||
if [ -s "$NVM_DIR/nvm.sh" ]; then
|
||||
load_nvm
|
||||
return
|
||||
fi
|
||||
|
||||
log "Installing NVM $NVM_VERSION"
|
||||
local installer="/tmp/nvm-install-${NVM_VERSION}.sh"
|
||||
fetch_to "https://raw.githubusercontent.com/nvm-sh/nvm/${NVM_VERSION}/install.sh" "$installer"
|
||||
bash "$installer"
|
||||
load_nvm
|
||||
command_exists nvm || die "NVM could not be loaded after installation."
|
||||
}
|
||||
|
||||
current_node_version() {
|
||||
if command_exists node; then
|
||||
node -p 'process.versions.node'
|
||||
fi
|
||||
}
|
||||
|
||||
current_pnpm_version() {
|
||||
if command_exists pnpm; then
|
||||
pnpm --version
|
||||
fi
|
||||
}
|
||||
|
||||
install_node_and_pnpm() {
|
||||
log "Configuring Node $NODE_VERSION and pnpm $PNPM_VERSION"
|
||||
install_nvm
|
||||
|
||||
nvm install "$NODE_VERSION"
|
||||
nvm alias default "$NODE_VERSION" >/dev/null
|
||||
nvm use "$NODE_VERSION" >/dev/null
|
||||
hash -r
|
||||
|
||||
if command_exists corepack; then
|
||||
corepack enable
|
||||
corepack prepare "pnpm@${PNPM_VERSION}" --activate
|
||||
hash -r
|
||||
fi
|
||||
|
||||
if ! command_exists pnpm || ! version_ge "$(current_pnpm_version)" "$PNPM_VERSION"; then
|
||||
npm install -g "pnpm@${PNPM_VERSION}"
|
||||
hash -r
|
||||
fi
|
||||
|
||||
if ! version_ge "$(current_node_version)" "$NODE_VERSION"; then
|
||||
die "Node $(current_node_version) is older than required $NODE_VERSION."
|
||||
fi
|
||||
if ! version_ge "$(current_pnpm_version)" "$PNPM_VERSION"; then
|
||||
die "pnpm $(current_pnpm_version) is older than required $PNPM_VERSION."
|
||||
fi
|
||||
}
|
||||
|
||||
install_frontend_deps() {
|
||||
log "Installing frontend dependencies"
|
||||
cd "$SCRIPT_DIR"
|
||||
pnpm install --frozen-lockfile
|
||||
}
|
||||
|
||||
configure_git_lfs() {
|
||||
repo_requires_git_lfs || return
|
||||
|
||||
log "Configuring Git LFS"
|
||||
command_exists git-lfs || die "git-lfs is required for this repository but is not installed."
|
||||
|
||||
cd "$SCRIPT_DIR"
|
||||
git lfs install --local >/dev/null
|
||||
}
|
||||
|
||||
configure_cross_cgo() {
|
||||
[ "$WITH_CROSS_CGO" -eq 1 ] || return
|
||||
|
||||
log "Configuring Makefile.local for cross-CGO sqlite builds"
|
||||
cd "$SCRIPT_DIR"
|
||||
if [ -f Makefile.local ] && grep -qF '# BEGIN configure.sh cross-cgo' Makefile.local; then
|
||||
printf 'Makefile.local already contains configure.sh cross-CGO settings.\n'
|
||||
return
|
||||
fi
|
||||
|
||||
cat >>Makefile.local <<'EOF'
|
||||
|
||||
# BEGIN configure.sh cross-cgo
|
||||
ifeq ($(GOOS)/$(GOARCH),windows/amd64)
|
||||
CC := x86_64-w64-mingw32-gcc
|
||||
CXX := x86_64-w64-mingw32-g++
|
||||
export CC
|
||||
export CXX
|
||||
endif
|
||||
|
||||
ifeq ($(GOOS)/$(GOARCH)/$(GOARM),linux/arm/7)
|
||||
CC := arm-linux-gnueabihf-gcc
|
||||
CXX := arm-linux-gnueabihf-g++
|
||||
export CC
|
||||
export CXX
|
||||
endif
|
||||
# END configure.sh cross-cgo
|
||||
EOF
|
||||
}
|
||||
|
||||
verify_environment() {
|
||||
log "Verifying build environment"
|
||||
activate_go_path
|
||||
load_nvm || true
|
||||
hash -r
|
||||
|
||||
local -a missing=()
|
||||
local -a problems=()
|
||||
local command_name
|
||||
for command_name in git make go node pnpm gcc pkg-config; do
|
||||
if ! command_exists "$command_name"; then
|
||||
missing+=("$command_name")
|
||||
fi
|
||||
done
|
||||
if repo_requires_git_lfs && ! command_exists git-lfs; then
|
||||
missing+=("git-lfs")
|
||||
fi
|
||||
|
||||
if command_exists go; then
|
||||
local found_go
|
||||
found_go="$(current_go_version)"
|
||||
[ "$found_go" = "$GO_VERSION" ] || problems+=("Go $found_go found, but $GO_VERSION is required.")
|
||||
fi
|
||||
|
||||
if command_exists node; then
|
||||
local found_node
|
||||
found_node="$(current_node_version)"
|
||||
version_ge "$found_node" "$NODE_VERSION" || problems+=("Node $found_node found, but >= $NODE_VERSION is required.")
|
||||
fi
|
||||
|
||||
if command_exists pnpm; then
|
||||
local found_pnpm
|
||||
found_pnpm="$(current_pnpm_version)"
|
||||
version_ge "$found_pnpm" "$PNPM_VERSION" || problems+=("pnpm $found_pnpm found, but >= $PNPM_VERSION is required.")
|
||||
fi
|
||||
|
||||
cd "$SCRIPT_DIR"
|
||||
if command_exists make && ! make help >/dev/null; then
|
||||
problems+=("make help failed.")
|
||||
fi
|
||||
|
||||
if [ "$WITH_CROSS_CGO" -eq 1 ]; then
|
||||
for command_name in arm-linux-gnueabihf-gcc x86_64-w64-mingw32-gcc; do
|
||||
if ! command_exists "$command_name"; then
|
||||
missing+=("$command_name")
|
||||
fi
|
||||
done
|
||||
fi
|
||||
|
||||
if [ ! -d "$SCRIPT_DIR/node_modules" ]; then
|
||||
problems+=("node_modules is missing; frontend dependencies are not installed.")
|
||||
fi
|
||||
|
||||
if [ "${#missing[@]}" -gt 0 ] || [ "${#problems[@]}" -gt 0 ]; then
|
||||
VERIFY_HAD_ISSUES=1
|
||||
if [ "${#missing[@]}" -gt 0 ]; then
|
||||
printf '\nMissing commands:\n'
|
||||
for command_name in "${missing[@]}"; do
|
||||
printf ' - %s\n' "$command_name"
|
||||
done
|
||||
fi
|
||||
if [ "${#problems[@]}" -gt 0 ]; then
|
||||
printf '\nConfiguration issues:\n'
|
||||
local problem
|
||||
for problem in "${problems[@]}"; do
|
||||
printf ' - %s\n' "$problem"
|
||||
done
|
||||
fi
|
||||
printf '\nTo fix the standard build environment, run ./configure.sh and choose 1) Normal.\n'
|
||||
printf 'For sqlite multi-arch builds, choose 2) With cross cgo.\n'
|
||||
if [ "$VERIFY_REPORT_ONLY" -eq 1 ]; then
|
||||
printf '\nVerify only completed; no changes were made.\n'
|
||||
return 0
|
||||
fi
|
||||
return 1
|
||||
fi
|
||||
|
||||
printf 'Go: %s\n' "$(go version)"
|
||||
printf 'Node: %s\n' "$(node --version)"
|
||||
printf 'pnpm: %s\n' "$(pnpm --version)"
|
||||
printf 'gcc: %s\n' "$(gcc --version | head -n 1)"
|
||||
if repo_requires_git_lfs; then
|
||||
printf 'git-lfs: %s\n' "$(git lfs version)"
|
||||
fi
|
||||
if [ -d "$SCRIPT_DIR/node_modules" ]; then
|
||||
printf 'node_modules: present\n'
|
||||
else
|
||||
printf 'node_modules: missing; run ./configure.sh or pnpm install --frozen-lockfile\n'
|
||||
fi
|
||||
}
|
||||
|
||||
if [ "$#" -eq 0 ] && [ -t 0 ]; then
|
||||
SHOW_MENU=1
|
||||
fi
|
||||
|
||||
while [ "$#" -gt 0 ]; do
|
||||
case "$1" in
|
||||
--with-cross-cgo)
|
||||
WITH_CROSS_CGO=1
|
||||
;;
|
||||
--skip-system)
|
||||
INSTALL_SYSTEM=0
|
||||
;;
|
||||
--skip-go)
|
||||
INSTALL_GO=0
|
||||
;;
|
||||
--skip-node)
|
||||
INSTALL_NODE=0
|
||||
;;
|
||||
--skip-frontend-deps)
|
||||
INSTALL_FRONTEND_DEPS=0
|
||||
;;
|
||||
--verify-only)
|
||||
VERIFY_ONLY=1
|
||||
INSTALL_SYSTEM=0
|
||||
INSTALL_GO=0
|
||||
INSTALL_NODE=0
|
||||
INSTALL_FRONTEND_DEPS=0
|
||||
;;
|
||||
--menu)
|
||||
SHOW_MENU=1
|
||||
;;
|
||||
-h | --help)
|
||||
usage
|
||||
exit 0
|
||||
;;
|
||||
*)
|
||||
usage
|
||||
die "Unknown option: $1"
|
||||
;;
|
||||
esac
|
||||
shift
|
||||
done
|
||||
|
||||
if [ "$SHOW_MENU" -eq 1 ]; then
|
||||
interactive_menu
|
||||
fi
|
||||
|
||||
if [ "$(id -u)" -eq 0 ]; then
|
||||
warn "You are running as root. NVM/Node will be configured for root, not for your normal user."
|
||||
fi
|
||||
|
||||
if [ "$VERIFY_ONLY" -eq 0 ]; then
|
||||
[ "$INSTALL_SYSTEM" -eq 0 ] || install_system_packages
|
||||
configure_git_lfs
|
||||
[ "$INSTALL_GO" -eq 0 ] || install_go
|
||||
[ "$INSTALL_NODE" -eq 0 ] || install_node_and_pnpm
|
||||
configure_cross_cgo
|
||||
[ "$INSTALL_FRONTEND_DEPS" -eq 0 ] || install_frontend_deps
|
||||
fi
|
||||
|
||||
verify_environment
|
||||
|
||||
if [ "$VERIFY_HAD_ISSUES" -eq 1 ]; then
|
||||
cat <<EOF
|
||||
|
||||
Done. Missing requirements were reported above and no changes were made.
|
||||
Run ./configure.sh again and choose:
|
||||
1) Normal
|
||||
|
||||
For sqlite builds across all smart-build architectures, choose:
|
||||
2) With cross cgo
|
||||
EOF
|
||||
else
|
||||
cat <<EOF
|
||||
|
||||
Done.
|
||||
Recommended next steps:
|
||||
./smart-build.sh
|
||||
|
||||
For sqlite builds across all smart-build architectures, prepare the heavier
|
||||
cross-CGO tools with:
|
||||
./configure.sh --with-cross-cgo
|
||||
EOF
|
||||
fi
|
||||
@@ -0,0 +1 @@
|
||||
34a58393847d8354e1a401512d0e56138e53bcae
|
||||
@@ -113,6 +113,13 @@ prime/
|
||||
/.claude/
|
||||
/.cursorrules
|
||||
/.cursor/
|
||||
# /.configure.sh
|
||||
# /configure.sh
|
||||
/.frontend.hash
|
||||
# /.smart-build.sh
|
||||
# /smart-build.sh
|
||||
# /.update-gitea.sh
|
||||
# /update-gitea.sh
|
||||
/.goosehints
|
||||
/.windsurfrules
|
||||
/.github/copilot-instructions.md
|
||||
|
||||
Executable
+894
@@ -0,0 +1,894 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
# This script safely imports selected upstream commits onto the current local
|
||||
# branch through cherry-pick.
|
||||
# It:
|
||||
# 1. checks that no conflicting git operation is already in progress;
|
||||
# 2. ensures the upstream remote exists and points to the official repository;
|
||||
# 3. lists upstream commits whose changes are not yet present on the current
|
||||
# branch;
|
||||
# 4. creates a safety backup branch and an exact worktree snapshot;
|
||||
# 5. stashes tracked and untracked local changes before the import;
|
||||
# 6. cherry-picks the selected upstream commits with `-x` so the original
|
||||
# upstream commit hash remains visible in the imported commit message;
|
||||
# 7. restores the stashed local changes only after the import completes.
|
||||
# If a conflict happens, the backup branch, the exact snapshot, and the saved
|
||||
# stash are all kept so the original state can be restored safely.
|
||||
|
||||
BRANCH="${BRANCH:-main}"
|
||||
REMOTE_NAME="${REMOTE_NAME:-upstream}"
|
||||
REMOTE_URL="${REMOTE_URL:-https://github.com/go-gitea/gitea.git}"
|
||||
REPO_ROOT=""
|
||||
GIT_DIR=""
|
||||
STATE_FILE=""
|
||||
SNAPSHOT_ROOT=""
|
||||
CURRENT_BRANCH=""
|
||||
BACKUP_BRANCH=""
|
||||
STASH_REF=""
|
||||
STASH_HASH=""
|
||||
STATE_BRANCH=""
|
||||
STATE_BACKUP_BRANCH=""
|
||||
STATE_STASH_HASH=""
|
||||
STATE_REMOTE_NAME=""
|
||||
STATE_REMOTE_URL=""
|
||||
STATE_TARGET_BRANCH=""
|
||||
STATE_START_HEAD=""
|
||||
STATE_SNAPSHOT_PATH=""
|
||||
STATE_IMPORT_COMMITS=""
|
||||
STATE_STATUS=""
|
||||
STATE_UPDATED_AT=""
|
||||
|
||||
say() {
|
||||
printf '%s\n' "$*"
|
||||
}
|
||||
|
||||
die() {
|
||||
say "ERROR: $*" >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
show_usage() {
|
||||
cat <<EOF
|
||||
Usage: $(basename "$0") [command]
|
||||
|
||||
Available commands:
|
||||
fetch
|
||||
Fetch the latest upstream changes only.
|
||||
list
|
||||
Show upstream commits whose changes are not yet present on the current branch.
|
||||
import <commit> [commit...]
|
||||
Cherry-pick one or more selected upstream commits with \`-x\`.
|
||||
import-range <from-commit> <to-commit>
|
||||
Cherry-pick an inclusive upstream commit range in upstream order.
|
||||
continue
|
||||
Continue an interrupted cherry-pick and restore the saved local stash once the import finishes.
|
||||
backup
|
||||
Create a safety backup branch from the current HEAD only.
|
||||
rollback [backup-branch|snapshot-dir]
|
||||
Restore the saved pre-import state, or an explicit backup branch / snapshot.
|
||||
restore-stash
|
||||
Re-apply the saved pre-import local stash from the last recorded import state.
|
||||
restore-snapshot [snapshot-dir]
|
||||
Restore the exact saved repository snapshot from the last recorded real action, or from a specific snapshot directory.
|
||||
status
|
||||
Show the current repository, branch, remote, local-change state, and saved import metadata.
|
||||
help
|
||||
Show this help text.
|
||||
|
||||
If no command is provided and the script is run from a terminal, an interactive
|
||||
menu is shown.
|
||||
|
||||
Recommended order:
|
||||
1. Run: ./.import-upstream-cherry-pick.sh status
|
||||
2. Run: ./.import-upstream-cherry-pick.sh list
|
||||
3. Choose the exact upstream commits you want to import.
|
||||
4. Run: ./.import-upstream-cherry-pick.sh import <commit...>
|
||||
or: ./.import-upstream-cherry-pick.sh import-range <from> <to>
|
||||
5. If cherry-pick stops with conflicts:
|
||||
- either resolve them and continue with: ./.import-upstream-cherry-pick.sh continue
|
||||
- or return safely with: ./.import-upstream-cherry-pick.sh rollback
|
||||
6. If restoring local changes after the import causes conflicts:
|
||||
- either resolve them manually
|
||||
- or return safely with: ./.import-upstream-cherry-pick.sh rollback
|
||||
7. Use: ./.import-upstream-cherry-pick.sh restore-snapshot
|
||||
when you want to restore the exact saved repository state, including
|
||||
untracked and ignored files that existed at snapshot time.
|
||||
EOF
|
||||
}
|
||||
|
||||
ensure_git_repo() {
|
||||
local raw_git_dir
|
||||
|
||||
REPO_ROOT="$(git rev-parse --show-toplevel 2>/dev/null)" || die "This script must be run inside a git repository."
|
||||
raw_git_dir="$(git rev-parse --git-dir)"
|
||||
case "$raw_git_dir" in
|
||||
/*) GIT_DIR="$raw_git_dir" ;;
|
||||
*) GIT_DIR="$REPO_ROOT/$raw_git_dir" ;;
|
||||
esac
|
||||
STATE_FILE="$GIT_DIR/.import-upstream-cherry-pick-state"
|
||||
SNAPSHOT_ROOT="$GIT_DIR/.import-upstream-cherry-pick-snapshots"
|
||||
}
|
||||
|
||||
write_state() {
|
||||
{
|
||||
printf 'STATE_BRANCH=%q\n' "$STATE_BRANCH"
|
||||
printf 'STATE_BACKUP_BRANCH=%q\n' "$STATE_BACKUP_BRANCH"
|
||||
printf 'STATE_STASH_HASH=%q\n' "$STATE_STASH_HASH"
|
||||
printf 'STATE_REMOTE_NAME=%q\n' "$STATE_REMOTE_NAME"
|
||||
printf 'STATE_REMOTE_URL=%q\n' "$STATE_REMOTE_URL"
|
||||
printf 'STATE_TARGET_BRANCH=%q\n' "$STATE_TARGET_BRANCH"
|
||||
printf 'STATE_START_HEAD=%q\n' "$STATE_START_HEAD"
|
||||
printf 'STATE_SNAPSHOT_PATH=%q\n' "$STATE_SNAPSHOT_PATH"
|
||||
printf 'STATE_IMPORT_COMMITS=%q\n' "$STATE_IMPORT_COMMITS"
|
||||
printf 'STATE_STATUS=%q\n' "$STATE_STATUS"
|
||||
printf 'STATE_UPDATED_AT=%q\n' "$(date +%Y-%m-%dT%H:%M:%S)"
|
||||
} >"$STATE_FILE"
|
||||
}
|
||||
|
||||
load_state() {
|
||||
ensure_git_repo
|
||||
[ -f "$STATE_FILE" ] || return 1
|
||||
# shellcheck disable=SC1090
|
||||
. "$STATE_FILE"
|
||||
return 0
|
||||
}
|
||||
|
||||
worktree_has_local_changes() {
|
||||
! git diff --quiet || ! git diff --cached --quiet || [ -n "$(git ls-files --others --exclude-standard)" ]
|
||||
}
|
||||
|
||||
has_cherry_pick_in_progress() {
|
||||
[ -e "$(git rev-parse --git-path CHERRY_PICK_HEAD)" ]
|
||||
}
|
||||
|
||||
sanitize_ref_name() {
|
||||
printf '%s\n' "${1//\//-}"
|
||||
}
|
||||
|
||||
ensure_rsync_available() {
|
||||
command -v rsync >/dev/null 2>&1 || die "rsync is required for exact repository snapshots."
|
||||
}
|
||||
|
||||
snapshot_repo_dir() {
|
||||
printf '%s\n' "$1/repo"
|
||||
}
|
||||
|
||||
is_valid_snapshot_dir() {
|
||||
[ -d "$1" ] && [ -d "$(snapshot_repo_dir "$1")" ]
|
||||
}
|
||||
|
||||
snapshot_metadata_value() {
|
||||
local snapshot_dir="$1" key="$2"
|
||||
|
||||
[ -f "$snapshot_dir/metadata.txt" ] || return 1
|
||||
sed -n "s/^${key}=//p" "$snapshot_dir/metadata.txt" | head -n 1
|
||||
}
|
||||
|
||||
create_worktree_snapshot_for_reason() {
|
||||
local reason="$1" safe_branch_name timestamp snapshot_dir snapshot_dir_repo
|
||||
|
||||
ensure_rsync_available
|
||||
safe_branch_name="$(sanitize_ref_name "$CURRENT_BRANCH")"
|
||||
timestamp="$(date +%Y%m%d-%H%M%S)"
|
||||
snapshot_dir="$SNAPSHOT_ROOT/$safe_branch_name/${timestamp}-${reason}"
|
||||
snapshot_dir_repo="$(snapshot_repo_dir "$snapshot_dir")"
|
||||
|
||||
mkdir -p "$snapshot_dir_repo"
|
||||
rsync --archive --delete --exclude='.git' "$REPO_ROOT"/ "$snapshot_dir_repo"/
|
||||
|
||||
{
|
||||
printf 'branch=%s\n' "$CURRENT_BRANCH"
|
||||
printf 'head=%s\n' "$(git rev-parse HEAD)"
|
||||
printf 'created_at=%s\n' "$(date +%Y-%m-%dT%H:%M:%S)"
|
||||
printf 'reason=%s\n' "$reason"
|
||||
} >"$snapshot_dir/metadata.txt"
|
||||
|
||||
printf '%s\n' "$snapshot_dir"
|
||||
}
|
||||
|
||||
restore_worktree_snapshot() {
|
||||
local snapshot_dir="$1" snapshot_dir_repo
|
||||
|
||||
ensure_rsync_available
|
||||
is_valid_snapshot_dir "$snapshot_dir" || die "Snapshot directory '$snapshot_dir' is not valid."
|
||||
snapshot_dir_repo="$(snapshot_repo_dir "$snapshot_dir")"
|
||||
|
||||
rsync --archive --delete --exclude='.git' "$snapshot_dir_repo"/ "$REPO_ROOT"/
|
||||
}
|
||||
|
||||
find_latest_snapshot_for_current() {
|
||||
local safe_branch_name snapshot_branch_dir
|
||||
safe_branch_name="$(sanitize_ref_name "$CURRENT_BRANCH")"
|
||||
snapshot_branch_dir="$SNAPSHOT_ROOT/$safe_branch_name"
|
||||
[ -d "$snapshot_branch_dir" ] || return 1
|
||||
find "$snapshot_branch_dir" -mindepth 1 -maxdepth 1 -type d | sort -r | head -n 1
|
||||
}
|
||||
|
||||
ensure_no_noncherrypick_git_operation_in_progress() {
|
||||
local git_path
|
||||
for git_path in MERGE_HEAD REVERT_HEAD BISECT_LOG rebase-merge rebase-apply; do
|
||||
if [ -e "$(git rev-parse --git-path "$git_path")" ]; then
|
||||
die "A git operation is already in progress ($git_path). Finish it before running this script."
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
ensure_no_git_operation_in_progress() {
|
||||
local git_path
|
||||
for git_path in CHERRY_PICK_HEAD MERGE_HEAD REVERT_HEAD BISECT_LOG rebase-merge rebase-apply; do
|
||||
if [ -e "$(git rev-parse --git-path "$git_path")" ]; then
|
||||
die "A git operation is already in progress ($git_path). Finish it before running this script."
|
||||
fi
|
||||
done
|
||||
|
||||
if [ -n "$(git diff --name-only --diff-filter=U)" ]; then
|
||||
die "There are unmerged files in the working tree. Resolve them first."
|
||||
fi
|
||||
}
|
||||
|
||||
ensure_current_branch() {
|
||||
CURRENT_BRANCH="$(git symbolic-ref --quiet --short HEAD || true)"
|
||||
[ -n "$CURRENT_BRANCH" ] || die "Detached HEAD is not supported. Check out a branch first."
|
||||
}
|
||||
|
||||
ensure_current_branch_with_state_fallback() {
|
||||
CURRENT_BRANCH="$(git symbolic-ref --quiet --short HEAD || true)"
|
||||
if [ -n "$CURRENT_BRANCH" ]; then
|
||||
return
|
||||
fi
|
||||
|
||||
if load_state && [ -n "${STATE_BRANCH:-}" ]; then
|
||||
CURRENT_BRANCH="$STATE_BRANCH"
|
||||
return
|
||||
fi
|
||||
|
||||
die "Detached HEAD is not supported here and no saved branch state was found."
|
||||
}
|
||||
|
||||
ensure_upstream_remote() {
|
||||
local current_remote_url
|
||||
|
||||
if current_remote_url="$(git remote get-url "$REMOTE_NAME" 2>/dev/null)"; then
|
||||
if [ "$current_remote_url" != "$REMOTE_URL" ]; then
|
||||
die "Remote '$REMOTE_NAME' points to '$current_remote_url', expected '$REMOTE_URL'."
|
||||
fi
|
||||
return
|
||||
fi
|
||||
|
||||
say "Adding remote '$REMOTE_NAME'..."
|
||||
git remote add "$REMOTE_NAME" "$REMOTE_URL"
|
||||
}
|
||||
|
||||
create_backup_branch_for_reason() {
|
||||
local reason="$1" safe_branch_name timestamp branch_name
|
||||
|
||||
safe_branch_name="$(sanitize_ref_name "$CURRENT_BRANCH")"
|
||||
timestamp="$(date +%Y%m%d-%H%M%S)"
|
||||
branch_name="backup/cherry-pick-${safe_branch_name}-${reason}-${timestamp}"
|
||||
|
||||
git branch "$branch_name" HEAD >/dev/null
|
||||
printf '%s\n' "$branch_name"
|
||||
}
|
||||
|
||||
find_latest_backup_branch_for_current() {
|
||||
local safe_branch_name
|
||||
|
||||
safe_branch_name="$(sanitize_ref_name "$CURRENT_BRANCH")"
|
||||
git for-each-ref --sort=-creatordate --format='%(refname:short)' "refs/heads/backup/cherry-pick-${safe_branch_name}-*" | head -n 1
|
||||
}
|
||||
|
||||
prepare_safety_before_real_action() {
|
||||
local backup_reason="$1"
|
||||
|
||||
STATE_START_HEAD="$(git rev-parse HEAD)"
|
||||
BACKUP_BRANCH="$(create_backup_branch_for_reason "$backup_reason")"
|
||||
STATE_SNAPSHOT_PATH="$(create_worktree_snapshot_for_reason "$backup_reason")"
|
||||
say "Safety backup branch created: $BACKUP_BRANCH"
|
||||
say "Exact worktree snapshot created: $STATE_SNAPSHOT_PATH"
|
||||
}
|
||||
|
||||
stash_current_changes() {
|
||||
local stash_prefix="$1" timestamp stash_name
|
||||
|
||||
STASH_REF=""
|
||||
STASH_HASH=""
|
||||
if ! worktree_has_local_changes; then
|
||||
say "No local tracked/untracked changes to stash."
|
||||
return
|
||||
fi
|
||||
|
||||
timestamp="$(date +%Y%m%d-%H%M%S)"
|
||||
stash_name="${stash_prefix}-$(sanitize_ref_name "$CURRENT_BRANCH")-${timestamp}"
|
||||
|
||||
say "Stashing local tracked and untracked changes..."
|
||||
git stash push --include-untracked --message "$stash_name" >/dev/null
|
||||
STASH_REF="$(git stash list -1 --format='%gd')"
|
||||
[ -n "$STASH_REF" ] || die "Failed to locate the created stash entry."
|
||||
STASH_HASH="$(git rev-parse "$STASH_REF")"
|
||||
[ -n "$STASH_HASH" ] || die "Failed to resolve the created stash hash."
|
||||
say "Local changes saved in $STASH_REF"
|
||||
}
|
||||
|
||||
fetch_upstream() {
|
||||
say "Fetching latest changes from $REMOTE_NAME/$BRANCH..."
|
||||
git fetch --prune "$REMOTE_NAME" "+refs/heads/$BRANCH:refs/remotes/$REMOTE_NAME/$BRANCH"
|
||||
git show-ref --verify --quiet "refs/remotes/$REMOTE_NAME/$BRANCH" || die "Remote branch '$REMOTE_NAME/$BRANCH' was not found."
|
||||
}
|
||||
|
||||
update_state() {
|
||||
STATE_BRANCH="$CURRENT_BRANCH"
|
||||
STATE_BACKUP_BRANCH="$BACKUP_BRANCH"
|
||||
STATE_STASH_HASH="$STASH_HASH"
|
||||
STATE_REMOTE_NAME="$REMOTE_NAME"
|
||||
STATE_REMOTE_URL="$REMOTE_URL"
|
||||
STATE_TARGET_BRANCH="$BRANCH"
|
||||
write_state
|
||||
}
|
||||
|
||||
find_stash_ref_by_hash() {
|
||||
local target_hash="$1" hash ref
|
||||
|
||||
while read -r hash ref; do
|
||||
if [ "$hash" = "$target_hash" ]; then
|
||||
printf '%s\n' "$ref"
|
||||
return 0
|
||||
fi
|
||||
done < <(git stash list --format='%H %gd')
|
||||
return 1
|
||||
}
|
||||
|
||||
drop_stash_by_hash_if_present() {
|
||||
local target_hash="$1" stash_ref
|
||||
|
||||
[ -n "$target_hash" ] || return 0
|
||||
if stash_ref="$(find_stash_ref_by_hash "$target_hash")"; then
|
||||
git stash drop "$stash_ref" >/dev/null
|
||||
fi
|
||||
}
|
||||
|
||||
restore_stash() {
|
||||
local keep_saved_copy="${1:-0}" restore_target
|
||||
|
||||
if [ -z "$STASH_HASH" ] && [ -z "$STASH_REF" ]; then
|
||||
return
|
||||
fi
|
||||
|
||||
restore_target="${STASH_HASH:-$STASH_REF}"
|
||||
say "Restoring stashed local changes from $restore_target..."
|
||||
if git stash apply --index "$restore_target"; then
|
||||
STASH_REF=""
|
||||
if [ "$keep_saved_copy" -eq 0 ]; then
|
||||
drop_stash_by_hash_if_present "$STASH_HASH"
|
||||
STASH_HASH=""
|
||||
STATE_STASH_HASH=""
|
||||
else
|
||||
STATE_STASH_HASH="${STASH_HASH:-$restore_target}"
|
||||
fi
|
||||
STATE_STATUS="completed"
|
||||
update_state
|
||||
if [ "$keep_saved_copy" -eq 0 ]; then
|
||||
say "Local changes restored successfully."
|
||||
else
|
||||
say "Local changes restored successfully. The original stash was kept for rollback safety."
|
||||
fi
|
||||
return
|
||||
fi
|
||||
|
||||
STATE_STATUS="restore_conflict"
|
||||
update_state
|
||||
say "Conflicts occurred while restoring local changes."
|
||||
say "Backup branch kept at: $BACKUP_BRANCH"
|
||||
say "Stash kept at: $restore_target"
|
||||
say "Resolve the conflicts manually, or return safely with: ./.import-upstream-cherry-pick.sh rollback"
|
||||
exit 1
|
||||
}
|
||||
|
||||
ordered_available_upstream_commits() {
|
||||
local available_commit_shas="" commit
|
||||
|
||||
available_commit_shas="$(git cherry -v HEAD "$REMOTE_NAME/$BRANCH" | awk '$1=="+"{print $2}')"
|
||||
[ -n "$available_commit_shas" ] || return 0
|
||||
|
||||
while IFS= read -r commit; do
|
||||
[ -n "$commit" ] || continue
|
||||
if printf '%s\n' "$available_commit_shas" | grep -Fxq "$commit"; then
|
||||
printf '%s\n' "$commit"
|
||||
fi
|
||||
done < <(git rev-list --reverse HEAD.."$REMOTE_NAME/$BRANCH")
|
||||
}
|
||||
|
||||
commit_is_available_for_import() {
|
||||
local commit="$1"
|
||||
|
||||
ordered_available_upstream_commits | grep -Fxq "$commit"
|
||||
}
|
||||
|
||||
resolve_import_commit() {
|
||||
local commit="$1"
|
||||
|
||||
git rev-parse --verify "${commit}^{commit}" 2>/dev/null || die "Commit '$commit' could not be resolved."
|
||||
}
|
||||
|
||||
validate_importable_commit() {
|
||||
local commit="$1"
|
||||
|
||||
git merge-base --is-ancestor "$commit" "$REMOTE_NAME/$BRANCH" || die "Commit '$commit' is not reachable from $REMOTE_NAME/$BRANCH."
|
||||
commit_is_available_for_import "$commit" || die "Commit '$commit' is not currently available for import into '$CURRENT_BRANCH'."
|
||||
}
|
||||
|
||||
show_available_commits() {
|
||||
local found_any=0 commit
|
||||
|
||||
while IFS= read -r commit; do
|
||||
[ -n "$commit" ] || continue
|
||||
found_any=1
|
||||
git show --no-patch --date=short --format=' - %h | %ad | %s' "$commit"
|
||||
done < <(ordered_available_upstream_commits)
|
||||
|
||||
if [ "$found_any" -eq 0 ]; then
|
||||
say "No upstream commits are currently available for cherry-pick import."
|
||||
fi
|
||||
}
|
||||
|
||||
run_status() {
|
||||
local stash_count latest_backup latest_snapshot
|
||||
|
||||
ensure_git_repo
|
||||
ensure_current_branch_with_state_fallback
|
||||
ensure_upstream_remote
|
||||
|
||||
stash_count="$(git stash list | wc -l | tr -d ' ')"
|
||||
latest_backup="$(find_latest_backup_branch_for_current || true)"
|
||||
latest_snapshot="$(find_latest_snapshot_for_current || true)"
|
||||
|
||||
say "Repository: $(git rev-parse --show-toplevel)"
|
||||
say "Current branch: $CURRENT_BRANCH"
|
||||
say "Upstream remote: $REMOTE_NAME -> $REMOTE_URL"
|
||||
say "Working tree:"
|
||||
if ! worktree_has_local_changes; then
|
||||
say " clean"
|
||||
else
|
||||
git status --short
|
||||
fi
|
||||
say "Stash entries: $stash_count"
|
||||
say "Latest backup for current branch: ${latest_backup:-none}"
|
||||
say "Latest snapshot for current branch: ${latest_snapshot:-none}"
|
||||
if load_state; then
|
||||
say "Saved import state: $STATE_STATUS"
|
||||
say "Saved backup branch: ${STATE_BACKUP_BRANCH:-none}"
|
||||
say "Saved starting commit: ${STATE_START_HEAD:-none}"
|
||||
say "Saved exact snapshot: ${STATE_SNAPSHOT_PATH:-none}"
|
||||
say "Saved original stash: ${STATE_STASH_HASH:-none}"
|
||||
say "Saved import commits: ${STATE_IMPORT_COMMITS:-none}"
|
||||
else
|
||||
say "Saved import state: none"
|
||||
fi
|
||||
}
|
||||
|
||||
run_fetch_only() {
|
||||
ensure_git_repo
|
||||
ensure_no_git_operation_in_progress
|
||||
ensure_current_branch
|
||||
ensure_upstream_remote
|
||||
fetch_upstream
|
||||
say "Latest changes fetched from $REMOTE_NAME/$BRANCH."
|
||||
}
|
||||
|
||||
run_list() {
|
||||
ensure_git_repo
|
||||
ensure_no_git_operation_in_progress
|
||||
ensure_current_branch
|
||||
ensure_upstream_remote
|
||||
fetch_upstream
|
||||
show_available_commits
|
||||
}
|
||||
|
||||
run_backup_only() {
|
||||
ensure_git_repo
|
||||
ensure_no_git_operation_in_progress
|
||||
ensure_current_branch
|
||||
ensure_upstream_remote
|
||||
BACKUP_BRANCH="$(create_backup_branch_for_reason "manual-backup")"
|
||||
say "Safety backup branch created: $BACKUP_BRANCH"
|
||||
}
|
||||
|
||||
run_import_commits() {
|
||||
local requested_commits=("$@") commit resolved_commit
|
||||
local -a selected_commits=()
|
||||
|
||||
[ "${#requested_commits[@]}" -gt 0 ] || die "Provide at least one upstream commit to import."
|
||||
ensure_git_repo
|
||||
ensure_no_git_operation_in_progress
|
||||
ensure_current_branch
|
||||
ensure_upstream_remote
|
||||
fetch_upstream
|
||||
|
||||
for commit in "${requested_commits[@]}"; do
|
||||
resolved_commit="$(resolve_import_commit "$commit")"
|
||||
validate_importable_commit "$resolved_commit"
|
||||
selected_commits+=("$resolved_commit")
|
||||
done
|
||||
|
||||
STATE_IMPORT_COMMITS="${selected_commits[*]}"
|
||||
prepare_safety_before_real_action "before-cherry-pick-import"
|
||||
stash_current_changes "pre-cherry-pick-import"
|
||||
STATE_STATUS="prepared"
|
||||
update_state
|
||||
|
||||
for commit in "${selected_commits[@]}"; do
|
||||
say "Cherry-picking upstream commit: $(git show --no-patch --format='%h %s' "$commit")"
|
||||
if ! git cherry-pick -x "$commit"; then
|
||||
STATE_STATUS="cherry_pick_conflict"
|
||||
update_state
|
||||
say "Cherry-pick stopped because of conflicts."
|
||||
say "Conflicting upstream commit: $(git show --no-patch --format='%h %s' CHERRY_PICK_HEAD)"
|
||||
say "Resolve conflicts and continue with: ./.import-upstream-cherry-pick.sh continue"
|
||||
say "Or return safely with: ./.import-upstream-cherry-pick.sh rollback"
|
||||
exit 1
|
||||
fi
|
||||
done
|
||||
|
||||
restore_stash 1
|
||||
say "Imported ${#selected_commits[@]} upstream commit(s) by cherry-pick."
|
||||
say "Safety backup branch available at: $BACKUP_BRANCH"
|
||||
say "Safety snapshot available at: $STATE_SNAPSHOT_PATH"
|
||||
if [ -n "$STATE_STASH_HASH" ]; then
|
||||
say "Original pre-import stash retained for rollback at: $STATE_STASH_HASH"
|
||||
fi
|
||||
}
|
||||
|
||||
run_import_range() {
|
||||
local from_commit="${1:-}" to_commit="${2:-}" from_resolved to_resolved commit
|
||||
local -a selected_commits=()
|
||||
|
||||
[ -n "$from_commit" ] || die "Provide the start commit for import-range."
|
||||
[ -n "$to_commit" ] || die "Provide the end commit for import-range."
|
||||
ensure_git_repo
|
||||
ensure_no_git_operation_in_progress
|
||||
ensure_current_branch
|
||||
ensure_upstream_remote
|
||||
fetch_upstream
|
||||
|
||||
from_resolved="$(resolve_import_commit "$from_commit")"
|
||||
to_resolved="$(resolve_import_commit "$to_commit")"
|
||||
git merge-base --is-ancestor "$from_resolved" "$REMOTE_NAME/$BRANCH" || die "Start commit '$from_commit' is not reachable from $REMOTE_NAME/$BRANCH."
|
||||
git merge-base --is-ancestor "$to_resolved" "$REMOTE_NAME/$BRANCH" || die "End commit '$to_commit' is not reachable from $REMOTE_NAME/$BRANCH."
|
||||
git merge-base --is-ancestor "$from_resolved" "$to_resolved" || die "Start commit '$from_commit' must be an ancestor of end commit '$to_commit' on $REMOTE_NAME/$BRANCH."
|
||||
|
||||
while IFS= read -r commit; do
|
||||
[ -n "$commit" ] || continue
|
||||
if commit_is_available_for_import "$commit"; then
|
||||
selected_commits+=("$commit")
|
||||
fi
|
||||
done < <(git rev-list --reverse "${from_resolved}^..${to_resolved}")
|
||||
|
||||
[ "${#selected_commits[@]}" -gt 0 ] || die "No importable commits were found in the requested range."
|
||||
run_import_commits "${selected_commits[@]}"
|
||||
}
|
||||
|
||||
run_continue() {
|
||||
ensure_git_repo
|
||||
ensure_current_branch_with_state_fallback
|
||||
ensure_upstream_remote
|
||||
load_state || die "No saved cherry-pick state was found."
|
||||
[ "$CURRENT_BRANCH" = "${STATE_BRANCH:-$CURRENT_BRANCH}" ] || die "Saved cherry-pick state belongs to branch '$STATE_BRANCH'. Check out that branch first."
|
||||
has_cherry_pick_in_progress || die "There is no in-progress cherry-pick to continue."
|
||||
|
||||
say "Continuing cherry-pick..."
|
||||
GIT_EDITOR=: git cherry-pick --continue
|
||||
|
||||
if has_cherry_pick_in_progress; then
|
||||
STATE_STATUS="cherry_pick_conflict"
|
||||
update_state
|
||||
say "Cherry-pick hit another conflict."
|
||||
say "Current conflicting upstream commit: $(git show --no-patch --format='%h %s' CHERRY_PICK_HEAD)"
|
||||
say "Resolve conflicts and run: ./.import-upstream-cherry-pick.sh continue"
|
||||
say "Or return safely with: ./.import-upstream-cherry-pick.sh rollback"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
STASH_HASH="${STATE_STASH_HASH:-}"
|
||||
STASH_REF=""
|
||||
BACKUP_BRANCH="${STATE_BACKUP_BRANCH:-}"
|
||||
restore_stash 1
|
||||
say "Cherry-pick import completed."
|
||||
}
|
||||
|
||||
run_restore_saved_stash() {
|
||||
ensure_git_repo
|
||||
ensure_no_git_operation_in_progress
|
||||
ensure_current_branch_with_state_fallback
|
||||
load_state || die "No saved import state was found."
|
||||
[ "$CURRENT_BRANCH" = "${STATE_BRANCH:-$CURRENT_BRANCH}" ] || die "Saved import state belongs to branch '$STATE_BRANCH'. Check out that branch first."
|
||||
[ -n "${STATE_STASH_HASH:-}" ] || die "There is no saved pre-import stash to restore."
|
||||
if worktree_has_local_changes; then
|
||||
die "The working tree is not clean. Commit, stash, or discard current changes before restoring the saved stash."
|
||||
fi
|
||||
|
||||
prepare_safety_before_real_action "before-restore-stash"
|
||||
STASH_HASH="$STATE_STASH_HASH"
|
||||
STASH_REF=""
|
||||
restore_stash 1
|
||||
say "Saved pre-import local changes restored."
|
||||
}
|
||||
|
||||
run_rollback() {
|
||||
local explicit_target="${1:-}" reset_target="" reset_snapshot=""
|
||||
local original_restore_stash_hash="" original_restore_start_head=""
|
||||
local rollback_safety_snapshot="" rollback_safety_backup="" rollback_safety_start_head=""
|
||||
local preserve_stash_hash=""
|
||||
|
||||
ensure_git_repo
|
||||
ensure_no_noncherrypick_git_operation_in_progress
|
||||
load_state || true
|
||||
ensure_current_branch_with_state_fallback
|
||||
ensure_upstream_remote
|
||||
|
||||
if [ -n "$explicit_target" ] && is_valid_snapshot_dir "$explicit_target"; then
|
||||
reset_snapshot="$explicit_target"
|
||||
elif [ -n "$explicit_target" ]; then
|
||||
git show-ref --verify --quiet "refs/heads/$explicit_target" || die "Backup branch '$explicit_target' does not exist."
|
||||
reset_target="$explicit_target"
|
||||
else
|
||||
if [ -n "${STATE_BRANCH:-}" ] && [ "$CURRENT_BRANCH" != "$STATE_BRANCH" ]; then
|
||||
die "Saved import state belongs to branch '$STATE_BRANCH'. Check out that branch or pass an explicit backup branch or snapshot."
|
||||
fi
|
||||
if [ -n "${STATE_SNAPSHOT_PATH:-}" ] && is_valid_snapshot_dir "$STATE_SNAPSHOT_PATH"; then
|
||||
reset_snapshot="$STATE_SNAPSHOT_PATH"
|
||||
fi
|
||||
if [ -n "${STATE_START_HEAD:-}" ]; then
|
||||
reset_target="$STATE_START_HEAD"
|
||||
elif [ -n "${STATE_BACKUP_BRANCH:-}" ]; then
|
||||
reset_target="$STATE_BACKUP_BRANCH"
|
||||
else
|
||||
reset_target="$(find_latest_backup_branch_for_current || true)"
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ -z "$reset_target" ] && [ -n "$reset_snapshot" ]; then
|
||||
reset_target="$(snapshot_metadata_value "$reset_snapshot" head || true)"
|
||||
fi
|
||||
|
||||
[ -n "$reset_target" ] || [ -n "$reset_snapshot" ] || die "No saved rollback target was found."
|
||||
|
||||
original_restore_stash_hash="${STATE_STASH_HASH:-}"
|
||||
original_restore_start_head="${STATE_START_HEAD:-}"
|
||||
if [ -z "$original_restore_start_head" ] && [ -n "$reset_snapshot" ]; then
|
||||
original_restore_start_head="$(snapshot_metadata_value "$reset_snapshot" head || true)"
|
||||
fi
|
||||
|
||||
if has_cherry_pick_in_progress; then
|
||||
say "Aborting in-progress cherry-pick before rollback..."
|
||||
git cherry-pick --abort || die "Failed to abort the in-progress cherry-pick."
|
||||
fi
|
||||
|
||||
if [ -n "$(git diff --name-only --diff-filter=U)" ]; then
|
||||
die "There are still unmerged files in the working tree. Resolve or discard them before rollback."
|
||||
fi
|
||||
|
||||
prepare_safety_before_real_action "before-rollback"
|
||||
rollback_safety_backup="$BACKUP_BRANCH"
|
||||
rollback_safety_snapshot="$STATE_SNAPSHOT_PATH"
|
||||
rollback_safety_start_head="$STATE_START_HEAD"
|
||||
|
||||
preserve_stash_hash=""
|
||||
if worktree_has_local_changes; then
|
||||
stash_current_changes "pre-rollback-preserve"
|
||||
preserve_stash_hash="$STASH_HASH"
|
||||
fi
|
||||
|
||||
if [ -n "$reset_target" ]; then
|
||||
say "Resetting '$CURRENT_BRANCH' to '$reset_target'..."
|
||||
git reset --hard "$reset_target" >/dev/null
|
||||
fi
|
||||
|
||||
if [ -n "$original_restore_stash_hash" ]; then
|
||||
STASH_HASH="$original_restore_stash_hash"
|
||||
STASH_REF=""
|
||||
BACKUP_BRANCH="$rollback_safety_backup"
|
||||
say "Restoring original pre-import local changes..."
|
||||
restore_stash 1
|
||||
fi
|
||||
|
||||
if [ -n "$reset_snapshot" ]; then
|
||||
say "Restoring exact worktree snapshot from: $reset_snapshot"
|
||||
restore_worktree_snapshot "$reset_snapshot"
|
||||
fi
|
||||
|
||||
STATE_BRANCH="$CURRENT_BRANCH"
|
||||
STATE_BACKUP_BRANCH="$rollback_safety_backup"
|
||||
STATE_STASH_HASH="$preserve_stash_hash"
|
||||
STATE_REMOTE_NAME="$REMOTE_NAME"
|
||||
STATE_REMOTE_URL="$REMOTE_URL"
|
||||
STATE_TARGET_BRANCH="$BRANCH"
|
||||
STATE_START_HEAD="$rollback_safety_start_head"
|
||||
STATE_SNAPSHOT_PATH="$rollback_safety_snapshot"
|
||||
STATE_IMPORT_COMMITS=""
|
||||
STATE_STATUS="rollback_completed"
|
||||
write_state
|
||||
|
||||
say "Rollback completed."
|
||||
say "Restored starting commit: ${original_restore_start_head:-$reset_target}"
|
||||
if [ -n "$reset_snapshot" ]; then
|
||||
say "Restored snapshot: $reset_snapshot"
|
||||
fi
|
||||
say "Safety backup of the pre-rollback state kept at: $rollback_safety_backup"
|
||||
say "Safety snapshot of the pre-rollback state kept at: $rollback_safety_snapshot"
|
||||
if [ -n "$preserve_stash_hash" ]; then
|
||||
say "Safety stash of the pre-rollback local changes kept at: $preserve_stash_hash"
|
||||
fi
|
||||
}
|
||||
|
||||
run_restore_snapshot() {
|
||||
local target_snapshot="${1:-}" restore_safety_backup="" restore_safety_snapshot=""
|
||||
local restore_safety_start_head="" restore_start_head="" preserve_stash_hash=""
|
||||
|
||||
ensure_git_repo
|
||||
ensure_no_noncherrypick_git_operation_in_progress
|
||||
load_state || die "No saved import state was found."
|
||||
ensure_current_branch_with_state_fallback
|
||||
ensure_upstream_remote
|
||||
|
||||
if [ -z "$target_snapshot" ]; then
|
||||
target_snapshot="${STATE_SNAPSHOT_PATH:-}"
|
||||
fi
|
||||
is_valid_snapshot_dir "$target_snapshot" || die "No valid saved snapshot was found to restore."
|
||||
restore_start_head="${STATE_START_HEAD:-}"
|
||||
if [ -z "$restore_start_head" ]; then
|
||||
restore_start_head="$(snapshot_metadata_value "$target_snapshot" head || true)"
|
||||
fi
|
||||
[ -n "$restore_start_head" ] || die "No saved starting commit was found for the snapshot restore."
|
||||
|
||||
if has_cherry_pick_in_progress; then
|
||||
say "Aborting in-progress cherry-pick before snapshot restore..."
|
||||
git cherry-pick --abort || die "Failed to abort the in-progress cherry-pick."
|
||||
fi
|
||||
|
||||
if [ -n "$(git diff --name-only --diff-filter=U)" ]; then
|
||||
die "There are still unmerged files in the working tree. Resolve or discard them before restoring the snapshot."
|
||||
fi
|
||||
|
||||
prepare_safety_before_real_action "before-restore-snapshot"
|
||||
restore_safety_backup="$BACKUP_BRANCH"
|
||||
restore_safety_snapshot="$STATE_SNAPSHOT_PATH"
|
||||
restore_safety_start_head="$STATE_START_HEAD"
|
||||
|
||||
if worktree_has_local_changes; then
|
||||
stash_current_changes "pre-restore-snapshot-preserve"
|
||||
preserve_stash_hash="$STASH_HASH"
|
||||
fi
|
||||
|
||||
say "Resetting '$CURRENT_BRANCH' to '$restore_start_head' before snapshot restore..."
|
||||
git reset --hard "$restore_start_head" >/dev/null
|
||||
|
||||
if [ -n "${STATE_STASH_HASH:-}" ]; then
|
||||
STASH_HASH="$STATE_STASH_HASH"
|
||||
STASH_REF=""
|
||||
BACKUP_BRANCH="$restore_safety_backup"
|
||||
say "Restoring saved pre-import local changes..."
|
||||
restore_stash 1
|
||||
fi
|
||||
|
||||
say "Restoring exact worktree snapshot from: $target_snapshot"
|
||||
restore_worktree_snapshot "$target_snapshot"
|
||||
|
||||
STATE_BRANCH="$CURRENT_BRANCH"
|
||||
STATE_BACKUP_BRANCH="$restore_safety_backup"
|
||||
STATE_STASH_HASH="$preserve_stash_hash"
|
||||
STATE_REMOTE_NAME="$REMOTE_NAME"
|
||||
STATE_REMOTE_URL="$REMOTE_URL"
|
||||
STATE_TARGET_BRANCH="$BRANCH"
|
||||
STATE_START_HEAD="$restore_safety_start_head"
|
||||
STATE_SNAPSHOT_PATH="$restore_safety_snapshot"
|
||||
STATE_IMPORT_COMMITS=""
|
||||
STATE_STATUS="snapshot_restored"
|
||||
write_state
|
||||
|
||||
say "Snapshot restore completed."
|
||||
say "Safety backup of the pre-restore state kept at: $restore_safety_backup"
|
||||
say "Safety snapshot of the pre-restore state kept at: $restore_safety_snapshot"
|
||||
if [ -n "$preserve_stash_hash" ]; then
|
||||
say "Safety stash of the pre-restore local changes kept at: $preserve_stash_hash"
|
||||
fi
|
||||
}
|
||||
|
||||
show_menu() {
|
||||
local choice import_commits range_from range_to snapshot_target rollback_target
|
||||
|
||||
while true; do
|
||||
cat <<EOF
|
||||
Available actions:
|
||||
1) Fetch upstream only
|
||||
2) List available upstream commits
|
||||
3) Import selected commit(s)
|
||||
4) Import an inclusive commit range
|
||||
5) Continue in-progress cherry-pick
|
||||
6) Rollback last import
|
||||
7) Restore saved stash
|
||||
8) Restore exact snapshot
|
||||
9) Create backup branch only
|
||||
10) Show repository status
|
||||
11) Help
|
||||
0) Exit
|
||||
EOF
|
||||
printf 'Choose an action: '
|
||||
read -r choice
|
||||
|
||||
case "$choice" in
|
||||
1) run_fetch_only ;;
|
||||
2) run_list ;;
|
||||
3)
|
||||
printf 'Enter upstream commit hash(es), separated by spaces: '
|
||||
read -r -a import_commits
|
||||
run_import_commits "${import_commits[@]}"
|
||||
return
|
||||
;;
|
||||
4)
|
||||
printf 'Enter the start commit hash: '
|
||||
read -r range_from
|
||||
printf 'Enter the end commit hash: '
|
||||
read -r range_to
|
||||
run_import_range "$range_from" "$range_to"
|
||||
return
|
||||
;;
|
||||
5)
|
||||
run_continue
|
||||
return
|
||||
;;
|
||||
6)
|
||||
printf 'Optional backup branch or snapshot path (leave empty for saved state): '
|
||||
read -r rollback_target
|
||||
run_rollback "$rollback_target"
|
||||
return
|
||||
;;
|
||||
7)
|
||||
run_restore_saved_stash
|
||||
return
|
||||
;;
|
||||
8)
|
||||
printf 'Optional snapshot path (leave empty for saved state): '
|
||||
read -r snapshot_target
|
||||
run_restore_snapshot "$snapshot_target"
|
||||
return
|
||||
;;
|
||||
9) run_backup_only ;;
|
||||
10) run_status ;;
|
||||
11) show_usage ;;
|
||||
0) exit 0 ;;
|
||||
*) say "Invalid menu selection: $choice" ;;
|
||||
esac
|
||||
done
|
||||
}
|
||||
|
||||
main() {
|
||||
case "${1:-menu}" in
|
||||
fetch) run_fetch_only ;;
|
||||
list) run_list ;;
|
||||
import)
|
||||
shift
|
||||
run_import_commits "$@"
|
||||
;;
|
||||
import-range) run_import_range "${2:-}" "${3:-}" ;;
|
||||
continue) run_continue ;;
|
||||
backup) run_backup_only ;;
|
||||
rollback) run_rollback "${2:-}" ;;
|
||||
restore-stash) run_restore_saved_stash ;;
|
||||
restore-snapshot) run_restore_snapshot "${2:-}" ;;
|
||||
status) run_status ;;
|
||||
help|-h|--help) show_usage ;;
|
||||
menu)
|
||||
if [ -t 0 ] && [ -t 1 ]; then
|
||||
show_menu
|
||||
else
|
||||
show_usage
|
||||
fi
|
||||
;;
|
||||
*)
|
||||
die "Unknown command: $1. Run with 'help' to see available options."
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
main "$@"
|
||||
Executable
+2440
File diff suppressed because it is too large
Load Diff
Executable
+435
@@ -0,0 +1,435 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Folosește instalarea Go standard dacă există, chiar dacă nu este în PATH.
|
||||
if [ -x "/usr/local/go/bin/go" ]; then
|
||||
export PATH="/usr/local/go/bin:$PATH"
|
||||
fi
|
||||
|
||||
# Încarcă NVM dacă este disponibil
|
||||
export NVM_DIR="$HOME/.nvm"
|
||||
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"
|
||||
|
||||
# Forțează folosirea versiunii 22
|
||||
nvm use 22 > /dev/null 2>&1 || echo "⚠️ NVM nu a putut activa Node 22 automatically."
|
||||
|
||||
resolve_build_ref() {
|
||||
git describe --tags --exact-match 2>/dev/null || git describe --tags --always
|
||||
}
|
||||
|
||||
require_docker_for_darwin_sqlite() {
|
||||
if ! command -v docker > /dev/null 2>&1; then
|
||||
echo "❌ Docker is required for macOS SQLite cross-builds."
|
||||
echo " Install the Docker CLI in this environment, or use the non-SQLite macOS build option."
|
||||
echo " If you are running inside a code-server container, also mount the host Docker socket."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if ! docker info > /dev/null 2>&1; then
|
||||
echo "❌ Docker is installed but the daemon is not reachable."
|
||||
echo " Start Docker, or expose the host Docker daemon to this container."
|
||||
echo " For a code-server container, mount /var/run/docker.sock from the host."
|
||||
if [ -n "${DOCKER_HOST:-}" ]; then
|
||||
echo " Current DOCKER_HOST: ${DOCKER_HOST}"
|
||||
else
|
||||
echo " Current DOCKER_HOST is unset."
|
||||
fi
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
resolve_xgo_image() {
|
||||
local xgo_version
|
||||
|
||||
xgo_version="$(awk '$1 == "XGO_VERSION" { print $3; exit }' Makefile 2>/dev/null)"
|
||||
if [ -z "$xgo_version" ]; then
|
||||
xgo_version="go-1.25.x"
|
||||
fi
|
||||
|
||||
printf 'ghcr.io/techknowlogick/xgo:%s' "$xgo_version"
|
||||
}
|
||||
|
||||
resolve_darwin_sqlite_repo_root() {
|
||||
local override_path
|
||||
|
||||
override_path="${SMART_BUILD_DARWIN_HOST_REPO_PATH:-}"
|
||||
if [ -z "$override_path" ]; then
|
||||
pwd -P
|
||||
return
|
||||
fi
|
||||
|
||||
if [ ! -d "$override_path" ] || [ ! -f "$override_path/go.mod" ]; then
|
||||
echo "❌ SMART_BUILD_DARWIN_HOST_REPO_PATH is set, but the path is not usable in this container:"
|
||||
echo " $override_path"
|
||||
echo " Mount the host repository path into the container at the same absolute path, then retry."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
printf '%s' "$override_path"
|
||||
}
|
||||
|
||||
validate_repo_bind_mount_for_darwin_sqlite() {
|
||||
local repo_path="$1"
|
||||
local xgo_image
|
||||
|
||||
xgo_image="$(resolve_xgo_image)"
|
||||
|
||||
if ! docker run --rm -v "$repo_path":/probe:ro --entrypoint sh "$xgo_image" -lc 'test -f /probe/go.mod'; then
|
||||
echo "❌ Docker can reach the daemon, but the daemon cannot mount this repository path correctly:"
|
||||
echo " $repo_path"
|
||||
echo " The xgo container only sees an empty or different host path, so /source/go.mod is missing there."
|
||||
echo " If smart-build runs inside a code-server container with the host Docker socket,"
|
||||
echo " the repository must be mounted from a host bind path that exists at the same absolute path."
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
write_sha256_file() {
|
||||
local artifact_path="$1"
|
||||
local artifact_dir artifact_name
|
||||
|
||||
artifact_dir="$(dirname "$artifact_path")"
|
||||
artifact_name="$(basename "$artifact_path")"
|
||||
|
||||
if command -v sha256sum > /dev/null 2>&1; then
|
||||
(
|
||||
cd "$artifact_dir" || exit 1
|
||||
sha256sum "$artifact_name" > "$artifact_name.sha256"
|
||||
)
|
||||
return
|
||||
fi
|
||||
|
||||
if command -v shasum > /dev/null 2>&1; then
|
||||
(
|
||||
cd "$artifact_dir" || exit 1
|
||||
shasum -a 256 "$artifact_name" > "$artifact_name.sha256"
|
||||
)
|
||||
return
|
||||
fi
|
||||
|
||||
echo "❌ Neither sha256sum nor shasum is available for checksum generation."
|
||||
exit 1
|
||||
}
|
||||
|
||||
# --- 1. VERIFICARE INTEGRITATE ȘI CURĂȚARE CACHE INIȚIALĂ ---
|
||||
echo "🔍 Initialization checks..."
|
||||
|
||||
if ! command -v go > /dev/null 2>&1; then
|
||||
echo "❌ Go nu este disponibil în PATH. Instalează Go 1.26.2 sau adaugă binarul go în PATH."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
notify_human_interaction() {
|
||||
local bell_oga="/usr/share/sounds/freedesktop/stereo/bell.oga"
|
||||
local bell_wav="/usr/share/sounds/alsa/Front_Center.wav"
|
||||
local in_vscode_terminal=0
|
||||
local notification_sent=0
|
||||
|
||||
if [ "${TERM_PROGRAM:-}" = "vscode" ] || [ -n "${VSCODE_IPC_HOOK_CLI:-}" ] || [ -n "${VSCODE_GIT_IPC_HANDLE:-}" ]; then
|
||||
in_vscode_terminal=1
|
||||
fi
|
||||
|
||||
if command -v notify-send > /dev/null 2>&1; then
|
||||
notify-send "Gitea smart-build" "Human input required in smart-build.sh" > /dev/null 2>&1 && notification_sent=1
|
||||
fi
|
||||
|
||||
if command -v canberra-gtk-play > /dev/null 2>&1; then
|
||||
canberra-gtk-play -i bell > /dev/null 2>&1 && return
|
||||
fi
|
||||
|
||||
if [ -f "$bell_oga" ] && command -v paplay > /dev/null 2>&1; then
|
||||
paplay "$bell_oga" > /dev/null 2>&1 && return
|
||||
fi
|
||||
|
||||
if [ -f "$bell_wav" ] && command -v aplay > /dev/null 2>&1; then
|
||||
aplay -q "$bell_wav" > /dev/null 2>&1 && return
|
||||
fi
|
||||
|
||||
if [ -f "$bell_wav" ] && command -v play > /dev/null 2>&1; then
|
||||
play -q "$bell_wav" > /dev/null 2>&1 && return
|
||||
fi
|
||||
|
||||
if [ -t 1 ]; then
|
||||
printf '\a'
|
||||
fi
|
||||
|
||||
if [ "$notification_sent" -eq 0 ] && [ "$in_vscode_terminal" -eq 1 ]; then
|
||||
printf '\033[1;33m%s\033[0m\n' ">>> Human input required below <<<"
|
||||
fi
|
||||
}
|
||||
|
||||
apply_moderate_build_limits() {
|
||||
local go_procs="$1"
|
||||
local node_memory="$2"
|
||||
|
||||
export GOMAXPROCS="$go_procs"
|
||||
export MAKEFLAGS="-j1"
|
||||
|
||||
if [[ "$NODE_OPTIONS" != *"--max-old-space-size="* ]]; then
|
||||
export NODE_OPTIONS="${NODE_OPTIONS:+$NODE_OPTIONS }--max-old-space-size=$node_memory"
|
||||
fi
|
||||
}
|
||||
|
||||
echo ""
|
||||
echo "⚙️ Select Build Load Profile:"
|
||||
echo " Normal keeps the default build behavior."
|
||||
echo " Moderate limits parallel jobs and keeps CPU/RAM usage lower."
|
||||
echo " Low Resource is slower, but safest for weaker machines."
|
||||
notify_human_interaction
|
||||
load_options=("Normal" "Moderate (GOMAXPROCS=2, make -j1)" "Low Resource (GOMAXPROCS=1, make -j1)" "Quit")
|
||||
select opt in "${load_options[@]}"
|
||||
do
|
||||
case $opt in
|
||||
"Normal")
|
||||
echo "✅ Selected: Normal build profile."
|
||||
break
|
||||
;;
|
||||
"Moderate (GOMAXPROCS=2, make -j1)")
|
||||
apply_moderate_build_limits 2 2048
|
||||
echo "✅ Selected: Moderate build profile."
|
||||
echo " GOMAXPROCS=$GOMAXPROCS MAKEFLAGS=\"$MAKEFLAGS\" NODE_OPTIONS=\"$NODE_OPTIONS\""
|
||||
break
|
||||
;;
|
||||
"Low Resource (GOMAXPROCS=1, make -j1)")
|
||||
apply_moderate_build_limits 1 2048
|
||||
echo "✅ Selected: Low Resource build profile."
|
||||
echo " GOMAXPROCS=$GOMAXPROCS MAKEFLAGS=\"$MAKEFLAGS\" NODE_OPTIONS=\"$NODE_OPTIONS\""
|
||||
break
|
||||
;;
|
||||
"Quit")
|
||||
exit 0
|
||||
;;
|
||||
*) echo "Opțiune invalidă $REPLY";;
|
||||
esac
|
||||
done
|
||||
|
||||
# Dacă compilarea anterioară a fost întreruptă, ștergem binarul parțial
|
||||
if [ -f "gitea" ] || [ -f "gitea.exe" ]; then
|
||||
echo "🧹 Garbages found. Cleanning..."
|
||||
rm -f gitea gitea.exe
|
||||
fi
|
||||
|
||||
# Verificăm dacă node_modules există. Dacă nu, forțăm pnpm install
|
||||
if [ ! -d "node_modules" ]; then
|
||||
echo "⚠️ node_modules missing. Instaling..."
|
||||
if ! pnpm install --frozen-lockfile; then
|
||||
echo "❌ Fail to install frontend dependencies."
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
# --- 2. LOGICĂ FRONTEND (CHECKSUM) ---
|
||||
CHECKSUM_FILE=".frontend.hash"
|
||||
CURRENT_HASH=$(find web_src package.json tailwind.config.js -type f -print0 2>/dev/null | xargs -0 sha1sum | sha1sum | awk '{print $1}')
|
||||
|
||||
if [ -f "$CHECKSUM_FILE" ] && [ "$CURRENT_HASH" == "$(cat $CHECKSUM_FILE)" ]; then
|
||||
echo "✅ Frontend is unchanged."
|
||||
else
|
||||
echo "🚀 Code changes detected. Running frontend build..."
|
||||
if ! make frontend; then
|
||||
echo "❌ Fail to build frontend assets."
|
||||
exit 1
|
||||
fi
|
||||
echo "$CURRENT_HASH" > "$CHECKSUM_FILE"
|
||||
fi
|
||||
|
||||
# --- 3. MENIU INTERACTIV PENTRU ARHITECTURĂ ---
|
||||
echo ""
|
||||
echo "🎯 Select Arch to build:"
|
||||
notify_human_interaction
|
||||
arch_options=("linux-amd64" "linux-armv7" "windows-amd64" "macos-amd64" "macos-arm64" "All Arch" "Quit")
|
||||
select opt in "${arch_options[@]}"
|
||||
do
|
||||
case $opt in
|
||||
"linux-amd64")
|
||||
TARGETS=("linux/amd64")
|
||||
break
|
||||
;;
|
||||
"linux-armv7")
|
||||
TARGETS=("linux/arm/7")
|
||||
break
|
||||
;;
|
||||
"windows-amd64")
|
||||
TARGETS=("windows/amd64")
|
||||
break
|
||||
;;
|
||||
"macos-amd64")
|
||||
TARGETS=("darwin/amd64")
|
||||
break
|
||||
;;
|
||||
"macos-arm64")
|
||||
TARGETS=("darwin/arm64")
|
||||
break
|
||||
;;
|
||||
"All Arch")
|
||||
TARGETS=("linux/amd64" "linux/arm/7" "windows/amd64" "darwin/amd64" "darwin/arm64")
|
||||
break
|
||||
;;
|
||||
"Quit")
|
||||
exit 0
|
||||
;;
|
||||
*) echo "Opțiune invalidă $REPLY";;
|
||||
esac
|
||||
done
|
||||
|
||||
echo ""
|
||||
echo "🏷️ Select Build Tags:"
|
||||
notify_human_interaction
|
||||
tag_options=("bindata" "bindata sqlite sqlite_unlock_notify" "Quit")
|
||||
select opt in "${tag_options[@]}"
|
||||
do
|
||||
case $opt in
|
||||
"bindata")
|
||||
BUILD_TAGS="bindata"
|
||||
break
|
||||
;;
|
||||
"bindata sqlite sqlite_unlock_notify")
|
||||
BUILD_TAGS="bindata sqlite sqlite_unlock_notify"
|
||||
BUILD_VARIANT="sqlite"
|
||||
break
|
||||
;;
|
||||
"Quit")
|
||||
exit 0
|
||||
;;
|
||||
*) echo "Opțiune invalidă $REPLY";;
|
||||
esac
|
||||
done
|
||||
|
||||
if [ -z "$BUILD_VARIANT" ]; then
|
||||
BUILD_VARIANT="default"
|
||||
fi
|
||||
|
||||
BUILD_REF="$(resolve_build_ref)"
|
||||
BUILD_REF="${BUILD_REF//\//-}"
|
||||
echo "🏷️ Build tag/reference: $BUILD_REF"
|
||||
|
||||
bindata_needs_update() {
|
||||
local source_dir="$1"
|
||||
local bindata_file="$2"
|
||||
|
||||
if [ ! -f "$bindata_file" ]; then
|
||||
return 0
|
||||
fi
|
||||
|
||||
find "$source_dir" -type f -newer "$bindata_file" -print -quit 2>/dev/null | grep -q .
|
||||
}
|
||||
|
||||
ensure_bindata_asset() {
|
||||
local label="$1"
|
||||
local source_dir="$2"
|
||||
local go_package="$3"
|
||||
local bindata_file="$4"
|
||||
|
||||
if bindata_needs_update "$source_dir" "$bindata_file"; then
|
||||
echo "♻️ Regenerating $label bindata..."
|
||||
if ! CC= GOOS= GOARCH= CGO_ENABLED=0 go generate -tags bindata "$go_package"; then
|
||||
echo "❌ Failed to regenerate $label bindata."
|
||||
exit 1
|
||||
fi
|
||||
else
|
||||
echo "✅ $label bindata is up to date."
|
||||
fi
|
||||
}
|
||||
|
||||
ensure_bindata_assets() {
|
||||
if [[ " $BUILD_TAGS " != *" bindata "* ]]; then
|
||||
return
|
||||
fi
|
||||
|
||||
echo "🔎 Checking embedded bindata assets..."
|
||||
ensure_bindata_asset "templates" "templates" "./modules/templates" "modules/templates/bindata.dat"
|
||||
ensure_bindata_asset "options" "options" "./modules/options" "modules/options/bindata.dat"
|
||||
ensure_bindata_asset "public" "public" "./modules/public" "modules/public/bindata.dat"
|
||||
ensure_bindata_asset "migration schemas" "modules/migration/schemas" "./modules/migration" "modules/migration/bindata.dat"
|
||||
}
|
||||
|
||||
ensure_bindata_assets
|
||||
|
||||
build_darwin_sqlite_target() {
|
||||
local arch="$1"
|
||||
local output="$2"
|
||||
local repo_root temp_dist built_file output_abs
|
||||
local built_files=()
|
||||
|
||||
require_docker_for_darwin_sqlite
|
||||
repo_root="$(resolve_darwin_sqlite_repo_root)"
|
||||
validate_repo_bind_mount_for_darwin_sqlite "$repo_root"
|
||||
output_abs="$(pwd -P)/$output"
|
||||
|
||||
temp_dist="$repo_root/dist/.smart-build-darwin-${arch}-$$"
|
||||
rm -rf "$temp_dist"
|
||||
if ! mkdir -p "$temp_dist"; then
|
||||
echo "❌ Failed to create a temporary macOS release directory in dist/."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "📦 Building for darwin/$arch with TAGS=\"$BUILD_TAGS\" via release-darwin..."
|
||||
if ! make -C "$repo_root" release-darwin TAGS="$BUILD_TAGS" DARWIN_ARCHS="darwin-10.12/$arch" DIST="$temp_dist"; then
|
||||
rm -rf "$temp_dist"
|
||||
echo "❌ Fail to build for darwin/$arch with SQLite"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
mapfile -t built_files < <(find "$temp_dist/binaries" -maxdepth 1 -type f | sort)
|
||||
if [ "${#built_files[@]}" -ne 1 ]; then
|
||||
rm -rf "$temp_dist"
|
||||
echo "❌ Unexpected macOS artifact count for darwin/$arch: ${#built_files[@]}"
|
||||
exit 1
|
||||
fi
|
||||
built_file="${built_files[0]}"
|
||||
|
||||
mv "$built_file" "$output_abs"
|
||||
rm -rf "$temp_dist"
|
||||
|
||||
write_sha256_file "$output_abs"
|
||||
echo "✅ Created: $output_abs"
|
||||
echo "✅ Created: $output_abs.sha256"
|
||||
}
|
||||
|
||||
build_standard_target() {
|
||||
local os="$1"
|
||||
local arch="$2"
|
||||
local arm_ver="$3"
|
||||
local output="$4"
|
||||
local ext="$5"
|
||||
|
||||
export GOOS=$os
|
||||
export GOARCH=$arch
|
||||
export GOARM=$arm_ver
|
||||
export CGO_ENABLED=0
|
||||
if [ "$BUILD_VARIANT" == "sqlite" ]; then
|
||||
export CGO_ENABLED=1
|
||||
fi
|
||||
|
||||
if make build TAGS="$BUILD_TAGS"; then
|
||||
mv "gitea$ext" "$output"
|
||||
write_sha256_file "$output"
|
||||
echo "✅ Created: $output"
|
||||
echo "✅ Created: $output.sha256"
|
||||
else
|
||||
echo "❌ Fail to build for $os/$arch${arm_ver:+/v$arm_ver}"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
# --- 4. COMPILARE ---
|
||||
mkdir -p dist
|
||||
for TARGET in "${TARGETS[@]}"; do
|
||||
IFS="/" read -r OS ARCH ARM_VER <<< "$TARGET"
|
||||
|
||||
EXT="" && [ "$OS" == "windows" ] && EXT=".exe"
|
||||
PLATFORM="$ARCH" && [ ! -z "$ARM_VER" ] && PLATFORM="armv$ARM_VER"
|
||||
VARIANT_SUFFIX="" && [ "$BUILD_VARIANT" == "sqlite" ] && VARIANT_SUFFIX="-sqlite"
|
||||
OUTPUT="dist/gitea-$BUILD_REF-$OS-$PLATFORM$VARIANT_SUFFIX$EXT"
|
||||
|
||||
if [ "$OS" == "darwin" ] && [ "$BUILD_VARIANT" == "sqlite" ]; then
|
||||
build_darwin_sqlite_target "$ARCH" "$OUTPUT"
|
||||
else
|
||||
echo "📦 Building for $OS/$ARCH ${ARM_VER:+(v$ARM_VER) }with TAGS=\"$BUILD_TAGS\"..."
|
||||
build_standard_target "$OS" "$ARCH" "$ARM_VER" "$OUTPUT" "$EXT"
|
||||
fi
|
||||
|
||||
unset GOOS GOARCH GOARM CGO_ENABLED
|
||||
done
|
||||
|
||||
echo "✨ Buid finished. Get file(s) from /dist"
|
||||
go clean -cache # || true
|
||||
Executable
+1091
File diff suppressed because it is too large
Load Diff
@@ -1,3 +1,5 @@
|
||||
## Core Repository Rules
|
||||
|
||||
- Use `make help` to find available development targets
|
||||
- Run `make fmt` to format `.go` files, and run `make lint-go` to lint them
|
||||
- Run `make lint-js` to lint `.ts` files
|
||||
@@ -9,3 +11,26 @@
|
||||
- In TypeScript, use `!` (non-null assertion) instead of `?.`/`??` when a value is known to always exist
|
||||
- Include authorship attribution in issue and pull request comments
|
||||
- Add `Co-Authored-By` lines to all commits, indicating name and model used
|
||||
|
||||
## Execution Rules (Token Optimization)
|
||||
|
||||
- DO NOT read full files unless they are explicitly targeted with `@filename`, referenced from instruction `*.md` files, or required to complete the user's task.
|
||||
- Assume the workspace structure described in `./.codex-context.md` and `./.codex-project-map.md` is the current baseline unless the user indicates otherwise.
|
||||
- DO NOT read `./.codex-history.md` end-to-end by default; search by keyword, subsystem, tag, or read only the latest relevant entries first.
|
||||
|
||||
## Project Context
|
||||
|
||||
- Read and follow `./.codex-context.md` as the persistent repository context before starting work and when validating final changes.
|
||||
- Use `./.codex-project-map.md` for the persistent structural and architectural map of the repository.
|
||||
|
||||
## Routing Rules for Tasks (Multi-Model Delegation)
|
||||
|
||||
Apply these routing preferences when the environment supports model selection. If the preferred model is unavailable, use the closest available model and note the fallback.
|
||||
|
||||
Priority for mixed tasks:
|
||||
Architecture & Orchestration > Go & Database Coding > Frontend & Template Tasks > DevOps & Terminal Execution
|
||||
|
||||
1. Architecture & Orchestration Tasks: Prefer `gpt-5.4` (Reasoning: High/Extra High). Use for complex requirement breakdown, solution design, and validation of large structural updates.
|
||||
2. Go & Database Coding Tasks: Prefer `gpt-5.3-codex` (Reasoning: Medium). This includes writing HTTP handlers, database queries, internal Go business logic, and server-side integration work.
|
||||
3. Frontend & Template Tasks: Prefer `gpt-5.3-codex` (Reasoning: Medium). This includes `templates/`, `web_src/`, CSS, and TypeScript changes.
|
||||
4. DevOps & Terminal Commands: Prefer `gpt-5.4-mini` (Reasoning: Low). Use for `pnpm`, `git`, `go mod`, `npm`, `make`, or `bash` execution flows and shell-oriented maintenance tasks.
|
||||
|
||||
+4496
-4496
File diff suppressed because it is too large
Load Diff
+5197
-5137
File diff suppressed because it is too large
Load Diff
@@ -95,7 +95,7 @@ else
|
||||
ifneq ($(STORED_VERSION),)
|
||||
GITEA_VERSION ?= $(STORED_VERSION)
|
||||
else
|
||||
GITEA_VERSION ?= $(shell git describe --tags --always | sed 's/-/+/' | sed 's/^v//')
|
||||
GITEA_VERSION ?= $(shell git describe --tags --always | sed -E 's/^v//; s/^(.*)-([0-9]+-g[0-9a-f]+)$$/\1+\2/')
|
||||
endif
|
||||
endif
|
||||
|
||||
@@ -107,6 +107,7 @@ endif
|
||||
LDFLAGS := $(LDFLAGS) -X "main.Version=$(GITEA_VERSION)" -X "main.Tags=$(TAGS)"
|
||||
|
||||
LINUX_ARCHS ?= linux/amd64,linux/386,linux/arm-5,linux/arm-6,linux/arm64,linux/riscv64
|
||||
DARWIN_ARCHS ?= darwin-10.12/amd64,darwin-10.12/arm64
|
||||
|
||||
GO_TEST_PACKAGES ?= $(filter-out $(shell $(GO) list code.gitea.io/gitea/models/migrations/...) code.gitea.io/gitea/tests/integration/migration-test code.gitea.io/gitea/tests code.gitea.io/gitea/tests/integration,$(shell $(GO) list ./... | grep -v /vendor/))
|
||||
MIGRATE_TEST_PACKAGES ?= $(shell $(GO) list code.gitea.io/gitea/models/migrations/...)
|
||||
@@ -685,7 +686,7 @@ release-linux: | $(DIST_DIRS)
|
||||
|
||||
.PHONY: release-darwin
|
||||
release-darwin: | $(DIST_DIRS)
|
||||
CGO_CFLAGS="$(CGO_CFLAGS)" $(GO) run $(XGO_PACKAGE) -go $(XGO_VERSION) -dest $(DIST)/binaries -tags 'netgo osusergo $(TAGS)' -ldflags '-s -w $(LDFLAGS)' -targets 'darwin-10.12/amd64,darwin-10.12/arm64' -out gitea-$(VERSION) .
|
||||
CGO_CFLAGS="$(CGO_CFLAGS)" $(GO) run $(XGO_PACKAGE) -go $(XGO_VERSION) -dest $(DIST)/binaries -tags 'netgo osusergo $(TAGS)' -ldflags '-s -w $(LDFLAGS)' -targets '$(DARWIN_ARCHS)' -out gitea-$(VERSION) .
|
||||
|
||||
.PHONY: release-freebsd
|
||||
release-freebsd: | $(DIST_DIRS)
|
||||
|
||||
@@ -19,6 +19,7 @@ import (
|
||||
|
||||
// regexp is based on go-license, excluding README and NOTICE
|
||||
// https://github.com/google/go-licenses/blob/master/licenses/find.go
|
||||
// also defined in vite.config.ts
|
||||
var licenseRe = regexp.MustCompile(`^(?i)((UN)?LICEN(S|C)E|COPYING).*$`)
|
||||
|
||||
// primaryLicenseRe matches exact primary license filenames without suffixes.
|
||||
|
||||
@@ -41,10 +41,10 @@
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;;
|
||||
;; App name that shows in every page title
|
||||
APP_NAME = ; Gitea: Git with a cup of tea
|
||||
;APP_NAME = Gitea: Git with a cup of tea
|
||||
;;
|
||||
;; RUN_USER will automatically detect the current user - but you can set it here change it if you run locally
|
||||
RUN_USER = ; git
|
||||
;RUN_USER =
|
||||
;;
|
||||
;; Application run mode, affects performance and debugging: "dev" or "prod", default is "prod"
|
||||
;; Mode "dev" makes Gitea easier to develop and debug, values other than "dev" are treated as "prod" which is for production use.
|
||||
@@ -461,6 +461,11 @@ INTERNAL_TOKEN =
|
||||
;; Name of cookie used to store authentication information.
|
||||
;COOKIE_REMEMBER_NAME = gitea_incredible
|
||||
;;
|
||||
;; URL or path that Gitea should redirect users to *after* performing its own logout.
|
||||
;; Use this, if needed, when authentication is handled by a reverse proxy or SSO.
|
||||
;; For example: "/my-sso/logout?return=/my-sso/home"
|
||||
;REVERSE_PROXY_LOGOUT_REDIRECT =
|
||||
;;
|
||||
;; Reverse proxy authentication header name of user name, email, and full name
|
||||
;REVERSE_PROXY_AUTHENTICATION_USER = X-WEBAUTH-USER
|
||||
;REVERSE_PROXY_AUTHENTICATION_EMAIL = X-WEBAUTH-EMAIL
|
||||
@@ -778,6 +783,11 @@ LEVEL = Info
|
||||
;; Disallow registration, only allow admins to create accounts.
|
||||
;DISABLE_REGISTRATION = false
|
||||
;;
|
||||
;; When DISABLE_REGISTRATION is true, choose how administrator-created accounts are provisioned.
|
||||
;; - local: create active local accounts immediately
|
||||
;; - invite: create inactive accounts that require the emailed invitation link before sign-in is enabled
|
||||
;ADMIN_CREATED_ACCOUNT_MODE = invite
|
||||
;;
|
||||
;; Allow registration only using gitea itself, it works only when DISABLE_REGISTRATION is false
|
||||
;ALLOW_ONLY_INTERNAL_REGISTRATION = false
|
||||
;;
|
||||
@@ -1608,6 +1618,16 @@ LEVEL = Info
|
||||
;;
|
||||
;; Default configuration for email notifications for users (user configurable). Options: enabled, onmention, disabled
|
||||
;DEFAULT_EMAIL_NOTIFICATIONS = enabled
|
||||
;;
|
||||
;; Enable the persistent Super Administrator role for protecting administrator management.
|
||||
;SUPER_ADMIN_ENABLED = true
|
||||
;;
|
||||
;; Controls who can change administrator and super administrator permissions.
|
||||
;; Options:
|
||||
;; - super_admin_only: only super administrators can modify or delete administrator accounts and manage all administrator privilege changes.
|
||||
;; - grantor_only: administrators can promote regular users to administrator and later manage only the administrator accounts they directly promoted.
|
||||
;; - grantor_inheritance: like grantor_only, but if the direct grantor becomes inactive or has sign-in disabled, management passes up the admin grant chain until an eligible administrator is found.
|
||||
;ADMIN_MANAGEMENT_POLICY = grantor_only
|
||||
;; Disabled features for users could be "deletion", "manage_ssh_keys", "manage_gpg_keys", "manage_mfa", "manage_credentials" more features can be disabled in future
|
||||
;; - deletion: a user cannot delete their own account
|
||||
;; - manage_ssh_keys: a user cannot configure ssh keys
|
||||
@@ -2580,8 +2600,8 @@ LEVEL = Info
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; The first locale will be used as the default if user browser's language doesn't match any locale in the list.
|
||||
;LANGS = en-US,zh-CN,zh-HK,zh-TW,de-DE,fr-FR,nl-NL,lv-LV,ru-RU,uk-UA,ja-JP,es-ES,pt-BR,pt-PT,pl-PL,bg-BG,it-IT,fi-FI,tr-TR,cs-CZ,sv-SE,ko-KR,el-GR,fa-IR,hu-HU,id-ID,ml-IN
|
||||
;NAMES = English,简体中文,繁體中文(香港),繁體中文(台灣),Deutsch,Français,Nederlands,Latviešu,Русский,Українська,日本語,Español,Português do Brasil,Português de Portugal,Polski,Български,Italiano,Suomi,Türkçe,Čeština,Српски,Svenska,한국어,Ελληνικά,فارسی,Magyar nyelv,Bahasa Indonesia,മലയാളം
|
||||
;LANGS = en-US,ro-RO,zh-CN,zh-HK,zh-TW,de-DE,fr-FR,nl-NL,lv-LV,ru-RU,uk-UA,ja-JP,es-ES,pt-BR,pt-PT,pl-PL,bg-BG,it-IT,fi-FI,tr-TR,cs-CZ,sv-SE,ko-KR,el-GR,fa-IR,hu-HU,id-ID,ml-IN
|
||||
;NAMES = English,Română,简体中文,繁體中文(香港),繁體中文(台灣),Deutsch,Français,Nederlands,Latviešu,Русский,Українська,日本語,Español,Português do Brasil,Português de Portugal,Polski,Български,Italiano,Suomi,Türkçe,Čeština,Српски,Svenska,한국어,Ελληνικά,فارسی,Magyar nyelv,Bahasa Indonesia,മലയാളം
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
@@ -926,6 +926,7 @@ export default defineConfig([
|
||||
{
|
||||
...playwright.configs['flat/recommended'],
|
||||
files: ['tests/e2e/**/*.test.ts'],
|
||||
languageOptions: {globals: {...globals.nodeBuiltin, ...globals.browser}},
|
||||
rules: {
|
||||
...playwright.configs['flat/recommended'].rules,
|
||||
'playwright/expect-expect': [0],
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
module code.gitea.io/gitea
|
||||
|
||||
go 1.26.1
|
||||
go 1.26.2
|
||||
|
||||
// rfc5280 said: "The serial number is an integer assigned by the CA to each certificate."
|
||||
// But some CAs use negative serial number, just relax the check. related:
|
||||
@@ -12,7 +12,7 @@ require (
|
||||
code.gitea.io/sdk/gitea v0.24.1
|
||||
codeberg.org/gusted/mcaptcha v0.0.0-20220723083913-4f3072e1d570
|
||||
connectrpc.com/connect v1.19.1
|
||||
gitea.com/go-chi/binding v0.0.0-20240430071103-39a851e106ed
|
||||
gitea.com/go-chi/binding v0.0.0-20260414111559-654cea7ac60a
|
||||
gitea.com/go-chi/cache v0.2.1
|
||||
gitea.com/go-chi/captcha v0.0.0-20240315150714-fb487f629098
|
||||
gitea.com/go-chi/session v0.0.0-20251124165456-68e0254e989e
|
||||
@@ -52,12 +52,11 @@ require (
|
||||
github.com/go-co-op/gocron/v2 v2.19.1
|
||||
github.com/go-enry/go-enry/v2 v2.9.5
|
||||
github.com/go-git/go-billy/v5 v5.8.0
|
||||
github.com/go-git/go-git/v5 v5.17.2
|
||||
github.com/go-git/go-git/v5 v5.18.0
|
||||
github.com/go-ldap/ldap/v3 v3.4.13
|
||||
github.com/go-redsync/redsync/v4 v4.16.0
|
||||
github.com/go-sql-driver/mysql v1.9.3
|
||||
github.com/go-webauthn/webauthn v0.16.1
|
||||
github.com/goccy/go-json v0.10.6
|
||||
github.com/gogs/chardet v0.0.0-20211120154057-b7413eaefb8f
|
||||
github.com/gogs/go-gogs-client v0.0.0-20210131175652-1d7215cd8d85
|
||||
github.com/golang-jwt/jwt/v5 v5.3.1
|
||||
@@ -196,6 +195,7 @@ require (
|
||||
github.com/go-ini/ini v1.67.0 // indirect
|
||||
github.com/go-viper/mapstructure/v2 v2.5.0 // indirect
|
||||
github.com/go-webauthn/x v0.2.2 // indirect
|
||||
github.com/goccy/go-json v0.10.6 // indirect
|
||||
github.com/golang-sql/civil v0.0.0-20220223132316-b832511892a9 // indirect
|
||||
github.com/golang-sql/sqlexp v0.1.0 // indirect
|
||||
github.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8 // indirect
|
||||
|
||||
@@ -18,8 +18,8 @@ filippo.io/edwards25519 v1.2.0 h1:crnVqOiS4jqYleHd9vaKZ+HKtHfllngJIiOpNpoJsjo=
|
||||
filippo.io/edwards25519 v1.2.0/go.mod h1:xzAOLCNug/yB62zG1bQ8uziwrIqIuxhctzJT18Q77mc=
|
||||
gitea.com/gitea/act v0.261.10 h1:ndwbtuMXXz1dpYF2iwY1/PkgKNETo4jmPXfinTZt8cs=
|
||||
gitea.com/gitea/act v0.261.10/go.mod h1:oIkqQHvU0lfuIWwcpqa4FmU+t3prA89tgkuHUTsrI2c=
|
||||
gitea.com/go-chi/binding v0.0.0-20240430071103-39a851e106ed h1:EZZBtilMLSZNWtHHcgq2mt6NSGhJSZBuduAlinMEmso=
|
||||
gitea.com/go-chi/binding v0.0.0-20240430071103-39a851e106ed/go.mod h1:E3i3cgB04dDx0v3CytCgRTTn9Z/9x891aet3r456RVw=
|
||||
gitea.com/go-chi/binding v0.0.0-20260414111559-654cea7ac60a h1:JHoBrfuTSF9Ke9aNfSYj1XRPBHjKPgCApVprnt2Am0M=
|
||||
gitea.com/go-chi/binding v0.0.0-20260414111559-654cea7ac60a/go.mod h1:FOsLJIMdpiHzBp3Vby6Wfkdw2ppGscrjgU1IC7E4/zQ=
|
||||
gitea.com/go-chi/cache v0.2.1 h1:bfAPkvXlbcZxPCpcmDVCWoHgiBSBmZN/QosnZvEC0+g=
|
||||
gitea.com/go-chi/cache v0.2.1/go.mod h1:Qic0HZ8hOHW62ETGbonpwz8WYypj9NieU9659wFUJ8Q=
|
||||
gitea.com/go-chi/captcha v0.0.0-20240315150714-fb487f629098 h1:p2ki+WK0cIeNQuqjR98IP2KZQKRzJJiV7aTeMAFwaWo=
|
||||
@@ -304,8 +304,8 @@ github.com/go-git/go-billy/v5 v5.8.0 h1:I8hjc3LbBlXTtVuFNJuwYuMiHvQJDq1AT6u4DwDz
|
||||
github.com/go-git/go-billy/v5 v5.8.0/go.mod h1:RpvI/rw4Vr5QA+Z60c6d6LXH0rYJo0uD5SqfmrrheCY=
|
||||
github.com/go-git/go-git-fixtures/v4 v4.3.2-0.20231010084843-55a94097c399 h1:eMje31YglSBqCdIqdhKBW8lokaMrL3uTkpGYlE2OOT4=
|
||||
github.com/go-git/go-git-fixtures/v4 v4.3.2-0.20231010084843-55a94097c399/go.mod h1:1OCfN199q1Jm3HZlxleg+Dw/mwps2Wbk9frAWm+4FII=
|
||||
github.com/go-git/go-git/v5 v5.17.2 h1:B+nkdlxdYrvyFK4GPXVU8w1U+YkbsgciIR7f2sZJ104=
|
||||
github.com/go-git/go-git/v5 v5.17.2/go.mod h1:pW/VmeqkanRFqR6AljLcs7EA7FbZaN5MQqO7oZADXpo=
|
||||
github.com/go-git/go-git/v5 v5.18.0 h1:O831KI+0PR51hM2kep6T8k+w0/LIAD490gvqMCvL5hM=
|
||||
github.com/go-git/go-git/v5 v5.18.0/go.mod h1:pW/VmeqkanRFqR6AljLcs7EA7FbZaN5MQqO7oZADXpo=
|
||||
github.com/go-ini/ini v1.67.0 h1:z6ZrTEZqSWOTyH2FlglNbNgARyHG8oLW9gMELqKr06A=
|
||||
github.com/go-ini/ini v1.67.0/go.mod h1:ByCAeIL28uOIIG0E3PJtZPDL8WnHpFKFOtgjp+3Ies8=
|
||||
github.com/go-jose/go-jose/v4 v4.1.3 h1:CVLmWDhDVRa6Mi/IgCgaopNosCaHz7zrMeF9MlZRkrs=
|
||||
|
||||
@@ -15,6 +15,7 @@ import (
|
||||
"code.gitea.io/gitea/models/perm"
|
||||
user_model "code.gitea.io/gitea/models/user"
|
||||
"code.gitea.io/gitea/modules/log"
|
||||
"code.gitea.io/gitea/modules/setting"
|
||||
"code.gitea.io/gitea/modules/timeutil"
|
||||
"code.gitea.io/gitea/modules/util"
|
||||
|
||||
@@ -64,7 +65,12 @@ func (key *PublicKey) AfterLoad() {
|
||||
|
||||
// OmitEmail returns content of public key without email address.
|
||||
func (key *PublicKey) OmitEmail() string {
|
||||
return strings.Join(strings.Split(key.Content, " ")[:2], " ")
|
||||
fields := strings.Split(key.Content, " ") // format: ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC... comment
|
||||
if len(fields) < 2 {
|
||||
setting.PanicInDevOrTesting("invalid public key %d content: %s", key.ID, key.Content)
|
||||
return "" // not a valid public key, it shouldn't really happen, the value is managed internally
|
||||
}
|
||||
return strings.Join(fields[:2], " ")
|
||||
}
|
||||
|
||||
func addKey(ctx context.Context, key *PublicKey) (err error) {
|
||||
|
||||
@@ -633,7 +633,7 @@ func GetActiveOAuth2SourceByAuthName(ctx context.Context, name string) (*Source,
|
||||
}
|
||||
|
||||
if !has {
|
||||
return nil, fmt.Errorf("oauth2 source not found, name: %q", name)
|
||||
return nil, util.NewNotExistErrorf("oauth2 source not found, name: %q", name)
|
||||
}
|
||||
|
||||
return authSource, nil
|
||||
|
||||
@@ -89,7 +89,7 @@
|
||||
ref: "refs/heads/test"
|
||||
commit_sha: "c2d72f548424103f01ee1dc02889c1e2bff816b0"
|
||||
event: "push"
|
||||
trigger_event: "push"
|
||||
trigger_event: "schedule"
|
||||
is_fork_pull_request: 0
|
||||
status: 1
|
||||
started: 1683636528
|
||||
|
||||
@@ -877,7 +877,12 @@ func ParseCodeOwnersLine(ctx context.Context, tokens []string) (*CodeOwnerRule,
|
||||
|
||||
warnings := make([]string, 0)
|
||||
|
||||
expr := fmt.Sprintf("^%s$", strings.TrimPrefix(tokens[0], "!"))
|
||||
// Strip leading "!" for negative rules, then strip leading "/" since
|
||||
// git returns relative paths (e.g. "docs/foo.md" not "/docs/foo.md")
|
||||
// and the regex is already anchored with ^...$, so the "/" is redundant.
|
||||
pattern := strings.TrimPrefix(tokens[0], "!")
|
||||
pattern = strings.TrimPrefix(pattern, "/")
|
||||
expr := fmt.Sprintf("^%s$", pattern)
|
||||
rule.Rule, err = regexp2.Compile(expr, regexp2.None)
|
||||
if err != nil {
|
||||
warnings = append(warnings, fmt.Sprintf("incorrect codeowner regexp: %s", err))
|
||||
|
||||
+83
-49
@@ -17,16 +17,43 @@ import (
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestPullRequest_LoadAttributes(t *testing.T) {
|
||||
func TestPullRequest(t *testing.T) {
|
||||
assert.NoError(t, unittest.PrepareTestDatabase())
|
||||
|
||||
t.Run("LoadAttributes", testPullRequestLoadAttributes)
|
||||
t.Run("LoadIssue", testPullRequestLoadIssue)
|
||||
t.Run("LoadBaseRepo", testPullRequestLoadBaseRepo)
|
||||
t.Run("LoadHeadRepo", testPullRequestLoadHeadRepo)
|
||||
t.Run("PullRequestsNewest", testPullRequestsNewest)
|
||||
t.Run("PullRequestsOldest", testPullRequestsOldest)
|
||||
t.Run("GetUnmergedPullRequest", testGetUnmergedPullRequest)
|
||||
t.Run("HasUnmergedPullRequestsByHeadInfo", testHasUnmergedPullRequestsByHeadInfo)
|
||||
t.Run("GetUnmergedPullRequestsByHeadInfo", testGetUnmergedPullRequestsByHeadInfo)
|
||||
t.Run("GetUnmergedPullRequestsByBaseInfo", testGetUnmergedPullRequestsByBaseInfo)
|
||||
t.Run("GetPullRequestByIndex", testGetPullRequestByIndex)
|
||||
t.Run("GetPullRequestByID", testGetPullRequestByID)
|
||||
t.Run("GetPullRequestByIssueID", testGetPullRequestByIssueID)
|
||||
t.Run("PullRequest_UpdateCols", testPullRequestUpdateCols)
|
||||
t.Run("PullRequest_IsWorkInProgress", testPullRequestIsWorkInProgress)
|
||||
t.Run("PullRequest_GetWorkInProgressPrefixWorkInProgress", testPullRequestGetWorkInProgressPrefixWorkInProgress)
|
||||
t.Run("DeleteOrphanedObjects", testDeleteOrphanedObjects)
|
||||
t.Run("ParseCodeOwnersLine", testParseCodeOwnersLine)
|
||||
t.Run("CodeOwnerAbsolutePathPatterns", testCodeOwnerAbsolutePathPatterns)
|
||||
t.Run("GetApprovers", testGetApprovers)
|
||||
t.Run("GetPullRequestByMergedCommit", testGetPullRequestByMergedCommit)
|
||||
t.Run("Migrate_InsertPullRequests", testMigrateInsertPullRequests)
|
||||
t.Run("PullRequestsClosedRecentSortType", testPullRequestsClosedRecentSortType)
|
||||
t.Run("LoadRequestedReviewers", testLoadRequestedReviewers)
|
||||
}
|
||||
|
||||
func testPullRequestLoadAttributes(t *testing.T) {
|
||||
pr := unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{ID: 1})
|
||||
assert.NoError(t, pr.LoadAttributes(t.Context()))
|
||||
assert.NotNil(t, pr.Merger)
|
||||
assert.Equal(t, pr.MergerID, pr.Merger.ID)
|
||||
}
|
||||
|
||||
func TestPullRequest_LoadIssue(t *testing.T) {
|
||||
assert.NoError(t, unittest.PrepareTestDatabase())
|
||||
func testPullRequestLoadIssue(t *testing.T) {
|
||||
pr := unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{ID: 1})
|
||||
assert.NoError(t, pr.LoadIssue(t.Context()))
|
||||
assert.NotNil(t, pr.Issue)
|
||||
@@ -36,8 +63,7 @@ func TestPullRequest_LoadIssue(t *testing.T) {
|
||||
assert.Equal(t, int64(2), pr.Issue.ID)
|
||||
}
|
||||
|
||||
func TestPullRequest_LoadBaseRepo(t *testing.T) {
|
||||
assert.NoError(t, unittest.PrepareTestDatabase())
|
||||
func testPullRequestLoadBaseRepo(t *testing.T) {
|
||||
pr := unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{ID: 1})
|
||||
assert.NoError(t, pr.LoadBaseRepo(t.Context()))
|
||||
assert.NotNil(t, pr.BaseRepo)
|
||||
@@ -47,8 +73,7 @@ func TestPullRequest_LoadBaseRepo(t *testing.T) {
|
||||
assert.Equal(t, pr.BaseRepoID, pr.BaseRepo.ID)
|
||||
}
|
||||
|
||||
func TestPullRequest_LoadHeadRepo(t *testing.T) {
|
||||
assert.NoError(t, unittest.PrepareTestDatabase())
|
||||
func testPullRequestLoadHeadRepo(t *testing.T) {
|
||||
pr := unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{ID: 1})
|
||||
assert.NoError(t, pr.LoadHeadRepo(t.Context()))
|
||||
assert.NotNil(t, pr.HeadRepo)
|
||||
@@ -59,8 +84,7 @@ func TestPullRequest_LoadHeadRepo(t *testing.T) {
|
||||
|
||||
// TODO TestNewPullRequest
|
||||
|
||||
func TestPullRequestsNewest(t *testing.T) {
|
||||
assert.NoError(t, unittest.PrepareTestDatabase())
|
||||
func testPullRequestsNewest(t *testing.T) {
|
||||
prs, count, err := issues_model.PullRequests(t.Context(), 1, &issues_model.PullRequestsOptions{
|
||||
ListOptions: db.ListOptions{
|
||||
Page: 1,
|
||||
@@ -77,7 +101,7 @@ func TestPullRequestsNewest(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestPullRequests_Closed_RecentSortType(t *testing.T) {
|
||||
func testPullRequestsClosedRecentSortType(t *testing.T) {
|
||||
// Issue ID | Closed At. | Updated At
|
||||
// 2 | 1707270001 | 1707270001
|
||||
// 3 | 1707271000 | 1707279999
|
||||
@@ -90,7 +114,6 @@ func TestPullRequests_Closed_RecentSortType(t *testing.T) {
|
||||
{"recentclose", []int64{11, 3, 2}},
|
||||
}
|
||||
|
||||
assert.NoError(t, unittest.PrepareTestDatabase())
|
||||
_, err := db.Exec(t.Context(), "UPDATE issue SET closed_unix = 1707270001, updated_unix = 1707270001, is_closed = true WHERE id = 2")
|
||||
require.NoError(t, err)
|
||||
_, err = db.Exec(t.Context(), "UPDATE issue SET closed_unix = 1707271000, updated_unix = 1707279999, is_closed = true WHERE id = 3")
|
||||
@@ -118,9 +141,7 @@ func TestPullRequests_Closed_RecentSortType(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestLoadRequestedReviewers(t *testing.T) {
|
||||
assert.NoError(t, unittest.PrepareTestDatabase())
|
||||
|
||||
func testLoadRequestedReviewers(t *testing.T) {
|
||||
pull := unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{ID: 2})
|
||||
assert.NoError(t, pull.LoadIssue(t.Context()))
|
||||
issue := pull.Issue
|
||||
@@ -146,8 +167,7 @@ func TestLoadRequestedReviewers(t *testing.T) {
|
||||
assert.Empty(t, pull.RequestedReviewers)
|
||||
}
|
||||
|
||||
func TestPullRequestsOldest(t *testing.T) {
|
||||
assert.NoError(t, unittest.PrepareTestDatabase())
|
||||
func testPullRequestsOldest(t *testing.T) {
|
||||
prs, count, err := issues_model.PullRequests(t.Context(), 1, &issues_model.PullRequestsOptions{
|
||||
ListOptions: db.ListOptions{
|
||||
Page: 1,
|
||||
@@ -164,8 +184,7 @@ func TestPullRequestsOldest(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetUnmergedPullRequest(t *testing.T) {
|
||||
assert.NoError(t, unittest.PrepareTestDatabase())
|
||||
func testGetUnmergedPullRequest(t *testing.T) {
|
||||
pr, err := issues_model.GetUnmergedPullRequest(t.Context(), 1, 1, "branch2", "master", issues_model.PullRequestFlowGithub)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, int64(2), pr.ID)
|
||||
@@ -175,9 +194,7 @@ func TestGetUnmergedPullRequest(t *testing.T) {
|
||||
assert.True(t, issues_model.IsErrPullRequestNotExist(err))
|
||||
}
|
||||
|
||||
func TestHasUnmergedPullRequestsByHeadInfo(t *testing.T) {
|
||||
assert.NoError(t, unittest.PrepareTestDatabase())
|
||||
|
||||
func testHasUnmergedPullRequestsByHeadInfo(t *testing.T) {
|
||||
exist, err := issues_model.HasUnmergedPullRequestsByHeadInfo(t.Context(), 1, "branch2")
|
||||
assert.NoError(t, err)
|
||||
assert.True(t, exist)
|
||||
@@ -187,8 +204,7 @@ func TestHasUnmergedPullRequestsByHeadInfo(t *testing.T) {
|
||||
assert.False(t, exist)
|
||||
}
|
||||
|
||||
func TestGetUnmergedPullRequestsByHeadInfo(t *testing.T) {
|
||||
assert.NoError(t, unittest.PrepareTestDatabase())
|
||||
func testGetUnmergedPullRequestsByHeadInfo(t *testing.T) {
|
||||
prs, err := issues_model.GetUnmergedPullRequestsByHeadInfo(t.Context(), 1, "branch2")
|
||||
assert.NoError(t, err)
|
||||
assert.Len(t, prs, 1)
|
||||
@@ -198,8 +214,7 @@ func TestGetUnmergedPullRequestsByHeadInfo(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetUnmergedPullRequestsByBaseInfo(t *testing.T) {
|
||||
assert.NoError(t, unittest.PrepareTestDatabase())
|
||||
func testGetUnmergedPullRequestsByBaseInfo(t *testing.T) {
|
||||
prs, err := issues_model.GetUnmergedPullRequestsByBaseInfo(t.Context(), 1, "master")
|
||||
assert.NoError(t, err)
|
||||
assert.Len(t, prs, 1)
|
||||
@@ -209,8 +224,7 @@ func TestGetUnmergedPullRequestsByBaseInfo(t *testing.T) {
|
||||
assert.Equal(t, "master", pr.BaseBranch)
|
||||
}
|
||||
|
||||
func TestGetPullRequestByIndex(t *testing.T) {
|
||||
assert.NoError(t, unittest.PrepareTestDatabase())
|
||||
func testGetPullRequestByIndex(t *testing.T) {
|
||||
pr, err := issues_model.GetPullRequestByIndex(t.Context(), 1, 2)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, int64(1), pr.BaseRepoID)
|
||||
@@ -225,8 +239,7 @@ func TestGetPullRequestByIndex(t *testing.T) {
|
||||
assert.True(t, issues_model.IsErrPullRequestNotExist(err))
|
||||
}
|
||||
|
||||
func TestGetPullRequestByID(t *testing.T) {
|
||||
assert.NoError(t, unittest.PrepareTestDatabase())
|
||||
func testGetPullRequestByID(t *testing.T) {
|
||||
pr, err := issues_model.GetPullRequestByID(t.Context(), 1)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, int64(1), pr.ID)
|
||||
@@ -237,8 +250,7 @@ func TestGetPullRequestByID(t *testing.T) {
|
||||
assert.True(t, issues_model.IsErrPullRequestNotExist(err))
|
||||
}
|
||||
|
||||
func TestGetPullRequestByIssueID(t *testing.T) {
|
||||
assert.NoError(t, unittest.PrepareTestDatabase())
|
||||
func testGetPullRequestByIssueID(t *testing.T) {
|
||||
pr, err := issues_model.GetPullRequestByIssueID(t.Context(), 2)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, int64(2), pr.IssueID)
|
||||
@@ -248,8 +260,7 @@ func TestGetPullRequestByIssueID(t *testing.T) {
|
||||
assert.True(t, issues_model.IsErrPullRequestNotExist(err))
|
||||
}
|
||||
|
||||
func TestPullRequest_UpdateCols(t *testing.T) {
|
||||
assert.NoError(t, unittest.PrepareTestDatabase())
|
||||
func testPullRequestUpdateCols(t *testing.T) {
|
||||
pr := &issues_model.PullRequest{
|
||||
ID: 1,
|
||||
BaseBranch: "baseBranch",
|
||||
@@ -265,9 +276,7 @@ func TestPullRequest_UpdateCols(t *testing.T) {
|
||||
|
||||
// TODO TestAddTestPullRequestTask
|
||||
|
||||
func TestPullRequest_IsWorkInProgress(t *testing.T) {
|
||||
assert.NoError(t, unittest.PrepareTestDatabase())
|
||||
|
||||
func testPullRequestIsWorkInProgress(t *testing.T) {
|
||||
pr := unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{ID: 2})
|
||||
pr.LoadIssue(t.Context())
|
||||
|
||||
@@ -280,9 +289,7 @@ func TestPullRequest_IsWorkInProgress(t *testing.T) {
|
||||
assert.True(t, pr.IsWorkInProgress(t.Context()))
|
||||
}
|
||||
|
||||
func TestPullRequest_GetWorkInProgressPrefixWorkInProgress(t *testing.T) {
|
||||
assert.NoError(t, unittest.PrepareTestDatabase())
|
||||
|
||||
func testPullRequestGetWorkInProgressPrefixWorkInProgress(t *testing.T) {
|
||||
pr := unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{ID: 2})
|
||||
pr.LoadIssue(t.Context())
|
||||
|
||||
@@ -296,9 +303,7 @@ func TestPullRequest_GetWorkInProgressPrefixWorkInProgress(t *testing.T) {
|
||||
assert.Equal(t, "[wip]", pr.GetWorkInProgressPrefix(t.Context()))
|
||||
}
|
||||
|
||||
func TestDeleteOrphanedObjects(t *testing.T) {
|
||||
assert.NoError(t, unittest.PrepareTestDatabase())
|
||||
|
||||
func testDeleteOrphanedObjects(t *testing.T) {
|
||||
countBefore, err := db.GetEngine(t.Context()).Count(&issues_model.PullRequest{})
|
||||
assert.NoError(t, err)
|
||||
|
||||
@@ -317,7 +322,7 @@ func TestDeleteOrphanedObjects(t *testing.T) {
|
||||
assert.Equal(t, countBefore, countAfter)
|
||||
}
|
||||
|
||||
func TestParseCodeOwnersLine(t *testing.T) {
|
||||
func testParseCodeOwnersLine(t *testing.T) {
|
||||
type CodeOwnerTest struct {
|
||||
Line string
|
||||
Tokens []string
|
||||
@@ -331,6 +336,8 @@ func TestParseCodeOwnersLine(t *testing.T) {
|
||||
{Line: `docs/(aws|google|azure)/[^/]*\\.(md|txt) @org3 @org2/team2`, Tokens: []string{`docs/(aws|google|azure)/[^/]*\.(md|txt)`, "@org3", "@org2/team2"}},
|
||||
{Line: `\#path @org3`, Tokens: []string{`#path`, "@org3"}},
|
||||
{Line: `path\ with\ spaces/ @org3`, Tokens: []string{`path with spaces/`, "@org3"}},
|
||||
{Line: `/docs/.*\\.md @user1`, Tokens: []string{`/docs/.*\.md`, "@user1"}},
|
||||
{Line: `!/assets/.*\\.(bin|exe|msi) @user1`, Tokens: []string{`!/assets/.*\.(bin|exe|msi)`, "@user1"}},
|
||||
}
|
||||
|
||||
for _, g := range given {
|
||||
@@ -339,8 +346,37 @@ func TestParseCodeOwnersLine(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetApprovers(t *testing.T) {
|
||||
assert.NoError(t, unittest.PrepareTestDatabase())
|
||||
func testCodeOwnerAbsolutePathPatterns(t *testing.T) {
|
||||
type testCase struct {
|
||||
content string
|
||||
file string
|
||||
expected bool
|
||||
}
|
||||
|
||||
cases := []testCase{
|
||||
// Absolute path pattern should match (leading "/" stripped)
|
||||
{content: "/README.md @user5\n", file: "README.md", expected: true},
|
||||
// Absolute path pattern in subdirectory
|
||||
{content: "/docs/.* @user5\n", file: "docs/foo.md", expected: true},
|
||||
// Absolute path should not match nested paths it shouldn't
|
||||
{content: "/docs/.* @user5\n", file: "other/docs/foo.md", expected: false},
|
||||
// Relative path still works
|
||||
{content: "README.md @user5\n", file: "README.md", expected: true},
|
||||
// Negated absolute path pattern
|
||||
{content: "!/.* @user5\n", file: "README.md", expected: false},
|
||||
}
|
||||
|
||||
for _, c := range cases {
|
||||
rules, _ := issues_model.GetCodeOwnersFromContent(t.Context(), c.content)
|
||||
require.NotEmpty(t, rules)
|
||||
rule := rules[0]
|
||||
regexpMatched, _ := rule.Rule.MatchString(c.file)
|
||||
ruleMatched := regexpMatched == !rule.Negative
|
||||
assert.Equal(t, c.expected, ruleMatched, "pattern %q against file %q", c.content, c.file)
|
||||
}
|
||||
}
|
||||
|
||||
func testGetApprovers(t *testing.T) {
|
||||
pr := unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{ID: 5})
|
||||
// Official reviews are already deduplicated. Allow unofficial reviews
|
||||
// to assert that there are no duplicated approvers.
|
||||
@@ -350,8 +386,7 @@ func TestGetApprovers(t *testing.T) {
|
||||
assert.Equal(t, expected, approvers)
|
||||
}
|
||||
|
||||
func TestGetPullRequestByMergedCommit(t *testing.T) {
|
||||
assert.NoError(t, unittest.PrepareTestDatabase())
|
||||
func testGetPullRequestByMergedCommit(t *testing.T) {
|
||||
pr, err := issues_model.GetPullRequestByMergedCommit(t.Context(), 1, "1a8823cd1a9549fde083f992f6b9b87a7ab74fb3")
|
||||
assert.NoError(t, err)
|
||||
assert.EqualValues(t, 1, pr.ID)
|
||||
@@ -362,8 +397,7 @@ func TestGetPullRequestByMergedCommit(t *testing.T) {
|
||||
assert.ErrorAs(t, err, &issues_model.ErrPullRequestNotExist{})
|
||||
}
|
||||
|
||||
func TestMigrate_InsertPullRequests(t *testing.T) {
|
||||
assert.NoError(t, unittest.PrepareTestDatabase())
|
||||
func testMigrateInsertPullRequests(t *testing.T) {
|
||||
reponame := "repo1"
|
||||
repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{Name: reponame})
|
||||
owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID})
|
||||
|
||||
@@ -8,10 +8,7 @@ import (
|
||||
"fmt"
|
||||
|
||||
"code.gitea.io/gitea/models/db"
|
||||
"code.gitea.io/gitea/models/perm"
|
||||
"code.gitea.io/gitea/models/unit"
|
||||
user_model "code.gitea.io/gitea/models/user"
|
||||
"code.gitea.io/gitea/modules/container"
|
||||
"code.gitea.io/gitea/modules/log"
|
||||
|
||||
"xorm.io/builder"
|
||||
@@ -129,49 +126,6 @@ func IsUserOrgOwner(ctx context.Context, users user_model.UserList, orgID int64)
|
||||
return results
|
||||
}
|
||||
|
||||
// GetOrgAssignees returns all users that have write access and can be assigned to issues
|
||||
// of the any repository in the organization.
|
||||
func GetOrgAssignees(ctx context.Context, orgID int64) (_ []*user_model.User, err error) {
|
||||
e := db.GetEngine(ctx)
|
||||
userIDs := make([]int64, 0, 10)
|
||||
if err = e.Table("access").
|
||||
Join("INNER", "repository", "`repository`.id = `access`.repo_id").
|
||||
Where("`repository`.owner_id = ? AND `access`.mode >= ?", orgID, perm.AccessModeWrite).
|
||||
Select("user_id").
|
||||
Find(&userIDs); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
additionalUserIDs := make([]int64, 0, 10)
|
||||
if err = e.Table("team_user").
|
||||
Join("INNER", "team_repo", "`team_repo`.team_id = `team_user`.team_id").
|
||||
Join("INNER", "team_unit", "`team_unit`.team_id = `team_user`.team_id").
|
||||
Join("INNER", "repository", "`repository`.id = `team_repo`.repo_id").
|
||||
Where("`repository`.owner_id = ? AND (`team_unit`.access_mode >= ? OR (`team_unit`.access_mode = ? AND `team_unit`.`type` = ?))",
|
||||
orgID, perm.AccessModeWrite, perm.AccessModeRead, unit.TypePullRequests).
|
||||
Distinct("`team_user`.uid").
|
||||
Select("`team_user`.uid").
|
||||
Find(&additionalUserIDs); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
uniqueUserIDs := make(container.Set[int64])
|
||||
uniqueUserIDs.AddMultiple(userIDs...)
|
||||
uniqueUserIDs.AddMultiple(additionalUserIDs...)
|
||||
|
||||
users := make([]*user_model.User, 0, len(uniqueUserIDs))
|
||||
if len(userIDs) > 0 {
|
||||
if err = e.In("id", uniqueUserIDs.Values()).
|
||||
Where(builder.Eq{"`user`.is_active": true}).
|
||||
OrderBy(user_model.GetOrderByName()).
|
||||
Find(&users); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
return users, nil
|
||||
}
|
||||
|
||||
func loadOrganizationOwners(ctx context.Context, users user_model.UserList, orgID int64) (map[int64]*TeamUser, error) {
|
||||
if len(users) == 0 {
|
||||
return nil, nil //nolint:nilnil // return nil when there are no users
|
||||
|
||||
@@ -52,13 +52,13 @@ func InsertProperty(ctx context.Context, refType PropertyType, refID int64, name
|
||||
// GetProperties gets all properties
|
||||
func GetProperties(ctx context.Context, refType PropertyType, refID int64) ([]*PackageProperty, error) {
|
||||
pps := make([]*PackageProperty, 0, 10)
|
||||
return pps, db.GetEngine(ctx).Where("ref_type = ? AND ref_id = ?", refType, refID).Find(&pps)
|
||||
return pps, db.GetEngine(ctx).Where("ref_type = ? AND ref_id = ?", refType, refID).OrderBy("id").Find(&pps)
|
||||
}
|
||||
|
||||
// GetPropertiesByName gets all properties with a specific name
|
||||
func GetPropertiesByName(ctx context.Context, refType PropertyType, refID int64, name string) ([]*PackageProperty, error) {
|
||||
pps := make([]*PackageProperty, 0, 10)
|
||||
return pps, db.GetEngine(ctx).Where("ref_type = ? AND ref_id = ? AND name = ?", refType, refID, name).Find(&pps)
|
||||
return pps, db.GetEngine(ctx).Where("ref_type = ? AND ref_id = ? AND name = ?", refType, refID, name).OrderBy("id").Find(&pps)
|
||||
}
|
||||
|
||||
// UpdateProperty updates a property
|
||||
|
||||
@@ -50,8 +50,8 @@ type RepoFileOptions struct {
|
||||
DeprecatedRepoName string // it is only a patch for the non-standard "markup" api
|
||||
DeprecatedOwnerName string // it is only a patch for the non-standard "markup" api
|
||||
|
||||
CurrentRefPath string // eg: "branch/main"
|
||||
CurrentTreePath string // eg: "path/to/file" in the repo
|
||||
CurrentRefPath string // eg: "branch/main", it is a sub URL path escaped by callers, TODO: rename to CurrentRefSubURL
|
||||
CurrentTreePath string // eg: "path/to/file" in the repo, it is the tree path without URL path escaping
|
||||
}
|
||||
|
||||
func NewRenderContextRepoFile(ctx context.Context, repo *repo_model.Repository, opts ...RepoFileOptions) *markup.RenderContext {
|
||||
@@ -70,6 +70,10 @@ func NewRenderContextRepoFile(ctx context.Context, repo *repo_model.Repository,
|
||||
"repo": helper.opts.DeprecatedRepoName,
|
||||
})
|
||||
}
|
||||
// External render's iframe needs this to generate correct links
|
||||
// TODO: maybe need to make it access "CurrentRefPath" directly (but impossible at the moment due to cycle-import)
|
||||
// CurrentRefPath is already path-escaped by callers
|
||||
rctx.RenderOptions.Metas["RefTypeNameSubURL"] = helper.opts.CurrentRefPath
|
||||
rctx = rctx.WithHelper(helper).WithEnableHeadingIDGeneration(true)
|
||||
return rctx
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@ import (
|
||||
"strings"
|
||||
|
||||
"code.gitea.io/gitea/models/db"
|
||||
"code.gitea.io/gitea/models/organization"
|
||||
"code.gitea.io/gitea/models/perm"
|
||||
"code.gitea.io/gitea/models/unit"
|
||||
user_model "code.gitea.io/gitea/models/user"
|
||||
@@ -94,8 +95,7 @@ func GetWatchedRepos(ctx context.Context, opts *WatchedReposOptions) ([]*Reposit
|
||||
return db.FindAndCount[Repository](ctx, opts)
|
||||
}
|
||||
|
||||
// GetRepoAssignees returns all users that have write access and can be assigned to issues
|
||||
// of the repository,
|
||||
// GetRepoAssignees returns all users that have write access and can be assigned to issues or pull-requests of the repository,
|
||||
func GetRepoAssignees(ctx context.Context, repo *Repository) (_ []*user_model.User, err error) {
|
||||
if err = repo.LoadOwner(ctx); err != nil {
|
||||
return nil, err
|
||||
@@ -114,15 +114,9 @@ func GetRepoAssignees(ctx context.Context, repo *Repository) (_ []*user_model.Us
|
||||
uniqueUserIDs.AddMultiple(userIDs...)
|
||||
|
||||
if repo.Owner.IsOrganization() {
|
||||
additionalUserIDs := make([]int64, 0, 10)
|
||||
if err = e.Table("team_user").
|
||||
Join("INNER", "team_repo", "`team_repo`.team_id = `team_user`.team_id").
|
||||
Join("INNER", "team_unit", "`team_unit`.team_id = `team_user`.team_id").
|
||||
Where("`team_repo`.repo_id = ? AND (`team_unit`.access_mode >= ? OR (`team_unit`.access_mode = ? AND `team_unit`.`type` = ?))",
|
||||
repo.ID, perm.AccessModeWrite, perm.AccessModeRead, unit.TypePullRequests).
|
||||
Distinct("`team_user`.uid").
|
||||
Select("`team_user`.uid").
|
||||
Find(&additionalUserIDs); err != nil {
|
||||
// issues and pull requests both need "assignee list"
|
||||
additionalUserIDs, err := organization.GetTeamUserIDsWithAccessToAnyRepoUnit(ctx, repo.OwnerID, repo.ID, perm.AccessModeRead, unit.TypeIssues, unit.TypePullRequests)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
uniqueUserIDs.AddMultiple(additionalUserIDs...)
|
||||
|
||||
@@ -6,7 +6,12 @@ package repo_test
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"code.gitea.io/gitea/models/db"
|
||||
"code.gitea.io/gitea/models/organization"
|
||||
perm_model "code.gitea.io/gitea/models/perm"
|
||||
access_model "code.gitea.io/gitea/models/perm/access"
|
||||
repo_model "code.gitea.io/gitea/models/repo"
|
||||
"code.gitea.io/gitea/models/unit"
|
||||
"code.gitea.io/gitea/models/unittest"
|
||||
user_model "code.gitea.io/gitea/models/user"
|
||||
|
||||
@@ -14,9 +19,14 @@ import (
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestRepoAssignees(t *testing.T) {
|
||||
assert.NoError(t, unittest.PrepareTestDatabase())
|
||||
func TestUserRepo(t *testing.T) {
|
||||
require.NoError(t, unittest.PrepareTestDatabase())
|
||||
t.Run("GetIssuePostersWithSearch", testUserRepoGetIssuePostersWithSearch)
|
||||
t.Run("Assignees", testUserRepoAssignees)
|
||||
t.Run("AssigneesNoTeamUnit", testRepoAssigneesNoTeamUnit)
|
||||
}
|
||||
|
||||
func testUserRepoAssignees(t *testing.T) {
|
||||
repo2 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 2})
|
||||
users, err := repo_model.GetRepoAssignees(t.Context(), repo2)
|
||||
assert.NoError(t, err)
|
||||
@@ -39,9 +49,29 @@ func TestRepoAssignees(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetIssuePostersWithSearch(t *testing.T) {
|
||||
assert.NoError(t, unittest.PrepareTestDatabase())
|
||||
func testRepoAssigneesNoTeamUnit(t *testing.T) {
|
||||
ctx := t.Context()
|
||||
|
||||
repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 32})
|
||||
require.NoError(t, repo.LoadOwner(ctx))
|
||||
require.True(t, repo.Owner.IsOrganization())
|
||||
|
||||
require.NoError(t, db.TruncateBeans(ctx, &organization.Team{}, &organization.TeamUser{}, &organization.TeamRepo{}, &organization.TeamUnit{}, &access_model.Access{}))
|
||||
|
||||
user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 4})
|
||||
team := &organization.Team{OrgID: repo.OwnerID, LowerName: "admin-team", AccessMode: perm_model.AccessModeAdmin}
|
||||
require.NoError(t, db.Insert(ctx, team))
|
||||
require.NoError(t, db.Insert(ctx, &organization.TeamUser{OrgID: repo.OwnerID, TeamID: team.ID, UID: user.ID}))
|
||||
require.NoError(t, db.Insert(ctx, &organization.TeamRepo{OrgID: repo.OwnerID, TeamID: team.ID, RepoID: repo.ID}))
|
||||
require.NoError(t, db.Insert(ctx, &organization.TeamUnit{OrgID: repo.OwnerID, TeamID: team.ID, Type: unit.TypePullRequests, AccessMode: perm_model.AccessModeNone}))
|
||||
|
||||
users, err := repo_model.GetRepoAssignees(ctx, repo)
|
||||
require.NoError(t, err)
|
||||
require.Len(t, users, 1)
|
||||
assert.ElementsMatch(t, []int64{4}, []int64{users[0].ID})
|
||||
}
|
||||
|
||||
func testUserRepoGetIssuePostersWithSearch(t *testing.T) {
|
||||
repo2 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 2})
|
||||
|
||||
users, err := repo_model.GetIssuePostersWithSearch(t.Context(), repo2, false, "USER")
|
||||
|
||||
@@ -0,0 +1,535 @@
|
||||
// Copyright 2026 The Gitea Authors. All rights reserved.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
package user
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"code.gitea.io/gitea/models/db"
|
||||
"code.gitea.io/gitea/modules/base"
|
||||
"code.gitea.io/gitea/modules/optional"
|
||||
|
||||
"xorm.io/builder"
|
||||
)
|
||||
|
||||
const (
|
||||
SettingsKeyAccountRequestStatus = "account_request.status"
|
||||
SettingsKeyAccountRequestExpiresUnix = "account_request.expires_unix"
|
||||
SettingsKeyAccountRequestSignupAttempts = "account_request.signup_attempts"
|
||||
SettingsKeyAccountRequestEmailValidatedUnix = "account_request.email_validated_unix"
|
||||
SettingsKeyAccountRequestReviewedUnix = "account_request.reviewed_unix"
|
||||
SettingsKeyAccountRequestReviewedBy = "account_request.reviewed_by"
|
||||
SettingsKeyAccountRequestValidationMailStatus = "account_request.validation_mail_status"
|
||||
SettingsKeyAccountRequestValidationMailUnix = "account_request.validation_mail_unix"
|
||||
SettingsKeyAccountRequestValidationResendHits = "account_request.validation_resend_hits"
|
||||
SettingsKeyAccountRequestValidationCodeHash = "account_request.validation_code_hash"
|
||||
SettingsKeyActivationMailStatus = "activation.mail_status"
|
||||
SettingsKeyActivationMailUnix = "activation.mail_unix"
|
||||
SettingsKeyActivationResendHits = "activation.resend_hits"
|
||||
SettingsKeyAdminInvitePending = "admin_invite.pending"
|
||||
SettingsKeyAdminInviteMailStatus = "admin_invite.mail_status"
|
||||
SettingsKeyAdminInviteMailUnix = "admin_invite.mail_unix"
|
||||
SettingsKeyAdminInviteResendHits = "admin_invite.resend_hits"
|
||||
|
||||
AccountRequestStatusPendingEmailValidation = "pending_email_validation"
|
||||
AccountRequestStatusPendingAdminReview = "pending_admin_review"
|
||||
AccountRequestStatusRejected = "rejected"
|
||||
AccountRequestStatusBlocked = "blocked"
|
||||
|
||||
AccountRequestValidationHours = 48
|
||||
AccountRequestMaxAttempts = 5
|
||||
AccountRequestMaxResendHits = 5
|
||||
ActivationMaxResendHits = 5
|
||||
AdminInviteMaxResendHits = 5
|
||||
|
||||
AccountRequestValidationMailStatusSucceeded = "succeeded"
|
||||
AccountRequestValidationMailStatusFailed = "failed"
|
||||
)
|
||||
|
||||
func GetAccountRequestStatus(ctx context.Context, user *User) (string, error) {
|
||||
status, err := GetUserSetting(ctx, user.ID, SettingsKeyAccountRequestStatus)
|
||||
if err != nil || status != "" {
|
||||
return status, err
|
||||
}
|
||||
hasValidationState, err := HasAccountRequestValidationState(ctx, user)
|
||||
if err != nil || !hasValidationState {
|
||||
return "", err
|
||||
}
|
||||
return AccountRequestStatusPendingEmailValidation, nil
|
||||
}
|
||||
|
||||
func SetAccountRequestStatus(ctx context.Context, userID int64, status string) error {
|
||||
if status == "" {
|
||||
return DeleteUserSetting(ctx, userID, SettingsKeyAccountRequestStatus)
|
||||
}
|
||||
return SetUserSetting(ctx, userID, SettingsKeyAccountRequestStatus, status)
|
||||
}
|
||||
|
||||
func HasAccountRequestValidationState(ctx context.Context, user *User) (bool, error) {
|
||||
if user == nil || user.IsActive {
|
||||
return false, nil
|
||||
}
|
||||
for _, key := range []string{
|
||||
SettingsKeyAccountRequestStatus,
|
||||
SettingsKeyAccountRequestExpiresUnix,
|
||||
SettingsKeyAccountRequestValidationMailStatus,
|
||||
SettingsKeyAccountRequestValidationCodeHash,
|
||||
} {
|
||||
value, err := GetUserSetting(ctx, user.ID, key)
|
||||
if err != nil || value != "" {
|
||||
return value != "", err
|
||||
}
|
||||
}
|
||||
return false, nil
|
||||
}
|
||||
|
||||
func getAccountRequestInt64(ctx context.Context, userID int64, key string) (int64, error) {
|
||||
value, err := GetUserSetting(ctx, userID, key)
|
||||
if err != nil || value == "" {
|
||||
return 0, err
|
||||
}
|
||||
return strconv.ParseInt(value, 10, 64)
|
||||
}
|
||||
|
||||
func setAccountRequestInt64(ctx context.Context, userID int64, key string, value int64) error {
|
||||
if value == 0 {
|
||||
return DeleteUserSetting(ctx, userID, key)
|
||||
}
|
||||
return SetUserSetting(ctx, userID, key, strconv.FormatInt(value, 10))
|
||||
}
|
||||
|
||||
func GetAccountRequestExpiry(ctx context.Context, user *User) (time.Time, error) {
|
||||
unix, err := getAccountRequestInt64(ctx, user.ID, SettingsKeyAccountRequestExpiresUnix)
|
||||
if err != nil || unix == 0 {
|
||||
return time.Time{}, err
|
||||
}
|
||||
return time.Unix(unix, 0), nil
|
||||
}
|
||||
|
||||
func RefreshAccountRequestValidationWindow(ctx context.Context, user *User) error {
|
||||
return setAccountRequestInt64(ctx, user.ID, SettingsKeyAccountRequestExpiresUnix, time.Now().Add(AccountRequestValidationHours*time.Hour).Unix())
|
||||
}
|
||||
|
||||
func GetAccountRequestSignupAttempts(ctx context.Context, user *User) (int, error) {
|
||||
value, err := getAccountRequestInt64(ctx, user.ID, SettingsKeyAccountRequestSignupAttempts)
|
||||
return int(value), err
|
||||
}
|
||||
|
||||
func SetAccountRequestSignupAttempts(ctx context.Context, userID int64, attempts int) error {
|
||||
return setAccountRequestInt64(ctx, userID, SettingsKeyAccountRequestSignupAttempts, int64(attempts))
|
||||
}
|
||||
|
||||
func GetAccountRequestValidationMailAttemptStatus(ctx context.Context, user *User) (string, error) {
|
||||
return GetUserSetting(ctx, user.ID, SettingsKeyAccountRequestValidationMailStatus)
|
||||
}
|
||||
|
||||
func GetAccountRequestValidationMailAttemptUnix(ctx context.Context, user *User) (int64, error) {
|
||||
return getAccountRequestInt64(ctx, user.ID, SettingsKeyAccountRequestValidationMailUnix)
|
||||
}
|
||||
|
||||
func GetAccountRequestValidationResendHits(ctx context.Context, user *User) (int, error) {
|
||||
value, err := getAccountRequestInt64(ctx, user.ID, SettingsKeyAccountRequestValidationResendHits)
|
||||
return int(value), err
|
||||
}
|
||||
|
||||
func SetAccountRequestValidationResendHits(ctx context.Context, userID int64, hits int) error {
|
||||
return setAccountRequestInt64(ctx, userID, SettingsKeyAccountRequestValidationResendHits, int64(hits))
|
||||
}
|
||||
|
||||
func SetAccountRequestValidationCode(ctx context.Context, userID int64, code string) error {
|
||||
if code == "" {
|
||||
return DeleteUserSetting(ctx, userID, SettingsKeyAccountRequestValidationCodeHash)
|
||||
}
|
||||
return SetUserSetting(ctx, userID, SettingsKeyAccountRequestValidationCodeHash, base.EncodeSha256(code))
|
||||
}
|
||||
|
||||
func IncrementAccountRequestValidationResendHits(ctx context.Context, user *User) (int, error) {
|
||||
hits, err := GetAccountRequestValidationResendHits(ctx, user)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
hits++
|
||||
if err := SetAccountRequestValidationResendHits(ctx, user.ID, hits); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return hits, nil
|
||||
}
|
||||
|
||||
func RecordAccountRequestValidationMailAttempt(ctx context.Context, userID int64, success bool) error {
|
||||
status := AccountRequestValidationMailStatusFailed
|
||||
if success {
|
||||
status = AccountRequestValidationMailStatusSucceeded
|
||||
}
|
||||
if err := SetUserSetting(ctx, userID, SettingsKeyAccountRequestValidationMailStatus, status); err != nil {
|
||||
return err
|
||||
}
|
||||
return setAccountRequestInt64(ctx, userID, SettingsKeyAccountRequestValidationMailUnix, time.Now().Unix())
|
||||
}
|
||||
|
||||
func GetActivationMailAttemptStatus(ctx context.Context, user *User) (string, error) {
|
||||
return GetUserSetting(ctx, user.ID, SettingsKeyActivationMailStatus)
|
||||
}
|
||||
|
||||
func GetActivationMailAttemptUnix(ctx context.Context, user *User) (int64, error) {
|
||||
return getAccountRequestInt64(ctx, user.ID, SettingsKeyActivationMailUnix)
|
||||
}
|
||||
|
||||
func GetActivationResendHits(ctx context.Context, user *User) (int, error) {
|
||||
value, err := getAccountRequestInt64(ctx, user.ID, SettingsKeyActivationResendHits)
|
||||
return int(value), err
|
||||
}
|
||||
|
||||
func SetActivationResendHits(ctx context.Context, userID int64, hits int) error {
|
||||
return setAccountRequestInt64(ctx, userID, SettingsKeyActivationResendHits, int64(hits))
|
||||
}
|
||||
|
||||
func IncrementActivationResendHits(ctx context.Context, user *User) (int, error) {
|
||||
hits, err := GetActivationResendHits(ctx, user)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
hits++
|
||||
if err := SetActivationResendHits(ctx, user.ID, hits); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return hits, nil
|
||||
}
|
||||
|
||||
func RecordActivationMailAttempt(ctx context.Context, userID int64, success bool) error {
|
||||
status := AccountRequestValidationMailStatusFailed
|
||||
if success {
|
||||
status = AccountRequestValidationMailStatusSucceeded
|
||||
}
|
||||
if err := SetUserSetting(ctx, userID, SettingsKeyActivationMailStatus, status); err != nil {
|
||||
return err
|
||||
}
|
||||
return setAccountRequestInt64(ctx, userID, SettingsKeyActivationMailUnix, time.Now().Unix())
|
||||
}
|
||||
|
||||
func SetAdminInvitePending(ctx context.Context, userID int64, pending bool) error {
|
||||
if !pending {
|
||||
return DeleteUserSetting(ctx, userID, SettingsKeyAdminInvitePending)
|
||||
}
|
||||
return SetUserSetting(ctx, userID, SettingsKeyAdminInvitePending, "true")
|
||||
}
|
||||
|
||||
func hasStoredAdminInviteCreator(ctx context.Context, userID int64) (bool, error) {
|
||||
for _, key := range []string{
|
||||
SettingsKeyAdminInviteCreatedBy,
|
||||
SettingsKeyAdminInviteCreatedByName,
|
||||
SettingsKeyAdminInviteCreatedByEmail,
|
||||
} {
|
||||
value, err := GetUserSetting(ctx, userID, key)
|
||||
if err == nil && value != "" {
|
||||
return true, nil
|
||||
}
|
||||
if err != nil && !IsErrUserSettingIsNotExist(err) {
|
||||
return false, err
|
||||
}
|
||||
}
|
||||
return false, nil
|
||||
}
|
||||
|
||||
func IsPendingAdminInvite(ctx context.Context, user *User) (bool, error) {
|
||||
if user == nil || user.IsActive {
|
||||
return false, nil
|
||||
}
|
||||
|
||||
pending, err := GetUserSetting(ctx, user.ID, SettingsKeyAdminInvitePending)
|
||||
if err == nil && pending == "true" {
|
||||
return true, nil
|
||||
}
|
||||
if err != nil && !IsErrUserSettingIsNotExist(err) {
|
||||
return false, err
|
||||
}
|
||||
if !user.ProhibitLogin {
|
||||
return false, nil
|
||||
}
|
||||
return hasStoredAdminInviteCreator(ctx, user.ID)
|
||||
}
|
||||
|
||||
func GetAdminInviteMailAttemptStatus(ctx context.Context, user *User) (string, error) {
|
||||
return GetUserSetting(ctx, user.ID, SettingsKeyAdminInviteMailStatus)
|
||||
}
|
||||
|
||||
func GetAdminInviteMailAttemptUnix(ctx context.Context, user *User) (int64, error) {
|
||||
return getAccountRequestInt64(ctx, user.ID, SettingsKeyAdminInviteMailUnix)
|
||||
}
|
||||
|
||||
func GetAdminInviteResendHits(ctx context.Context, user *User) (int, error) {
|
||||
value, err := getAccountRequestInt64(ctx, user.ID, SettingsKeyAdminInviteResendHits)
|
||||
return int(value), err
|
||||
}
|
||||
|
||||
func SetAdminInviteResendHits(ctx context.Context, userID int64, hits int) error {
|
||||
return setAccountRequestInt64(ctx, userID, SettingsKeyAdminInviteResendHits, int64(hits))
|
||||
}
|
||||
|
||||
func IncrementAdminInviteResendHits(ctx context.Context, user *User) (int, error) {
|
||||
hits, err := GetAdminInviteResendHits(ctx, user)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
hits++
|
||||
if err := SetAdminInviteResendHits(ctx, user.ID, hits); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return hits, nil
|
||||
}
|
||||
|
||||
func RecordAdminInviteMailAttempt(ctx context.Context, userID int64, success bool) error {
|
||||
status := AccountRequestValidationMailStatusFailed
|
||||
if success {
|
||||
status = AccountRequestValidationMailStatusSucceeded
|
||||
}
|
||||
if err := SetUserSetting(ctx, userID, SettingsKeyAdminInviteMailStatus, status); err != nil {
|
||||
return err
|
||||
}
|
||||
return setAccountRequestInt64(ctx, userID, SettingsKeyAdminInviteMailUnix, time.Now().Unix())
|
||||
}
|
||||
|
||||
func ClearAdminInviteState(ctx context.Context, userID int64) error {
|
||||
for _, key := range []string{
|
||||
SettingsKeyAdminInvitePending,
|
||||
SettingsKeyAdminInviteMailStatus,
|
||||
SettingsKeyAdminInviteMailUnix,
|
||||
SettingsKeyAdminInviteResendHits,
|
||||
} {
|
||||
if err := DeleteUserSetting(ctx, userID, key); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func ClearActivationResendState(ctx context.Context, userID int64) error {
|
||||
for _, key := range []string{
|
||||
SettingsKeyActivationMailStatus,
|
||||
SettingsKeyActivationMailUnix,
|
||||
SettingsKeyActivationResendHits,
|
||||
} {
|
||||
if err := DeleteUserSetting(ctx, userID, key); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func IsAccountRequestExpired(ctx context.Context, user *User) (bool, error) {
|
||||
status, err := GetAccountRequestStatus(ctx, user)
|
||||
if err != nil || status != AccountRequestStatusPendingEmailValidation {
|
||||
return false, err
|
||||
}
|
||||
expiresAt, err := GetAccountRequestExpiry(ctx, user)
|
||||
if err != nil || expiresAt.IsZero() {
|
||||
return false, err
|
||||
}
|
||||
return time.Now().After(expiresAt), nil
|
||||
}
|
||||
|
||||
func ActivateAccountRequestPrimaryEmail(ctx context.Context, user *User) error {
|
||||
return db.WithTx(ctx, func(ctx context.Context) error {
|
||||
addr, exist, err := db.Get[EmailAddress](ctx, builder.Eq{"uid": user.ID, "lower_email": strings.ToLower(user.Email)})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if !exist {
|
||||
return fmt.Errorf("no such email: %d (%s)", user.ID, user.Email)
|
||||
}
|
||||
if addr.IsActivated {
|
||||
return nil
|
||||
}
|
||||
return updateActivation(ctx, addr, true)
|
||||
})
|
||||
}
|
||||
|
||||
func ResetAccountRequestToPendingEmailValidation(ctx context.Context, user *User) error {
|
||||
if err := SetAccountRequestStatus(ctx, user.ID, AccountRequestStatusPendingEmailValidation); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := RefreshAccountRequestValidationWindow(ctx, user); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := SetAccountRequestSignupAttempts(ctx, user.ID, 1); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := SetAccountRequestValidationResendHits(ctx, user.ID, 0); err != nil {
|
||||
return err
|
||||
}
|
||||
_ = DeleteUserSetting(ctx, user.ID, SettingsKeyAccountRequestEmailValidatedUnix)
|
||||
_ = DeleteUserSetting(ctx, user.ID, SettingsKeyAccountRequestReviewedUnix)
|
||||
_ = DeleteUserSetting(ctx, user.ID, SettingsKeyAccountRequestReviewedBy)
|
||||
_ = DeleteUserSetting(ctx, user.ID, SettingsKeyAccountRequestValidationCodeHash)
|
||||
user.ProhibitLogin = false
|
||||
_, err := db.GetEngine(ctx).ID(user.ID).Cols("prohibit_login").Update(user)
|
||||
return err
|
||||
}
|
||||
|
||||
func IncrementAccountRequestSignupAttempts(ctx context.Context, user *User) (attempts int, blocked bool, _ error) {
|
||||
attempts, err := GetAccountRequestSignupAttempts(ctx, user)
|
||||
if err != nil {
|
||||
return 0, false, err
|
||||
}
|
||||
attempts++
|
||||
if err := SetAccountRequestSignupAttempts(ctx, user.ID, attempts); err != nil {
|
||||
return 0, false, err
|
||||
}
|
||||
if attempts < AccountRequestMaxAttempts {
|
||||
return attempts, false, nil
|
||||
}
|
||||
if err := SetAccountRequestStatus(ctx, user.ID, AccountRequestStatusBlocked); err != nil {
|
||||
return 0, false, err
|
||||
}
|
||||
user.ProhibitLogin = true
|
||||
_, err = db.GetEngine(ctx).ID(user.ID).Cols("prohibit_login").Update(user)
|
||||
return attempts, true, err
|
||||
}
|
||||
|
||||
func MarkAccountRequestPendingAdminReview(ctx context.Context, user *User) error {
|
||||
if err := ActivateAccountRequestPrimaryEmail(ctx, user); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := SetAccountRequestStatus(ctx, user.ID, AccountRequestStatusPendingAdminReview); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := setAccountRequestInt64(ctx, user.ID, SettingsKeyAccountRequestEmailValidatedUnix, time.Now().Unix()); err != nil {
|
||||
return err
|
||||
}
|
||||
_ = DeleteUserSetting(ctx, user.ID, SettingsKeyAccountRequestExpiresUnix)
|
||||
_ = DeleteUserSetting(ctx, user.ID, SettingsKeyAccountRequestValidationResendHits)
|
||||
_ = DeleteUserSetting(ctx, user.ID, SettingsKeyAccountRequestValidationCodeHash)
|
||||
return nil
|
||||
}
|
||||
|
||||
func RejectAccountRequest(ctx context.Context, user *User, reviewerID int64) error {
|
||||
if err := SetAccountRequestStatus(ctx, user.ID, AccountRequestStatusRejected); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := setAccountRequestInt64(ctx, user.ID, SettingsKeyAccountRequestReviewedUnix, time.Now().Unix()); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := setAccountRequestInt64(ctx, user.ID, SettingsKeyAccountRequestReviewedBy, reviewerID); err != nil {
|
||||
return err
|
||||
}
|
||||
user.ProhibitLogin = true
|
||||
_, err := db.GetEngine(ctx).ID(user.ID).Cols("prohibit_login").Update(user)
|
||||
return err
|
||||
}
|
||||
|
||||
func ApproveAccountRequest(ctx context.Context, user *User, reviewerID int64) error {
|
||||
if err := ActivateAccountRequestPrimaryEmail(ctx, user); err != nil {
|
||||
return err
|
||||
}
|
||||
var err error
|
||||
user.IsActive = true
|
||||
user.ProhibitLogin = false
|
||||
if user.Rands, err = GetUserSalt(); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := UpdateUserCols(ctx, user, "is_active", "prohibit_login", "rands"); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := setAccountRequestInt64(ctx, user.ID, SettingsKeyAccountRequestReviewedUnix, time.Now().Unix()); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := setAccountRequestInt64(ctx, user.ID, SettingsKeyAccountRequestReviewedBy, reviewerID); err != nil {
|
||||
return err
|
||||
}
|
||||
_ = DeleteUserSetting(ctx, user.ID, SettingsKeyAccountRequestStatus)
|
||||
_ = DeleteUserSetting(ctx, user.ID, SettingsKeyAccountRequestExpiresUnix)
|
||||
_ = DeleteUserSetting(ctx, user.ID, SettingsKeyAccountRequestSignupAttempts)
|
||||
_ = DeleteUserSetting(ctx, user.ID, SettingsKeyAccountRequestValidationResendHits)
|
||||
_ = DeleteUserSetting(ctx, user.ID, SettingsKeyAccountRequestValidationCodeHash)
|
||||
return nil
|
||||
}
|
||||
|
||||
func UnblockAccountRequest(ctx context.Context, user *User) error {
|
||||
return ResetAccountRequestToPendingEmailValidation(ctx, user)
|
||||
}
|
||||
|
||||
func GenerateAccountRequestValidationCode(user *User) string {
|
||||
data := makeTimeLimitCodeHashData(&TimeLimitCodeOptions{Purpose: TimeLimitCodeAccountRequest}, user)
|
||||
code := base.CreateTimeLimitCode(data, AccountRequestValidationHours*60, time.Now(), nil)
|
||||
code += hex.EncodeToString([]byte(user.LowerName))
|
||||
return code
|
||||
}
|
||||
|
||||
func VerifyAccountRequestValidationCode(ctx context.Context, code string) (user *User) {
|
||||
if user = GetVerifyUser(ctx, code); user != nil {
|
||||
prefix := code[:base.TimeLimitCodeLength]
|
||||
hasValidationState, err := HasAccountRequestValidationState(ctx, user)
|
||||
if err != nil || !hasValidationState {
|
||||
return nil
|
||||
}
|
||||
for _, purpose := range []TimeLimitCodePurpose{TimeLimitCodeAccountRequest, TimeLimitCodeActivateAccount} {
|
||||
data := makeTimeLimitCodeHashData(&TimeLimitCodeOptions{Purpose: purpose}, user)
|
||||
if base.VerifyTimeLimitCode(time.Now(), data, AccountRequestValidationHours*60, prefix) {
|
||||
return user
|
||||
}
|
||||
}
|
||||
storedHash, err := GetUserSetting(ctx, user.ID, SettingsKeyAccountRequestValidationCodeHash)
|
||||
if err == nil && storedHash != "" && storedHash == base.EncodeSha256(code) {
|
||||
return user
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func GetUserByAnyEmail(ctx context.Context, email string) (*User, error) {
|
||||
email = strings.TrimSpace(email)
|
||||
if err := validateEmailBasic(email); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
addr := &EmailAddress{LowerEmail: strings.ToLower(email)}
|
||||
has, err := db.GetEngine(ctx).Get(addr)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if !has {
|
||||
return nil, ErrUserNotExist{Name: email}
|
||||
}
|
||||
return GetUserByID(ctx, addr.UID)
|
||||
}
|
||||
|
||||
func DeleteExpiredPendingAccountRequests(ctx context.Context) error {
|
||||
users, _, err := SearchUsers(ctx, SearchUserOptions{
|
||||
Types: []UserType{UserTypeIndividual, UserTypeUserReserved},
|
||||
IsActive: optional.Some(false),
|
||||
ListOptions: db.ListOptionsAll,
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for _, user := range users {
|
||||
status, err := GetAccountRequestStatus(ctx, user)
|
||||
if err != nil || status != AccountRequestStatusPendingEmailValidation {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
continue
|
||||
}
|
||||
expired, err := IsAccountRequestExpired(ctx, user)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if !expired {
|
||||
continue
|
||||
}
|
||||
if _, err := db.GetEngine(ctx).Where("uid=?", user.ID).Delete(&EmailAddress{}); err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err := db.GetEngine(ctx).Where("uid=?", user.ID).Delete(&Setting{}); err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err := db.GetEngine(ctx).ID(user.ID).Delete(&User{}); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -0,0 +1,95 @@
|
||||
// Copyright 2026 The Gitea Authors. All rights reserved.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
package user_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"code.gitea.io/gitea/models/unittest"
|
||||
user_model "code.gitea.io/gitea/models/user"
|
||||
"code.gitea.io/gitea/modules/setting"
|
||||
"code.gitea.io/gitea/modules/test"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestAccountRequestValidationCode(t *testing.T) {
|
||||
require.NoError(t, unittest.PrepareTestDatabase())
|
||||
defer test.MockVariableValue(&setting.Service.RegisterManualConfirm, true)()
|
||||
|
||||
user := &user_model.User{
|
||||
Name: "account-request-code-user",
|
||||
Email: "account-request-code-user@example.com",
|
||||
Passwd: "password",
|
||||
}
|
||||
require.NoError(t, user_model.CreateUser(t.Context(), user, &user_model.Meta{}))
|
||||
require.NoError(t, user_model.ResetAccountRequestToPendingEmailValidation(t.Context(), user))
|
||||
|
||||
code := user_model.GenerateAccountRequestValidationCode(user)
|
||||
verifiedUser := user_model.VerifyAccountRequestValidationCode(t.Context(), code)
|
||||
require.NotNil(t, verifiedUser)
|
||||
require.Equal(t, user.ID, verifiedUser.ID)
|
||||
}
|
||||
|
||||
func TestAccountRequestValidationCodeStoredFallback(t *testing.T) {
|
||||
require.NoError(t, unittest.PrepareTestDatabase())
|
||||
defer test.MockVariableValue(&setting.Service.RegisterManualConfirm, true)()
|
||||
|
||||
user := &user_model.User{
|
||||
Name: "account-request-stored-code-user",
|
||||
Email: "account-request-stored-code-user@example.com",
|
||||
Passwd: "password",
|
||||
}
|
||||
require.NoError(t, user_model.CreateUser(t.Context(), user, &user_model.Meta{}))
|
||||
require.NoError(t, user_model.ResetAccountRequestToPendingEmailValidation(t.Context(), user))
|
||||
|
||||
code := user_model.GenerateAccountRequestValidationCode(user)
|
||||
require.NoError(t, user_model.SetAccountRequestValidationCode(t.Context(), user.ID, code))
|
||||
|
||||
user.Rands = "changed-rands-after-email"
|
||||
require.NoError(t, user_model.UpdateUserCols(t.Context(), user, "rands"))
|
||||
|
||||
verifiedUser := user_model.VerifyAccountRequestValidationCode(t.Context(), code)
|
||||
require.NotNil(t, verifiedUser)
|
||||
require.Equal(t, user.ID, verifiedUser.ID)
|
||||
}
|
||||
|
||||
func TestAccountRequestValidationCodeMissingStatusFallback(t *testing.T) {
|
||||
require.NoError(t, unittest.PrepareTestDatabase())
|
||||
defer test.MockVariableValue(&setting.Service.RegisterManualConfirm, true)()
|
||||
|
||||
user := &user_model.User{
|
||||
Name: "account-request-missing-status-user",
|
||||
Email: "account-request-missing-status-user@example.com",
|
||||
Passwd: "password",
|
||||
}
|
||||
require.NoError(t, user_model.CreateUser(t.Context(), user, &user_model.Meta{}))
|
||||
require.NoError(t, user_model.ResetAccountRequestToPendingEmailValidation(t.Context(), user))
|
||||
require.NoError(t, user_model.DeleteUserSetting(t.Context(), user.ID, user_model.SettingsKeyAccountRequestStatus))
|
||||
|
||||
status, err := user_model.GetAccountRequestStatus(t.Context(), user)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, user_model.AccountRequestStatusPendingEmailValidation, status)
|
||||
|
||||
code := user_model.GenerateAccountRequestValidationCode(user)
|
||||
verifiedUser := user_model.VerifyAccountRequestValidationCode(t.Context(), code)
|
||||
require.NotNil(t, verifiedUser)
|
||||
require.Equal(t, user.ID, verifiedUser.ID)
|
||||
}
|
||||
|
||||
func TestAccountRequestValidationCodeIgnoresClassicActivation(t *testing.T) {
|
||||
require.NoError(t, unittest.PrepareTestDatabase())
|
||||
defer test.MockVariableValue(&setting.Service.RegisterEmailConfirm, true)()
|
||||
defer test.MockVariableValue(&setting.Service.RegisterManualConfirm, false)()
|
||||
|
||||
user := &user_model.User{
|
||||
Name: "classic-activation-user",
|
||||
Email: "classic-activation-user@example.com",
|
||||
Passwd: "password",
|
||||
}
|
||||
require.NoError(t, user_model.CreateUser(t.Context(), user, &user_model.Meta{}))
|
||||
|
||||
code := user_model.GenerateUserTimeLimitCode(&user_model.TimeLimitCodeOptions{Purpose: user_model.TimeLimitCodeActivateAccount}, user)
|
||||
require.Nil(t, user_model.VerifyAccountRequestValidationCode(t.Context(), code))
|
||||
}
|
||||
@@ -0,0 +1,106 @@
|
||||
// Copyright 2026 The Gitea Authors. All rights reserved.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
package user
|
||||
|
||||
import (
|
||||
"context"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
const BootstrapAdminActorName = "GOD"
|
||||
|
||||
func getUserSettingInt64(ctx context.Context, userID int64, key string) (int64, bool, error) {
|
||||
value, err := GetUserSetting(ctx, userID, key)
|
||||
if err != nil {
|
||||
if IsErrUserSettingIsNotExist(err) {
|
||||
return 0, false, nil
|
||||
}
|
||||
return 0, false, err
|
||||
}
|
||||
if value == "" {
|
||||
return 0, false, nil
|
||||
}
|
||||
parsed, err := strconv.ParseInt(value, 10, 64)
|
||||
if err != nil {
|
||||
return 0, false, err
|
||||
}
|
||||
return parsed, true, nil
|
||||
}
|
||||
|
||||
func GetAdminGrantorID(ctx context.Context, userID int64) (int64, bool, error) {
|
||||
return getUserSettingInt64(ctx, userID, SettingsKeyAdminGrantedBy)
|
||||
}
|
||||
|
||||
func GetSuperAdminGrantorID(ctx context.Context, userID int64) (int64, bool, error) {
|
||||
return getUserSettingInt64(ctx, userID, SettingsKeySuperAdminGrantedBy)
|
||||
}
|
||||
|
||||
func HasBootstrapAdminGrant(ctx context.Context, userID int64) (bool, error) {
|
||||
for _, key := range []string{SettingsKeyAdminGrantedByName, SettingsKeySuperAdminGrantedByName} {
|
||||
value, err := GetUserSetting(ctx, userID, key)
|
||||
if err != nil {
|
||||
if IsErrUserSettingIsNotExist(err) {
|
||||
continue
|
||||
}
|
||||
return false, err
|
||||
}
|
||||
if value == BootstrapAdminActorName {
|
||||
return true, nil
|
||||
}
|
||||
}
|
||||
return false, nil
|
||||
}
|
||||
|
||||
func IsGrantorOf(ctx context.Context, grantedUserID, possibleGrantorID int64) (bool, error) {
|
||||
for _, getter := range []func(context.Context, int64) (int64, bool, error){GetAdminGrantorID, GetSuperAdminGrantorID} {
|
||||
grantorID, has, err := getter(ctx, grantedUserID)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
if has && grantorID == possibleGrantorID {
|
||||
return true, nil
|
||||
}
|
||||
}
|
||||
return false, nil
|
||||
}
|
||||
|
||||
func IsEligibleAdminGrantor(ctx context.Context, userID int64) (bool, error) {
|
||||
u, err := GetUserByID(ctx, userID)
|
||||
if err != nil {
|
||||
if IsErrUserNotExist(err) {
|
||||
return false, nil
|
||||
}
|
||||
return false, err
|
||||
}
|
||||
return u.IsAdmin && u.IsActive && !u.ProhibitLogin, nil
|
||||
}
|
||||
|
||||
func GetEffectiveAdminGrantorID(ctx context.Context, userID int64) (int64, bool, error) {
|
||||
visited := map[int64]struct{}{userID: {}}
|
||||
currentUserID := userID
|
||||
|
||||
for {
|
||||
grantorID, has, err := GetAdminGrantorID(ctx, currentUserID)
|
||||
if err != nil {
|
||||
return 0, false, err
|
||||
}
|
||||
if !has {
|
||||
return 0, false, nil
|
||||
}
|
||||
if _, ok := visited[grantorID]; ok {
|
||||
return 0, false, nil
|
||||
}
|
||||
visited[grantorID] = struct{}{}
|
||||
|
||||
eligible, err := IsEligibleAdminGrantor(ctx, grantorID)
|
||||
if err != nil {
|
||||
return 0, false, err
|
||||
}
|
||||
if eligible {
|
||||
return grantorID, true, nil
|
||||
}
|
||||
|
||||
currentUserID = grantorID
|
||||
}
|
||||
}
|
||||
@@ -64,7 +64,7 @@ type GetBadgeUsersOptions struct {
|
||||
func GetBadgeUsers(ctx context.Context, opts *GetBadgeUsersOptions) ([]*User, int64, error) {
|
||||
sess := db.GetEngine(ctx).
|
||||
Select("`user`.*").
|
||||
Join("INNER", "user_badge", "`user_badge`.user_id=user.id").
|
||||
Join("INNER", "user_badge", "`user_badge`.user_id=`user`.id").
|
||||
Join("INNER", "badge", "`user_badge`.badge_id=badge.id").
|
||||
Where("badge.slug=?", opts.BadgeSlug)
|
||||
|
||||
|
||||
@@ -3,9 +3,22 @@
|
||||
|
||||
package user
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"code.gitea.io/gitea/models/db"
|
||||
"code.gitea.io/gitea/modules/optional"
|
||||
)
|
||||
|
||||
const (
|
||||
// SettingsKeyHiddenCommentTypes is the setting key for hidden comment types
|
||||
SettingsKeyHiddenCommentTypes = "issue.hidden_comment_types"
|
||||
// SettingsKeyPersistentFooter is the setting key for whether the footer remains visible in the viewport
|
||||
SettingsKeyPersistentFooter = "ui.persistent_footer"
|
||||
// SettingsKeyPersistentNavbar is the setting key for whether the navigation bar remains visible in the viewport
|
||||
SettingsKeyPersistentNavbar = "ui.persistent_navbar"
|
||||
// SettingsKeyStickySideMenus is the setting key for whether settings/admin side menus remain visible while scrolling
|
||||
SettingsKeyStickySideMenus = "ui.sticky_side_menus"
|
||||
// SettingsKeyDiffWhitespaceBehavior is the setting key for whitespace behavior of diff
|
||||
SettingsKeyDiffWhitespaceBehavior = "diff.whitespace_behaviour"
|
||||
// SettingsKeyShowOutdatedComments is the setting key whether or not to show outdated comments in PRs
|
||||
@@ -18,10 +31,101 @@ const (
|
||||
|
||||
SettingsKeyCodeViewShowFileTree = "code_view.show_file_tree"
|
||||
|
||||
SettingsKeyEmailNotificationGiteaActions = "email_notification.gitea_actions"
|
||||
SettingEmailNotificationGiteaActionsAll = "all"
|
||||
SettingEmailNotificationGiteaActionsFailureOnly = "failure-only" // Default for actions email preference
|
||||
SettingEmailNotificationGiteaActionsDisabled = "disabled"
|
||||
SettingsKeyEmailNotificationNewAccountRequests = "email_notification.new_account_requests"
|
||||
SettingEmailNotificationNewAccountRequestsEnabled = "enabled"
|
||||
SettingEmailNotificationNewAccountRequestsDisabled = "disabled"
|
||||
SettingsKeyEmailNotificationGiteaActions = "email_notification.gitea_actions"
|
||||
SettingEmailNotificationGiteaActionsAll = "all"
|
||||
SettingEmailNotificationGiteaActionsFailureOnly = "failure-only" // Default for actions email preference
|
||||
SettingEmailNotificationGiteaActionsDisabled = "disabled"
|
||||
|
||||
SettingsKeyActionsConfig = "actions.config"
|
||||
)
|
||||
|
||||
func GetEmailNotificationNewAccountRequestsPreference(ctx context.Context, user *User) (string, error) {
|
||||
def := SettingEmailNotificationNewAccountRequestsDisabled
|
||||
if user.IsAdmin {
|
||||
def = SettingEmailNotificationNewAccountRequestsEnabled
|
||||
}
|
||||
|
||||
return GetUserSetting(ctx, user.ID, SettingsKeyEmailNotificationNewAccountRequests, def)
|
||||
}
|
||||
|
||||
func IsEmailNotificationNewAccountRequestsEnabled(ctx context.Context, user *User) (bool, error) {
|
||||
preference, err := GetEmailNotificationNewAccountRequestsPreference(ctx, user)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
return preference == SettingEmailNotificationNewAccountRequestsEnabled, nil
|
||||
}
|
||||
|
||||
func CountAdminsWithNewAccountRequestNotificationsEnabled(ctx context.Context) (int, error) {
|
||||
admins, _, err := SearchUsers(ctx, SearchUserOptions{
|
||||
Types: []UserType{UserTypeIndividual},
|
||||
IsAdmin: optional.Some(true),
|
||||
IsActive: optional.Some(true),
|
||||
ListOptions: db.ListOptionsAll,
|
||||
})
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
count := 0
|
||||
for _, admin := range admins {
|
||||
enabled, err := IsEmailNotificationNewAccountRequestsEnabled(ctx, admin)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
if enabled {
|
||||
count++
|
||||
}
|
||||
}
|
||||
|
||||
return count, nil
|
||||
}
|
||||
|
||||
func IsLastAdminWithNewAccountRequestNotificationsEnabled(ctx context.Context, user *User) (bool, error) {
|
||||
if !user.IsAdmin || !user.IsActive {
|
||||
return false, nil
|
||||
}
|
||||
|
||||
enabled, err := IsEmailNotificationNewAccountRequestsEnabled(ctx, user)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
if !enabled {
|
||||
return false, nil
|
||||
}
|
||||
|
||||
count, err := CountAdminsWithNewAccountRequestNotificationsEnabled(ctx)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
return count <= 1, nil
|
||||
}
|
||||
|
||||
func ShouldEnableNewAccountRequestNotificationsFallback(ctx context.Context, actor, target *User) (bool, error) {
|
||||
if actor == nil || target == nil || actor.ID == target.ID {
|
||||
return false, nil
|
||||
}
|
||||
if !actor.IsAdmin || !actor.IsActive {
|
||||
return false, nil
|
||||
}
|
||||
|
||||
targetIsLastNotifier, err := IsLastAdminWithNewAccountRequestNotificationsEnabled(ctx, target)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
if !targetIsLastNotifier {
|
||||
return false, nil
|
||||
}
|
||||
|
||||
actorEnabled, err := IsEmailNotificationNewAccountRequestsEnabled(ctx, actor)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
return !actorEnabled, nil
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
package user_test
|
||||
|
||||
import (
|
||||
"strconv"
|
||||
"testing"
|
||||
|
||||
"code.gitea.io/gitea/models/unittest"
|
||||
@@ -57,3 +58,42 @@ func TestSettings(t *testing.T) {
|
||||
assert.NoError(t, err)
|
||||
assert.Empty(t, settings)
|
||||
}
|
||||
|
||||
func TestPersistentFooterSetting(t *testing.T) {
|
||||
assert.NoError(t, unittest.PrepareTestDatabase())
|
||||
|
||||
assert.NoError(t, user_model.SetUserSetting(t.Context(), 99, user_model.SettingsKeyPersistentFooter, "true"))
|
||||
|
||||
val, err := user_model.GetUserSetting(t.Context(), 99, user_model.SettingsKeyPersistentFooter, "false")
|
||||
assert.NoError(t, err)
|
||||
|
||||
enabled, err := strconv.ParseBool(val)
|
||||
assert.NoError(t, err)
|
||||
assert.True(t, enabled)
|
||||
}
|
||||
|
||||
func TestPersistentNavbarSetting(t *testing.T) {
|
||||
assert.NoError(t, unittest.PrepareTestDatabase())
|
||||
|
||||
assert.NoError(t, user_model.SetUserSetting(t.Context(), 99, user_model.SettingsKeyPersistentNavbar, "true"))
|
||||
|
||||
val, err := user_model.GetUserSetting(t.Context(), 99, user_model.SettingsKeyPersistentNavbar, "false")
|
||||
assert.NoError(t, err)
|
||||
|
||||
enabled, err := strconv.ParseBool(val)
|
||||
assert.NoError(t, err)
|
||||
assert.True(t, enabled)
|
||||
}
|
||||
|
||||
func TestStickySideMenusSetting(t *testing.T) {
|
||||
assert.NoError(t, unittest.PrepareTestDatabase())
|
||||
|
||||
assert.NoError(t, user_model.SetUserSetting(t.Context(), 99, user_model.SettingsKeyStickySideMenus, "true"))
|
||||
|
||||
val, err := user_model.GetUserSetting(t.Context(), 99, user_model.SettingsKeyStickySideMenus, "false")
|
||||
assert.NoError(t, err)
|
||||
|
||||
enabled, err := strconv.ParseBool(val)
|
||||
assert.NoError(t, err)
|
||||
assert.True(t, enabled)
|
||||
}
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
// Copyright 2026 The Gitea Authors. All rights reserved.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
package user_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"code.gitea.io/gitea/models/unittest"
|
||||
user_model "code.gitea.io/gitea/models/user"
|
||||
"code.gitea.io/gitea/modules/setting"
|
||||
"code.gitea.io/gitea/modules/test"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestResetPasswordTimeLimitCodeUsesResetPasswordLifetime(t *testing.T) {
|
||||
require.NoError(t, unittest.PrepareTestDatabase())
|
||||
defer test.MockVariableValue(&setting.Service.ActiveCodeLives, 0)()
|
||||
defer test.MockVariableValue(&setting.Service.ResetPwdCodeLives, 180)()
|
||||
|
||||
user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
|
||||
opts := &user_model.TimeLimitCodeOptions{Purpose: user_model.TimeLimitCodeResetPassword}
|
||||
code := user_model.GenerateUserTimeLimitCode(opts, user)
|
||||
|
||||
require.Equal(t, "000180", code[12:18])
|
||||
require.NotNil(t, user_model.VerifyUserTimeLimitCode(t.Context(), opts, code))
|
||||
}
|
||||
|
||||
func TestAdminInviteTimeLimitCodeUsesInvitationLifetime(t *testing.T) {
|
||||
require.NoError(t, unittest.PrepareTestDatabase())
|
||||
defer test.MockVariableValue(&setting.Service.ActiveCodeLives, 0)()
|
||||
|
||||
user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
|
||||
opts := &user_model.TimeLimitCodeOptions{Purpose: user_model.TimeLimitCodeAdminInvite}
|
||||
code := user_model.GenerateUserTimeLimitCode(opts, user)
|
||||
|
||||
require.Equal(t, "001440", code[12:18])
|
||||
require.NotNil(t, user_model.VerifyUserTimeLimitCode(t.Context(), opts, code))
|
||||
}
|
||||
+57
-3
@@ -819,7 +819,7 @@ func (err ErrDeleteLastAdminUser) Error() string {
|
||||
|
||||
// IsLastAdminUser check whether user is the last admin
|
||||
func IsLastAdminUser(ctx context.Context, user *User) bool {
|
||||
if user.IsAdmin && CountUsers(ctx, &CountUserFilter{IsAdmin: optional.Some(true)}) <= 1 {
|
||||
if user.IsAdmin && user.IsActive && CountUsers(ctx, &CountUserFilter{IsAdmin: optional.Some(true), IsActive: optional.Some(true)}) <= 1 {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
@@ -900,8 +900,52 @@ type TimeLimitCodePurpose string
|
||||
|
||||
const (
|
||||
TimeLimitCodeActivateAccount TimeLimitCodePurpose = "activate_account"
|
||||
TimeLimitCodeAccountRequest TimeLimitCodePurpose = "account_request"
|
||||
TimeLimitCodeActivateEmail TimeLimitCodePurpose = "activate_email"
|
||||
TimeLimitCodeResetPassword TimeLimitCodePurpose = "reset_password"
|
||||
TimeLimitCodeAdminAccess TimeLimitCodePurpose = "admin_access"
|
||||
TimeLimitCodeAdminInvite TimeLimitCodePurpose = "admin_invite"
|
||||
)
|
||||
|
||||
const AdminInviteCodeLives = 24 * 60
|
||||
|
||||
const (
|
||||
SettingsKeyAdminInviteCreatedBy = "admin_invite.created_by"
|
||||
SettingsKeyAdminInviteCreatedByName = "admin_invite.created_by_name"
|
||||
SettingsKeyAdminInviteCreatedByEmail = "admin_invite.created_by_email"
|
||||
SettingsKeyAdminGrantedUnix = "admin_grant.granted_unix"
|
||||
SettingsKeyAdminGrantedBy = "admin_grant.granted_by"
|
||||
SettingsKeyAdminGrantedByName = "admin_grant.granted_by_name"
|
||||
SettingsKeyAdminGrantedByEmail = "admin_grant.granted_by_email"
|
||||
SettingsKeyAdminGrantedReason = "admin_grant.reason"
|
||||
SettingsKeyAdminActivatedBy = "admin_activation.activated_by"
|
||||
SettingsKeyAdminActivatedByName = "admin_activation.activated_by_name"
|
||||
SettingsKeyAdminActivatedByEmail = "admin_activation.activated_by_email"
|
||||
SettingsKeyAdminDeactivatedUnix = "admin_deactivation.deactivated_unix"
|
||||
SettingsKeyAdminDeactivatedBy = "admin_deactivation.deactivated_by"
|
||||
SettingsKeyAdminDeactivatedByName = "admin_deactivation.deactivated_by_name"
|
||||
SettingsKeyAdminDeactivatedByEmail = "admin_deactivation.deactivated_by_email"
|
||||
SettingsKeyAdminDeactivatedReason = "admin_deactivation.reason"
|
||||
SettingsKeyAdminProhibitLoginUnix = "admin_prohibit_login.prohibited_unix"
|
||||
SettingsKeyAdminProhibitLoginBy = "admin_prohibit_login.prohibited_by"
|
||||
SettingsKeyAdminProhibitLoginByName = "admin_prohibit_login.prohibited_by_name"
|
||||
SettingsKeyAdminProhibitLoginByEmail = "admin_prohibit_login.prohibited_by_email"
|
||||
SettingsKeyAdminProhibitLoginReason = "admin_prohibit_login.reason"
|
||||
SettingsKeyAdminRestrictedUnix = "admin_restriction.restricted_unix"
|
||||
SettingsKeyAdminRestrictedBy = "admin_restriction.restricted_by"
|
||||
SettingsKeyAdminRestrictedByName = "admin_restriction.restricted_by_name"
|
||||
SettingsKeyAdminRestrictedByEmail = "admin_restriction.restricted_by_email"
|
||||
SettingsKeyAdminRestrictedReason = "admin_restriction.reason"
|
||||
SettingsKeySuperAdminEnabled = "super_admin.enabled"
|
||||
SettingsKeySuperAdminGrantedUnix = "super_admin.granted_unix"
|
||||
SettingsKeySuperAdminGrantedBy = "super_admin.granted_by"
|
||||
SettingsKeySuperAdminGrantedByName = "super_admin.granted_by_name"
|
||||
SettingsKeySuperAdminGrantedByEmail = "super_admin.granted_by_email"
|
||||
SettingsKeySuperAdminRevokedUnix = "super_admin.revoked_unix"
|
||||
SettingsKeySuperAdminRevokedBy = "super_admin.revoked_by"
|
||||
SettingsKeySuperAdminRevokedByName = "super_admin.revoked_by_name"
|
||||
SettingsKeySuperAdminRevokedByEmail = "super_admin.revoked_by_email"
|
||||
SettingsKeySuperAdminRevokedReason = "super_admin.revoked_reason"
|
||||
)
|
||||
|
||||
type TimeLimitCodeOptions struct {
|
||||
@@ -913,11 +957,21 @@ func makeTimeLimitCodeHashData(opts *TimeLimitCodeOptions, u *User) string {
|
||||
return fmt.Sprintf("%s|%d|%s|%s|%s|%s", opts.Purpose, u.ID, strings.ToLower(util.IfZero(opts.NewEmail, u.Email)), u.LowerName, u.Passwd, u.Rands)
|
||||
}
|
||||
|
||||
func timeLimitCodeLives(opts *TimeLimitCodeOptions) int {
|
||||
if opts.Purpose == TimeLimitCodeResetPassword || opts.Purpose == TimeLimitCodeAdminAccess {
|
||||
return setting.Service.ResetPwdCodeLives
|
||||
}
|
||||
if opts.Purpose == TimeLimitCodeAdminInvite {
|
||||
return AdminInviteCodeLives
|
||||
}
|
||||
return setting.Service.ActiveCodeLives
|
||||
}
|
||||
|
||||
// GenerateUserTimeLimitCode generates a time-limit code based on user information and given e-mail.
|
||||
// TODO: need to use cache or db to store it to make sure a code can only be consumed once
|
||||
func GenerateUserTimeLimitCode(opts *TimeLimitCodeOptions, u *User) string {
|
||||
data := makeTimeLimitCodeHashData(opts, u)
|
||||
code := base.CreateTimeLimitCode(data, setting.Service.ActiveCodeLives, time.Now(), nil)
|
||||
code := base.CreateTimeLimitCode(data, timeLimitCodeLives(opts), time.Now(), nil)
|
||||
code += hex.EncodeToString([]byte(u.LowerName)) // Add tail hex username
|
||||
return code
|
||||
}
|
||||
@@ -928,7 +982,7 @@ func VerifyUserTimeLimitCode(ctx context.Context, opts *TimeLimitCodeOptions, co
|
||||
// time limit code
|
||||
prefix := code[:base.TimeLimitCodeLength]
|
||||
data := makeTimeLimitCodeHashData(opts, user)
|
||||
if base.VerifyTimeLimitCode(time.Now(), data, setting.Service.ActiveCodeLives, prefix) {
|
||||
if base.VerifyTimeLimitCode(time.Now(), data, timeLimitCodeLives(opts), prefix) {
|
||||
return user
|
||||
}
|
||||
}
|
||||
|
||||
@@ -103,10 +103,20 @@ func GetEventsFromContent(content []byte) ([]*jobparser.Event, error) {
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := ValidateWorkflowContent(content); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return events, nil
|
||||
}
|
||||
|
||||
// ValidateWorkflowContent catches structural errors (e.g. blank lines in run: | blocks)
|
||||
// that model.ReadWorkflow alone does not detect.
|
||||
func ValidateWorkflowContent(content []byte) error {
|
||||
_, err := jobparser.Parse(content)
|
||||
return err
|
||||
}
|
||||
|
||||
func DetectWorkflows(
|
||||
gitRepo *git.Repository,
|
||||
commit *git.Commit,
|
||||
|
||||
@@ -9,16 +9,26 @@ import (
|
||||
"code.gitea.io/gitea/modules/git"
|
||||
"code.gitea.io/gitea/modules/setting"
|
||||
api "code.gitea.io/gitea/modules/structs"
|
||||
"code.gitea.io/gitea/modules/test"
|
||||
webhook_module "code.gitea.io/gitea/modules/webhook"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func fullWorkflowContent(part string) []byte {
|
||||
return []byte(`
|
||||
name: test
|
||||
` + part + `
|
||||
jobs:
|
||||
test:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- run: echo hello
|
||||
`)
|
||||
}
|
||||
|
||||
func TestIsWorkflow(t *testing.T) {
|
||||
oldDirs := setting.Actions.WorkflowDirs
|
||||
defer func() {
|
||||
setting.Actions.WorkflowDirs = oldDirs
|
||||
}()
|
||||
defer test.MockVariableValue(&setting.Actions.WorkflowDirs)()
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
@@ -218,7 +228,7 @@ func TestDetectMatched(t *testing.T) {
|
||||
|
||||
for _, tc := range testCases {
|
||||
t.Run(tc.desc, func(t *testing.T) {
|
||||
evts, err := GetEventsFromContent([]byte(tc.yamlOn))
|
||||
evts, err := GetEventsFromContent(fullWorkflowContent(tc.yamlOn))
|
||||
assert.NoError(t, err)
|
||||
assert.Len(t, evts, 1)
|
||||
assert.Equal(t, tc.expected, detectMatched(nil, tc.commit, tc.triggedEvent, tc.payload, evts[0]))
|
||||
@@ -373,7 +383,7 @@ func TestMatchIssuesEvent(t *testing.T) {
|
||||
|
||||
for _, tc := range testCases {
|
||||
t.Run(tc.desc, func(t *testing.T) {
|
||||
evts, err := GetEventsFromContent([]byte(tc.yamlOn))
|
||||
evts, err := GetEventsFromContent(fullWorkflowContent(tc.yamlOn))
|
||||
assert.NoError(t, err)
|
||||
assert.Len(t, evts, 1)
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
package dump
|
||||
|
||||
import (
|
||||
"archive/zip"
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
@@ -85,7 +86,7 @@ func NewDumper(ctx context.Context, format string, output io.Writer) (*Dumper, e
|
||||
var comp archives.ArchiverAsync
|
||||
switch format {
|
||||
case "zip":
|
||||
comp = archives.Zip{}
|
||||
comp = archives.Zip{Compression: zip.Deflate}
|
||||
case "tar":
|
||||
comp = archives.Tar{}
|
||||
case "tar.sz":
|
||||
|
||||
@@ -13,63 +13,45 @@ import (
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync/atomic"
|
||||
"time"
|
||||
|
||||
"code.gitea.io/gitea/modules/git/gitcmd"
|
||||
"code.gitea.io/gitea/modules/log"
|
||||
"code.gitea.io/gitea/modules/util"
|
||||
)
|
||||
|
||||
var catFileBatchDebugWaitClose atomic.Int64
|
||||
|
||||
type catFileBatchCommunicator struct {
|
||||
closeFunc func(err error)
|
||||
closeFunc atomic.Pointer[func(err error)]
|
||||
reqWriter io.Writer
|
||||
respReader *bufio.Reader
|
||||
debugGitCmd *gitcmd.Command
|
||||
}
|
||||
|
||||
func (b *catFileBatchCommunicator) Close() {
|
||||
if b.closeFunc != nil {
|
||||
b.closeFunc(nil)
|
||||
b.closeFunc = nil
|
||||
func (b *catFileBatchCommunicator) Close(err ...error) {
|
||||
if fn := b.closeFunc.Swap(nil); fn != nil {
|
||||
(*fn)(util.OptionalArg(err))
|
||||
}
|
||||
}
|
||||
|
||||
// newCatFileBatch opens git cat-file --batch in the provided repo and returns a stdin pipe, a stdout reader and cancel function
|
||||
func newCatFileBatch(ctx context.Context, repoPath string, cmdCatFile *gitcmd.Command) (ret *catFileBatchCommunicator) {
|
||||
// newCatFileBatch opens git cat-file --batch/--batch-check/--batch-command command and prepares the stdin/stdout pipes for communication.
|
||||
func newCatFileBatch(ctx context.Context, repoPath string, cmdCatFile *gitcmd.Command) *catFileBatchCommunicator {
|
||||
ctx, ctxCancel := context.WithCancelCause(ctx)
|
||||
|
||||
// We often want to feed the commits in order into cat-file --batch, followed by their trees and subtrees as necessary.
|
||||
stdinWriter, stdoutReader, stdPipeClose := cmdCatFile.MakeStdinStdoutPipe()
|
||||
pipeClose := func() {
|
||||
if delay := catFileBatchDebugWaitClose.Load(); delay > 0 {
|
||||
time.Sleep(time.Duration(delay)) // for testing purpose only
|
||||
}
|
||||
stdPipeClose()
|
||||
}
|
||||
closeFunc := func(err error) {
|
||||
ctxCancel(err)
|
||||
pipeClose()
|
||||
}
|
||||
return newCatFileBatchWithCloseFunc(ctx, repoPath, cmdCatFile, stdinWriter, stdoutReader, closeFunc)
|
||||
}
|
||||
|
||||
func newCatFileBatchWithCloseFunc(ctx context.Context, repoPath string, cmdCatFile *gitcmd.Command,
|
||||
stdinWriter gitcmd.PipeWriter, stdoutReader gitcmd.PipeReader, closeFunc func(err error),
|
||||
) *catFileBatchCommunicator {
|
||||
ret := &catFileBatchCommunicator{
|
||||
debugGitCmd: cmdCatFile,
|
||||
closeFunc: closeFunc,
|
||||
reqWriter: stdinWriter,
|
||||
respReader: bufio.NewReaderSize(stdoutReader, 32*1024), // use a buffered reader for rich operations
|
||||
}
|
||||
ret.closeFunc.Store(new(func(err error) {
|
||||
ctxCancel(err)
|
||||
stdPipeClose()
|
||||
}))
|
||||
|
||||
err := cmdCatFile.WithDir(repoPath).StartWithStderr(ctx)
|
||||
if err != nil {
|
||||
log.Error("Unable to start git command %v: %v", cmdCatFile.LogString(), err)
|
||||
// ideally here it should return the error, but it would require refactoring all callers
|
||||
// so just return a dummy communicator that does nothing, almost the same behavior as before, not bad
|
||||
closeFunc(err)
|
||||
ret.Close(err)
|
||||
return ret
|
||||
}
|
||||
|
||||
@@ -78,12 +60,33 @@ func newCatFileBatchWithCloseFunc(ctx context.Context, repoPath string, cmdCatFi
|
||||
if err != nil && !errors.Is(err, context.Canceled) {
|
||||
log.Error("cat-file --batch command failed in repo %s, error: %v", repoPath, err)
|
||||
}
|
||||
closeFunc(err)
|
||||
ret.Close(err)
|
||||
}()
|
||||
|
||||
return ret
|
||||
}
|
||||
|
||||
func (b *catFileBatchCommunicator) debugKill() (ret struct {
|
||||
beforeClose chan struct{}
|
||||
blockClose chan struct{}
|
||||
afterClose chan struct{}
|
||||
},
|
||||
) {
|
||||
ret.beforeClose = make(chan struct{})
|
||||
ret.blockClose = make(chan struct{})
|
||||
ret.afterClose = make(chan struct{})
|
||||
oldCloseFunc := b.closeFunc.Load()
|
||||
b.closeFunc.Store(new(func(err error) {
|
||||
b.closeFunc.Store(nil)
|
||||
close(ret.beforeClose)
|
||||
<-ret.blockClose
|
||||
(*oldCloseFunc)(err)
|
||||
close(ret.afterClose)
|
||||
}))
|
||||
b.debugGitCmd.DebugKill()
|
||||
return ret
|
||||
}
|
||||
|
||||
// catFileBatchParseInfoLine reads the header line from cat-file --batch
|
||||
// We expect: <oid> SP <type> SP <size> LF
|
||||
// then leaving the rest of the stream "<contents> LF" to be read
|
||||
|
||||
@@ -7,9 +7,7 @@ import (
|
||||
"io"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"sync"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"code.gitea.io/gitea/modules/test"
|
||||
|
||||
@@ -39,13 +37,22 @@ func testCatFileBatch(t *testing.T) {
|
||||
require.Error(t, err)
|
||||
})
|
||||
|
||||
simulateQueryTerminated := func(pipeCloseDelay, pipeReadDelay time.Duration) (errRead error) {
|
||||
catFileBatchDebugWaitClose.Store(int64(pipeCloseDelay))
|
||||
defer catFileBatchDebugWaitClose.Store(0)
|
||||
simulateQueryTerminated := func(t *testing.T, errBeforePipeClose, errAfterPipeClose error) {
|
||||
readError := func(t *testing.T, r io.Reader, expectedErr error) {
|
||||
if expectedErr == nil {
|
||||
return // expectedErr == nil means this read should be skipped
|
||||
}
|
||||
n, err := r.Read(make([]byte, 100))
|
||||
assert.Zero(t, n)
|
||||
assert.ErrorIs(t, err, expectedErr)
|
||||
}
|
||||
|
||||
batch, err := NewBatch(t.Context(), filepath.Join(testReposDir, "repo1_bare"))
|
||||
require.NoError(t, err)
|
||||
defer batch.Close()
|
||||
_, _ = batch.QueryInfo("e2129701f1a4d54dc44f03c93bca0a2aec7c5449")
|
||||
_, err = batch.QueryInfo("e2129701f1a4d54dc44f03c93bca0a2aec7c5449")
|
||||
require.NoError(t, err)
|
||||
|
||||
var c *catFileBatchCommunicator
|
||||
switch b := batch.(type) {
|
||||
case *catFileBatchLegacy:
|
||||
@@ -58,24 +65,18 @@ func testCatFileBatch(t *testing.T) {
|
||||
t.FailNow()
|
||||
}
|
||||
|
||||
wg := sync.WaitGroup{}
|
||||
wg.Go(func() {
|
||||
time.Sleep(pipeReadDelay)
|
||||
var n int
|
||||
n, errRead = c.respReader.Read(make([]byte, 100))
|
||||
assert.Zero(t, n)
|
||||
})
|
||||
time.Sleep(10 * time.Millisecond)
|
||||
c.debugGitCmd.DebugKill()
|
||||
wg.Wait()
|
||||
return errRead
|
||||
}
|
||||
require.NotEqual(t, errBeforePipeClose == nil, errAfterPipeClose == nil, "must set exactly one of the expected errors")
|
||||
|
||||
inceptor := c.debugKill()
|
||||
<-inceptor.beforeClose // wait for the command's Close to be called, the pipe is not closed yet
|
||||
readError(t, c.respReader, errBeforePipeClose) // then caller will read on an open pipe which will be closed soon
|
||||
close(inceptor.blockClose) // continue to close the pipe
|
||||
<-inceptor.afterClose // wait for the pipe to be closed
|
||||
readError(t, c.respReader, errAfterPipeClose) // then caller will read on a closed pipe
|
||||
}
|
||||
t.Run("QueryTerminated", func(t *testing.T) {
|
||||
err := simulateQueryTerminated(0, 20*time.Millisecond)
|
||||
assert.ErrorIs(t, err, os.ErrClosed) // pipes are closed faster
|
||||
err = simulateQueryTerminated(40*time.Millisecond, 20*time.Millisecond)
|
||||
assert.ErrorIs(t, err, io.EOF) // reader is faster
|
||||
simulateQueryTerminated(t, io.EOF, nil) // reader is faster
|
||||
simulateQueryTerminated(t, nil, os.ErrClosed) // pipes are closed faster
|
||||
})
|
||||
|
||||
batch, err := NewBatch(t.Context(), filepath.Join(testReposDir, "repo1_bare"))
|
||||
|
||||
@@ -1,35 +0,0 @@
|
||||
// Copyright 2025 The Gitea Authors. All rights reserved.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
package json
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"io"
|
||||
|
||||
"github.com/goccy/go-json"
|
||||
)
|
||||
|
||||
var _ Interface = jsonGoccy{}
|
||||
|
||||
type jsonGoccy struct{}
|
||||
|
||||
func (jsonGoccy) Marshal(v any) ([]byte, error) {
|
||||
return json.Marshal(v)
|
||||
}
|
||||
|
||||
func (jsonGoccy) Unmarshal(data []byte, v any) error {
|
||||
return json.Unmarshal(data, v)
|
||||
}
|
||||
|
||||
func (jsonGoccy) NewEncoder(writer io.Writer) Encoder {
|
||||
return json.NewEncoder(writer)
|
||||
}
|
||||
|
||||
func (jsonGoccy) NewDecoder(reader io.Reader) Decoder {
|
||||
return json.NewDecoder(reader)
|
||||
}
|
||||
|
||||
func (jsonGoccy) Indent(dst *bytes.Buffer, src []byte, prefix, indent string) error {
|
||||
return json.Indent(dst, src, prefix, indent)
|
||||
}
|
||||
@@ -6,12 +6,12 @@
|
||||
package json
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"encoding/json" //nolint:depguard // this package wraps it
|
||||
"io"
|
||||
)
|
||||
|
||||
func getDefaultJSONHandler() Interface {
|
||||
return jsonGoccy{}
|
||||
return jsonV1{}
|
||||
}
|
||||
|
||||
func MarshalKeepOptionalEmpty(v any) ([]byte, error) {
|
||||
|
||||
Vendored
+27
-1
@@ -21,7 +21,33 @@ import (
|
||||
|
||||
// RegisterRenderers registers all supported third part renderers according settings
|
||||
func RegisterRenderers() {
|
||||
markup.RegisterRenderer(&openAPIRenderer{})
|
||||
markup.RegisterRenderer(&frontendRenderer{
|
||||
name: "openapi-swagger",
|
||||
patterns: []string{
|
||||
"openapi.yaml",
|
||||
"openapi.yml",
|
||||
"openapi.json",
|
||||
"swagger.yaml",
|
||||
"swagger.yml",
|
||||
"swagger.json",
|
||||
},
|
||||
})
|
||||
|
||||
markup.RegisterRenderer(&frontendRenderer{
|
||||
name: "viewer-3d",
|
||||
patterns: []string{
|
||||
// It needs more logic to make it overall right (render a text 3D model automatically):
|
||||
// we need to distinguish the ambiguous filename extensions.
|
||||
// For example: "*.amf, *.obj, *.off, *.step" might be or not be a 3D model file.
|
||||
// So when it is a text file, we can't assume that "we only render it by 3D plugin",
|
||||
// otherwise the end users would be impossible to view its real content when the file is not a 3D model.
|
||||
"*.3dm", "*.3ds", "*.3mf", "*.amf", "*.bim", "*.brep",
|
||||
"*.dae", "*.fbx", "*.fcstd", "*.glb", "*.gltf",
|
||||
"*.ifc", "*.igs", "*.iges", "*.stp", "*.step",
|
||||
"*.stl", "*.obj", "*.off", "*.ply", "*.wrl",
|
||||
},
|
||||
})
|
||||
|
||||
for _, renderer := range setting.ExternalMarkupRenderers {
|
||||
markup.RegisterRenderer(&Renderer{renderer})
|
||||
}
|
||||
|
||||
Vendored
+95
@@ -0,0 +1,95 @@
|
||||
// Copyright 2026 The Gitea Authors. All rights reserved.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
package external
|
||||
|
||||
import (
|
||||
"encoding/base64"
|
||||
"io"
|
||||
"unicode/utf8"
|
||||
|
||||
"code.gitea.io/gitea/modules/htmlutil"
|
||||
"code.gitea.io/gitea/modules/markup"
|
||||
"code.gitea.io/gitea/modules/public"
|
||||
"code.gitea.io/gitea/modules/setting"
|
||||
"code.gitea.io/gitea/modules/util"
|
||||
)
|
||||
|
||||
type frontendRenderer struct {
|
||||
name string
|
||||
patterns []string
|
||||
}
|
||||
|
||||
var (
|
||||
_ markup.PostProcessRenderer = (*frontendRenderer)(nil)
|
||||
_ markup.ExternalRenderer = (*frontendRenderer)(nil)
|
||||
)
|
||||
|
||||
func (p *frontendRenderer) Name() string {
|
||||
return p.name
|
||||
}
|
||||
|
||||
func (p *frontendRenderer) NeedPostProcess() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (p *frontendRenderer) FileNamePatterns() []string {
|
||||
// TODO: the file extensions are ambiguous, even if the file name matches, it doesn't mean that the file is a 3D model
|
||||
// There are some approaches to make it more accurate, but they are all complicated:
|
||||
// A. Make backend know everything (detect a file is a 3D model or not)
|
||||
// B. Let frontend renders to try render one by one
|
||||
//
|
||||
// If there would be more frontend renders in the future, we need to implement the "frontend" approach:
|
||||
// 1. Make backend or parent window collect the supported extensions of frontend renders (done: backend external render framework)
|
||||
// 2. If the current file matches any extension, start the general iframe embedded render (done: this renderer)
|
||||
// 3. The iframe window calls the frontend renders one by one (done: frontend external render)
|
||||
// 4. Report the render result to parent by postMessage (TODO: when needed)
|
||||
return p.patterns
|
||||
}
|
||||
|
||||
func (p *frontendRenderer) SanitizerRules() []setting.MarkupSanitizerRule {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (p *frontendRenderer) GetExternalRendererOptions() (ret markup.ExternalRendererOptions) {
|
||||
ret.SanitizerDisabled = true
|
||||
ret.DisplayInIframe = true
|
||||
ret.ContentSandbox = "allow-scripts allow-forms allow-modals allow-popups allow-downloads"
|
||||
return ret
|
||||
}
|
||||
|
||||
func (p *frontendRenderer) Render(ctx *markup.RenderContext, input io.Reader, output io.Writer) error {
|
||||
if ctx.RenderOptions.StandalonePageOptions == nil {
|
||||
opts := p.GetExternalRendererOptions()
|
||||
return markup.RenderIFrame(ctx, &opts, output)
|
||||
}
|
||||
|
||||
content, err := util.ReadWithLimit(input, int(setting.UI.MaxDisplayFileSize))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
contentEncoding, contentString := "text", util.UnsafeBytesToString(content)
|
||||
if !utf8.Valid(content) {
|
||||
contentEncoding = "base64"
|
||||
contentString = base64.StdEncoding.EncodeToString(content)
|
||||
}
|
||||
|
||||
_, err = htmlutil.HTMLPrintf(output,
|
||||
`<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<!-- external-render-helper will be injected here by the markup render -->
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
</head>
|
||||
<body>
|
||||
<div id="frontend-render-viewer" data-frontend-renders="%s" data-file-tree-path="%s"></div>
|
||||
<textarea id="frontend-render-data" data-content-encoding="%s" hidden>%s</textarea>
|
||||
<script nonce type="module" src="%s"></script>
|
||||
</body>
|
||||
</html>`,
|
||||
p.name, ctx.RenderOptions.RelativePath,
|
||||
contentEncoding, contentString,
|
||||
public.AssetURI("js/external-render-frontend.js"))
|
||||
return err
|
||||
}
|
||||
Vendored
-84
@@ -1,84 +0,0 @@
|
||||
// Copyright 2026 The Gitea Authors. All rights reserved.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
package external
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"html"
|
||||
"io"
|
||||
|
||||
"code.gitea.io/gitea/modules/markup"
|
||||
"code.gitea.io/gitea/modules/public"
|
||||
"code.gitea.io/gitea/modules/setting"
|
||||
"code.gitea.io/gitea/modules/util"
|
||||
)
|
||||
|
||||
type openAPIRenderer struct{}
|
||||
|
||||
var (
|
||||
_ markup.PostProcessRenderer = (*openAPIRenderer)(nil)
|
||||
_ markup.ExternalRenderer = (*openAPIRenderer)(nil)
|
||||
)
|
||||
|
||||
func (p *openAPIRenderer) Name() string {
|
||||
return "openapi"
|
||||
}
|
||||
|
||||
func (p *openAPIRenderer) NeedPostProcess() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (p *openAPIRenderer) FileNamePatterns() []string {
|
||||
return []string{
|
||||
"openapi.yaml",
|
||||
"openapi.yml",
|
||||
"openapi.json",
|
||||
"swagger.yaml",
|
||||
"swagger.yml",
|
||||
"swagger.json",
|
||||
}
|
||||
}
|
||||
|
||||
func (p *openAPIRenderer) SanitizerRules() []setting.MarkupSanitizerRule {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (p *openAPIRenderer) GetExternalRendererOptions() (ret markup.ExternalRendererOptions) {
|
||||
ret.SanitizerDisabled = true
|
||||
ret.DisplayInIframe = true
|
||||
ret.ContentSandbox = "allow-scripts allow-forms allow-modals allow-popups allow-downloads"
|
||||
return ret
|
||||
}
|
||||
|
||||
func (p *openAPIRenderer) Render(ctx *markup.RenderContext, input io.Reader, output io.Writer) error {
|
||||
if ctx.RenderOptions.StandalonePageOptions == nil {
|
||||
opts := p.GetExternalRendererOptions()
|
||||
return markup.RenderIFrame(ctx, &opts, output)
|
||||
}
|
||||
|
||||
content, err := util.ReadWithLimit(input, int(setting.UI.MaxDisplayFileSize))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// HINT: SWAGGER-OPENAPI-VIEWER: another place "templates/swagger/openapi-viewer.tmpl"
|
||||
_, err = io.WriteString(output, fmt.Sprintf(
|
||||
`<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<link rel="stylesheet" href="%s">
|
||||
</head>
|
||||
<body>
|
||||
<div id="swagger-ui"><textarea class="swagger-spec-content" data-spec-filename="%s">%s</textarea></div>
|
||||
<script type="module" src="%s"></script>
|
||||
</body>
|
||||
</html>`,
|
||||
public.AssetURI("css/swagger.css"),
|
||||
html.EscapeString(ctx.RenderOptions.RelativePath),
|
||||
html.EscapeString(util.UnsafeBytesToString(content)),
|
||||
public.AssetURI("js/swagger.js"),
|
||||
))
|
||||
return err
|
||||
}
|
||||
@@ -6,6 +6,7 @@ package markup
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"html/template"
|
||||
"io"
|
||||
@@ -43,7 +44,8 @@ type WebThemeInterface interface {
|
||||
}
|
||||
|
||||
type StandalonePageOptions struct {
|
||||
CurrentWebTheme WebThemeInterface
|
||||
CurrentWebTheme WebThemeInterface
|
||||
RenderQueryString string
|
||||
}
|
||||
|
||||
type RenderOptions struct {
|
||||
@@ -206,17 +208,23 @@ func RenderString(ctx *RenderContext, content string) (string, error) {
|
||||
}
|
||||
|
||||
func RenderIFrame(ctx *RenderContext, opts *ExternalRendererOptions, output io.Writer) error {
|
||||
ownerName, repoName := ctx.RenderOptions.Metas["user"], ctx.RenderOptions.Metas["repo"]
|
||||
refSubURL := ctx.RenderOptions.Metas["RefTypeNameSubURL"]
|
||||
if ownerName == "" || repoName == "" || refSubURL == "" {
|
||||
setting.PanicInDevOrTesting("RenderIFrame requires user, repo and RefTypeNameSubURL metas")
|
||||
return errors.New("RenderIFrame requires user, repo and RefTypeNameSubURL metas")
|
||||
}
|
||||
src := fmt.Sprintf("%s/%s/%s/render/%s/%s", setting.AppSubURL,
|
||||
url.PathEscape(ctx.RenderOptions.Metas["user"]),
|
||||
url.PathEscape(ctx.RenderOptions.Metas["repo"]),
|
||||
util.PathEscapeSegments(ctx.RenderOptions.Metas["RefTypeNameSubURL"]),
|
||||
url.PathEscape(ownerName),
|
||||
url.PathEscape(repoName),
|
||||
ctx.RenderOptions.Metas["RefTypeNameSubURL"],
|
||||
util.PathEscapeSegments(ctx.RenderOptions.RelativePath),
|
||||
)
|
||||
var extraAttrs template.HTML
|
||||
if opts.ContentSandbox != "" {
|
||||
extraAttrs = htmlutil.HTMLFormat(` sandbox="%s"`, opts.ContentSandbox)
|
||||
}
|
||||
_, err := htmlutil.HTMLPrintf(output, `<iframe data-src="%s" class="external-render-iframe"%s></iframe>`, src, extraAttrs)
|
||||
_, err := htmlutil.HTMLPrintf(output, `<iframe data-src="%s" data-global-init="initExternalRenderIframe" class="external-render-iframe"%s></iframe>`, src, extraAttrs)
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -228,7 +236,7 @@ func pipes() (io.ReadCloser, io.WriteCloser, func()) {
|
||||
}
|
||||
}
|
||||
|
||||
func getExternalRendererOptions(renderer Renderer) (ret ExternalRendererOptions, _ bool) {
|
||||
func GetExternalRendererOptions(renderer Renderer) (ret ExternalRendererOptions, _ bool) {
|
||||
if externalRender, ok := renderer.(ExternalRenderer); ok {
|
||||
return externalRender.GetExternalRendererOptions(), true
|
||||
}
|
||||
@@ -237,7 +245,7 @@ func getExternalRendererOptions(renderer Renderer) (ret ExternalRendererOptions,
|
||||
|
||||
func RenderWithRenderer(ctx *RenderContext, renderer Renderer, input io.Reader, output io.Writer) error {
|
||||
var extraHeadHTML template.HTML
|
||||
if extOpts, ok := getExternalRendererOptions(renderer); ok && extOpts.DisplayInIframe {
|
||||
if extOpts, ok := GetExternalRendererOptions(renderer); ok && extOpts.DisplayInIframe {
|
||||
if ctx.RenderOptions.StandalonePageOptions == nil {
|
||||
// for an external "DisplayInIFrame" render, it could only output its content in a standalone page
|
||||
// otherwise, a <iframe> should be outputted to embed the external rendered page
|
||||
@@ -248,7 +256,12 @@ func RenderWithRenderer(ctx *RenderContext, renderer Renderer, input io.Reader,
|
||||
extraLinkHref := ctx.RenderOptions.StandalonePageOptions.CurrentWebTheme.PublicAssetURI()
|
||||
// "<script>" must go before "<link>", to make Golang's http.DetectContentType() can still recognize the content as "text/html"
|
||||
// DO NOT use "type=module", the script must run as early as possible, to set up the environment in the iframe
|
||||
extraHeadHTML = htmlutil.HTMLFormat(`<script crossorigin src="%s"></script><link rel="stylesheet" href="%s">`, extraScriptSrc, extraLinkHref)
|
||||
extraHeadHTML = htmlutil.HTMLFormat(
|
||||
`<script nonce crossorigin src="%s" id="gitea-external-render-helper" data-render-query-string="%s"></script>`+
|
||||
`<link rel="stylesheet" href="%s">`,
|
||||
extraScriptSrc, ctx.RenderOptions.StandalonePageOptions.RenderQueryString,
|
||||
extraLinkHref,
|
||||
)
|
||||
}
|
||||
|
||||
ctx.usedByRender = true
|
||||
|
||||
@@ -24,8 +24,8 @@ func TestRenderIFrame(t *testing.T) {
|
||||
|
||||
// the value is read from config RENDER_CONTENT_SANDBOX, empty means "disabled"
|
||||
ret := render(ctx, ExternalRendererOptions{ContentSandbox: ""})
|
||||
assert.Equal(t, `<iframe data-src="/test-owner/test-repo/render/src/branch/master/tree-path" class="external-render-iframe"></iframe>`, ret)
|
||||
assert.Equal(t, `<iframe data-src="/test-owner/test-repo/render/src/branch/master/tree-path" data-global-init="initExternalRenderIframe" class="external-render-iframe"></iframe>`, ret)
|
||||
|
||||
ret = render(ctx, ExternalRendererOptions{ContentSandbox: "allow"})
|
||||
assert.Equal(t, `<iframe data-src="/test-owner/test-repo/render/src/branch/master/tree-path" class="external-render-iframe" sandbox="allow"></iframe>`, ret)
|
||||
assert.Equal(t, `<iframe data-src="/test-owner/test-repo/render/src/branch/master/tree-path" data-global-init="initExternalRenderIframe" class="external-render-iframe" sandbox="allow"></iframe>`, ret)
|
||||
}
|
||||
|
||||
@@ -47,6 +47,7 @@ type Metadata struct {
|
||||
Keywords []string `json:"keywords,omitempty"`
|
||||
RepositoryURL string `json:"repository_url,omitempty"`
|
||||
License string `json:"license,omitempty"`
|
||||
LicenseURL string `json:"license_url,omitempty"`
|
||||
Author Person `json:"author"`
|
||||
Manifests map[string]*Manifest `json:"manifests,omitempty"`
|
||||
}
|
||||
@@ -67,7 +68,8 @@ type SoftwareSourceCode struct {
|
||||
Keywords []string `json:"keywords,omitempty"`
|
||||
CodeRepository string `json:"codeRepository,omitempty"`
|
||||
License string `json:"license,omitempty"`
|
||||
Author Person `json:"author"`
|
||||
LicenseURL string `json:"licenseURL,omitempty"`
|
||||
Author *Person `json:"author,omitempty"`
|
||||
ProgrammingLanguage ProgrammingLanguage `json:"programmingLanguage"`
|
||||
RepositoryURLs []string `json:"repositoryURLs,omitempty"`
|
||||
}
|
||||
@@ -181,26 +183,31 @@ func ParsePackage(sr io.ReaderAt, size int64, mr io.Reader) (*Package, error) {
|
||||
if err := json.NewDecoder(mr).Decode(&ssc); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
p.Metadata.Description = ssc.Description
|
||||
p.Metadata.Keywords = ssc.Keywords
|
||||
p.Metadata.License = ssc.License
|
||||
author := Person{
|
||||
Name: ssc.Author.Name,
|
||||
GivenName: ssc.Author.GivenName,
|
||||
MiddleName: ssc.Author.MiddleName,
|
||||
FamilyName: ssc.Author.FamilyName,
|
||||
p.Metadata.LicenseURL = ssc.LicenseURL
|
||||
if ssc.Author != nil {
|
||||
author := Person{
|
||||
Name: ssc.Author.Name,
|
||||
GivenName: ssc.Author.GivenName,
|
||||
MiddleName: ssc.Author.MiddleName,
|
||||
FamilyName: ssc.Author.FamilyName,
|
||||
}
|
||||
// If Name is not provided, generate it from individual name components
|
||||
if author.Name == "" {
|
||||
author.Name = author.String()
|
||||
}
|
||||
p.Metadata.Author = author
|
||||
}
|
||||
// If Name is not provided, generate it from individual name components
|
||||
if author.Name == "" {
|
||||
author.Name = author.String()
|
||||
}
|
||||
p.Metadata.Author = author
|
||||
|
||||
p.Metadata.RepositoryURL = ssc.CodeRepository
|
||||
if !validation.IsValidURL(p.Metadata.RepositoryURL) {
|
||||
p.Metadata.RepositoryURL = ""
|
||||
}
|
||||
if !validation.IsValidURL(p.Metadata.LicenseURL) {
|
||||
p.Metadata.LicenseURL = ""
|
||||
}
|
||||
|
||||
p.RepositoryURLs = ssc.RepositoryURLs
|
||||
}
|
||||
|
||||
@@ -4,11 +4,12 @@
|
||||
package swift
|
||||
|
||||
import (
|
||||
"archive/zip"
|
||||
"bytes"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"code.gitea.io/gitea/modules/test"
|
||||
|
||||
"github.com/hashicorp/go-version"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
@@ -18,36 +19,24 @@ const (
|
||||
packageVersion = "1.0.1"
|
||||
packageDescription = "Package Description"
|
||||
packageRepositoryURL = "https://gitea.io/gitea/gitea"
|
||||
packageLicenseURL = "https://opensource.org/license/mit"
|
||||
packageAuthor = "KN4CK3R"
|
||||
packageLicense = "MIT"
|
||||
)
|
||||
|
||||
func TestParsePackage(t *testing.T) {
|
||||
createArchive := func(files map[string][]byte) *bytes.Reader {
|
||||
var buf bytes.Buffer
|
||||
zw := zip.NewWriter(&buf)
|
||||
for filename, content := range files {
|
||||
w, _ := zw.Create(filename)
|
||||
w.Write(content)
|
||||
}
|
||||
zw.Close()
|
||||
return bytes.NewReader(buf.Bytes())
|
||||
}
|
||||
|
||||
t.Run("MissingManifestFile", func(t *testing.T) {
|
||||
data := createArchive(map[string][]byte{"dummy.txt": {}})
|
||||
|
||||
p, err := ParsePackage(data, data.Size(), nil)
|
||||
data := test.WriteZipArchive(map[string]string{"dummy.txt": ""})
|
||||
p, err := ParsePackage(bytes.NewReader(data.Bytes()), int64(data.Len()), nil)
|
||||
assert.Nil(t, p)
|
||||
assert.ErrorIs(t, err, ErrMissingManifestFile)
|
||||
})
|
||||
|
||||
t.Run("ManifestFileTooLarge", func(t *testing.T) {
|
||||
data := createArchive(map[string][]byte{
|
||||
"Package.swift": make([]byte, maxManifestFileSize+1),
|
||||
data := test.WriteZipArchive(map[string]string{
|
||||
"Package.swift": strings.Repeat("a", maxManifestFileSize+1),
|
||||
})
|
||||
|
||||
p, err := ParsePackage(data, data.Size(), nil)
|
||||
p, err := ParsePackage(bytes.NewReader(data.Bytes()), int64(data.Len()), nil)
|
||||
assert.Nil(t, p)
|
||||
assert.ErrorIs(t, err, ErrManifestFileTooLarge)
|
||||
})
|
||||
@@ -56,12 +45,12 @@ func TestParsePackage(t *testing.T) {
|
||||
content1 := "// swift-tools-version:5.7\n//\n// Package.swift"
|
||||
content2 := "// swift-tools-version:5.6\n//\n// Package@swift-5.6.swift"
|
||||
|
||||
data := createArchive(map[string][]byte{
|
||||
"Package.swift": []byte(content1),
|
||||
"Package@swift-5.5.swift": []byte(content2),
|
||||
data := test.WriteZipArchive(map[string]string{
|
||||
"Package.swift": content1,
|
||||
"Package@swift-5.5.swift": content2,
|
||||
})
|
||||
|
||||
p, err := ParsePackage(data, data.Size(), nil)
|
||||
p, err := ParsePackage(bytes.NewReader(data.Bytes()), int64(data.Len()), nil)
|
||||
assert.NotNil(t, p)
|
||||
assert.NoError(t, err)
|
||||
|
||||
@@ -77,14 +66,13 @@ func TestParsePackage(t *testing.T) {
|
||||
})
|
||||
|
||||
t.Run("WithMetadata", func(t *testing.T) {
|
||||
data := createArchive(map[string][]byte{
|
||||
"Package.swift": []byte("// swift-tools-version:5.7\n//\n// Package.swift"),
|
||||
data := test.WriteZipArchive(map[string]string{
|
||||
"Package.swift": "// swift-tools-version:5.7\n//\n// Package.swift",
|
||||
})
|
||||
|
||||
p, err := ParsePackage(
|
||||
data,
|
||||
data.Size(),
|
||||
strings.NewReader(`{"name":"`+packageName+`","version":"`+packageVersion+`","description":"`+packageDescription+`","keywords":["swift","package"],"license":"`+packageLicense+`","codeRepository":"`+packageRepositoryURL+`","author":{"givenName":"`+packageAuthor+`"},"repositoryURLs":["`+packageRepositoryURL+`"]}`),
|
||||
bytes.NewReader(data.Bytes()), int64(data.Len()),
|
||||
strings.NewReader(`{"name":"`+packageName+`","version":"`+packageVersion+`","description":"`+packageDescription+`","keywords":["swift","package"],"license":"`+packageLicense+`","licenseURL":"`+packageLicenseURL+`","codeRepository":"`+packageRepositoryURL+`","author":{"givenName":"`+packageAuthor+`"},"repositoryURLs":["`+packageRepositoryURL+`"]}`),
|
||||
)
|
||||
assert.NotNil(t, p)
|
||||
assert.NoError(t, err)
|
||||
@@ -97,6 +85,7 @@ func TestParsePackage(t *testing.T) {
|
||||
assert.Equal(t, packageDescription, p.Metadata.Description)
|
||||
assert.ElementsMatch(t, []string{"swift", "package"}, p.Metadata.Keywords)
|
||||
assert.Equal(t, packageLicense, p.Metadata.License)
|
||||
assert.Equal(t, packageLicenseURL, p.Metadata.LicenseURL)
|
||||
assert.Equal(t, packageAuthor, p.Metadata.Author.Name)
|
||||
assert.Equal(t, packageAuthor, p.Metadata.Author.GivenName)
|
||||
assert.Equal(t, packageRepositoryURL, p.Metadata.RepositoryURL)
|
||||
@@ -104,14 +93,13 @@ func TestParsePackage(t *testing.T) {
|
||||
})
|
||||
|
||||
t.Run("WithExplicitNameField", func(t *testing.T) {
|
||||
data := createArchive(map[string][]byte{
|
||||
"Package.swift": []byte("// swift-tools-version:5.7\n//\n// Package.swift"),
|
||||
data := test.WriteZipArchive(map[string]string{
|
||||
"Package.swift": "// swift-tools-version:5.7\n//\n// Package.swift",
|
||||
})
|
||||
|
||||
authorName := "John Doe"
|
||||
p, err := ParsePackage(
|
||||
data,
|
||||
data.Size(),
|
||||
bytes.NewReader(data.Bytes()), int64(data.Len()),
|
||||
strings.NewReader(`{"name":"`+packageName+`","version":"`+packageVersion+`","description":"`+packageDescription+`","author":{"name":"`+authorName+`","givenName":"John","familyName":"Doe"}}`),
|
||||
)
|
||||
assert.NotNil(t, p)
|
||||
@@ -122,15 +110,30 @@ func TestParsePackage(t *testing.T) {
|
||||
assert.Equal(t, "Doe", p.Metadata.Author.FamilyName)
|
||||
})
|
||||
|
||||
t.Run("WithEmptyJSONMetadata", func(t *testing.T) {
|
||||
data := test.WriteZipArchive(map[string]string{
|
||||
"Package.swift": "// swift-tools-version:5.7\n//\n// Package.swift",
|
||||
})
|
||||
|
||||
p, err := ParsePackage(
|
||||
bytes.NewReader(data.Bytes()), int64(data.Len()),
|
||||
strings.NewReader(`{}`),
|
||||
)
|
||||
assert.NotNil(t, p)
|
||||
assert.NoError(t, err)
|
||||
assert.NotNil(t, p.Metadata)
|
||||
assert.Empty(t, p.Metadata.Author.Name)
|
||||
assert.Empty(t, p.RepositoryURLs)
|
||||
})
|
||||
|
||||
t.Run("NameFieldGeneration", func(t *testing.T) {
|
||||
data := createArchive(map[string][]byte{
|
||||
"Package.swift": []byte("// swift-tools-version:5.7\n//\n// Package.swift"),
|
||||
data := test.WriteZipArchive(map[string]string{
|
||||
"Package.swift": "// swift-tools-version:5.7\n//\n// Package.swift",
|
||||
})
|
||||
|
||||
// Test with only individual name components - Name should be auto-generated
|
||||
p, err := ParsePackage(
|
||||
data,
|
||||
data.Size(),
|
||||
bytes.NewReader(data.Bytes()), int64(data.Len()),
|
||||
strings.NewReader(`{"author":{"givenName":"John","middleName":"Q","familyName":"Doe"}}`),
|
||||
)
|
||||
assert.NotNil(t, p)
|
||||
|
||||
@@ -56,6 +56,8 @@ func parseManifest(data []byte) (map[string]string, map[string]string) {
|
||||
paths[key] = entry.File
|
||||
names[entry.File] = entry.Name
|
||||
// Map associated CSS files, e.g. "css/index.css" -> "css/index.B3zrQPqD.css"
|
||||
// FIXME: INCORRECT-VITE-MANIFEST-PARSER: the logic is wrong, Vite manifest doesn't work this way
|
||||
// It just happens to be correct for the current modules dependencies
|
||||
for _, css := range entry.CSS {
|
||||
cssKey := path.Dir(css) + "/" + entry.Name + path.Ext(css)
|
||||
paths[cssKey] = css
|
||||
|
||||
@@ -12,10 +12,29 @@ import (
|
||||
var Admin struct {
|
||||
DisableRegularOrgCreation bool
|
||||
DefaultEmailNotification string
|
||||
SuperAdminEnabled bool
|
||||
AdminManagementPolicy string
|
||||
UserDisabledFeatures container.Set[string]
|
||||
ExternalUserDisableFeatures container.Set[string]
|
||||
}
|
||||
|
||||
const (
|
||||
AdminManagementPolicySuperAdminOnly = "super_admin_only"
|
||||
AdminManagementPolicyGrantorOnly = "grantor_only"
|
||||
AdminManagementPolicyGrantorInheritance = "grantor_inheritance"
|
||||
AdminManagementPolicyAdminsCanPromote = "admins_can_promote_users"
|
||||
AdminManagementPolicySuperAdminApproval = "super_admin_approval"
|
||||
defaultAdminManagementPolicy = AdminManagementPolicyGrantorOnly
|
||||
)
|
||||
|
||||
var validAdminManagementPolicies = container.SetOf(
|
||||
AdminManagementPolicySuperAdminOnly,
|
||||
AdminManagementPolicyGrantorOnly,
|
||||
AdminManagementPolicyGrantorInheritance,
|
||||
AdminManagementPolicyAdminsCanPromote,
|
||||
AdminManagementPolicySuperAdminApproval,
|
||||
)
|
||||
|
||||
var validUserFeatures = container.SetOf(
|
||||
UserFeatureDeletion,
|
||||
UserFeatureManageSSHKeys,
|
||||
@@ -30,9 +49,16 @@ func loadAdminFrom(rootCfg ConfigProvider) {
|
||||
sec := rootCfg.Section("admin")
|
||||
Admin.DisableRegularOrgCreation = sec.Key("DISABLE_REGULAR_ORG_CREATION").MustBool(false)
|
||||
Admin.DefaultEmailNotification = sec.Key("DEFAULT_EMAIL_NOTIFICATIONS").MustString("enabled")
|
||||
Admin.SuperAdminEnabled = sec.Key("SUPER_ADMIN_ENABLED").MustBool(true)
|
||||
Admin.AdminManagementPolicy = normalizeAdminManagementPolicy(sec.Key("ADMIN_MANAGEMENT_POLICY").MustString(defaultAdminManagementPolicy))
|
||||
Admin.UserDisabledFeatures = container.SetOf(sec.Key("USER_DISABLED_FEATURES").Strings(",")...)
|
||||
Admin.ExternalUserDisableFeatures = container.SetOf(sec.Key("EXTERNAL_USER_DISABLE_FEATURES").Strings(",")...).Union(Admin.UserDisabledFeatures)
|
||||
|
||||
if !validAdminManagementPolicies.Contains(Admin.AdminManagementPolicy) {
|
||||
log.Warn("ADMIN_MANAGEMENT_POLICY contains unknown policy %q, using %q", Admin.AdminManagementPolicy, defaultAdminManagementPolicy)
|
||||
Admin.AdminManagementPolicy = defaultAdminManagementPolicy
|
||||
}
|
||||
|
||||
for feature := range Admin.UserDisabledFeatures {
|
||||
if !validUserFeatures.Contains(feature) {
|
||||
log.Warn("USER_DISABLED_FEATURES contains unknown feature %q", feature)
|
||||
@@ -45,6 +71,17 @@ func loadAdminFrom(rootCfg ConfigProvider) {
|
||||
}
|
||||
}
|
||||
|
||||
func normalizeAdminManagementPolicy(policy string) string {
|
||||
switch policy {
|
||||
case AdminManagementPolicyAdminsCanPromote:
|
||||
return AdminManagementPolicyGrantorOnly
|
||||
case AdminManagementPolicySuperAdminApproval:
|
||||
return AdminManagementPolicySuperAdminOnly
|
||||
default:
|
||||
return policy
|
||||
}
|
||||
}
|
||||
|
||||
const (
|
||||
UserFeatureDeletion = "deletion"
|
||||
UserFeatureManageSSHKeys = "manage_ssh_keys"
|
||||
|
||||
@@ -6,6 +6,7 @@ package setting
|
||||
// defaultI18nLangNames must be a slice, we need the order
|
||||
var defaultI18nLangNames = []string{
|
||||
"en-US", "English",
|
||||
"ro-RO", "Română",
|
||||
"zh-CN", "简体中文",
|
||||
"zh-HK", "繁體中文(香港)",
|
||||
"zh-TW", "繁體中文(台灣)",
|
||||
|
||||
@@ -31,6 +31,7 @@ var (
|
||||
ReverseProxyAuthEmail string
|
||||
ReverseProxyAuthFullName string
|
||||
ReverseProxyLimit int
|
||||
ReverseProxyLogoutRedirect string
|
||||
ReverseProxyTrustedProxies []string
|
||||
MinPasswordLength int
|
||||
ImportLocalPaths bool
|
||||
@@ -124,6 +125,7 @@ func loadSecurityFrom(rootCfg ConfigProvider) {
|
||||
ReverseProxyAuthFullName = sec.Key("REVERSE_PROXY_AUTHENTICATION_FULL_NAME").MustString("X-WEBAUTH-FULLNAME")
|
||||
|
||||
ReverseProxyLimit = sec.Key("REVERSE_PROXY_LIMIT").MustInt(1)
|
||||
ReverseProxyLogoutRedirect = sec.Key("REVERSE_PROXY_LOGOUT_REDIRECT").String()
|
||||
ReverseProxyTrustedProxies = sec.Key("REVERSE_PROXY_TRUSTED_PROXIES").Strings(",")
|
||||
if len(ReverseProxyTrustedProxies) == 0 {
|
||||
ReverseProxyTrustedProxies = []string{"127.0.0.0/8", "::1/128"}
|
||||
|
||||
@@ -21,6 +21,9 @@ const (
|
||||
HCaptcha = "hcaptcha"
|
||||
MCaptcha = "mcaptcha"
|
||||
CfTurnstile = "cfturnstile"
|
||||
|
||||
AdminCreatedAccountModeLocal = "local"
|
||||
AdminCreatedAccountModeInvite = "invite"
|
||||
)
|
||||
|
||||
// Service settings
|
||||
@@ -38,6 +41,7 @@ var Service = struct {
|
||||
EmailDomainAllowList []glob.Glob
|
||||
EmailDomainBlockList []glob.Glob
|
||||
DisableRegistration bool
|
||||
AdminCreatedAccountMode string
|
||||
AllowOnlyInternalRegistration bool
|
||||
AllowOnlyExternalRegistration bool
|
||||
ShowRegistrationButton bool
|
||||
@@ -149,6 +153,11 @@ func loadServiceFrom(rootCfg ConfigProvider) {
|
||||
Service.ActiveCodeLives = sec.Key("ACTIVE_CODE_LIVE_MINUTES").MustInt(180)
|
||||
Service.ResetPwdCodeLives = sec.Key("RESET_PASSWD_CODE_LIVE_MINUTES").MustInt(180)
|
||||
Service.DisableRegistration = sec.Key("DISABLE_REGISTRATION").MustBool()
|
||||
defaultAdminCreatedAccountMode := AdminCreatedAccountModeLocal
|
||||
if Service.DisableRegistration {
|
||||
defaultAdminCreatedAccountMode = AdminCreatedAccountModeInvite
|
||||
}
|
||||
Service.AdminCreatedAccountMode = sec.Key("ADMIN_CREATED_ACCOUNT_MODE").In(defaultAdminCreatedAccountMode, []string{AdminCreatedAccountModeLocal, AdminCreatedAccountModeInvite})
|
||||
Service.AllowOnlyInternalRegistration = sec.Key("ALLOW_ONLY_INTERNAL_REGISTRATION").MustBool()
|
||||
Service.AllowOnlyExternalRegistration = sec.Key("ALLOW_ONLY_EXTERNAL_REGISTRATION").MustBool()
|
||||
if Service.AllowOnlyExternalRegistration && Service.AllowOnlyInternalRegistration {
|
||||
|
||||
@@ -201,7 +201,7 @@ func mustCurrentRunUserMatch(rootCfg ConfigProvider) {
|
||||
if HasInstallLock(rootCfg) {
|
||||
currentUser, match := IsRunUserMatchCurrentUser(RunUser)
|
||||
if !match {
|
||||
log.Fatal("Expect user '%s' but current user is: %s", RunUser, currentUser)
|
||||
log.Fatal("Expect user '%s' (RUN_USER in app.ini) but current user is: %s", RunUser, currentUser)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ package templates
|
||||
|
||||
import (
|
||||
"html/template"
|
||||
"net/url"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
@@ -169,9 +170,21 @@ func TestQueryBuild(t *testing.T) {
|
||||
})
|
||||
}
|
||||
|
||||
const queryNonASCII = " !\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~" // all non-letter & non-number chars
|
||||
|
||||
func TestQueryEscape(t *testing.T) {
|
||||
// this test is a reference for "urlQueryEscape" in JS
|
||||
in := "!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~" // all non-letter & non-number chars
|
||||
expected := "%21%22%23%24%25%26%27%28%29%2A%2B%2C-.%2F%3A%3B%3C%3D%3E%3F%40%5B%5C%5D%5E_%60%7B%7C%7D~"
|
||||
assert.Equal(t, expected, string(queryEscape(in)))
|
||||
// Special case for space encoding:
|
||||
// * RFC 3986: Uniform Resource Identifier (URI): %20
|
||||
// * WHATWG HTML: application/x-www-form-urlencoded: +
|
||||
// * JavaScript: encodeURIComponent() uses "%20". URLSearchParams uses "+"
|
||||
// * Golang: QueryEscape uses "+"
|
||||
expected := "+%21%22%23%24%25%26%27%28%29%2A%2B%2C-.%2F%3A%3B%3C%3D%3E%3F%40%5B%5C%5D%5E_%60%7B%7C%7D~"
|
||||
assert.Equal(t, expected, url.QueryEscape(queryNonASCII))
|
||||
}
|
||||
|
||||
func TestPathEscape(t *testing.T) {
|
||||
// this test is a reference for "pathEscape" in JS
|
||||
expected := "%20%21%22%23$%25&%27%28%29%2A+%2C-.%2F:%3B%3C=%3E%3F@%5B%5C%5D%5E_%60%7B%7C%7D~"
|
||||
assert.Equal(t, expected, url.PathEscape(queryNonASCII))
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ package test
|
||||
|
||||
import (
|
||||
"archive/tar"
|
||||
"archive/zip"
|
||||
"bytes"
|
||||
"compress/gzip"
|
||||
"io"
|
||||
@@ -97,6 +98,17 @@ func WriteTarArchive(files map[string]string) *bytes.Buffer {
|
||||
return WriteTarCompression(func(w io.Writer) io.WriteCloser { return util.NopCloser{Writer: w} }, files)
|
||||
}
|
||||
|
||||
func WriteZipArchive(files map[string]string) *bytes.Buffer {
|
||||
buf := &bytes.Buffer{}
|
||||
zw := zip.NewWriter(buf)
|
||||
for name, content := range files {
|
||||
w, _ := zw.Create(name)
|
||||
_, _ = w.Write([]byte(content))
|
||||
}
|
||||
_ = zw.Close()
|
||||
return buf
|
||||
}
|
||||
|
||||
func WriteTarCompression[F func(io.Writer) io.WriteCloser | func(io.Writer) (io.WriteCloser, error)](compression F, files map[string]string) *bytes.Buffer {
|
||||
buf := &bytes.Buffer{}
|
||||
var cw io.WriteCloser
|
||||
|
||||
@@ -255,11 +255,13 @@ func EnumValue[T comparable](val EnumConst[T]) (ret T, valid bool) {
|
||||
return enums[0], false
|
||||
}
|
||||
|
||||
func ReserveLineBreakForTextarea(input string) string {
|
||||
func NormalizeStringEOL(input string) string {
|
||||
// Since the content is from a form which is a textarea, the line endings are \r\n.
|
||||
// It's a standard behavior of HTML.
|
||||
// But we want to store them as \n like what GitHub does.
|
||||
// And users are unlikely to really need to keep the \r.
|
||||
// But in most cases, we only want "\n" for EOL
|
||||
// * Text files: use "\n" by default because "\r\n" sometimes doesn't work in POSIX
|
||||
// * Actions values: store them as "\n" like what GitHub does.
|
||||
// And users are unlikely to really need the "\r".
|
||||
// Other than this, we should respect the original content, even leading or trailing spaces.
|
||||
return strings.ReplaceAll(input, "\r\n", "\n")
|
||||
return UnsafeBytesToString(NormalizeEOL(UnsafeStringToBytes(input)))
|
||||
}
|
||||
|
||||
@@ -175,9 +175,9 @@ func TestToTitleCase(t *testing.T) {
|
||||
assert.Equal(t, `Foo Bar Baz`, ToTitleCase(`FOO BAR BAZ`))
|
||||
}
|
||||
|
||||
func TestReserveLineBreakForTextarea(t *testing.T) {
|
||||
assert.Equal(t, "test\ndata", ReserveLineBreakForTextarea("test\r\ndata"))
|
||||
assert.Equal(t, "test\ndata\n", ReserveLineBreakForTextarea("test\r\ndata\r\n"))
|
||||
func TestNormalizeStringEOL(t *testing.T) {
|
||||
assert.Equal(t, "test\ndata", NormalizeStringEOL("test\r\ndata"))
|
||||
assert.Equal(t, " test\ndata\n ", NormalizeStringEOL(" test\rdata\r "))
|
||||
}
|
||||
|
||||
func TestOptionalArg(t *testing.T) {
|
||||
@@ -192,3 +192,10 @@ func TestOptionalArg(t *testing.T) {
|
||||
assert.Equal(t, 42, bar(nil))
|
||||
assert.Equal(t, 100, bar(nil, 100))
|
||||
}
|
||||
|
||||
func TestPathEscapeSegments(t *testing.T) {
|
||||
assert.Equal(t, "a", PathEscapeSegments("a"))
|
||||
assert.Equal(t, "a/b", PathEscapeSegments("a/b"))
|
||||
assert.Equal(t, "a/b%20c", PathEscapeSegments("a/b c"))
|
||||
assert.Equal(t, "a/b+c", PathEscapeSegments("a/b+c"))
|
||||
}
|
||||
|
||||
@@ -5,12 +5,14 @@ package validation
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"regexp"
|
||||
"strings"
|
||||
|
||||
"code.gitea.io/gitea/modules/auth"
|
||||
"code.gitea.io/gitea/modules/git"
|
||||
"code.gitea.io/gitea/modules/glob"
|
||||
"code.gitea.io/gitea/modules/json"
|
||||
"code.gitea.io/gitea/modules/util"
|
||||
|
||||
"gitea.com/go-chi/binding"
|
||||
@@ -31,8 +33,23 @@ const (
|
||||
ErrInvalidBadgeSlug = "InvalidBadgeSlug"
|
||||
)
|
||||
|
||||
type jsonProvider struct{}
|
||||
|
||||
func (j jsonProvider) Marshal(v any) ([]byte, error) { return json.Marshal(v) }
|
||||
|
||||
func (j jsonProvider) Unmarshal(data []byte, v any) error { return json.Unmarshal(data, v) }
|
||||
|
||||
func (j jsonProvider) NewDecoder(reader io.Reader) binding.JSONDecoder {
|
||||
return json.NewDecoder(reader)
|
||||
}
|
||||
|
||||
func (j jsonProvider) NewEncoder(writer io.Writer) binding.JSONEncoder {
|
||||
return json.NewEncoder(writer)
|
||||
}
|
||||
|
||||
// AddBindingRules adds additional binding rules
|
||||
func AddBindingRules() {
|
||||
binding.JSONProvider = jsonProvider{}
|
||||
addGitRefNameBindingRule()
|
||||
addValidURLListBindingRule()
|
||||
addValidURLBindingRule()
|
||||
|
||||
@@ -17,6 +17,7 @@ import (
|
||||
const (
|
||||
CookieWebBannerDismissed = "gitea_disbnr"
|
||||
CookieTheme = "gitea_theme"
|
||||
CookiePersistentFooter = "gitea_persistent_footer"
|
||||
cookieRedirectTo = "redirect_to"
|
||||
)
|
||||
|
||||
|
||||
@@ -183,8 +183,10 @@
|
||||
"startpage.lightweight_desc": "Gitea má minimální požadavky a může běžet na Raspberry Pi. Šetřete energii vašeho stroje!",
|
||||
"startpage.license_desc": "Vše je na <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"%[1]s\">%[2]s</a>! Připojte se tím, že <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"%[3]s\">přispějete</a> a uděláte tento projekt ještě lepší. Nestyďte se být přispěvatel!",
|
||||
"install.install": "Instalace",
|
||||
"install.installing_desc": "Installing now, please wait…",
|
||||
"install.title": "Výchozí konfigurace",
|
||||
"install.docker_helper": "Pokud spouštíte Gitea v Dockeru, přečtěte si <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"%s\">dokumentaci</a>, než budete měnit jakákoliv nastavení.",
|
||||
"install.require_db_desc": "Gitea requires MySQL, PostgreSQL, MSSQL, SQLite3 or TiDB (MySQL protocol).",
|
||||
"install.db_title": "Nastavení databáze",
|
||||
"install.db_type": "Typ databáze",
|
||||
"install.host": "Hostitel",
|
||||
@@ -193,17 +195,26 @@
|
||||
"install.db_name": "Název databáze",
|
||||
"install.db_schema": "Schéma",
|
||||
"install.db_schema_helper": "Ponechte prázdné pro výchozí nastavení databáze („public“).",
|
||||
"install.ssl_mode": "SSL",
|
||||
"install.path": "Cesta",
|
||||
"install.sqlite_helper": "Cesta k souboru SQLite3 databáze.<br>Pokud spouštíte Gitea jako službu, zadejte absolutní cestu.",
|
||||
"install.reinstall_error": "Pokoušíte se nainstalovat do existující databáze Gitea",
|
||||
"install.reinstall_confirm_message": "Přeinstalování s existující databází Gitea může způsobit více problémů. Ve většině případů byste měli použít existující „app.ini“ pro spuštění Gitea. Pokud víte, co děláte, potvrďte následující:",
|
||||
"install.reinstall_confirm_check_1": "The data encrypted by the SECRET_KEY in app.ini may be lost: users may not be able to log in with 2FA/OTP and mirrors may not function correctly. By checking this box, you confirm that the current app.ini file contains the correct SECRET_KEY.",
|
||||
"install.reinstall_confirm_check_2": "The repositories and settings may need to be resynchronized. By checking this box, you confirm that you will resynchronize the hooks for the repositories and authorized_keys file manually. You confirm that you will ensure that repository and mirror settings are correct.",
|
||||
"install.reinstall_confirm_check_3": "Potvrzujete, že jste si naprosto jisti, že tato Gitea je spuštěna se správným umístěním souboru app.ini a že jste si jisti, že musíte provést novou instalaci. Potvrzujete, že berete na vědomí výše uvedená rizika.",
|
||||
"install.err_empty_db_path": "Cesta k SQLite3 databázi nemůže být prázdná.",
|
||||
"install.no_admin_and_disable_registration": "Nemůžete vypnout registraci účtů bez vytvoření účtu správce.",
|
||||
"install.err_empty_admin_password": "Heslo administrátora nemůže být prázdné.",
|
||||
"install.err_empty_admin_email": "The administrator email address cannot be empty.",
|
||||
"install.err_admin_name_is_reserved": "Administrator username is invalid. Username is reserved.",
|
||||
"install.err_admin_name_pattern_not_allowed": "Administrator username is invalid. The username matches a reserved pattern.",
|
||||
"install.err_admin_name_is_invalid": "Administrator username is invalid",
|
||||
"install.general_title": "Obecná nastavení",
|
||||
"install.app_name": "Název stránky",
|
||||
"install.app_name_helper": "Zde můžete zadat název vaší společnosti.",
|
||||
"install.default_language": "Default Language",
|
||||
"install.default_language_helper": "Used when a user's browser language does not match an available locale.",
|
||||
"install.repo_path": "Kořenový adresář repozitářů",
|
||||
"install.repo_path_helper": "Všechny vzdálené repozitáře Gitu budou uloženy do tohoto adresáře.",
|
||||
"install.lfs_path": "Kořenový adresář Git LFS",
|
||||
@@ -215,6 +226,7 @@
|
||||
"install.ssh_port": "Port SSH serveru",
|
||||
"install.ssh_port_helper": "Číslo portu, na kterém SSH server naslouchá. Když ponecháte prázdné, SSH server zakážete.",
|
||||
"install.http_port": "Port, na kterém Gitea naslouchá HTTP protokolu",
|
||||
"install.http_port_helper": "Port number the Gitea web server will listen on.",
|
||||
"install.app_url": "Základní URL Gitea",
|
||||
"install.app_url_helper": "Základní adresa pro HTTP(S) URL adresy pro klonování a e-mailová oznámení.",
|
||||
"install.log_root_path": "Adresář logů",
|
||||
@@ -228,15 +240,33 @@
|
||||
"install.smtp_from_helper": "E-mailová adresa, kterou bude Gitea používat. Zadejte běžnou e-mailovou adresu, nebo použijte formát \"Jméno\"<email@example.com>.",
|
||||
"install.mailer_user": "Uživatelské jméno SMTP",
|
||||
"install.mailer_password": "Heslo pro SMTP",
|
||||
"install.test_mail_to": "Send Testing Email",
|
||||
"install.test_mail_missing_host": "Please enter the SMTP host before testing email delivery.",
|
||||
"install.test_mail_missing_recipient": "Please enter a recipient email address before testing email delivery.",
|
||||
"install.registration_title": "Registration Management",
|
||||
"install.registration_mode": "Registration Mode",
|
||||
"install.registration_mode.admin_only": "Administrator-managed accounts only",
|
||||
"install.registration_mode.admin_only_helper": "Disable self-registration and let administrators create new accounts using the selected administrator-created account mode.",
|
||||
"install.admin_created_account_mode": "Administrator-Created Account Mode",
|
||||
"install.admin_created_account_mode.local": "Create local accounts directly",
|
||||
"install.admin_created_account_mode.local_helper": "Creates active local accounts immediately. Administrators can optionally notify the user by email after creation.",
|
||||
"install.admin_created_account_mode.invite": "Create invitation-based accounts",
|
||||
"install.admin_created_account_mode.invite_helper": "Creates inactive accounts with sign-in disabled until the user accepts the emailed invitation link.",
|
||||
"install.registration_mode.local_only": "Local registration only",
|
||||
"install.registration_mode.local_only_helper": "Allow new accounts only through Gitea's built-in registration form.",
|
||||
"install.registration_mode.external_only": "External registration only",
|
||||
"install.registration_mode.external_only_helper": "Disable the local registration form and accept new accounts only from external identity providers.",
|
||||
"install.registration_mode.local_and_external": "Local and external registration",
|
||||
"install.registration_mode.local_and_external_helper": "Allow new accounts through both Gitea's local registration form and external identity providers.",
|
||||
"install.registration_local_options": "Local Registration Options",
|
||||
"install.registration_external_options": "External Registration Options",
|
||||
"install.register_confirm": "Pro registraci vyžadovat potvrzení e-mailu",
|
||||
"install.register_confirm_helper": "Require users to verify their email address before they can continue.",
|
||||
"install.register_manual_confirm": "Require Administrator Approval After Email Validation",
|
||||
"install.register_manual_confirm_helper": "New accounts stay pending until an administrator reviews and approves the request.",
|
||||
"install.mail_notify": "Povolit e-mailová oznámení",
|
||||
"install.mail_notify_helper": "Controls routine notification emails such as watches, mentions, and administrative notices. Activation and invitation emails still use the SMTP configuration above.",
|
||||
"install.server_service_title": "Nastavení serveru a dalších služeb",
|
||||
"install.offline_mode": "Povolit místní režim",
|
||||
"install.offline_mode_popup": "Zakázat sítě pro doručování obsahu a poskytovat veškerý obsah lokálně.",
|
||||
"install.disable_gravatar": "Zakázat Gravatar",
|
||||
"install.disable_gravatar_popup": "Zakážete Gravatar a jiné cizí zdroje avatarů. Pokud uživatel nenahraje avatar, bude použit výchozí.",
|
||||
"install.federated_avatar_lookup": "Povolit avatary z veřejných zdrojů",
|
||||
"install.federated_avatar_lookup_popup": "Povolte vyhledání avatarů z veřejných zdrojů pro využití služeb založených na libravatar.",
|
||||
"install.disable_registration": "Vypnout možnost uživatelské registrace",
|
||||
"install.disable_registration_popup": "Vypnout možnost registrace. Pouze správci budou moci vytvářet účty.",
|
||||
"install.allow_only_external_registration_popup": "Povolit registraci pouze prostřednictvím externích služeb",
|
||||
@@ -244,6 +274,8 @@
|
||||
"install.openid_signin_popup": "Umožňuje uživateli přihlásit se pomocí OpenID.",
|
||||
"install.openid_signup": "Povolit automatickou registraci pomocí OpenID",
|
||||
"install.openid_signup_popup": "Umožňuje uživateli automaticky se registrovat pomocí OpenID.",
|
||||
"install.openid_signin_helper": "Allow users to sign in through OpenID providers.",
|
||||
"install.openid_signup_helper": "Allow new accounts to be created through OpenID providers.",
|
||||
"install.enable_captcha": "Povolit CAPTCHA při registraci",
|
||||
"install.enable_captcha_popup": "Vyžadovat správně zadaný text CAPTCHA při registraci.",
|
||||
"install.require_sign_in_view": "Vyžadovat přihlášení k zobrazení stránek",
|
||||
@@ -254,6 +286,13 @@
|
||||
"install.admin_password": "Heslo",
|
||||
"install.confirm_password": "Potvrdit heslo",
|
||||
"install.admin_email": "E-mailová adresa",
|
||||
"install.admin_management_policy": "Administration Management Policy",
|
||||
"install.admin_management_policy.super_admin_only": "Only super admins manage admins",
|
||||
"install.admin_management_policy.super_admin_only_helper": "Regular admins can manage only non-admin accounts. Any admin-to-admin change or deletion requires a super administrator.",
|
||||
"install.admin_management_policy.grantor_only": "Grantor manages promoted admins",
|
||||
"install.admin_management_policy.grantor_only_helper": "Regular admins can promote users to administrator and can later modify or delete only the administrators they directly promoted.",
|
||||
"install.admin_management_policy.grantor_inheritance": "Grantor chain with inheritance",
|
||||
"install.admin_management_policy.grantor_inheritance_helper": "Like grantor-only, but if the direct grantor becomes inactive or has sign-in disabled, management passes up the admin grant chain until an eligible admin is found. If none is found, super admins keep control.",
|
||||
"install.install_btn_confirm": "Nainstalovat Gitea",
|
||||
"install.test_git_failed": "Chyba při testu příkazu 'git': %v",
|
||||
"install.sqlite3_not_available": "Tato verze Gitea nepodporuje SQLite3. Stáhněte si oficiální binární verzi od %s (nikoli verzi „gobuild“).",
|
||||
@@ -261,7 +300,6 @@
|
||||
"install.invalid_db_table": "Databázová tabulka „%s“ je neplatná: %v",
|
||||
"install.invalid_repo_path": "Kořenový adresář repozitářů není správný: %v",
|
||||
"install.invalid_app_data_path": "Cesta k datům aplikace je neplatná: %v",
|
||||
"install.run_user_not_match": "\"Run as\" uživatelské jméno není aktuální uživatelské jméno: %s -> %s",
|
||||
"install.internal_token_failed": "Nepodařilo se vytvořit interní token: %v",
|
||||
"install.secret_key_failed": "Nepodařilo se vytvořit tajný klíč: %v",
|
||||
"install.save_config_failed": "Uložení konfigurace se nezdařilo: %v",
|
||||
@@ -277,6 +315,7 @@
|
||||
"install.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“.",
|
||||
"install.password_algorithm": "Hash algoritmus hesla",
|
||||
"install.invalid_password_algorithm": "Neplatný algoritmus hash hesla",
|
||||
"install.password_algorithm_helper": "Set the password hashing algorithm. Algorithms have differing requirements and strengths. The argon2 algorithm is rather secure but uses a lot of memory and may be inappropriate for small systems.",
|
||||
"install.enable_update_checker": "Povolit kontrolu aktualizací",
|
||||
"install.enable_update_checker_helper": "Kontroluje vydání nových verzí pravidelně připojením ke gitea.io.",
|
||||
"install.env_config_keys": "Konfigurace prostředí",
|
||||
@@ -326,6 +365,9 @@
|
||||
"auth.sign_up_now": "Zaregistruj se nyní.",
|
||||
"auth.sign_up_successful": "Účet byl úspěšně vytvořen. Vítejte!",
|
||||
"auth.confirmation_mail_sent_prompt_ex": "Nový potvrzovací e-mail byl odeslán na <b>%s</b>. Zkontrolujte prosím svou doručenou poštu během následujících %s a dokončete proces registrace. Pokud je Vaše registrační e-mailová adresa nesprávná, můžete se znovu přihlásit a změnit ji.",
|
||||
"auth.confirmation_mail_pending_signup": "A confirmation email has already been sent to <b>%s</b>. Please activate it before creating another account.",
|
||||
"auth.confirmation_mail_resend_failed": "The confirmation email could not be sent. Please try again later or contact an administrator.",
|
||||
"auth.confirmation_mail_resend_not_available": "This account can no longer receive confirmation emails.",
|
||||
"auth.must_change_password": "Aktualizujte své heslo",
|
||||
"auth.allow_password_change": "Vyžádat od uživatele změnu hesla (doporučeno)",
|
||||
"auth.reset_password_mail_sent_prompt": "Na adresu <b>%s</b> 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.",
|
||||
@@ -2615,6 +2657,7 @@
|
||||
"admin.users.created": "Vytvořen",
|
||||
"admin.users.last_login": "Poslední přihlášení",
|
||||
"admin.users.send_register_notify": "Odeslat upozornění při registraci uživatele",
|
||||
"admin.users.send_register_invite": "Send User Registration Invitation",
|
||||
"admin.users.new_success": "Uživatelský účet „%s“ byl vytvořen.",
|
||||
"admin.users.edit": "Upravit",
|
||||
"admin.users.auth_source": "Zdroj ověřování",
|
||||
@@ -3306,5 +3349,15 @@
|
||||
"git.filemode.normal_file": "Normální soubor",
|
||||
"git.filemode.executable_file": "Spustitelný soubor",
|
||||
"git.filemode.symbolic_link": "Symbolický odkaz",
|
||||
"git.filemode.submodule": "Submodul"
|
||||
"git.filemode.submodule": "Submodul",
|
||||
"auth.accept_your_invitation": "Accept Your Invitation",
|
||||
"auth.invitation_mail_pending_login": "An invitation email has already been sent to <b>%s</b>. Please accept it before signing in.",
|
||||
"auth.invitation_mail_sent_prompt_ex": "A new invitation email has been sent to <b>%s</b>. Please use the link within the next %s to activate your account.",
|
||||
"auth.invitation_mail_resend_failed": "The invitation email could not be sent. Please try again later or contact an administrator.",
|
||||
"auth.invitation_mail_resend_not_available": "This account can no longer receive invitation emails.",
|
||||
"auth.invitation_resend_prompt": "Did not receive the invitation email?",
|
||||
"auth.invitation_resend_button": "Resend",
|
||||
"admin.users.send_register_notify_helper": "The account will be activated and validated immediately.",
|
||||
"admin.users.send_register_invite_helper": "The user must accept the emailed invitation before the account becomes active.",
|
||||
"install.language_balloon": "Choose a language"
|
||||
}
|
||||
|
||||
@@ -174,26 +174,39 @@
|
||||
"startpage.lightweight_desc": "Gitea hat minimale Systemanforderungen und kann selbst auf einem günstigen und stromsparenden Raspberry Pi betrieben werden!",
|
||||
"startpage.license": "Quelloffen",
|
||||
"startpage.license_desc": "Hol dir den Code unter <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"%[1]s\">%[2]s</a>! Leiste deinen <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"%[3]s\">Beitrag</a> bei der Verbesserung dieses Projekts. Trau dich!",
|
||||
"install.install": "Installation",
|
||||
"install.installing_desc": "Installing now, please wait…",
|
||||
"install.title": "Erstkonfiguration",
|
||||
"install.docker_helper": "Wenn du Gitea in einem Docker-Container nutzt, lies bitte die <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"%s\">Dokumentation</a>, bevor du irgendwelche Einstellungen veränderst.",
|
||||
"install.require_db_desc": "Gitea benötigt MySQL, PostgreSQL, MSSQL, SQLite3 oder TiDB (MySQL-Protokoll).",
|
||||
"install.db_title": "Datenbankeinstellungen",
|
||||
"install.db_type": "Datenbanktyp",
|
||||
"install.host": "Host",
|
||||
"install.user": "Benutzername",
|
||||
"install.password": "Passwort",
|
||||
"install.db_name": "Datenbankname",
|
||||
"install.db_schema": "Schema",
|
||||
"install.db_schema_helper": "Leer lassen, um das Standard-Schema (\"public\") zu verwenden.",
|
||||
"install.ssl_mode": "SSL",
|
||||
"install.path": "Pfad",
|
||||
"install.sqlite_helper": "Dateipfad zur SQLite3 Datenbank.<br>Gebe einen absoluten Pfad an, wenn Gitea als Service gestartet wird.",
|
||||
"install.reinstall_error": "Du versuchst, in eine bereits existierende Gitea Datenbank zu installieren",
|
||||
"install.reinstall_confirm_message": "Eine Neuinstallation mit einer bestehenden Gitea-Datenbank kann mehrere Probleme verursachen. In den meisten Fällen solltest du deine vorhandene \"app.ini\" verwenden, um Gitea auszuführen. Wenn du weist, was du tust, bestätigen die folgenden Angaben:",
|
||||
"install.reinstall_confirm_check_1": "The data encrypted by the SECRET_KEY in app.ini may be lost: users may not be able to log in with 2FA/OTP and mirrors may not function correctly. By checking this box, you confirm that the current app.ini file contains the correct SECRET_KEY.",
|
||||
"install.reinstall_confirm_check_2": "The repositories and settings may need to be resynchronized. By checking this box, you confirm that you will resynchronize the hooks for the repositories and authorized_keys file manually. You confirm that you will ensure that repository and mirror settings are correct.",
|
||||
"install.reinstall_confirm_check_3": "Du bestätigst, dass du absolut sicher bist, dass diese Gitea mit der richtigen app.ini läuft, und du sicher bist, dass du neu installieren musst. Du bestätigst, dass du die oben genannten Risiken anerkennst.",
|
||||
"install.err_empty_db_path": "Der SQLite3 Datenbankpfad darf nicht leer sein.",
|
||||
"install.no_admin_and_disable_registration": "Du kannst Selbst-Registrierungen nicht deaktivieren, ohne ein Administratorkonto zu erstellen.",
|
||||
"install.err_empty_admin_password": "Das Administrator-Passwort darf nicht leer sein.",
|
||||
"install.err_empty_admin_email": "The administrator email address cannot be empty.",
|
||||
"install.err_admin_name_is_reserved": "Administrator username is invalid. Username is reserved.",
|
||||
"install.err_admin_name_pattern_not_allowed": "Administrator username is invalid. The username matches a reserved pattern.",
|
||||
"install.err_admin_name_is_invalid": "Administrator username is invalid",
|
||||
"install.general_title": "Allgemeine Einstellungen",
|
||||
"install.app_name": "Seitentitel",
|
||||
"install.app_name_helper": "Du kannst hier den Namen deines Unternehmens eingeben.",
|
||||
"install.default_language": "Default Language",
|
||||
"install.default_language_helper": "Used when a user's browser language does not match an available locale.",
|
||||
"install.repo_path": "Repository-Verzeichnis",
|
||||
"install.repo_path_helper": "Remote-Git-Repositories werden in diesem Verzeichnis gespeichert.",
|
||||
"install.lfs_path": "Git-LFS-Wurzelpfad",
|
||||
@@ -205,6 +218,7 @@
|
||||
"install.ssh_port": "SSH-Server-Port",
|
||||
"install.ssh_port_helper": "Der Port deines SSH-Servers. Leer lassen, um SSH zu deaktivieren.",
|
||||
"install.http_port": "Gitea-HTTP-Listen-Port",
|
||||
"install.http_port_helper": "Port number the Gitea web server will listen on.",
|
||||
"install.app_url": "Gitea-Basis-URL",
|
||||
"install.app_url_helper": "Adresse für HTTP(S)-Klon-URLs und E-Mail-Benachrichtigungen.",
|
||||
"install.log_root_path": "Logdateipfad",
|
||||
@@ -218,15 +232,33 @@
|
||||
"install.smtp_from_helper": "E-Mail-Adresse, die von Gitea genutzt werden soll. Bitte gib die E-Mail-Adresse im Format „\"Name\" <email@example.com>“ ein.",
|
||||
"install.mailer_user": "SMTP-Benutzername",
|
||||
"install.mailer_password": "SMTP-Passwort",
|
||||
"install.test_mail_to": "Send Testing Email",
|
||||
"install.test_mail_missing_host": "Please enter the SMTP host before testing email delivery.",
|
||||
"install.test_mail_missing_recipient": "Please enter a recipient email address before testing email delivery.",
|
||||
"install.registration_title": "Registration Management",
|
||||
"install.registration_mode": "Registration Mode",
|
||||
"install.registration_mode.admin_only": "Administrator-managed accounts only",
|
||||
"install.registration_mode.admin_only_helper": "Disable self-registration and let administrators create new accounts using the selected administrator-created account mode.",
|
||||
"install.admin_created_account_mode": "Administrator-Created Account Mode",
|
||||
"install.admin_created_account_mode.local": "Create local accounts directly",
|
||||
"install.admin_created_account_mode.local_helper": "Creates active local accounts immediately. Administrators can optionally notify the user by email after creation.",
|
||||
"install.admin_created_account_mode.invite": "Create invitation-based accounts",
|
||||
"install.admin_created_account_mode.invite_helper": "Creates inactive accounts with sign-in disabled until the user accepts the emailed invitation link.",
|
||||
"install.registration_mode.local_only": "Local registration only",
|
||||
"install.registration_mode.local_only_helper": "Allow new accounts only through Gitea's built-in registration form.",
|
||||
"install.registration_mode.external_only": "External registration only",
|
||||
"install.registration_mode.external_only_helper": "Disable the local registration form and accept new accounts only from external identity providers.",
|
||||
"install.registration_mode.local_and_external": "Local and external registration",
|
||||
"install.registration_mode.local_and_external_helper": "Allow new accounts through both Gitea's local registration form and external identity providers.",
|
||||
"install.registration_local_options": "Local Registration Options",
|
||||
"install.registration_external_options": "External Registration Options",
|
||||
"install.register_confirm": "E-Mail-Bestätigung benötigt zum Registrieren",
|
||||
"install.register_confirm_helper": "Require users to verify their email address before they can continue.",
|
||||
"install.register_manual_confirm": "Require Administrator Approval After Email Validation",
|
||||
"install.register_manual_confirm_helper": "New accounts stay pending until an administrator reviews and approves the request.",
|
||||
"install.mail_notify": "E-Mail-Benachrichtigungen aktivieren",
|
||||
"install.mail_notify_helper": "Controls routine notification emails such as watches, mentions, and administrative notices. Activation and invitation emails still use the SMTP configuration above.",
|
||||
"install.server_service_title": "Sonstige Server- und Drittserviceeinstellungen",
|
||||
"install.offline_mode": "Offline-Modus aktivieren",
|
||||
"install.offline_mode_popup": "Drittanbieter-CDNs deaktivieren und alle Ressourcen lokal zur Verfügung stellen.",
|
||||
"install.disable_gravatar": "Gravatar deaktivieren",
|
||||
"install.disable_gravatar_popup": "Gravatar und Drittanbieter-Avatar-Quellen deaktivieren. Ein Standardavatar wird verwendet, bis der Nutzer einen eigenen Avatar hochlädt.",
|
||||
"install.federated_avatar_lookup": "Föderierte Profilbilder einschalten",
|
||||
"install.federated_avatar_lookup_popup": "Föderierte Profilbilder via Libravatar aktivieren.",
|
||||
"install.disable_registration": "Registrierung deaktivieren",
|
||||
"install.disable_registration_popup": "Registrierung neuer Benutzer deaktivieren. Nur Administratoren werden neue Benutzerkonten anlegen können.",
|
||||
"install.allow_only_external_registration_popup": "Registrierung nur über externe Services erlauben",
|
||||
@@ -234,6 +266,8 @@
|
||||
"install.openid_signin_popup": "Benutzeranmeldung via OpenID aktivieren.",
|
||||
"install.openid_signup": "OpenID-Selbstregistrierung aktivieren",
|
||||
"install.openid_signup_popup": "OpenID-basierte Selbstregistrierung aktivieren.",
|
||||
"install.openid_signin_helper": "Allow users to sign in through OpenID providers.",
|
||||
"install.openid_signup_helper": "Allow new accounts to be created through OpenID providers.",
|
||||
"install.enable_captcha": "Registrierungs-Captcha aktivieren",
|
||||
"install.enable_captcha_popup": "Captcha-Eingabe bei der Registrierung erforderlich.",
|
||||
"install.require_sign_in_view": "Ansehen erfordert Anmeldung",
|
||||
@@ -244,6 +278,13 @@
|
||||
"install.admin_password": "Passwort",
|
||||
"install.confirm_password": "Passwort bestätigen",
|
||||
"install.admin_email": "E-Mail-Adresse",
|
||||
"install.admin_management_policy": "Administration Management Policy",
|
||||
"install.admin_management_policy.super_admin_only": "Only super admins manage admins",
|
||||
"install.admin_management_policy.super_admin_only_helper": "Regular admins can manage only non-admin accounts. Any admin-to-admin change or deletion requires a super administrator.",
|
||||
"install.admin_management_policy.grantor_only": "Grantor manages promoted admins",
|
||||
"install.admin_management_policy.grantor_only_helper": "Regular admins can promote users to administrator and can later modify or delete only the administrators they directly promoted.",
|
||||
"install.admin_management_policy.grantor_inheritance": "Grantor chain with inheritance",
|
||||
"install.admin_management_policy.grantor_inheritance_helper": "Like grantor-only, but if the direct grantor becomes inactive or has sign-in disabled, management passes up the admin grant chain until an eligible admin is found. If none is found, super admins keep control.",
|
||||
"install.install_btn_confirm": "Gitea installieren",
|
||||
"install.test_git_failed": "Fehler beim Test des „git“-Befehls: %v",
|
||||
"install.sqlite3_not_available": "Diese Gitea-Version unterstützt SQLite3 nicht. Bitte lade die offizielle binäre Version von %s herunter (nicht die „gobuild“-Version).",
|
||||
@@ -251,7 +292,6 @@
|
||||
"install.invalid_db_table": "Die Datenbanktabelle \"%s\" ist ungültig: %v",
|
||||
"install.invalid_repo_path": "Repository-Verzeichnis ist ungültig: %v",
|
||||
"install.invalid_app_data_path": "Der App-Daten-Pfad ist ungültig: %v",
|
||||
"install.run_user_not_match": "Der „Ausführen als“-Benutzername ist nicht der aktuelle Benutzername: %s -> %s",
|
||||
"install.internal_token_failed": "Fehler beim Generieren des internen Tokens: %v",
|
||||
"install.secret_key_failed": "Fehler beim Generieren des geheimen Schlüssels: %v",
|
||||
"install.save_config_failed": "Fehler beim Speichern der Konfiguration: %v",
|
||||
@@ -267,6 +307,7 @@
|
||||
"install.no_reply_address_helper": "Domain-Name für Benutzer mit einer versteckten Emailadresse. Zum Beispiel wird der Benutzername „Joe“ in Git als „joe@noreply.example.org“ protokolliert, wenn die versteckte E-Mail-Domain „noreply.example.org“ festgelegt ist.",
|
||||
"install.password_algorithm": "Passwort Hashing Algorithmus",
|
||||
"install.invalid_password_algorithm": "Ungültiger Passwort-Hash-Algorithmus",
|
||||
"install.password_algorithm_helper": "Set the password hashing algorithm. Algorithms have differing requirements and strengths. The argon2 algorithm is rather secure but uses a lot of memory and may be inappropriate for small systems.",
|
||||
"install.enable_update_checker": "Aktualisierungsprüfung aktivieren",
|
||||
"install.enable_update_checker_helper": "Stellt regelmäßig eine Verbindung zu gitea.io her, um nach neuen Versionen zu prüfen.",
|
||||
"install.env_config_keys": "Umgebungskonfiguration",
|
||||
@@ -319,6 +360,9 @@
|
||||
"auth.sign_up_now": "Jetzt registrieren.",
|
||||
"auth.sign_up_successful": "Konto wurde erfolgreich erstellt. Willkommen!",
|
||||
"auth.confirmation_mail_sent_prompt_ex": "Eine neue Bestätigungs-E-Mail wurde an <b>%s</b>gesendet. Bitte überprüfe deinen Posteingang innerhalb der nächsten %s, um den Registrierungsprozess abzuschließen. Wenn deine Registrierungs-E-Mail-Adresse falsch ist, kannst du dich erneut anmelden und diese ändern.",
|
||||
"auth.confirmation_mail_pending_signup": "A confirmation email has already been sent to <b>%s</b>. Please activate it before creating another account.",
|
||||
"auth.confirmation_mail_resend_failed": "The confirmation email could not be sent. Please try again later or contact an administrator.",
|
||||
"auth.confirmation_mail_resend_not_available": "This account can no longer receive confirmation emails.",
|
||||
"auth.must_change_password": "Aktualisiere dein Passwort",
|
||||
"auth.allow_password_change": "Verlange vom Benutzer das Passwort zu ändern (empfohlen)",
|
||||
"auth.reset_password_mail_sent_prompt": "Eine Bestätigungs-E-Mail wurde an <b>%s</b> gesendet. Bitte überprüfe dein Postfach innerhalb von %s, um den Wiederherstellungsprozess abzuschließen.",
|
||||
@@ -2584,6 +2628,7 @@
|
||||
"admin.users.created": "Registriert am",
|
||||
"admin.users.last_login": "Letzte Anmeldung",
|
||||
"admin.users.send_register_notify": "Benutzer-Registrierungsbenachrichtigung senden",
|
||||
"admin.users.send_register_invite": "Send User Registration Invitation",
|
||||
"admin.users.new_success": "Der Account \"%s\" wurde erstellt.",
|
||||
"admin.users.edit": "Bearbeiten",
|
||||
"admin.users.auth_source": "Authentifizierungsquelle",
|
||||
@@ -3248,5 +3293,15 @@
|
||||
"git.filemode.normal_file": "Normale Datei",
|
||||
"git.filemode.executable_file": "Ausführbare Datei",
|
||||
"git.filemode.symbolic_link": "Softlink",
|
||||
"git.filemode.submodule": "Submodul"
|
||||
"git.filemode.submodule": "Submodul",
|
||||
"auth.accept_your_invitation": "Accept Your Invitation",
|
||||
"auth.invitation_mail_pending_login": "An invitation email has already been sent to <b>%s</b>. Please accept it before signing in.",
|
||||
"auth.invitation_mail_sent_prompt_ex": "A new invitation email has been sent to <b>%s</b>. Please use the link within the next %s to activate your account.",
|
||||
"auth.invitation_mail_resend_failed": "The invitation email could not be sent. Please try again later or contact an administrator.",
|
||||
"auth.invitation_mail_resend_not_available": "This account can no longer receive invitation emails.",
|
||||
"auth.invitation_resend_prompt": "Did not receive the invitation email?",
|
||||
"auth.invitation_resend_button": "Resend",
|
||||
"admin.users.send_register_notify_helper": "The account will be activated and validated immediately.",
|
||||
"admin.users.send_register_invite_helper": "The user must accept the emailed invitation before the account becomes active.",
|
||||
"install.language_balloon": "Choose a language"
|
||||
}
|
||||
|
||||
@@ -156,6 +156,7 @@
|
||||
"startpage.lightweight_desc": "Gitea έχει χαμηλές ελάχιστες απαιτήσεις και μπορεί να τρέξει σε ένα οικονομικό Raspberry Pi. Εξοικονομήστε ενέργεια!",
|
||||
"startpage.license": "Ανοικτού κώδικα",
|
||||
"install.install": "Εγκατάσταση",
|
||||
"install.installing_desc": "Installing now, please wait…",
|
||||
"install.title": "Αρχικές Ρυθμίσεις",
|
||||
"install.docker_helper": "Αν εκτελέσετε το Gitea μέσα στο Docker, παρακαλώ διαβάστε την <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"%s\">τεκμηρίωση</a> πριν αλλάξετε τις ρυθμίσεις.",
|
||||
"install.require_db_desc": "Το Gitea απαιτεί MySQL, PostgreSQL, MSSQL, SQLite3 ή TiDB (με πρωτόκολλο MySQL).",
|
||||
@@ -167,17 +168,26 @@
|
||||
"install.db_name": "Όνομα Βάσης Δεδομένων",
|
||||
"install.db_schema": "Σχήμα",
|
||||
"install.db_schema_helper": "Αφήστε κενό για την προεπιλογή της βάσης δεδομένων (\"public\").",
|
||||
"install.ssl_mode": "SSL",
|
||||
"install.path": "Διαδρομή",
|
||||
"install.sqlite_helper": "Διαδρομή αρχείου για τη βάση δεδομένων SQLite3.<br>Εισάγετε μια απόλυτη διαδρομή αν εκτελείτε το Gitea ως υπηρεσία.",
|
||||
"install.reinstall_error": "Προσπαθείτε να εγκαταστήσετε σε μια υπάρχουσα βάση δεδομένων Gitea",
|
||||
"install.reinstall_confirm_message": "Η επανεγκατάσταση με μια υπάρχουσα βάση δεδομένων Gitea μπορεί να προκαλέσει πολλαπλά προβλήματα. Στις περισσότερες περιπτώσεις, θα πρέπει να χρησιμοποιήσετε το υπάρχον \"app.ini\" για να εκτελέσετε το Gitea. Αν γνωρίζετε τι κάνετε, επιβεβαιώστε τα εξής:",
|
||||
"install.reinstall_confirm_check_1": "The data encrypted by the SECRET_KEY in app.ini may be lost: users may not be able to log in with 2FA/OTP and mirrors may not function correctly. By checking this box, you confirm that the current app.ini file contains the correct SECRET_KEY.",
|
||||
"install.reinstall_confirm_check_2": "The repositories and settings may need to be resynchronized. By checking this box, you confirm that you will resynchronize the hooks for the repositories and authorized_keys file manually. You confirm that you will ensure that repository and mirror settings are correct.",
|
||||
"install.reinstall_confirm_check_3": "Επιβεβαιώνετε ότι είστε απολύτως σίγουροι ότι αυτό το Gitea τρέχει στη σωστή τοποθεσία στο app.ini και ότι είστε σίγουροι ότι θα πρέπει να επανεγκαταστήσετε. Επιβεβαιώνετε ότι αναγνωρίζετε τους παραπάνω κινδύνους.",
|
||||
"install.err_empty_db_path": "Η διαδρομή της βάσης δεδομένων SQLite3 δεν μπορεί να είναι κενή.",
|
||||
"install.no_admin_and_disable_registration": "Δεν μπορείτε να απενεργοποιήσετε την ιδιο-εγγραφή χρήστη χωρίς να έχετε δημιουργήσει διαχειριστικό λογαριασμό.",
|
||||
"install.err_empty_admin_password": "Ο κωδικός πρόσβασης του διαχειριστή δεν μπορεί να είναι κενός.",
|
||||
"install.err_empty_admin_email": "The administrator email address cannot be empty.",
|
||||
"install.err_admin_name_is_reserved": "Administrator username is invalid. Username is reserved.",
|
||||
"install.err_admin_name_pattern_not_allowed": "Administrator username is invalid. The username matches a reserved pattern.",
|
||||
"install.err_admin_name_is_invalid": "Administrator username is invalid",
|
||||
"install.general_title": "Γενικές Ρυθμίσεις",
|
||||
"install.app_name": "Τίτλος Ιστοτόπου",
|
||||
"install.app_name_helper": "Μπορείτε να εισάγετε το όνομα της εταιρείας σας εδώ.",
|
||||
"install.default_language": "Default Language",
|
||||
"install.default_language_helper": "Used when a user's browser language does not match an available locale.",
|
||||
"install.repo_path": "Ριζική Διαδρομή Αποθετηρίου",
|
||||
"install.repo_path_helper": "Τα απομακρυσμένα αποθετήρια Git θα αποθηκεύονται σε αυτόν τον κατάλογο.",
|
||||
"install.lfs_path": "Ριζική Διαδρομή Git LFS",
|
||||
@@ -189,6 +199,7 @@
|
||||
"install.ssh_port": "Θύρα της υπηρεσίας SSH",
|
||||
"install.ssh_port_helper": "Αριθμός θύρας που ακούει η υπηρεσία SSH. Αφήστε κενό για να το απενεργοποιήσετε.",
|
||||
"install.http_port": "Η HTTP θύρα που ακούει το Gitea",
|
||||
"install.http_port_helper": "Port number the Gitea web server will listen on.",
|
||||
"install.app_url": "Βασικό URL του Gitea",
|
||||
"install.app_url_helper": "Βασική Διεύθυνση για τα URL κλωνοποίησης μέσω HTTP(S) και για τις ειδοποιήσεις μέσω email.",
|
||||
"install.log_root_path": "Διαδρομή Αρχείων Καταγραφής",
|
||||
@@ -198,18 +209,37 @@
|
||||
"install.smtp_addr": "Διακομιστής SMTP",
|
||||
"install.smtp_port": "Θύρα SMTP",
|
||||
"install.smtp_from": "Αποστολή Email Ως",
|
||||
"install.smtp_from_invalid": "The \"Send Email As\" address is invalid",
|
||||
"install.smtp_from_helper": "Η διεύθυνση email που θα χρησιμοποιεί το Gitea. Εισάγετε μια απλή διεύθυνση ηλεκτρονικού ταχυδρομείου ή χρησιμοποιήστε τη μορφή \"Όνομα\" <email@example.com>.",
|
||||
"install.mailer_user": "Όνομα Χρήστη SMTP",
|
||||
"install.mailer_password": "Κωδικός SMTP",
|
||||
"install.test_mail_to": "Send Testing Email",
|
||||
"install.test_mail_missing_host": "Please enter the SMTP host before testing email delivery.",
|
||||
"install.test_mail_missing_recipient": "Please enter a recipient email address before testing email delivery.",
|
||||
"install.registration_title": "Registration Management",
|
||||
"install.registration_mode": "Registration Mode",
|
||||
"install.registration_mode.admin_only": "Administrator-managed accounts only",
|
||||
"install.registration_mode.admin_only_helper": "Disable self-registration and let administrators create new accounts using the selected administrator-created account mode.",
|
||||
"install.admin_created_account_mode": "Administrator-Created Account Mode",
|
||||
"install.admin_created_account_mode.local": "Create local accounts directly",
|
||||
"install.admin_created_account_mode.local_helper": "Creates active local accounts immediately. Administrators can optionally notify the user by email after creation.",
|
||||
"install.admin_created_account_mode.invite": "Create invitation-based accounts",
|
||||
"install.admin_created_account_mode.invite_helper": "Creates inactive accounts with sign-in disabled until the user accepts the emailed invitation link.",
|
||||
"install.registration_mode.local_only": "Local registration only",
|
||||
"install.registration_mode.local_only_helper": "Allow new accounts only through Gitea's built-in registration form.",
|
||||
"install.registration_mode.external_only": "External registration only",
|
||||
"install.registration_mode.external_only_helper": "Disable the local registration form and accept new accounts only from external identity providers.",
|
||||
"install.registration_mode.local_and_external": "Local and external registration",
|
||||
"install.registration_mode.local_and_external_helper": "Allow new accounts through both Gitea's local registration form and external identity providers.",
|
||||
"install.registration_local_options": "Local Registration Options",
|
||||
"install.registration_external_options": "External Registration Options",
|
||||
"install.register_confirm": "Απαιτείται Επιβεβαίωση της Διεύθυνσης Εmail για Εγγραφή",
|
||||
"install.register_confirm_helper": "Require users to verify their email address before they can continue.",
|
||||
"install.register_manual_confirm": "Require Administrator Approval After Email Validation",
|
||||
"install.register_manual_confirm_helper": "New accounts stay pending until an administrator reviews and approves the request.",
|
||||
"install.mail_notify": "Ενεργοποίηση Ειδοποιήσεων με Email",
|
||||
"install.mail_notify_helper": "Controls routine notification emails such as watches, mentions, and administrative notices. Activation and invitation emails still use the SMTP configuration above.",
|
||||
"install.server_service_title": "Ρυθμίσεις Διακομιστή και Υπηρεσιών Τρίτων",
|
||||
"install.offline_mode": "Ενεργοποίηση Τοπικής Λειτουργίας",
|
||||
"install.offline_mode_popup": "Απενεργοποιήση των δικτύων διανομής περιεχομένου τρίτων και σερβίρετε όλων των πόρων τοπικά.",
|
||||
"install.disable_gravatar": "Απενεργοποίηση Gravatar",
|
||||
"install.disable_gravatar_popup": "Απενεργοποιήση του Gravatar και των εξωτερικών πηγών avatar. Θα χρησιμοποιηθεί ένα προεπιλεγμένο avatar εκτός αν ένας χρήστης ανεβάσει τοπικά ένα avatar.",
|
||||
"install.federated_avatar_lookup": "Ενεργοποίηση Ομόσπονδων Avatars",
|
||||
"install.federated_avatar_lookup_popup": "Ενεργοποίηση ομόσπονδης αναζήτησης avatar χρησιμοποιώντας το Libravatar.",
|
||||
"install.disable_registration": "Απενεργοποίηση Αυτοεγγραφής",
|
||||
"install.disable_registration_popup": "Απενεργοποίηση αυτοεγγραφής χρήστη. Μόνο οι διαχειριστές θα μπορούν να δημιουργήσουν νέους λογαριασμούς χρηστών.",
|
||||
"install.allow_only_external_registration_popup": "Να Επιτρέπεται Η Εγγραφή Μόνο Μέσω Εξωτερικών Υπηρεσιών",
|
||||
@@ -217,6 +247,8 @@
|
||||
"install.openid_signin_popup": "Ενεργοποίηση σύνδεσης χρήστη μέσω OpenID.",
|
||||
"install.openid_signup": "Ενεργοποίηση Ιδιοεγγραφής μέσω OpenID",
|
||||
"install.openid_signup_popup": "Ενεργοποίηση ιδιοεγγραφής χρηστών με βάση το OpenID.",
|
||||
"install.openid_signin_helper": "Allow users to sign in through OpenID providers.",
|
||||
"install.openid_signup_helper": "Allow new accounts to be created through OpenID providers.",
|
||||
"install.enable_captcha": "Ενεργοποίηση CAPTCHA στην εγγραφή",
|
||||
"install.enable_captcha_popup": "Απαιτείται ένα CAPTCHA για τη ιδιοεγγραφή του χρήστη.",
|
||||
"install.require_sign_in_view": "Απαιτείται Είσοδος για τη Προβολή Σελίδων",
|
||||
@@ -227,6 +259,13 @@
|
||||
"install.admin_password": "Κωδικός Πρόσβασης",
|
||||
"install.confirm_password": "Επιβεβαίωση Κωδικού Πρόσβασης",
|
||||
"install.admin_email": "Διεύθυνση Email",
|
||||
"install.admin_management_policy": "Administration Management Policy",
|
||||
"install.admin_management_policy.super_admin_only": "Only super admins manage admins",
|
||||
"install.admin_management_policy.super_admin_only_helper": "Regular admins can manage only non-admin accounts. Any admin-to-admin change or deletion requires a super administrator.",
|
||||
"install.admin_management_policy.grantor_only": "Grantor manages promoted admins",
|
||||
"install.admin_management_policy.grantor_only_helper": "Regular admins can promote users to administrator and can later modify or delete only the administrators they directly promoted.",
|
||||
"install.admin_management_policy.grantor_inheritance": "Grantor chain with inheritance",
|
||||
"install.admin_management_policy.grantor_inheritance_helper": "Like grantor-only, but if the direct grantor becomes inactive or has sign-in disabled, management passes up the admin grant chain until an eligible admin is found. If none is found, super admins keep control.",
|
||||
"install.install_btn_confirm": "Εγκατάσταση Gitea",
|
||||
"install.test_git_failed": "Αδυναμία δοκιμής της εντολής 'git': %v",
|
||||
"install.sqlite3_not_available": "Αυτή η έκδοση Gitea δεν υποστηρίζει την SQLite3. Παρακαλώ κατεβάστε την επίσημη δυαδική έκδοση από το %s (όχι την έκδοση 'gobuild').",
|
||||
@@ -234,7 +273,6 @@
|
||||
"install.invalid_db_table": "Ο πίνακας βάσης δεδομένων \"%s\" δεν είναι έγκυρος: %v",
|
||||
"install.invalid_repo_path": "Η αρχική διαδρομή των αποθετηρίων δεν είναι έγκυρη: %v",
|
||||
"install.invalid_app_data_path": "Η διαδρομή δεδομένων εφαρμογής (app data) δεν είναι έγκυρη: %v",
|
||||
"install.run_user_not_match": "Το όνομα χρήστη 'εκτέλεση ως' δεν είναι το τρέχον όνομα χρήστη: %s -> %s",
|
||||
"install.internal_token_failed": "Αποτυχία δημιουργίας εσωτερικού διακριτικού: %v",
|
||||
"install.secret_key_failed": "Αποτυχία δημιουργίας μυστικού κλειδιού: %v",
|
||||
"install.save_config_failed": "Αποτυχία αποθήκευσης ρυθμίσεων: %v",
|
||||
@@ -250,10 +288,12 @@
|
||||
"install.no_reply_address_helper": "Όνομα τομέα για χρήστες με μια κρυφή διεύθυνση email. Για παράδειγμα, το όνομα χρήστη 'nikos' θα συνδεθεί στο Git ως 'nikos@noreply.example.org' αν ο κρυφός τομέας email έχει οριστεί ως 'noreply.example.org'.",
|
||||
"install.password_algorithm": "Αλγόριθμος Hash Κωδικού Πρόσβασης",
|
||||
"install.invalid_password_algorithm": "Μη έγκυρος αλγόριθμος κωδικού πρόσβασης",
|
||||
"install.password_algorithm_helper": "Set the password hashing algorithm. Algorithms have differing requirements and strengths. The argon2 algorithm is rather secure but uses a lot of memory and may be inappropriate for small systems.",
|
||||
"install.enable_update_checker": "Ενεργοποίηση Ελεγκτή Ενημερώσεων",
|
||||
"install.enable_update_checker_helper": "Ελέγχει περιοδικά για νέες εκδόσεις κάνοντας σύνδεση στο gitea.io.",
|
||||
"install.env_config_keys": "Ρυθμίσεις Περιβάλλοντος",
|
||||
"install.env_config_keys_prompt": "Οι ακόλουθες μεταβλητές περιβάλλοντος θα εφαρμοστούν επίσης στο αρχείο ρυθμίσεων σας:",
|
||||
"install.config_write_file_prompt": "These configuration options will be written into: %s",
|
||||
"home.uname_holder": "Όνομα Χρήστη ή Διεύθυνση Email",
|
||||
"home.password_holder": "Κωδικός Πρόσβασης",
|
||||
"home.switch_dashboard_context": "Εναλλαγή Περιεχομένων Αρχικού Πίνακα",
|
||||
@@ -293,6 +333,9 @@
|
||||
"auth.forgot_password": "Ξεχάσατε τον κωδικό πρόσβασης;",
|
||||
"auth.sign_up_successful": "Ο λογαριασμός δημιουργήθηκε επιτυχώς. Καλώς ορίσατε!",
|
||||
"auth.must_change_password": "Ενημερώστε τον κωδικό πρόσβασης σας",
|
||||
"auth.confirmation_mail_pending_signup": "A confirmation email has already been sent to <b>%s</b>. Please activate it before creating another account.",
|
||||
"auth.confirmation_mail_resend_failed": "The confirmation email could not be sent. Please try again later or contact an administrator.",
|
||||
"auth.confirmation_mail_resend_not_available": "This account can no longer receive confirmation emails.",
|
||||
"auth.allow_password_change": "Απαιτείται από το χρήστη να αλλάξει τον κωδικό πρόσβασης (συνιστόμενο)",
|
||||
"auth.reset_password_mail_sent_prompt": "Ένα email επιβεβαίωσης έχει σταλεί στο <b>%s</b>. Παρακαλώ ελέγξτε τα εισερχόμενα σας στις επόμενες %s για να ολοκληρώσετε τη διαδικασία ανάκτησης λογαριασμού.",
|
||||
"auth.active_your_account": "Ενεργοποιήστε Το Λογαριασμό Σας",
|
||||
@@ -2356,6 +2399,7 @@
|
||||
"admin.users.created": "Δημιουργήθηκε",
|
||||
"admin.users.last_login": "Τελευταία Σύνδεση",
|
||||
"admin.users.send_register_notify": "Αποστολή Ειδοποίησης Εγγραφής Χρήστη",
|
||||
"admin.users.send_register_invite": "Send User Registration Invitation",
|
||||
"admin.users.new_success": "Ο λογαριασμός χρήστη \"%s\" δημιουργήθηκε.",
|
||||
"admin.users.edit": "Επεξεργασία",
|
||||
"admin.users.auth_source": "Πηγή Ταυτοποίησης",
|
||||
@@ -3000,5 +3044,15 @@
|
||||
"git.filemode.directory": "Φάκελος",
|
||||
"git.filemode.normal_file": "Κανονικό αρχείο",
|
||||
"git.filemode.executable_file": "Εκτελέσιμο αρχείο",
|
||||
"git.filemode.submodule": "Υπομονάδα"
|
||||
"git.filemode.submodule": "Υπομονάδα",
|
||||
"auth.accept_your_invitation": "Accept Your Invitation",
|
||||
"auth.invitation_mail_pending_login": "An invitation email has already been sent to <b>%s</b>. Please accept it before signing in.",
|
||||
"auth.invitation_mail_sent_prompt_ex": "A new invitation email has been sent to <b>%s</b>. Please use the link within the next %s to activate your account.",
|
||||
"auth.invitation_mail_resend_failed": "The invitation email could not be sent. Please try again later or contact an administrator.",
|
||||
"auth.invitation_mail_resend_not_available": "This account can no longer receive invitation emails.",
|
||||
"auth.invitation_resend_prompt": "Did not receive the invitation email?",
|
||||
"auth.invitation_resend_button": "Resend",
|
||||
"admin.users.send_register_notify_helper": "The account will be activated and validated immediately.",
|
||||
"admin.users.send_register_invite_helper": "The user must accept the emailed invitation before the account becomes active.",
|
||||
"install.language_balloon": "Choose a language"
|
||||
}
|
||||
|
||||
@@ -236,7 +236,20 @@
|
||||
"install.install": "Installation",
|
||||
"install.installing_desc": "Installing now, please wait…",
|
||||
"install.title": "Initial Configuration",
|
||||
"install.language_balloon": "Choose a language",
|
||||
"install.docker_helper": "If you run Gitea inside Docker, please read the <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"%s\">documentation</a> before changing any settings.",
|
||||
"install.import_app_ini_title": "Import Existing Configuration",
|
||||
"install.import_app_ini_desc": "Upload an existing app.ini file to prefill this installer form with the configuration values it already contains.",
|
||||
"install.import_app_ini_file": "app.ini File",
|
||||
"install.import_app_ini_helper": "Optional. INI file only, up to %d KB. The imported values are copied into the installer form so you can review and adjust them before saving.",
|
||||
"install.import_app_ini_sensitive_secrets": "Import sensitive secrets from app.ini",
|
||||
"install.import_app_ini_sensitive_secrets_helper": "Optional. Also import LFS_JWT_SECRET, INTERNAL_TOKEN, and JWT_SECRET from the uploaded configuration. Use this for restores or migrations where existing signed tokens must continue working.",
|
||||
"install.import_app_ini_button": "Load app.ini",
|
||||
"install.import_app_ini_missing": "Please choose an app.ini file to import.",
|
||||
"install.import_app_ini_read_failed": "Could not read the uploaded app.ini file: %v",
|
||||
"install.import_app_ini_too_big": "The uploaded app.ini file exceeds the maximum size of %d KB.",
|
||||
"install.import_app_ini_invalid": "The uploaded app.ini file could not be parsed: %v",
|
||||
"install.import_app_ini_success": "Configuration values were loaded from app.ini. Review the imported settings before continuing.",
|
||||
"install.require_db_desc": "Gitea requires MySQL, PostgreSQL, MSSQL, SQLite3 or TiDB (MySQL protocol).",
|
||||
"install.db_title": "Database Settings",
|
||||
"install.db_type": "Database Type",
|
||||
@@ -264,12 +277,14 @@
|
||||
"install.general_title": "General Settings",
|
||||
"install.app_name": "Site Title",
|
||||
"install.app_name_helper": "You can enter your company name here.",
|
||||
"install.default_language": "Default Language",
|
||||
"install.default_language_helper": "Used when a user's browser language does not match an available locale.",
|
||||
"install.repo_path": "Repository Root Path",
|
||||
"install.repo_path_helper": "Remote Git repositories will be saved to this directory.",
|
||||
"install.lfs_path": "Git LFS Root Path",
|
||||
"install.lfs_path_helper": "Files tracked by Git LFS will be stored in this directory. Leave empty to disable.",
|
||||
"install.run_user": "Run As Username",
|
||||
"install.run_user_helper": "The operating system username that Gitea runs as. Note that this user must have access to the repository root path.",
|
||||
"install.run_user_helper": "The operating system username that Gitea runs as, it must have write access to the data paths. This value is auto-detected and cannot be changed here. To use a different user, restart Gitea under that account.",
|
||||
"install.domain": "Server Domain",
|
||||
"install.domain_helper": "Domain or host address for the server.",
|
||||
"install.ssh_port": "SSH Server Port",
|
||||
@@ -281,6 +296,28 @@
|
||||
"install.log_root_path": "Log Path",
|
||||
"install.log_root_path_helper": "Log files will be written to this directory.",
|
||||
"install.optional_title": "Optional Settings",
|
||||
"install.branding_title": "Branding",
|
||||
"install.branding_desc": "Upload optional custom logo and favicon files. If you leave any field empty, Gitea will continue using the built-in asset for that file.",
|
||||
"install.branding.shared_assets": "Use the same logo files for favicon assets",
|
||||
"install.branding.shared_assets_helper": "When enabled, the uploaded logo SVG and logo PNG will also be reused as the favicon SVG and favicon PNG, so you only need one upload per format.",
|
||||
"install.branding.logo_svg": "Logo SVG",
|
||||
"install.branding.logo_and_favicon_svg": "Logo & Favicon SVG",
|
||||
"install.branding.logo_svg_helper": "Optional. SVG only, up to %d KB. Recommended for scalable UI branding.",
|
||||
"install.branding.logo_png": "Logo PNG",
|
||||
"install.branding.logo_and_favicon_png": "Logo & Favicon PNG",
|
||||
"install.branding.logo_png_helper": "Optional. PNG only, up to %d KB. Must be square and at least %dx%d pixels. 512x512 is recommended for manifest and social preview fallbacks.",
|
||||
"install.branding.loading_png": "Install Progress PNG",
|
||||
"install.branding.loading_png_helper": "Optional. PNG or animated PNG only, up to %d KB. Must be square and at least %dx%d pixels. Use this to replace the post-install progress graphic.",
|
||||
"install.branding.favicon_svg": "Favicon SVG",
|
||||
"install.branding.favicon_svg_helper": "Optional. SVG only, up to %d KB. Use a simple square icon for best browser compatibility.",
|
||||
"install.branding.favicon_png": "Favicon PNG",
|
||||
"install.branding.favicon_png_helper": "Optional. PNG only, up to %d KB. Must be square and at least %dx%d pixels. 512x512 is recommended; browsers will downscale as needed.",
|
||||
"install.branding.upload_read_failed": "Could not read %s: %v",
|
||||
"install.branding.upload_too_big": "%s exceeds the maximum size of %d KB.",
|
||||
"install.branding.upload_invalid_type": "%s must be a %s file.",
|
||||
"install.branding.upload_png_square": "%s must be a square PNG image.",
|
||||
"install.branding.upload_png_too_small": "%s must be at least %dx%d pixels.",
|
||||
"install.branding.upload_save_failed": "Could not save branding files: %v",
|
||||
"install.email_title": "Email Settings",
|
||||
"install.smtp_addr": "SMTP Host",
|
||||
"install.smtp_port": "SMTP Port",
|
||||
@@ -289,8 +326,32 @@
|
||||
"install.smtp_from_helper": "Email address Gitea will use. Enter a plain email address or use the \"Name\" <email@example.com> format.",
|
||||
"install.mailer_user": "SMTP Username",
|
||||
"install.mailer_password": "SMTP Password",
|
||||
"install.test_mail_to": "Send Testing Email",
|
||||
"install.test_mail_missing_host": "Please enter the SMTP host before testing email delivery.",
|
||||
"install.test_mail_missing_recipient": "Please enter a recipient email address before testing email delivery.",
|
||||
"install.registration_title": "Registration Management",
|
||||
"install.registration_mode": "Registration Mode",
|
||||
"install.registration_mode.admin_only": "Administrator-managed accounts only",
|
||||
"install.registration_mode.admin_only_helper": "Disable self-registration and let administrators create new accounts using the selected administrator-created account mode.",
|
||||
"install.admin_created_account_mode": "Administrator-Created Account Mode",
|
||||
"install.admin_created_account_mode.local": "Create local accounts directly",
|
||||
"install.admin_created_account_mode.local_helper": "Creates active local accounts immediately. Administrators can optionally notify the user by email after creation.",
|
||||
"install.admin_created_account_mode.invite": "Create invitation-based accounts",
|
||||
"install.admin_created_account_mode.invite_helper": "Creates inactive accounts with sign-in disabled until the user accepts the emailed invitation link.",
|
||||
"install.registration_mode.local_only": "Local registration only",
|
||||
"install.registration_mode.local_only_helper": "Allow new accounts only through Gitea's built-in registration form.",
|
||||
"install.registration_mode.external_only": "External registration only",
|
||||
"install.registration_mode.external_only_helper": "Disable the local registration form and accept new accounts only from external identity providers.",
|
||||
"install.registration_mode.local_and_external": "Local and external registration",
|
||||
"install.registration_mode.local_and_external_helper": "Allow new accounts through both Gitea's local registration form and external identity providers.",
|
||||
"install.registration_local_options": "Local Registration Options",
|
||||
"install.registration_external_options": "External Registration Options",
|
||||
"install.register_confirm": "Require Email Confirmation to Register",
|
||||
"install.register_confirm_helper": "Require users to verify their email address before they can continue.",
|
||||
"install.register_manual_confirm": "Require Administrator Approval After Email Validation",
|
||||
"install.register_manual_confirm_helper": "New accounts stay pending until an administrator reviews and approves the request.",
|
||||
"install.mail_notify": "Enable Email Notifications",
|
||||
"install.mail_notify_helper": "Controls routine notification emails such as watches, mentions, and administrative notices. Activation and invitation emails still use the SMTP configuration above.",
|
||||
"install.server_service_title": "Server and Third-Party Service Settings",
|
||||
"install.disable_registration": "Disable Self-Registration",
|
||||
"install.disable_registration_popup": "Disable user self-registration. Only administrators will be able to create new user accounts.",
|
||||
@@ -299,16 +360,25 @@
|
||||
"install.openid_signin_popup": "Enable user sign-in via OpenID.",
|
||||
"install.openid_signup": "Enable OpenID Self-Registration",
|
||||
"install.openid_signup_popup": "Enable OpenID-based user self-registration.",
|
||||
"install.openid_signin_helper": "Allow users to sign in through OpenID providers.",
|
||||
"install.openid_signup_helper": "Allow new accounts to be created through OpenID providers.",
|
||||
"install.enable_captcha": "Enable registration CAPTCHA",
|
||||
"install.enable_captcha_popup": "Require a CAPTCHA for user self-registration.",
|
||||
"install.require_sign_in_view": "Require Sign-In to View Pages",
|
||||
"install.require_sign_in_view_popup": "Limit page access to signed-in users. Visitors will only see the sign-in and registration pages.",
|
||||
"install.admin_setting_desc": "Creating an administrator account is optional. The first registered user will automatically become an administrator.",
|
||||
"install.admin_title": "Administrator Account Settings",
|
||||
"install.admin_name": "Administrator Username",
|
||||
"install.admin_setting_desc": "Creating a super administrator account is optional. The first registered user will automatically become a super administrator.",
|
||||
"install.admin_title": "Super Administrator Account Settings",
|
||||
"install.admin_name": "Super Administrator Username",
|
||||
"install.admin_password": "Password",
|
||||
"install.confirm_password": "Confirm Password",
|
||||
"install.admin_email": "Email Address",
|
||||
"install.admin_management_policy": "Administration Management Policy",
|
||||
"install.admin_management_policy.super_admin_only": "Only super admins manage admins",
|
||||
"install.admin_management_policy.super_admin_only_helper": "Regular admins can manage only non-admin accounts. Any admin-to-admin change or deletion requires a super administrator.",
|
||||
"install.admin_management_policy.grantor_only": "Grantor manages promoted admins",
|
||||
"install.admin_management_policy.grantor_only_helper": "Regular admins can promote users to administrator and can later modify or delete only the administrators they directly promoted.",
|
||||
"install.admin_management_policy.grantor_inheritance": "Grantor chain with inheritance",
|
||||
"install.admin_management_policy.grantor_inheritance_helper": "Like grantor-only, but if the direct grantor becomes inactive or has sign-in disabled, management passes up the admin grant chain until an eligible admin is found. If none is found, super admins keep control.",
|
||||
"install.install_btn_confirm": "Install Gitea",
|
||||
"install.test_git_failed": "Could not test 'git' command: %v",
|
||||
"install.sqlite3_not_available": "This Gitea version does not support SQLite3. Please download the official binary version from %s (not the 'gobuild' version).",
|
||||
@@ -316,7 +386,6 @@
|
||||
"install.invalid_db_table": "The database table \"%s\" is invalid: %v",
|
||||
"install.invalid_repo_path": "The repository root path is invalid: %v",
|
||||
"install.invalid_app_data_path": "The app data path is invalid: %v",
|
||||
"install.run_user_not_match": "The 'run as' username is not the current username: %s -> %s",
|
||||
"install.internal_token_failed": "Failed to generate internal token: %v",
|
||||
"install.secret_key_failed": "Failed to generate secret key: %v",
|
||||
"install.save_config_failed": "Failed to save configuration: %v",
|
||||
@@ -380,15 +449,44 @@
|
||||
"auth.disable_register_prompt": "Registration is disabled. Please contact your site administrator.",
|
||||
"auth.disable_register_mail": "Email confirmation for registration is disabled.",
|
||||
"auth.manual_activation_only": "Contact your site administrator to complete activation.",
|
||||
"auth.account_request_validation_sent": "We sent you a validation email for this account request. The link is valid for 48 hours.",
|
||||
"auth.account_request_validation_pending_login": "A validation email has already been sent to %s for this account request. Please validate it before signing in.",
|
||||
"auth.account_request_validation_pending_signup": "A validation email has already been sent to %s for this account request. Please validate it before creating another account.",
|
||||
"auth.account_request_validation_resent": "We sent a new validation email for this account request.",
|
||||
"auth.account_request_validation_resend_failed": "The validation email could not be sent. Please try again later or contact an administrator.",
|
||||
"auth.account_request_validation_expired": "This account request validation link has expired. Please register again.",
|
||||
"auth.account_request_admin_review_pending": "Your email address has been validated. An administrator will now review your account request.",
|
||||
"auth.account_request_validated_waiting_admin": "Your account request was validated successfully. Please wait for an administrator to review it.",
|
||||
"auth.account_request_resend": "Resend",
|
||||
"auth.account_request_resend_prompt": "Did not receive the email?",
|
||||
"auth.account_request_resend_button": "Resend",
|
||||
"auth.account_request_spam_hint": "Please also check your Spam/Junk folder.",
|
||||
"auth.account_request_resend_not_available": "This account request can no longer receive a validation email.",
|
||||
"auth.accept_your_invitation": "Accept Your Invitation",
|
||||
"auth.invitation_mail_pending_login": "An invitation email has already been sent to <b>%s</b>. Please accept it before signing in.",
|
||||
"auth.invitation_mail_sent_prompt_ex": "A new invitation email has been sent to <b>%s</b>. Please use the link within the next %s to activate your account.",
|
||||
"auth.invitation_mail_resend_failed": "The invitation email could not be sent. Please try again later or contact an administrator.",
|
||||
"auth.invitation_mail_resend_not_available": "This account can no longer receive invitation emails.",
|
||||
"auth.invitation_resend_prompt": "Did not receive the invitation email?",
|
||||
"auth.invitation_resend_button": "Resend",
|
||||
"auth.admin_notify_recover_password_spam_hint": "We couldn't verify your password. Please use account recovery and also check your Spam/Junk folder.",
|
||||
"auth.account_request_blocked": "This account request has been blocked after %d unconfirmed attempts. An administrator must unblock it.",
|
||||
"auth.account_request_rejected_signup": "This account request was rejected. An administrator must unblock it before the same email address can be used again.",
|
||||
"auth.remember_me": "Remember This Device",
|
||||
"auth.remember_me.compromised": "The login token is not valid anymore which may indicate a compromised account. Please check your account for unusual activities.",
|
||||
"auth.forgot_password_title": "Forgot Password",
|
||||
"auth.forgot_password": "Forgot password?",
|
||||
"auth.show_password": "Show password",
|
||||
"auth.hide_password": "Hide password",
|
||||
"auth.need_account": "Need an account?",
|
||||
"auth.sign_up_tip": "You are registering the first account in the system, which has administrator privileges. Please carefully remember your username and password. If you forget the username or password, please refer to the Gitea documentation to recover the account.",
|
||||
"auth.sign_up_now": "Register now.",
|
||||
"auth.sign_up_successful": "Account was successfully created. Welcome!",
|
||||
"auth.confirmation_mail_failed": "We could not send a confirmation email to %s, so the account was not created. Please verify the email address and try again.",
|
||||
"auth.confirmation_mail_sent_prompt_ex": "A new confirmation email has been sent to <b>%s</b>. Please check your inbox within the next %s to complete the registration process. If your registration email address is incorrect, you can sign in again and change it.",
|
||||
"auth.confirmation_mail_pending_signup": "A confirmation email has already been sent to <b>%s</b>. Please activate it before creating another account.",
|
||||
"auth.confirmation_mail_resend_failed": "The confirmation email could not be sent. Please try again later or contact an administrator.",
|
||||
"auth.confirmation_mail_resend_not_available": "This account can no longer receive confirmation emails.",
|
||||
"auth.must_change_password": "Update your password",
|
||||
"auth.allow_password_change": "Require user to change password (recommended)",
|
||||
"auth.reset_password_mail_sent_prompt": "A confirmation email has been sent to <b>%s</b>. Please check your inbox within the next %s to complete the account recovery process.",
|
||||
@@ -463,11 +561,42 @@
|
||||
"mail.activate_email": "Verify your email address",
|
||||
"mail.activate_email.title": "%s, please verify your email address",
|
||||
"mail.activate_email.text": "Please click the following link to verify your email address within <b>%s</b>:",
|
||||
"mail.new_account_request": "New account request on %s",
|
||||
"mail.new_account_request.title": "New account request on %s",
|
||||
"mail.new_account_request.text_1": "A new user account request is awaiting administrator review on %s.",
|
||||
"mail.new_account_request.text_2": "Requested account: <b>%[1]s</b> (%[2]s).",
|
||||
"mail.new_account_request.text_3": "Review and activate the account here:",
|
||||
"mail.account_request.validate": "Validate your account request",
|
||||
"mail.account_request.validate.title": "%s, validate your account request",
|
||||
"mail.account_request.validate.text_1": "Hi <b>%[1]s</b>, please validate your account request for %[2]s.",
|
||||
"mail.account_request.validate.text_2": "Click the following link within <b>%s</b> to validate your email address and submit the request for administrator review:",
|
||||
"mail.account_request.approved": "Your account request for %s was approved",
|
||||
"mail.account_request.approved.title": "Your account request for %s was approved",
|
||||
"mail.account_request.approved.text_1": "Hi <b>%[1]s</b>, your account request for %[2]s was approved.",
|
||||
"mail.account_request.approved.text_2": "You can now sign in with your account.",
|
||||
"mail.account_request.rejected": "Your account request for %s was rejected",
|
||||
"mail.account_request.rejected.title": "Your account request for %s was rejected",
|
||||
"mail.account_request.rejected.text_1": "Hi <b>%[1]s</b>, your account request for %[2]s was rejected.",
|
||||
"mail.account_request.rejected.text_2": "The account remains blocked until an administrator unblocks it.",
|
||||
"mail.register_notify": "Welcome to %s",
|
||||
"mail.register_notify.title": "%[1]s, welcome to %[2]s",
|
||||
"mail.register_notify.text_1": "This is your registration confirmation email for %s!",
|
||||
"mail.register_notify.text_2": "You can now log in via username: %s.",
|
||||
"mail.register_notify.text_3": "If this account has been created for you, please <a href=\"%s\">set your password</a> first.",
|
||||
"mail.register_notify.text_1": "Administrator \"%[1]s\" created an account for you on %s.",
|
||||
"mail.register_notify.text_1_no_admin": "An account was created for you on %s.",
|
||||
"mail.register_notify.text_2": "You can sign in with username: %s.",
|
||||
"mail.register_notify.text_3": "Before signing in, please use your personal link to <a href=\"%s\">set your password</a>.",
|
||||
"mail.admin_invite": "You are invited to join %s",
|
||||
"mail.admin_invite.title": "Invitation to join %s",
|
||||
"mail.admin_invite.text_1": "Administrator \"%[1]s\" created an account for you and invites you to join %[2]s.",
|
||||
"mail.admin_invite.text_2": "If you accept our invitation, please use the link below:",
|
||||
"mail.admin_invite.note": "Note: This link is valid for %s.",
|
||||
"mail.admin_invite.accepted": "%[1]s accepted your invitation to join %[2]s",
|
||||
"mail.admin_invite.accepted.title": "Invitation accepted for %s",
|
||||
"mail.admin_invite.accepted.text_1": "%[1]s (@%[2]s) accepted your invitation and joined %[3]s.",
|
||||
"mail.admin_status_changed": "Your account status on %s was changed",
|
||||
"mail.admin_status_changed.title": "Your account status on %s was changed",
|
||||
"mail.admin_status_changed.text_1": "Hi <b>%[1]s</b>, your account status on %[2]s was changed.",
|
||||
"mail.admin_status_changed.text_2": "This action was performed by administrator <b>%s</b>.",
|
||||
"mail.admin_status_changed.reason": "Reason:",
|
||||
"mail.reset_password": "Recover your account",
|
||||
"mail.reset_password.title": "%s, you have requested to recover your account",
|
||||
"mail.reset_password.text": "Please click the following link to recover your account within <b>%s</b>:",
|
||||
@@ -638,14 +767,8 @@
|
||||
"user.block.unblock.failure": "Failed to unblock user: %s",
|
||||
"user.block.blocked": "You have blocked this user.",
|
||||
"user.block.title": "Block a user",
|
||||
"user.block.info": "Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.",
|
||||
"user.block.info_1": "Blocking a user prevents the following actions on your account and your repositories:",
|
||||
"user.block.info_2": "following your account",
|
||||
"user.block.info_3": "send you notifications by @mentioning your username",
|
||||
"user.block.info_4": "inviting you as a collaborator to their repositories",
|
||||
"user.block.info_5": "starring, forking or watching on repositories",
|
||||
"user.block.info_6": "opening and commenting on issues or pull requests",
|
||||
"user.block.info_7": "reacting to your comments in issues or pull requests",
|
||||
"user.block.info": "Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues.",
|
||||
"user.block.info.docs": "Learn more about blocking a user.",
|
||||
"user.block.user_to_block": "User to block",
|
||||
"user.block.note": "Note",
|
||||
"user.block.note.title": "Optional note:",
|
||||
@@ -697,6 +820,7 @@
|
||||
"settings.hidden_comment_types_description": "Comment types checked here will not be shown on issue pages. Checking \"Label\", for example, removes all \"{user} added/removed {label}\" comments.",
|
||||
"settings.hidden_comment_types.ref_tooltip": "Comments where this issue was referenced from another issue/commit/…",
|
||||
"settings.hidden_comment_types.issue_ref_tooltip": "Comments where the user changes the branch/tag associated with the issue",
|
||||
"settings.select_all": "Select",
|
||||
"settings.comment_type_group_reference": "Reference",
|
||||
"settings.comment_type_group_label": "Label",
|
||||
"settings.comment_type_group_milestone": "Milestone",
|
||||
@@ -712,6 +836,17 @@
|
||||
"settings.comment_type_group_project": "Project",
|
||||
"settings.comment_type_group_issue_ref": "Issue reference",
|
||||
"settings.saved_successfully": "Your settings were saved successfully.",
|
||||
"settings.persistent_layout": "Persistent layout",
|
||||
"settings.persistent_layout_desc": "Choose which interface regions should remain visible while the page scrolls.",
|
||||
"settings.footer": "Footer",
|
||||
"settings.footer_desc": "Choose whether the site footer should remain visible at the bottom of the viewport.",
|
||||
"settings.show_persistent_footer": "Keep the footer visible on screen",
|
||||
"settings.navigation_bar": "Navigation bar",
|
||||
"settings.navigation_bar_desc": "Choose whether the top navigation bar should remain visible while the page scrolls.",
|
||||
"settings.show_persistent_navbar": "Keep the navigation bar visible while scrolling",
|
||||
"settings.side_menus": "Side menus",
|
||||
"settings.side_menus_desc": "Choose whether the left menus in user settings and the admin area should remain visible while the page content scrolls.",
|
||||
"settings.show_sticky_side_menus": "Keep the left menus visible while scrolling",
|
||||
"settings.privacy": "Privacy",
|
||||
"settings.keep_activity_private": "Hide Activity from profile page",
|
||||
"settings.keep_activity_private_popup": "Makes the activity visible only for you and the admins",
|
||||
@@ -949,6 +1084,9 @@
|
||||
"settings.email_notifications.disable": "Disable Email Notifications",
|
||||
"settings.email_notifications.submit": "Set Email Preference",
|
||||
"settings.email_notifications.andyourown": "And Your Own Notifications",
|
||||
"settings.email_notifications.new_account_requests": "New account request notifications",
|
||||
"settings.email_notifications.new_account_requests.desc": "Email me when a new user account is waiting for administrator approval.",
|
||||
"settings.email_notifications.new_account_requests.last_admin": "At least one admin must keep new account request notifications enabled.",
|
||||
"settings.email_notifications.actions.desc": "Notifications for workflow runs on repositories set up with <a target=\"_blank\" href=\"%s\">Gitea Actions</a>.",
|
||||
"settings.email_notifications.actions.failure_only": "Only notify for failed workflow runs",
|
||||
"settings.visibility": "User visibility",
|
||||
@@ -2937,6 +3075,8 @@
|
||||
"admin.dashboard.cron.finished": "Cron: %[1]s has finished",
|
||||
"admin.dashboard.delete_inactive_accounts": "Delete all unactivated accounts",
|
||||
"admin.dashboard.delete_inactive_accounts.started": "Task to delete all unactivated accounts started",
|
||||
"admin.dashboard.delete_expired_account_requests": "Delete expired account requests awaiting email validation",
|
||||
"admin.dashboard.delete_expired_account_requests.started": "Task to delete expired account requests awaiting email validation started",
|
||||
"admin.dashboard.delete_repo_archives": "Delete all repositories' archives (ZIP, TAR.GZ, etc..)",
|
||||
"admin.dashboard.delete_repo_archives.started": "Task to delete all repository archives started",
|
||||
"admin.dashboard.delete_missing_repos": "Delete all repositories missing their Git files",
|
||||
@@ -3017,6 +3157,9 @@
|
||||
"admin.users.last_login": "Last Sign-In",
|
||||
"admin.users.never_login": "Never Signed In",
|
||||
"admin.users.send_register_notify": "Send User Registration Notification",
|
||||
"admin.users.send_register_notify_helper": "The account will be activated and validated immediately.",
|
||||
"admin.users.send_register_invite": "Send User Registration Invitation",
|
||||
"admin.users.send_register_invite_helper": "The user must accept the emailed invitation before the account becomes active.",
|
||||
"admin.users.new_success": "The user account \"%s\" has been created.",
|
||||
"admin.users.edit": "Edit",
|
||||
"admin.users.auth_source": "Authentication Source",
|
||||
@@ -3030,6 +3173,8 @@
|
||||
"admin.users.is_activated": "User Account Is Activated",
|
||||
"admin.users.prohibit_login": "Disable Sign-In",
|
||||
"admin.users.is_admin": "Is Administrator",
|
||||
"admin.users.is_super_admin": "Is Super Administrator",
|
||||
"admin.users.super_admin": "Super Admin",
|
||||
"admin.users.is_restricted": "Is Restricted",
|
||||
"admin.users.allow_git_hook": "May Create Git Hooks",
|
||||
"admin.users.allow_git_hook_tooltip": "Git Hooks are executed as the OS user running Gitea and will have the same level of host access. As a result, users with this special Git Hook privilege can access and modify all Gitea repositories as well as the database used by Gitea. Consequently they are also able to gain Gitea administrator privileges.",
|
||||
@@ -3038,12 +3183,44 @@
|
||||
"admin.users.update_profile": "Update User Account",
|
||||
"admin.users.delete_account": "Delete User Account",
|
||||
"admin.users.cannot_delete_self": "You cannot delete yourself",
|
||||
"admin.users.cannot_delete_grantor": "You cannot delete the administrator who granted your privileges.",
|
||||
"admin.users.admin_grantor.required": "You can only manage administrator accounts that belong to your grant chain.",
|
||||
"admin.users.god_immutable": "Accounts granted by GOD cannot be modified or deleted.",
|
||||
"admin.users.still_own_repo": "This user still owns one or more repositories. Delete or transfer these repositories first.",
|
||||
"admin.users.still_has_org": "This user is a member of an organization. Remove the user from any organizations first.",
|
||||
"admin.users.purge": "Purge User",
|
||||
"admin.users.purge_help": "Forcibly delete user and any repositories, organizations, and packages owned by the user. All comments will be deleted too.",
|
||||
"admin.users.still_own_packages": "This user still owns one or more packages. Delete these packages first.",
|
||||
"admin.users.deletion_success": "The user account has been deleted.",
|
||||
"admin.users.account_request.status": "Account request status",
|
||||
"admin.users.account_request.attempts": "Unconfirmed attempts: %d",
|
||||
"admin.users.account_request.validation_mail": "Validation email attempt",
|
||||
"admin.users.account_request.activate": "Activate Request",
|
||||
"admin.users.account_request.reject": "Reject Request",
|
||||
"admin.users.account_request.unblock": "Unblock Request",
|
||||
"admin.users.account_request.approved": "The account request has been approved.",
|
||||
"admin.users.account_request.rejected": "The account request has been rejected.",
|
||||
"admin.users.account_request.unblocked": "The account request has been unblocked and a new validation email was sent.",
|
||||
"admin.users.account_request.invalid_action": "This account request action is not available for the current request state.",
|
||||
"admin.users.account_request.active_managed_externally": "Activation for this account is currently managed by the account request workflow.",
|
||||
"admin.users.status_change.reason": "Reason:",
|
||||
"admin.users.status_change.reason_required": "Please provide a reason for this account status change.",
|
||||
"admin.users.status_change.admin_granted": "Congratulations, your account has been promoted to administrator.",
|
||||
"admin.users.status_change.admin_revoked": "Administrator privileges have been removed from your account.",
|
||||
"admin.users.status_change.super_admin_granted": "Congratulations, your account has been promoted to super administrator.",
|
||||
"admin.users.status_change.super_admin_revoked": "Super administrator privileges have been removed from your account.",
|
||||
"admin.users.status_change.deactivated": "Your account has been invalidated and can no longer be accessed.",
|
||||
"admin.users.status_change.reactivated": "Your account has been reactivated and can be accessed again.",
|
||||
"admin.users.status_change.prohibit_login": "Sign-in has been disabled for your account.",
|
||||
"admin.users.status_change.allow_login": "Sign-in has been enabled again for your account.",
|
||||
"admin.users.status_change.restricted": "Your account has been restricted and can only access resources explicitly granted to it.",
|
||||
"admin.users.status_change.unrestricted": "The restricted status has been removed from your account.",
|
||||
"admin.users.super_admin.required": "Only a super administrator can manage administrator accounts.",
|
||||
"admin.users.super_admin.last": "You cannot remove the last super administrator. There must be at least one super administrator.",
|
||||
"admin.users.account_request.status.pending_email_validation": "Waiting for email validation",
|
||||
"admin.users.account_request.status.pending_admin_review": "Waiting for administrator review",
|
||||
"admin.users.account_request.status.rejected": "Rejected",
|
||||
"admin.users.account_request.status.blocked": "Blocked",
|
||||
"admin.users.reset_2fa": "Reset 2FA",
|
||||
"admin.users.list_status_filter.menu_text": "Filter",
|
||||
"admin.users.list_status_filter.reset": "Reset",
|
||||
|
||||
@@ -151,6 +151,7 @@
|
||||
"startpage.lightweight_desc": "Gitea tiene pocos requisitos y puede funcionar en una Raspberry Pi barata. ¡Ahorra energía!",
|
||||
"startpage.license": "Código abierto",
|
||||
"install.install": "Instalación",
|
||||
"install.installing_desc": "Installing now, please wait…",
|
||||
"install.title": "Configuración inicial",
|
||||
"install.docker_helper": "Si está ejecutando Gitea dentro de un contenedor Docker, por favor lea la <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"%s\">documentación</a> antes de realizar cambios en la configuración.",
|
||||
"install.require_db_desc": "Gitea requiere una base de datos MySQL, PostgreSQL, MSSQL, SQLite3 o TiDB (usar el protocolo MySQL).",
|
||||
@@ -162,17 +163,26 @@
|
||||
"install.db_name": "Nombre de la base de datos",
|
||||
"install.db_schema": "Esquema",
|
||||
"install.db_schema_helper": "Dejar en blanco para la base de datos por defecto (\"public\").",
|
||||
"install.ssl_mode": "SSL",
|
||||
"install.path": "Ruta",
|
||||
"install.sqlite_helper": "Ruta del archivo de la base de datos SQLite3.<br>Escriba una ruta de acceso absoluta si ejecuta Gitea como servicio.",
|
||||
"install.reinstall_error": "Usted está intentando instalar en una base de datos de Gitea existente",
|
||||
"install.reinstall_confirm_message": "Reinstalar con una base de datos de Gitea existente puede causar múltiples problemas. En la mayoría de los casos, debería utilizar su actual \"app.ini\" para ejecutar Gitea. Si sabe lo que está haciendo, confirme lo siguiente:",
|
||||
"install.reinstall_confirm_check_1": "The data encrypted by the SECRET_KEY in app.ini may be lost: users may not be able to log in with 2FA/OTP and mirrors may not function correctly. By checking this box, you confirm that the current app.ini file contains the correct SECRET_KEY.",
|
||||
"install.reinstall_confirm_check_2": "The repositories and settings may need to be resynchronized. By checking this box, you confirm that you will resynchronize the hooks for the repositories and authorized_keys file manually. You confirm that you will ensure that repository and mirror settings are correct.",
|
||||
"install.reinstall_confirm_check_3": "Confirma que está absolutamente seguro de que este Gitea se está ejecutando con el app.ini correcto y que está seguro de que tiene que volver a instalar. Confirma que reconoce los riesgos anteriores.",
|
||||
"install.err_empty_db_path": "La ruta a la base de datos SQLite3 no puede estar vacía.",
|
||||
"install.no_admin_and_disable_registration": "No puede deshabilitar el auto-registro sin crear una cuenta de administrador.",
|
||||
"install.err_empty_admin_password": "La contraseña del administrador no puede estar vacía.",
|
||||
"install.err_empty_admin_email": "The administrator email address cannot be empty.",
|
||||
"install.err_admin_name_is_reserved": "Administrator username is invalid. Username is reserved.",
|
||||
"install.err_admin_name_pattern_not_allowed": "Administrator username is invalid. The username matches a reserved pattern.",
|
||||
"install.err_admin_name_is_invalid": "Administrator username is invalid",
|
||||
"install.general_title": "Configuración general",
|
||||
"install.app_name": "Título del sitio",
|
||||
"install.app_name_helper": "Puede colocar aquí el nombre de su empresa.",
|
||||
"install.default_language": "Default Language",
|
||||
"install.default_language_helper": "Used when a user's browser language does not match an available locale.",
|
||||
"install.repo_path": "Ruta de la raiz del repositorio",
|
||||
"install.repo_path_helper": "Los repositorios Git se guardarán en este directorio.",
|
||||
"install.lfs_path": "Ruta raíz de Git LFS",
|
||||
@@ -184,6 +194,7 @@
|
||||
"install.ssh_port": "Puerto de servidor SSH",
|
||||
"install.ssh_port_helper": "Número de puerto en el que está escuchando su servidor SSH. Déjelo vacío para deshabilitarlo.",
|
||||
"install.http_port": "Puerto de escucha HTTP de Gitea",
|
||||
"install.http_port_helper": "Port number the Gitea web server will listen on.",
|
||||
"install.app_url": "URL base de Gitea",
|
||||
"install.app_url_helper": "Dirección base para URLs de clonación HTTP(S) y notificaciones de correo electrónico.",
|
||||
"install.log_root_path": "Ruta del registro",
|
||||
@@ -193,18 +204,37 @@
|
||||
"install.smtp_addr": "Servidor SMTP",
|
||||
"install.smtp_port": "Puerto SMTP",
|
||||
"install.smtp_from": "Enviar correos electrónicos como",
|
||||
"install.smtp_from_invalid": "The \"Send Email As\" address is invalid",
|
||||
"install.smtp_from_helper": "Dirección de correo electrónico que utilizará Gitea. Introduzca una dirección de correo electrónico normal o utilice el formato \"Nombre\" <email@example.com>.",
|
||||
"install.mailer_user": "Nombre de usuario SMTP",
|
||||
"install.mailer_password": "Contraseña SMTP",
|
||||
"install.test_mail_to": "Send Testing Email",
|
||||
"install.test_mail_missing_host": "Please enter the SMTP host before testing email delivery.",
|
||||
"install.test_mail_missing_recipient": "Please enter a recipient email address before testing email delivery.",
|
||||
"install.registration_title": "Registration Management",
|
||||
"install.registration_mode": "Registration Mode",
|
||||
"install.registration_mode.admin_only": "Administrator-managed accounts only",
|
||||
"install.registration_mode.admin_only_helper": "Disable self-registration and let administrators create new accounts using the selected administrator-created account mode.",
|
||||
"install.admin_created_account_mode": "Administrator-Created Account Mode",
|
||||
"install.admin_created_account_mode.local": "Create local accounts directly",
|
||||
"install.admin_created_account_mode.local_helper": "Creates active local accounts immediately. Administrators can optionally notify the user by email after creation.",
|
||||
"install.admin_created_account_mode.invite": "Create invitation-based accounts",
|
||||
"install.admin_created_account_mode.invite_helper": "Creates inactive accounts with sign-in disabled until the user accepts the emailed invitation link.",
|
||||
"install.registration_mode.local_only": "Local registration only",
|
||||
"install.registration_mode.local_only_helper": "Allow new accounts only through Gitea's built-in registration form.",
|
||||
"install.registration_mode.external_only": "External registration only",
|
||||
"install.registration_mode.external_only_helper": "Disable the local registration form and accept new accounts only from external identity providers.",
|
||||
"install.registration_mode.local_and_external": "Local and external registration",
|
||||
"install.registration_mode.local_and_external_helper": "Allow new accounts through both Gitea's local registration form and external identity providers.",
|
||||
"install.registration_local_options": "Local Registration Options",
|
||||
"install.registration_external_options": "External Registration Options",
|
||||
"install.register_confirm": "Requerir confirmación de correo electrónico para registrarse",
|
||||
"install.register_confirm_helper": "Require users to verify their email address before they can continue.",
|
||||
"install.register_manual_confirm": "Require Administrator Approval After Email Validation",
|
||||
"install.register_manual_confirm_helper": "New accounts stay pending until an administrator reviews and approves the request.",
|
||||
"install.mail_notify": "Habilitar las notificaciones por correo electrónico",
|
||||
"install.mail_notify_helper": "Controls routine notification emails such as watches, mentions, and administrative notices. Activation and invitation emails still use the SMTP configuration above.",
|
||||
"install.server_service_title": "Configuración del servidor y de servicios de terceros",
|
||||
"install.offline_mode": "Habilitar autenticación Local",
|
||||
"install.offline_mode_popup": "Deshabilitar redes de distribución de contenido de terceros y servir todos los recursos localmente.",
|
||||
"install.disable_gravatar": "Desactivar Gravatar",
|
||||
"install.disable_gravatar_popup": "Desactivar el Gravatar y fuentes de avatares de terceros. Se utilizará un avatar por defecto a menos que un usuario suba un avatar localmente.",
|
||||
"install.federated_avatar_lookup": "Habilitar avatares federados",
|
||||
"install.federated_avatar_lookup_popup": "Habilitar búsqueda de avatares federador para usar el servicio federado de código abierto basado en libravatar.",
|
||||
"install.disable_registration": "Deshabilitar auto-registro",
|
||||
"install.disable_registration_popup": "Deshabilitar auto-registro de usuarios. Sólo los administradores podrán crear nuevas cuentas de usuario.",
|
||||
"install.allow_only_external_registration_popup": "Permitir el registro únicamente a través de servicios externos",
|
||||
@@ -212,6 +242,8 @@
|
||||
"install.openid_signin_popup": "Habilitar el inicio de sesión de usuarios con OpenID.",
|
||||
"install.openid_signup": "Habilitar el auto-registro con OpenID",
|
||||
"install.openid_signup_popup": "Habilitar autorregistro de usuario basado en OpenID.",
|
||||
"install.openid_signin_helper": "Allow users to sign in through OpenID providers.",
|
||||
"install.openid_signup_helper": "Allow new accounts to be created through OpenID providers.",
|
||||
"install.enable_captcha": "Requerir CAPTCHA durante el registro",
|
||||
"install.enable_captcha_popup": "Requerir CAPTCHA para auto-registro de usuario.",
|
||||
"install.require_sign_in_view": "Requerir inicio de sesión para ver páginas",
|
||||
@@ -222,6 +254,13 @@
|
||||
"install.admin_password": "Contraseña",
|
||||
"install.confirm_password": "Confirmar Contraseña",
|
||||
"install.admin_email": "Correo electrónico",
|
||||
"install.admin_management_policy": "Administration Management Policy",
|
||||
"install.admin_management_policy.super_admin_only": "Only super admins manage admins",
|
||||
"install.admin_management_policy.super_admin_only_helper": "Regular admins can manage only non-admin accounts. Any admin-to-admin change or deletion requires a super administrator.",
|
||||
"install.admin_management_policy.grantor_only": "Grantor manages promoted admins",
|
||||
"install.admin_management_policy.grantor_only_helper": "Regular admins can promote users to administrator and can later modify or delete only the administrators they directly promoted.",
|
||||
"install.admin_management_policy.grantor_inheritance": "Grantor chain with inheritance",
|
||||
"install.admin_management_policy.grantor_inheritance_helper": "Like grantor-only, but if the direct grantor becomes inactive or has sign-in disabled, management passes up the admin grant chain until an eligible admin is found. If none is found, super admins keep control.",
|
||||
"install.install_btn_confirm": "Instalar Gitea",
|
||||
"install.test_git_failed": "Fallo al probar el comando 'git': %v",
|
||||
"install.sqlite3_not_available": "Esta versión de Gitea no soporta SQLite3. Por favor, descarga la versión binaria oficial de %s (no la versión 'gobuild').",
|
||||
@@ -229,7 +268,6 @@
|
||||
"install.invalid_db_table": "La tabla \"%s\" de la base de datos no es válida: %v",
|
||||
"install.invalid_repo_path": "La ruta de la raíz del repositorio no es válida: %v",
|
||||
"install.invalid_app_data_path": "La ruta de datos de la aplicación (APP_DATA_PATH) no es válida: %v",
|
||||
"install.run_user_not_match": "El nombre de usuario 'ejecutar como' no es el nombre actual de usuario: %s -> %s",
|
||||
"install.internal_token_failed": "Fallo al generar el INTERNAL_TOKEN: %v",
|
||||
"install.secret_key_failed": "Fallo al generar el SECRET_KEY: %v",
|
||||
"install.save_config_failed": "Error al guardar la configuración: %v",
|
||||
@@ -245,10 +283,12 @@
|
||||
"install.no_reply_address_helper": "Nombre de dominio para usuarios con dirección de correo electrónico oculta. Por ejemplo, el usuario 'joe' quedará registrado en Git como 'joe@noreply.example.org' si el dominio de correo electrónico oculto se establece a 'noreply.example.org'.",
|
||||
"install.password_algorithm": "Algoritmo Hash de Contraseña",
|
||||
"install.invalid_password_algorithm": "Algoritmo hash de contraseña no válido",
|
||||
"install.password_algorithm_helper": "Set the password hashing algorithm. Algorithms have differing requirements and strengths. The argon2 algorithm is rather secure but uses a lot of memory and may be inappropriate for small systems.",
|
||||
"install.enable_update_checker": "Activar comprobador de actualizaciones",
|
||||
"install.enable_update_checker_helper": "Comprueba el lanzamiento de nuevas versiones periódicamente en gitea.io.",
|
||||
"install.env_config_keys": "Configuración del entorno",
|
||||
"install.env_config_keys_prompt": "Las siguientes variables de entorno también se aplicarán a su archivo de configuración:",
|
||||
"install.config_write_file_prompt": "These configuration options will be written into: %s",
|
||||
"home.uname_holder": "Nombre de usuario o correo electrónico",
|
||||
"home.password_holder": "Contraseña",
|
||||
"home.switch_dashboard_context": "Cambiar el contexto del Dashboard",
|
||||
@@ -287,6 +327,9 @@
|
||||
"auth.forgot_password": "¿Has olvidado tu contraseña?",
|
||||
"auth.sign_up_successful": "La cuenta se ha creado correctamente. ¡Bienvenido!",
|
||||
"auth.must_change_password": "Actualizar su contraseña",
|
||||
"auth.confirmation_mail_pending_signup": "A confirmation email has already been sent to <b>%s</b>. Please activate it before creating another account.",
|
||||
"auth.confirmation_mail_resend_failed": "The confirmation email could not be sent. Please try again later or contact an administrator.",
|
||||
"auth.confirmation_mail_resend_not_available": "This account can no longer receive confirmation emails.",
|
||||
"auth.allow_password_change": "Obligar al usuario a cambiar la contraseña (recomendado)",
|
||||
"auth.reset_password_mail_sent_prompt": "Un correo de confirmación se ha enviado a <b>%s</b>. Compruebe su bandeja de entrada en las siguientes %s para completar el proceso de recuperación de la cuenta.",
|
||||
"auth.active_your_account": "Activa tu cuenta",
|
||||
@@ -2322,6 +2365,7 @@
|
||||
"admin.users.created": "Creado",
|
||||
"admin.users.last_login": "Último registro",
|
||||
"admin.users.send_register_notify": "Enviar notificación de registro de usuario",
|
||||
"admin.users.send_register_invite": "Send User Registration Invitation",
|
||||
"admin.users.new_success": "Se ha creado la cuenta de usuario \"%s\".",
|
||||
"admin.users.edit": "Editar",
|
||||
"admin.users.auth_source": "Origen de Autenticación",
|
||||
@@ -2959,5 +3003,15 @@
|
||||
"git.filemode.normal_file": "Archivo normal",
|
||||
"git.filemode.executable_file": "Archivo ejecutable",
|
||||
"git.filemode.symbolic_link": "Enlace simbólico",
|
||||
"git.filemode.submodule": "Submódulo"
|
||||
"git.filemode.submodule": "Submódulo",
|
||||
"auth.accept_your_invitation": "Accept Your Invitation",
|
||||
"auth.invitation_mail_pending_login": "An invitation email has already been sent to <b>%s</b>. Please accept it before signing in.",
|
||||
"auth.invitation_mail_sent_prompt_ex": "A new invitation email has been sent to <b>%s</b>. Please use the link within the next %s to activate your account.",
|
||||
"auth.invitation_mail_resend_failed": "The invitation email could not be sent. Please try again later or contact an administrator.",
|
||||
"auth.invitation_mail_resend_not_available": "This account can no longer receive invitation emails.",
|
||||
"auth.invitation_resend_prompt": "Did not receive the invitation email?",
|
||||
"auth.invitation_resend_button": "Resend",
|
||||
"admin.users.send_register_notify_helper": "The account will be activated and validated immediately.",
|
||||
"admin.users.send_register_invite_helper": "The user must accept the emailed invitation before the account becomes active.",
|
||||
"install.language_balloon": "Choose a language"
|
||||
}
|
||||
|
||||
@@ -94,8 +94,10 @@
|
||||
"startpage.lightweight_desc": "گیتی با حداقل منابع میتوانید برای روی دستگاه Raspberry Pi اجرا شود و مصرف انرژی شما را کاهش دهد!",
|
||||
"startpage.license": "متن باز",
|
||||
"install.install": "نصب و راه اندازی",
|
||||
"install.installing_desc": "Installing now, please wait…",
|
||||
"install.title": "تنظیمات اولیه",
|
||||
"install.docker_helper": "اگر گیتی را با داکر اجرا کردهاید، لطفا قبل از هر تغییری <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"%s\">مستندات</a> را مطالعه نمایید.",
|
||||
"install.require_db_desc": "Gitea requires MySQL, PostgreSQL, MSSQL, SQLite3 or TiDB (MySQL protocol).",
|
||||
"install.db_title": "تنظیمات پایگاه داده",
|
||||
"install.db_type": "نوع پایگاه داده",
|
||||
"install.host": "میزبان",
|
||||
@@ -104,27 +106,38 @@
|
||||
"install.db_name": "نام پایگاه داده",
|
||||
"install.db_schema": "قالب",
|
||||
"install.db_schema_helper": "برای مقدار پیش فرض پایگاه داده خالی بگذارید (\"public\").",
|
||||
"install.ssl_mode": "SSL",
|
||||
"install.path": "مسیر",
|
||||
"install.sqlite_helper": "مسیر فایل برای دیتابیس SQLite3. <br>اگر گیتی را به عنوان یک سرویس اجرا میکنید، یک مسیر کامل وارد کنید.",
|
||||
"install.reinstall_error": "شما در حال تلاش هستید برای نصب روی یک پایگاه داده Gitea که موجود است",
|
||||
"install.reinstall_confirm_message": "نصب مجدد با پایگاه داده Gitea موجود می تواند مشکلات متعددی ایجاد کند. در بیشتر موارد، باید از \"app.ini\" موجود خود برای اجرای Gitea استفاده کنید. اگر می دانید چه کاری انجام می دهید، موارد زیر را تأیید کنید:",
|
||||
"install.reinstall_confirm_check_1": "The data encrypted by the SECRET_KEY in app.ini may be lost: users may not be able to log in with 2FA/OTP and mirrors may not function correctly. By checking this box, you confirm that the current app.ini file contains the correct SECRET_KEY.",
|
||||
"install.reinstall_confirm_check_2": "The repositories and settings may need to be resynchronized. By checking this box, you confirm that you will resynchronize the hooks for the repositories and authorized_keys file manually. You confirm that you will ensure that repository and mirror settings are correct.",
|
||||
"install.reinstall_confirm_check_3": "شما تأیید می کنید که کاملاً مطمئن هستید که این Gitea با مکان صحیح app.ini اجرا می شود و مطمئن هستید که باید دوباره نصب کنید. شما تأیید می کنید که خطرات فوق را تأیید می کنید.",
|
||||
"install.err_empty_db_path": "مسیر دیتابیس SQLite3 نمیتواند خالی باشد.",
|
||||
"install.no_admin_and_disable_registration": "شما بدون ایجاد حساب کاربری مدیر نمیتوانید عضویت را غیر فعال کنید.",
|
||||
"install.err_empty_admin_password": "کلمه عبور حساب مدیر نمی تواند خالی باشد.",
|
||||
"install.err_empty_admin_email": "The administrator email address cannot be empty.",
|
||||
"install.err_admin_name_is_reserved": "Administrator username is invalid. Username is reserved.",
|
||||
"install.err_admin_name_pattern_not_allowed": "Administrator username is invalid. The username matches a reserved pattern.",
|
||||
"install.err_admin_name_is_invalid": "Administrator username is invalid",
|
||||
"install.general_title": "تنظیمات عمومی",
|
||||
"install.app_name": "عنوان سایت",
|
||||
"install.app_name_helper": "شما می توانید نام شرکت خود را در اینجا وارد کنید.",
|
||||
"install.default_language": "Default Language",
|
||||
"install.default_language_helper": "Used when a user's browser language does not match an available locale.",
|
||||
"install.repo_path": "مسیر ریشه مخزن",
|
||||
"install.repo_path_helper": "تمام مخازن کد راه دور در این پوشه ذخیره میشوند.",
|
||||
"install.lfs_path": "مسیر Git LFS",
|
||||
"install.lfs_path_helper": "فایل هایی که توسط Git LFS دنبال میشوند در این پوشه ذخیره خواهند شد. درصورت خالی بودن فیلد این قابلیت غیرفعال خواهد بود.",
|
||||
"install.run_user": "اجرا به عنوان نام کاربری",
|
||||
"install.run_user_helper": "The operating system username that Gitea runs as, it must have write access to the data paths. This value is auto-detected and cannot be changed here. To use a different user, restart Gitea under that account.",
|
||||
"install.domain": "دامنه سرور",
|
||||
"install.domain_helper": "آدرس میزبان یا دامنه برای سرور.",
|
||||
"install.ssh_port": "پورت SSH سرور",
|
||||
"install.ssh_port_helper": "شماره درگاهی که سرور SSH گوش می دهد. برای غیر فعال کردن خالی بگذارید.",
|
||||
"install.http_port": "پورت HTTP گیتی",
|
||||
"install.http_port_helper": "Port number the Gitea web server will listen on.",
|
||||
"install.app_url": "آدرس پایه گیتی",
|
||||
"install.app_url_helper": "آدرس پایه برای URLهای اجماع HTTP(S) و هشدار های رایانامه (ایمیل).",
|
||||
"install.log_root_path": "مسیر گزارشها",
|
||||
@@ -134,18 +147,37 @@
|
||||
"install.smtp_addr": "میزبان SMTP",
|
||||
"install.smtp_port": "گذرگاه(پورت) SMTP",
|
||||
"install.smtp_from": "ارسال ایمیل به عنوان",
|
||||
"install.smtp_from_invalid": "The \"Send Email As\" address is invalid",
|
||||
"install.smtp_from_helper": "آدرس ایمیلی که گیتی استفاده میکند. یک ایمیل وارد کنید یا به \"Name\" <email@example.com> شکل استفاده کنید.",
|
||||
"install.mailer_user": "نام کاربری SMTP",
|
||||
"install.mailer_password": "گذرواژه SMTP",
|
||||
"install.test_mail_to": "Send Testing Email",
|
||||
"install.test_mail_missing_host": "Please enter the SMTP host before testing email delivery.",
|
||||
"install.test_mail_missing_recipient": "Please enter a recipient email address before testing email delivery.",
|
||||
"install.registration_title": "Registration Management",
|
||||
"install.registration_mode": "Registration Mode",
|
||||
"install.registration_mode.admin_only": "Administrator-managed accounts only",
|
||||
"install.registration_mode.admin_only_helper": "Disable self-registration and let administrators create new accounts using the selected administrator-created account mode.",
|
||||
"install.admin_created_account_mode": "Administrator-Created Account Mode",
|
||||
"install.admin_created_account_mode.local": "Create local accounts directly",
|
||||
"install.admin_created_account_mode.local_helper": "Creates active local accounts immediately. Administrators can optionally notify the user by email after creation.",
|
||||
"install.admin_created_account_mode.invite": "Create invitation-based accounts",
|
||||
"install.admin_created_account_mode.invite_helper": "Creates inactive accounts with sign-in disabled until the user accepts the emailed invitation link.",
|
||||
"install.registration_mode.local_only": "Local registration only",
|
||||
"install.registration_mode.local_only_helper": "Allow new accounts only through Gitea's built-in registration form.",
|
||||
"install.registration_mode.external_only": "External registration only",
|
||||
"install.registration_mode.external_only_helper": "Disable the local registration form and accept new accounts only from external identity providers.",
|
||||
"install.registration_mode.local_and_external": "Local and external registration",
|
||||
"install.registration_mode.local_and_external_helper": "Allow new accounts through both Gitea's local registration form and external identity providers.",
|
||||
"install.registration_local_options": "Local Registration Options",
|
||||
"install.registration_external_options": "External Registration Options",
|
||||
"install.register_confirm": "نیاز به تایید ایمیل ثبت نام",
|
||||
"install.register_confirm_helper": "Require users to verify their email address before they can continue.",
|
||||
"install.register_manual_confirm": "Require Administrator Approval After Email Validation",
|
||||
"install.register_manual_confirm_helper": "New accounts stay pending until an administrator reviews and approves the request.",
|
||||
"install.mail_notify": "فعالسازی اعلانهای ایمیل",
|
||||
"install.mail_notify_helper": "Controls routine notification emails such as watches, mentions, and administrative notices. Activation and invitation emails still use the SMTP configuration above.",
|
||||
"install.server_service_title": "تنظیمات سرور و سرویسهای شخص ثالث",
|
||||
"install.offline_mode": "فعال کردن حالت محلی",
|
||||
"install.offline_mode_popup": "غیر فعال کردن شبکه های شخص ثالث تحویل محتوا و استفاده از تمام منابع به صورت محلی.",
|
||||
"install.disable_gravatar": "غیر فعال کردن Gravatar",
|
||||
"install.disable_gravatar_popup": "غیر فعال کردن کلیک و منابع آواتار شخص ثالث. مگر در مواردی که کاربر محلی بارگزاری آواتار پیش فرض استفاده خواهد شد.",
|
||||
"install.federated_avatar_lookup": "فعال سازی آواتار مشترک",
|
||||
"install.federated_avatar_lookup_popup": "مراجعه مشترک آواتار با استفاده از Libravatar را قادر می سازد.",
|
||||
"install.disable_registration": "غیرفعالکردن خود ثبت نامی",
|
||||
"install.disable_registration_popup": "غیرفعال کردن ثبت نام کاربر. تنها مدیر ها قادر خواهند بود حساب کاربری جدید اضافه کنند.",
|
||||
"install.allow_only_external_registration_popup": "اجازه ثبت نام فقط از طریق خدمات خارجی",
|
||||
@@ -153,22 +185,32 @@
|
||||
"install.openid_signin_popup": "فعالسازی ورود کاربر با OpenID.",
|
||||
"install.openid_signup": "فعالسازی ثبت نام با OpenID",
|
||||
"install.openid_signup_popup": "فعال سازی ثبت نام با استفاده از OpenID.",
|
||||
"install.openid_signin_helper": "Allow users to sign in through OpenID providers.",
|
||||
"install.openid_signup_helper": "Allow new accounts to be created through OpenID providers.",
|
||||
"install.enable_captcha": "فعالسازی CAPTCHA برای ثبت نام",
|
||||
"install.enable_captcha_popup": "عضویت افراد نیازمند کپچا است.",
|
||||
"install.require_sign_in_view": "فعالسازی نیازمند به ورود در هنگام مشاهده صفحات",
|
||||
"install.require_sign_in_view_popup": "Limit page access to signed-in users. Visitors will only see the sign-in and registration pages.",
|
||||
"install.admin_setting_desc": "ساخت حساب مدیر اختیاری است. اولین کاربری که ثبتنام میکنید مدیر خواهد بود.",
|
||||
"install.admin_title": "تنظیمات حساب مدیر",
|
||||
"install.admin_name": "نام کاربری مدیر",
|
||||
"install.admin_password": "گذرواژه",
|
||||
"install.confirm_password": "تکرارگذواژه",
|
||||
"install.admin_email": "نشانی رایانامه (ایمیل)",
|
||||
"install.admin_management_policy": "Administration Management Policy",
|
||||
"install.admin_management_policy.super_admin_only": "Only super admins manage admins",
|
||||
"install.admin_management_policy.super_admin_only_helper": "Regular admins can manage only non-admin accounts. Any admin-to-admin change or deletion requires a super administrator.",
|
||||
"install.admin_management_policy.grantor_only": "Grantor manages promoted admins",
|
||||
"install.admin_management_policy.grantor_only_helper": "Regular admins can promote users to administrator and can later modify or delete only the administrators they directly promoted.",
|
||||
"install.admin_management_policy.grantor_inheritance": "Grantor chain with inheritance",
|
||||
"install.admin_management_policy.grantor_inheritance_helper": "Like grantor-only, but if the direct grantor becomes inactive or has sign-in disabled, management passes up the admin grant chain until an eligible admin is found. If none is found, super admins keep control.",
|
||||
"install.install_btn_confirm": "نصب گیتی",
|
||||
"install.test_git_failed": "عدم توانایی در آزمایش دستور 'git' توضیح بیشتر: %v",
|
||||
"install.sqlite3_not_available": "نسخه مورد استفاده شما از SQLite3 پشتیبانی نمی کند. لطفا نسخه باینری رسمی را از s% دانلود کنید و از ورژن gobuild هم استفاده نکنید.",
|
||||
"install.invalid_db_setting": "تنظیمات پایگاه داده معتبر نیست: %v",
|
||||
"install.invalid_db_table": "The database table \"%s\" is invalid: %v",
|
||||
"install.invalid_repo_path": "مسیر ریشه مخزن نامعتبر است: %v",
|
||||
"install.invalid_app_data_path": "مسیر داده برنامه نامعتبر است: %v",
|
||||
"install.run_user_not_match": "نام کاربری 'اجرا به عنوان' نام کاربری فعلی نیست: %s -> %s",
|
||||
"install.internal_token_failed": "کد داخلی ایجاد نشد: %v",
|
||||
"install.secret_key_failed": "کلید مخفی ایجاد نشد: %v",
|
||||
"install.save_config_failed": "تنظیمات ذخیره نشد: %v",
|
||||
@@ -183,6 +225,13 @@
|
||||
"install.no_reply_address": "مخفی کردن دامنه ایمیل",
|
||||
"install.no_reply_address_helper": "نام دامنه برای کاربران دارای آدرس ایمیل پنهان است. به عنوان مثال ، اگر نام دامنه ایمیل مخفی روی \"noreply.example.org\" تنظیم شده باشد ، نام کاربری \"joe\" در Git به عنوان \"joe@noreply.example.org\" وارد می شود",
|
||||
"install.password_algorithm": "الگوریتم درهمساز گذرواژه",
|
||||
"install.invalid_password_algorithm": "Invalid password hash algorithm",
|
||||
"install.password_algorithm_helper": "Set the password hashing algorithm. Algorithms have differing requirements and strengths. The argon2 algorithm is rather secure but uses a lot of memory and may be inappropriate for small systems.",
|
||||
"install.enable_update_checker": "Enable Update Checker",
|
||||
"install.enable_update_checker_helper": "Checks for new version releases periodically by connecting to gitea.io.",
|
||||
"install.env_config_keys": "Environment Configuration",
|
||||
"install.env_config_keys_prompt": "The following environment variables will also be applied to your configuration file:",
|
||||
"install.config_write_file_prompt": "These configuration options will be written into: %s",
|
||||
"home.uname_holder": "نام کاربری یا نشانی ایمیل",
|
||||
"home.password_holder": "گذرواژه",
|
||||
"home.switch_dashboard_context": "تغییر محتوای پیشخوان",
|
||||
@@ -216,6 +265,9 @@
|
||||
"auth.forgot_password_title": "گذرواژه خود را فراموش کرده ام",
|
||||
"auth.forgot_password": "گذرواژه خود را فراموش کردهاید؟",
|
||||
"auth.must_change_password": "گذرواژه خود را به روز کنید",
|
||||
"auth.confirmation_mail_pending_signup": "A confirmation email has already been sent to <b>%s</b>. Please activate it before creating another account.",
|
||||
"auth.confirmation_mail_resend_failed": "The confirmation email could not be sent. Please try again later or contact an administrator.",
|
||||
"auth.confirmation_mail_resend_not_available": "This account can no longer receive confirmation emails.",
|
||||
"auth.allow_password_change": "نیاز به کاربر برای تغییرگذرواژه (توصیه می شود)",
|
||||
"auth.reset_password_mail_sent_prompt": "ایمیل تاییدیه جدیدی به <b>%s</b> ارسال شد. لطفا صندوق ورودی خود را در %s آینده برای فرآیند بازیابی حساب کاربری خود بررسی کنید.",
|
||||
"auth.active_your_account": "حساب خود را فعال کنید",
|
||||
@@ -1838,6 +1890,7 @@
|
||||
"admin.users.created": "ایجاد شده",
|
||||
"admin.users.last_login": "آخرین ورود",
|
||||
"admin.users.send_register_notify": "ارسال اعلان ثبت نام کاربر",
|
||||
"admin.users.send_register_invite": "Send User Registration Invitation",
|
||||
"admin.users.edit": "ویرایش",
|
||||
"admin.users.auth_source": "منبع احراز هویت",
|
||||
"admin.users.local": "محلی",
|
||||
@@ -2228,5 +2281,15 @@
|
||||
"actions.runners.status.active": "فعال",
|
||||
"actions.runners.version": "نسخه",
|
||||
"actions.runs.commit": "کامیت",
|
||||
"git.filemode.symbolic_link": "پیوند نمادین"
|
||||
"git.filemode.symbolic_link": "پیوند نمادین",
|
||||
"auth.accept_your_invitation": "Accept Your Invitation",
|
||||
"auth.invitation_mail_pending_login": "An invitation email has already been sent to <b>%s</b>. Please accept it before signing in.",
|
||||
"auth.invitation_mail_sent_prompt_ex": "A new invitation email has been sent to <b>%s</b>. Please use the link within the next %s to activate your account.",
|
||||
"auth.invitation_mail_resend_failed": "The invitation email could not be sent. Please try again later or contact an administrator.",
|
||||
"auth.invitation_mail_resend_not_available": "This account can no longer receive invitation emails.",
|
||||
"auth.invitation_resend_prompt": "Did not receive the invitation email?",
|
||||
"auth.invitation_resend_button": "Resend",
|
||||
"admin.users.send_register_notify_helper": "The account will be activated and validated immediately.",
|
||||
"admin.users.send_register_invite_helper": "The user must accept the emailed invitation before the account becomes active.",
|
||||
"install.language_balloon": "Choose a language"
|
||||
}
|
||||
|
||||
@@ -108,6 +108,7 @@
|
||||
"startpage.lightweight_desc": "Gitealla on vähäiset vähimmäisvaatimukset, joten se toimii jopa halvassa Raspberry Pi:ssä. Säästä koneesi energiaa!",
|
||||
"startpage.license": "Avoin lähdekoodi",
|
||||
"install.install": "Asennus",
|
||||
"install.installing_desc": "Installing now, please wait…",
|
||||
"install.title": "Alkuperäiset asetukset",
|
||||
"install.docker_helper": "Jos ajat Giteaa Dockerin sisällä, lue <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"%s\">ohjeet</a> ennen minkään asetuksen muuttamista.",
|
||||
"install.require_db_desc": "Gitea tarvitsee toimiakseen MySQL, PostgreSQL, MSSQL, SQLite3 tai TiDB (MySQL protokolla) tietokannan.",
|
||||
@@ -118,26 +119,39 @@
|
||||
"install.password": "Salasana",
|
||||
"install.db_name": "Tietokannan nimi",
|
||||
"install.db_schema": "Skeema",
|
||||
"install.db_schema_helper": "Leave blank for database default (\"public\").",
|
||||
"install.ssl_mode": "SSL",
|
||||
"install.path": "Polku",
|
||||
"install.sqlite_helper": "SQLite3-tietokannan tiedostopolku.<br>Syötä absoluuttinen polku, jos ajat Giteaa palveluna.",
|
||||
"install.reinstall_error": "Yrität asentaa olemassa olevaan Gitea tietokantaan",
|
||||
"install.reinstall_confirm_message": "Asentaminen uudelleen olemassa olevalla Gitea-tietokannalla voi aiheuttaa useita ongelmia. Useimmissa tapauksissa sinun pitäisi käyttää olemassa olevia \"app.ini\" asetuksia Gitean käyttöön. Jos tiedät mitä teet, vahvista seuraavat seikat:",
|
||||
"install.reinstall_confirm_check_1": "The data encrypted by the SECRET_KEY in app.ini may be lost: users may not be able to log in with 2FA/OTP and mirrors may not function correctly. By checking this box, you confirm that the current app.ini file contains the correct SECRET_KEY.",
|
||||
"install.reinstall_confirm_check_2": "The repositories and settings may need to be resynchronized. By checking this box, you confirm that you will resynchronize the hooks for the repositories and authorized_keys file manually. You confirm that you will ensure that repository and mirror settings are correct.",
|
||||
"install.reinstall_confirm_check_3": "Vahvistat, että olet täysin varma siitä, että tämä Gitea toimii oikealla app.ini sijainnilla ja että olet varma, että sinun täytyy asentaa uudelleen. Vahvistat, että tunnustat edellä mainitut riskit.",
|
||||
"install.err_empty_db_path": "SQLite3-tietokannan polku ei voi olla tyhjä.",
|
||||
"install.no_admin_and_disable_registration": "Et voi kytkeä rekisteröintiä pois luomatta sitä ennen ylläpitotiliä.",
|
||||
"install.err_empty_admin_password": "Ylläpitäjän salasana ei voi olla tyhjä.",
|
||||
"install.err_empty_admin_email": "The administrator email address cannot be empty.",
|
||||
"install.err_admin_name_is_reserved": "Administrator username is invalid. Username is reserved.",
|
||||
"install.err_admin_name_pattern_not_allowed": "Administrator username is invalid. The username matches a reserved pattern.",
|
||||
"install.err_admin_name_is_invalid": "Administrator username is invalid",
|
||||
"install.general_title": "Yleiset asetukset",
|
||||
"install.app_name": "Sivuston otsikko",
|
||||
"install.app_name_helper": "Voit syöttää yrityksesi nimen tähän.",
|
||||
"install.default_language": "Default Language",
|
||||
"install.default_language_helper": "Used when a user's browser language does not match an available locale.",
|
||||
"install.repo_path": "Repon juuren polku",
|
||||
"install.repo_path_helper": "Muualla olevat git-repositoriot tullaan tallentamaan tähän kansioon.",
|
||||
"install.lfs_path": "Git LFS -juuripolku",
|
||||
"install.lfs_path_helper": "Git LFS:n ylläpitämät tiedostot tullaan tallentamaan tähän hakemistoon. Jätä tyhjäksi kytkeäksesi toiminnon pois.",
|
||||
"install.run_user": "Aja käyttäjänä",
|
||||
"install.run_user_helper": "The operating system username that Gitea runs as, it must have write access to the data paths. This value is auto-detected and cannot be changed here. To use a different user, restart Gitea under that account.",
|
||||
"install.domain": "Palvelimen verkkotunnus",
|
||||
"install.domain_helper": "Domain or host address for the server.",
|
||||
"install.ssh_port": "SSH-palvelimen portti",
|
||||
"install.ssh_port_helper": "Porttinumero, jossa SSH-palvelimesi kuuntelee. Jätä tyhjäksi kytkeäksesi pois.",
|
||||
"install.http_port": "Gitean HTTP-kuunteluportti",
|
||||
"install.http_port_helper": "Port number the Gitea web server will listen on.",
|
||||
"install.app_url": "Gitean juuriosoite",
|
||||
"install.app_url_helper": "Juuriosoite HTTP(S)-klooniosoitteille ja sähköpostimuistutuksille.",
|
||||
"install.log_root_path": "Lokin polku",
|
||||
@@ -147,18 +161,37 @@
|
||||
"install.smtp_addr": "SMTP isäntä",
|
||||
"install.smtp_port": "SMTP portti",
|
||||
"install.smtp_from": "Lähetä sähköpostit osoitteella",
|
||||
"install.smtp_from_invalid": "The \"Send Email As\" address is invalid",
|
||||
"install.smtp_from_helper": "Sähköpostiosoite, jota Gitea käyttää. Kirjoita osoite ”nimi” <email@example.com> -muodossa.",
|
||||
"install.mailer_user": "SMTP-käyttäjätunnus",
|
||||
"install.mailer_password": "SMTP-salasana",
|
||||
"install.test_mail_to": "Send Testing Email",
|
||||
"install.test_mail_missing_host": "Please enter the SMTP host before testing email delivery.",
|
||||
"install.test_mail_missing_recipient": "Please enter a recipient email address before testing email delivery.",
|
||||
"install.registration_title": "Registration Management",
|
||||
"install.registration_mode": "Registration Mode",
|
||||
"install.registration_mode.admin_only": "Administrator-managed accounts only",
|
||||
"install.registration_mode.admin_only_helper": "Disable self-registration and let administrators create new accounts using the selected administrator-created account mode.",
|
||||
"install.admin_created_account_mode": "Administrator-Created Account Mode",
|
||||
"install.admin_created_account_mode.local": "Create local accounts directly",
|
||||
"install.admin_created_account_mode.local_helper": "Creates active local accounts immediately. Administrators can optionally notify the user by email after creation.",
|
||||
"install.admin_created_account_mode.invite": "Create invitation-based accounts",
|
||||
"install.admin_created_account_mode.invite_helper": "Creates inactive accounts with sign-in disabled until the user accepts the emailed invitation link.",
|
||||
"install.registration_mode.local_only": "Local registration only",
|
||||
"install.registration_mode.local_only_helper": "Allow new accounts only through Gitea's built-in registration form.",
|
||||
"install.registration_mode.external_only": "External registration only",
|
||||
"install.registration_mode.external_only_helper": "Disable the local registration form and accept new accounts only from external identity providers.",
|
||||
"install.registration_mode.local_and_external": "Local and external registration",
|
||||
"install.registration_mode.local_and_external_helper": "Allow new accounts through both Gitea's local registration form and external identity providers.",
|
||||
"install.registration_local_options": "Local Registration Options",
|
||||
"install.registration_external_options": "External Registration Options",
|
||||
"install.register_confirm": "Vaadi sähköpostin vahvistaminen rekisteröintiin",
|
||||
"install.register_confirm_helper": "Require users to verify their email address before they can continue.",
|
||||
"install.register_manual_confirm": "Require Administrator Approval After Email Validation",
|
||||
"install.register_manual_confirm_helper": "New accounts stay pending until an administrator reviews and approves the request.",
|
||||
"install.mail_notify": "Ota käyttöön sähköpostiilmoitukset",
|
||||
"install.mail_notify_helper": "Controls routine notification emails such as watches, mentions, and administrative notices. Activation and invitation emails still use the SMTP configuration above.",
|
||||
"install.server_service_title": "Palvelin ja kolmansien osapuolten palveluiden asetukset",
|
||||
"install.offline_mode": "Ota käyttöön lokaali tila",
|
||||
"install.offline_mode_popup": "Poista kolmannen osapuolen sisällöstä jakeluverkot ja tarjoa kaikki resurssit paikallisesti.",
|
||||
"install.disable_gravatar": "Poista Gravatar käytöstä",
|
||||
"install.disable_gravatar_popup": "Poista Gravatar ja kolmannen osapuolen avaratir käytöstä. Oletus-avatar näytetään, ellei käyttäjä ole ladannut omaansa.",
|
||||
"install.federated_avatar_lookup": "Käytä ulkopuolisia profiilikuvia",
|
||||
"install.federated_avatar_lookup_popup": "Enable federated avatars lookup to use federated open source service based on libravatar.",
|
||||
"install.disable_registration": "Poista rekisteröinti käytöstä",
|
||||
"install.disable_registration_popup": "Poista käyttäjän itse-rekisteröinti, vain ylläpito voi luoda tilejä.",
|
||||
"install.allow_only_external_registration_popup": "Salli rekisteröinti vain ulkopuolisista palveluista",
|
||||
@@ -166,30 +199,53 @@
|
||||
"install.openid_signin_popup": "Ota käyttöön kirjautuminen OpenID:n kautta.",
|
||||
"install.openid_signup": "Ota käyttöön OpenID itse-rekisteröinti",
|
||||
"install.openid_signup_popup": "Ota käyttöön OpenID-pohjainen käyttäjän itse-rekisteröinti.",
|
||||
"install.openid_signin_helper": "Allow users to sign in through OpenID providers.",
|
||||
"install.openid_signup_helper": "Allow new accounts to be created through OpenID providers.",
|
||||
"install.enable_captcha": "Ota käyttöön CAPTCHA rekisteröityessä",
|
||||
"install.enable_captcha_popup": "Pakollinen captcha käyttäjän itse rekisteröityessä.",
|
||||
"install.require_sign_in_view": "Vaadi sisäänkirjautuminen sivujen näkemiseksi",
|
||||
"install.require_sign_in_view_popup": "Limit page access to signed-in users. Visitors will only see the sign-in and registration pages.",
|
||||
"install.admin_setting_desc": "Ylläpitotilin luominen on valinnaista. Ensimmäisestä rekisteröityneestä käyttäjästä tulee automaattisesti ylläpitäjä.",
|
||||
"install.admin_title": "Ylläpitotilin asetukset",
|
||||
"install.admin_name": "Ylläpitäjän käyttäjätunnus",
|
||||
"install.admin_password": "Salasana",
|
||||
"install.confirm_password": "Varmista salasana",
|
||||
"install.admin_email": "Sähköpostiosoite",
|
||||
"install.admin_management_policy": "Administration Management Policy",
|
||||
"install.admin_management_policy.super_admin_only": "Only super admins manage admins",
|
||||
"install.admin_management_policy.super_admin_only_helper": "Regular admins can manage only non-admin accounts. Any admin-to-admin change or deletion requires a super administrator.",
|
||||
"install.admin_management_policy.grantor_only": "Grantor manages promoted admins",
|
||||
"install.admin_management_policy.grantor_only_helper": "Regular admins can promote users to administrator and can later modify or delete only the administrators they directly promoted.",
|
||||
"install.admin_management_policy.grantor_inheritance": "Grantor chain with inheritance",
|
||||
"install.admin_management_policy.grantor_inheritance_helper": "Like grantor-only, but if the direct grantor becomes inactive or has sign-in disabled, management passes up the admin grant chain until an eligible admin is found. If none is found, super admins keep control.",
|
||||
"install.install_btn_confirm": "Asenna Gitea",
|
||||
"install.test_git_failed": "Epäonnistui testata 'git' komentoa: %v",
|
||||
"install.sqlite3_not_available": "Tämä Gitea versio ei tue SQLite3. Lataa virallinen binääriversio kohteesta %s (ei 'gobuild' versio).",
|
||||
"install.invalid_db_setting": "Tietokanta-asetukset ovat väärin: %v",
|
||||
"install.invalid_db_table": "The database table \"%s\" is invalid: %v",
|
||||
"install.invalid_repo_path": "Repojen juuri polku on virheellinen: %v",
|
||||
"install.invalid_app_data_path": "Sovelluksen datapolku on virheellinen: %v",
|
||||
"install.internal_token_failed": "Sisäisen pääsymerkin luonti epäonnistui: %v",
|
||||
"install.secret_key_failed": "Failed to generate secret key: %v",
|
||||
"install.save_config_failed": "Asetusten tallentaminen epäonnistui: %v",
|
||||
"install.invalid_admin_setting": "Administrator account setting is invalid: %v",
|
||||
"install.invalid_log_root_path": "The log path is invalid: %v",
|
||||
"install.default_keep_email_private": "Piilota sähköpostiosoitteet oletuksena",
|
||||
"install.default_keep_email_private_popup": "Piilota oletusarvoisesti uusien käyttäjätilien sähköpostiosoitteet.",
|
||||
"install.default_allow_create_organization": "Allow Creation of Organizations by Default",
|
||||
"install.default_allow_create_organization_popup": "Allow new user accounts to create organizations by default.",
|
||||
"install.default_enable_timetracking": "Ota ajan seuranta oletusarvoisesti käyttöön",
|
||||
"install.default_enable_timetracking_popup": "Ota käyttöön uusien repojen aikaseuranta oletusarvoisesti.",
|
||||
"install.no_reply_address": "Piilotettu sähköpostin verkkotunnus",
|
||||
"install.no_reply_address_helper": "Verkkotunnuksen nimi käyttäjille, joilla on piilotettu sähköpostiosoite. Esimerkiksi käyttäjätunnus 'joe' kirjataan Git nimellä 'joe@noreply.example.org' jos piilotettu sähköpostiosoite on asetettu 'noreply.example.org'.",
|
||||
"install.password_algorithm": "Salasanan hajautusalgoritmi",
|
||||
"install.invalid_password_algorithm": "Invalid password hash algorithm",
|
||||
"install.password_algorithm_helper": "Set the password hashing algorithm. Algorithms have differing requirements and strengths. The argon2 algorithm is rather secure but uses a lot of memory and may be inappropriate for small systems.",
|
||||
"install.enable_update_checker": "Enable Update Checker",
|
||||
"install.enable_update_checker_helper": "Checks for new version releases periodically by connecting to gitea.io.",
|
||||
"install.env_config_keys": "Environment Configuration",
|
||||
"install.env_config_keys_prompt": "The following environment variables will also be applied to your configuration file:",
|
||||
"install.config_write_file_prompt": "These configuration options will be written into: %s",
|
||||
"home.uname_holder": "Käyttäjätunnus tai sähköpostiosoite",
|
||||
"home.password_holder": "Salasana",
|
||||
"home.switch_dashboard_context": "Vaihda kojelaudan kontekstia",
|
||||
@@ -223,6 +279,9 @@
|
||||
"auth.forgot_password_title": "Unohtuiko salasana",
|
||||
"auth.forgot_password": "Unohtuiko salasana?",
|
||||
"auth.must_change_password": "Vaihda salasanasi",
|
||||
"auth.confirmation_mail_pending_signup": "A confirmation email has already been sent to <b>%s</b>. Please activate it before creating another account.",
|
||||
"auth.confirmation_mail_resend_failed": "The confirmation email could not be sent. Please try again later or contact an administrator.",
|
||||
"auth.confirmation_mail_resend_not_available": "This account can no longer receive confirmation emails.",
|
||||
"auth.allow_password_change": "Vaadi käyttäjää vaihtamaan salasanansa (suositeltava)",
|
||||
"auth.reset_password_mail_sent_prompt": "Varmistussähköposti on lähetetty osoitteeseen <b>%s</b>. Tarkista saapuneet seuraavan %s tunnin sisällä saadaksesi tilin palauttamisen valmiiksi.",
|
||||
"auth.active_your_account": "Aktivoi tilisi",
|
||||
@@ -1237,6 +1296,7 @@
|
||||
"admin.users.allow_create_organization": "Voi luoda organisaatioita",
|
||||
"admin.users.update_profile": "Päivitä käyttäjän tili",
|
||||
"admin.users.delete_account": "Poista käyttäjän tili",
|
||||
"admin.users.send_register_invite": "Send User Registration Invitation",
|
||||
"admin.users.list_status_filter.menu_text": "Suodata",
|
||||
"admin.users.list_status_filter.reset": "Tyhjennä",
|
||||
"admin.users.list_status_filter.is_active": "Aktiivinen",
|
||||
@@ -1474,5 +1534,15 @@
|
||||
"actions.runners.labels": "Tunnisteet",
|
||||
"actions.runners.task_list.run": "Suorita",
|
||||
"actions.runners.task_list.repository": "Repo",
|
||||
"actions.runners.version": "Versio"
|
||||
"actions.runners.version": "Versio",
|
||||
"auth.accept_your_invitation": "Accept Your Invitation",
|
||||
"auth.invitation_mail_pending_login": "An invitation email has already been sent to <b>%s</b>. Please accept it before signing in.",
|
||||
"auth.invitation_mail_sent_prompt_ex": "A new invitation email has been sent to <b>%s</b>. Please use the link within the next %s to activate your account.",
|
||||
"auth.invitation_mail_resend_failed": "The invitation email could not be sent. Please try again later or contact an administrator.",
|
||||
"auth.invitation_mail_resend_not_available": "This account can no longer receive invitation emails.",
|
||||
"auth.invitation_resend_prompt": "Did not receive the invitation email?",
|
||||
"auth.invitation_resend_button": "Resend",
|
||||
"admin.users.send_register_notify_helper": "The account will be activated and validated immediately.",
|
||||
"admin.users.send_register_invite_helper": "The user must accept the emailed invitation before the account becomes active.",
|
||||
"install.language_balloon": "Choose a language"
|
||||
}
|
||||
|
||||
@@ -262,6 +262,8 @@
|
||||
"install.general_title": "Configuration générale",
|
||||
"install.app_name": "Titre du site",
|
||||
"install.app_name_helper": "Entrez ici le nom de votre société.",
|
||||
"install.default_language": "Default Language",
|
||||
"install.default_language_helper": "Used when a user's browser language does not match an available locale.",
|
||||
"install.repo_path": "Emplacement racine des dépôts",
|
||||
"install.repo_path_helper": "Les dépôts Git distants seront stockés dans ce répertoire.",
|
||||
"install.lfs_path": "Répertoire racine Git LFS",
|
||||
@@ -287,8 +289,32 @@
|
||||
"install.smtp_from_helper": "Adresse courriel utilisée par Gitea. Utilisez directement votre adresse ou la forme « Nom <email@example.com> ».",
|
||||
"install.mailer_user": "Utilisateur SMTP",
|
||||
"install.mailer_password": "Mot de passe SMTP",
|
||||
"install.test_mail_to": "Send Testing Email",
|
||||
"install.test_mail_missing_host": "Please enter the SMTP host before testing email delivery.",
|
||||
"install.test_mail_missing_recipient": "Please enter a recipient email address before testing email delivery.",
|
||||
"install.registration_title": "Registration Management",
|
||||
"install.registration_mode": "Registration Mode",
|
||||
"install.registration_mode.admin_only": "Administrator-managed accounts only",
|
||||
"install.registration_mode.admin_only_helper": "Disable self-registration and let administrators create new accounts using the selected administrator-created account mode.",
|
||||
"install.admin_created_account_mode": "Administrator-Created Account Mode",
|
||||
"install.admin_created_account_mode.local": "Create local accounts directly",
|
||||
"install.admin_created_account_mode.local_helper": "Creates active local accounts immediately. Administrators can optionally notify the user by email after creation.",
|
||||
"install.admin_created_account_mode.invite": "Create invitation-based accounts",
|
||||
"install.admin_created_account_mode.invite_helper": "Creates inactive accounts with sign-in disabled until the user accepts the emailed invitation link.",
|
||||
"install.registration_mode.local_only": "Local registration only",
|
||||
"install.registration_mode.local_only_helper": "Allow new accounts only through Gitea's built-in registration form.",
|
||||
"install.registration_mode.external_only": "External registration only",
|
||||
"install.registration_mode.external_only_helper": "Disable the local registration form and accept new accounts only from external identity providers.",
|
||||
"install.registration_mode.local_and_external": "Local and external registration",
|
||||
"install.registration_mode.local_and_external_helper": "Allow new accounts through both Gitea's local registration form and external identity providers.",
|
||||
"install.registration_local_options": "Local Registration Options",
|
||||
"install.registration_external_options": "External Registration Options",
|
||||
"install.register_confirm": "Exiger la confirmation du courriel lors de l’inscription",
|
||||
"install.register_confirm_helper": "Require users to verify their email address before they can continue.",
|
||||
"install.register_manual_confirm": "Require Administrator Approval After Email Validation",
|
||||
"install.register_manual_confirm_helper": "New accounts stay pending until an administrator reviews and approves the request.",
|
||||
"install.mail_notify": "Activer les notifications par courriel",
|
||||
"install.mail_notify_helper": "Controls routine notification emails such as watches, mentions, and administrative notices. Activation and invitation emails still use the SMTP configuration above.",
|
||||
"install.server_service_title": "Paramètres Serveur et Tierce Parties",
|
||||
"install.disable_registration": "Désactiver le formulaire d'inscription",
|
||||
"install.disable_registration_popup": "Désactiver les nouvelles inscriptions. Seuls les administrateurs pourront créer de nouveaux comptes utilisateurs.",
|
||||
@@ -297,6 +323,8 @@
|
||||
"install.openid_signin_popup": "Activer l'authentification via OpenID.",
|
||||
"install.openid_signup": "Activer l'inscription OpenID",
|
||||
"install.openid_signup_popup": "Activer l'inscription avec OpenID.",
|
||||
"install.openid_signin_helper": "Allow users to sign in through OpenID providers.",
|
||||
"install.openid_signup_helper": "Allow new accounts to be created through OpenID providers.",
|
||||
"install.enable_captcha": "Activer le CAPTCHA d'inscription",
|
||||
"install.enable_captcha_popup": "Demander un CAPTCHA à l'inscription.",
|
||||
"install.require_sign_in_view": "Exiger la connexion à un compte pour afficher les pages",
|
||||
@@ -307,6 +335,13 @@
|
||||
"install.admin_password": "Mot de passe",
|
||||
"install.confirm_password": "Confirmez le mot de passe",
|
||||
"install.admin_email": "Courriel",
|
||||
"install.admin_management_policy": "Administration Management Policy",
|
||||
"install.admin_management_policy.super_admin_only": "Only super admins manage admins",
|
||||
"install.admin_management_policy.super_admin_only_helper": "Regular admins can manage only non-admin accounts. Any admin-to-admin change or deletion requires a super administrator.",
|
||||
"install.admin_management_policy.grantor_only": "Grantor manages promoted admins",
|
||||
"install.admin_management_policy.grantor_only_helper": "Regular admins can promote users to administrator and can later modify or delete only the administrators they directly promoted.",
|
||||
"install.admin_management_policy.grantor_inheritance": "Grantor chain with inheritance",
|
||||
"install.admin_management_policy.grantor_inheritance_helper": "Like grantor-only, but if the direct grantor becomes inactive or has sign-in disabled, management passes up the admin grant chain until an eligible admin is found. If none is found, super admins keep control.",
|
||||
"install.install_btn_confirm": "Installer Gitea",
|
||||
"install.test_git_failed": "Le test de la commande \"git\" a échoué : %v",
|
||||
"install.sqlite3_not_available": "Cette version de Gitea ne supporte pas SQLite3. Veuillez télécharger la version binaire officielle de %s (pas la version 'gobuild').",
|
||||
@@ -314,7 +349,6 @@
|
||||
"install.invalid_db_table": "La table \"%s\" de la base de données est invalide : %v",
|
||||
"install.invalid_repo_path": "Le chemin racine du dépôt est invalide : %v",
|
||||
"install.invalid_app_data_path": "Le chemin des données de l'application est invalide : %v",
|
||||
"install.run_user_not_match": "Le nom d'utilisateur sous lequel Gitea est configuré n'est pas le nom d'utilisateur actuel: %s -> %s",
|
||||
"install.internal_token_failed": "Impossible de générer le jeton interne : %v",
|
||||
"install.secret_key_failed": "Impossible de générer la clé secrète : %v",
|
||||
"install.save_config_failed": "L'enregistrement de la configuration %v a échoué",
|
||||
@@ -387,6 +421,9 @@
|
||||
"auth.sign_up_now": "Inscrivez-vous dès maintenant !",
|
||||
"auth.sign_up_successful": "Le compte a été créé avec succès. Bienvenue !",
|
||||
"auth.confirmation_mail_sent_prompt_ex": "Un nouveau courriel de confirmation a été envoyé à <b>%s</b>. Veuillez vérifier votre boîte de réception dans la prochaine %s pour terminer le processus d’inscription. Si votre adresse courriel est incorrecte, vous pouvez vous reconnecter et la modifier.",
|
||||
"auth.confirmation_mail_pending_signup": "A confirmation email has already been sent to <b>%s</b>. Please activate it before creating another account.",
|
||||
"auth.confirmation_mail_resend_failed": "The confirmation email could not be sent. Please try again later or contact an administrator.",
|
||||
"auth.confirmation_mail_resend_not_available": "This account can no longer receive confirmation emails.",
|
||||
"auth.must_change_password": "Réinitialisez votre mot de passe",
|
||||
"auth.allow_password_change": "Demande à l'utilisateur de changer son mot de passe (recommandé)",
|
||||
"auth.reset_password_mail_sent_prompt": "Un mail de confirmation a été envoyé à <b>%s</b>. Veuillez vérifier votre boîte de réception dans les prochaines %s pour terminer la procédure de récupération du compte.",
|
||||
@@ -3006,6 +3043,7 @@
|
||||
"admin.users.last_login": "Dernière connexion",
|
||||
"admin.users.never_login": "Jamais connecté",
|
||||
"admin.users.send_register_notify": "Envoyer une notification d'inscription",
|
||||
"admin.users.send_register_invite": "Send User Registration Invitation",
|
||||
"admin.users.new_success": "Le compte \"%s\" a bien été créé.",
|
||||
"admin.users.edit": "Éditer",
|
||||
"admin.users.auth_source": "Sources d'authentification",
|
||||
@@ -3819,5 +3857,15 @@
|
||||
"actions.general.cross_repo_desc": "Permet aux dépôts sélectionnés d’être visible en lecture-seule par tous les dépôts de ce propriétaire à l’aide de GITEA_TOKEN lors de l’exécution des tâches d’actions.",
|
||||
"actions.general.cross_repo_selected": "Dépôts sélectionnés",
|
||||
"actions.general.cross_repo_target_repos": "Dépôts cibles",
|
||||
"actions.general.cross_repo_add": "Ajouter un dépôt cible"
|
||||
"actions.general.cross_repo_add": "Ajouter un dépôt cible",
|
||||
"auth.accept_your_invitation": "Accept Your Invitation",
|
||||
"auth.invitation_mail_pending_login": "An invitation email has already been sent to <b>%s</b>. Please accept it before signing in.",
|
||||
"auth.invitation_mail_sent_prompt_ex": "A new invitation email has been sent to <b>%s</b>. Please use the link within the next %s to activate your account.",
|
||||
"auth.invitation_mail_resend_failed": "The invitation email could not be sent. Please try again later or contact an administrator.",
|
||||
"auth.invitation_mail_resend_not_available": "This account can no longer receive invitation emails.",
|
||||
"auth.invitation_resend_prompt": "Did not receive the invitation email?",
|
||||
"auth.invitation_resend_button": "Resend",
|
||||
"admin.users.send_register_notify_helper": "The account will be activated and validated immediately.",
|
||||
"admin.users.send_register_invite_helper": "The user must accept the emailed invitation before the account becomes active.",
|
||||
"install.language_balloon": "Choose a language"
|
||||
}
|
||||
|
||||
@@ -262,6 +262,8 @@
|
||||
"install.general_title": "Socruithe Ginearálta",
|
||||
"install.app_name": "Teideal an tSuímh",
|
||||
"install.app_name_helper": "Is féidir leat ainm do chuideachta a iontráil anseo.",
|
||||
"install.default_language": "Default Language",
|
||||
"install.default_language_helper": "Used when a user's browser language does not match an available locale.",
|
||||
"install.repo_path": "Cosán Fréimhe an Stór",
|
||||
"install.repo_path_helper": "Sábhálfar stórais iargúlta Git chuig an eolaire seo.",
|
||||
"install.lfs_path": "Cosán Fréamh Git LFS",
|
||||
@@ -287,8 +289,32 @@
|
||||
"install.smtp_from_helper": "Seoladh ríomhphoist a úsáidfidh Gitea. Cuir isteach seoladh ríomhphoist simplí nó úsáid an fhormáid \"Ainm\" <email@example.com>.",
|
||||
"install.mailer_user": "SMTP Ainm úsáideora",
|
||||
"install.mailer_password": "Pasfhocal SMTP",
|
||||
"install.test_mail_to": "Send Testing Email",
|
||||
"install.test_mail_missing_host": "Please enter the SMTP host before testing email delivery.",
|
||||
"install.test_mail_missing_recipient": "Please enter a recipient email address before testing email delivery.",
|
||||
"install.registration_title": "Registration Management",
|
||||
"install.registration_mode": "Registration Mode",
|
||||
"install.registration_mode.admin_only": "Administrator-managed accounts only",
|
||||
"install.registration_mode.admin_only_helper": "Disable self-registration and let administrators create new accounts using the selected administrator-created account mode.",
|
||||
"install.admin_created_account_mode": "Administrator-Created Account Mode",
|
||||
"install.admin_created_account_mode.local": "Create local accounts directly",
|
||||
"install.admin_created_account_mode.local_helper": "Creates active local accounts immediately. Administrators can optionally notify the user by email after creation.",
|
||||
"install.admin_created_account_mode.invite": "Create invitation-based accounts",
|
||||
"install.admin_created_account_mode.invite_helper": "Creates inactive accounts with sign-in disabled until the user accepts the emailed invitation link.",
|
||||
"install.registration_mode.local_only": "Local registration only",
|
||||
"install.registration_mode.local_only_helper": "Allow new accounts only through Gitea's built-in registration form.",
|
||||
"install.registration_mode.external_only": "External registration only",
|
||||
"install.registration_mode.external_only_helper": "Disable the local registration form and accept new accounts only from external identity providers.",
|
||||
"install.registration_mode.local_and_external": "Local and external registration",
|
||||
"install.registration_mode.local_and_external_helper": "Allow new accounts through both Gitea's local registration form and external identity providers.",
|
||||
"install.registration_local_options": "Local Registration Options",
|
||||
"install.registration_external_options": "External Registration Options",
|
||||
"install.register_confirm": "Deimhniú Ríomhphoist a cheangal le Clárú",
|
||||
"install.register_confirm_helper": "Require users to verify their email address before they can continue.",
|
||||
"install.register_manual_confirm": "Require Administrator Approval After Email Validation",
|
||||
"install.register_manual_confirm_helper": "New accounts stay pending until an administrator reviews and approves the request.",
|
||||
"install.mail_notify": "Cumasaigh Fógraí Ríomhphoist",
|
||||
"install.mail_notify_helper": "Controls routine notification emails such as watches, mentions, and administrative notices. Activation and invitation emails still use the SMTP configuration above.",
|
||||
"install.server_service_title": "Socruithe Freastalaí agus Seirbhíse Tríú Páirtí",
|
||||
"install.disable_registration": "Díchumasaigh Féin-Chlárú",
|
||||
"install.disable_registration_popup": "Díchumasaigh féinchlárú úsáideora. Ní bheidh ach riarthóirí in ann cuntais úsáideora nua a chruthú.",
|
||||
@@ -297,6 +323,8 @@
|
||||
"install.openid_signin_popup": "Cumasaigh síniú isteach úsáideora trí OpenID.",
|
||||
"install.openid_signup": "Cumasaigh Féinchlárú OpenID",
|
||||
"install.openid_signup_popup": "Cumasaigh féinchlárú úsáideora bunaithe ar OpenID.",
|
||||
"install.openid_signin_helper": "Allow users to sign in through OpenID providers.",
|
||||
"install.openid_signup_helper": "Allow new accounts to be created through OpenID providers.",
|
||||
"install.enable_captcha": "Cumasaigh clárú CAPTCHA",
|
||||
"install.enable_captcha_popup": "Teastaíonn CAPTCHA le haghaidh féinchlárú úsáideora.",
|
||||
"install.require_sign_in_view": "Teastaíonn Sínigh isteach chun Leathanaigh Amharc",
|
||||
@@ -307,6 +335,13 @@
|
||||
"install.admin_password": "Pasfhocal",
|
||||
"install.confirm_password": "Deimhnigh Pasfhocal",
|
||||
"install.admin_email": "Seoladh ríomhphoist",
|
||||
"install.admin_management_policy": "Administration Management Policy",
|
||||
"install.admin_management_policy.super_admin_only": "Only super admins manage admins",
|
||||
"install.admin_management_policy.super_admin_only_helper": "Regular admins can manage only non-admin accounts. Any admin-to-admin change or deletion requires a super administrator.",
|
||||
"install.admin_management_policy.grantor_only": "Grantor manages promoted admins",
|
||||
"install.admin_management_policy.grantor_only_helper": "Regular admins can promote users to administrator and can later modify or delete only the administrators they directly promoted.",
|
||||
"install.admin_management_policy.grantor_inheritance": "Grantor chain with inheritance",
|
||||
"install.admin_management_policy.grantor_inheritance_helper": "Like grantor-only, but if the direct grantor becomes inactive or has sign-in disabled, management passes up the admin grant chain until an eligible admin is found. If none is found, super admins keep control.",
|
||||
"install.install_btn_confirm": "Suiteáil Gitea",
|
||||
"install.test_git_failed": "Ní féidir ordú 'git' a thástáil: %v",
|
||||
"install.sqlite3_not_available": "Ní thacaíonn an leagan Gitea seo le SQLite3. Íoslódáil an leagan dénártha oifigiúil ó %s (ní an leagan 'gobuild').",
|
||||
@@ -314,7 +349,6 @@
|
||||
"install.invalid_db_table": "Tá an tábla bunachar sonraí \"%s\" neamhbhailí: %v",
|
||||
"install.invalid_repo_path": "Tá cosán fréimhe an stór neamhbhailí:%v",
|
||||
"install.invalid_app_data_path": "Tá cosán sonraí an aip neamhbhailí:%v",
|
||||
"install.run_user_not_match": "Ní hé an t-ainm úsáideora 'rith mar' an t-ainm úsáideora reatha: %s -> %s",
|
||||
"install.internal_token_failed": "Theip ar chomhartha inmheánach a ghiniúint:%v",
|
||||
"install.secret_key_failed": "Theip ar an eochair rúnda a ghiniúint:%v",
|
||||
"install.save_config_failed": "Theip ar chumraíocht a shábháil:%v",
|
||||
@@ -387,6 +421,9 @@
|
||||
"auth.sign_up_now": "Cláraigh anois.",
|
||||
"auth.sign_up_successful": "Cruthaíodh cuntas go rathúil. Fáilte romhat!",
|
||||
"auth.confirmation_mail_sent_prompt_ex": "Tá ríomhphost dearbhaithe nua seolta chuig <b>%s</b>. Seiceáil do bhosca isteach laistigh den chéad %s eile chun an próiseas clárúcháin a chur i gcrích. Má tá do sheoladh ríomhphoist clárúcháin mícheart, is féidir leat síniú isteach arís agus é a athrú.",
|
||||
"auth.confirmation_mail_pending_signup": "A confirmation email has already been sent to <b>%s</b>. Please activate it before creating another account.",
|
||||
"auth.confirmation_mail_resend_failed": "The confirmation email could not be sent. Please try again later or contact an administrator.",
|
||||
"auth.confirmation_mail_resend_not_available": "This account can no longer receive confirmation emails.",
|
||||
"auth.must_change_password": "Nuashonraigh do phasfhocal",
|
||||
"auth.allow_password_change": "A cheangal ar an úsáideoir pasfhocal a athrú (molta)",
|
||||
"auth.reset_password_mail_sent_prompt": "Seoladh ríomhphost deimhnithe chu <b>ig %s</b>. Seiceáil do bhosca isteach laistigh den chéad %s eile chun an próiseas aisghabhála cuntais a chríochnú.",
|
||||
@@ -3008,6 +3045,7 @@
|
||||
"admin.users.last_login": "Sínigh Isteach Deiridh",
|
||||
"admin.users.never_login": "Ná Sínigh Isteach riamh",
|
||||
"admin.users.send_register_notify": "Seol Fógra um Chlárú Úsáideora",
|
||||
"admin.users.send_register_invite": "Send User Registration Invitation",
|
||||
"admin.users.new_success": "Tá an cuntas úsáideora \"%s\" cruthaithe.",
|
||||
"admin.users.edit": "Eagar",
|
||||
"admin.users.auth_source": "Foinse Fíordheimhnithe",
|
||||
@@ -3819,5 +3857,15 @@
|
||||
"actions.general.cross_repo_desc": "Ceadaigh rochtain (léamh amháin) a bheith ag na stórtha uile san úinéir seo ar na stórtha roghnaithe le GITEA_TOKEN agus poist Gníomhartha á reáchtáil.",
|
||||
"actions.general.cross_repo_selected": "Stórtha roghnaithe",
|
||||
"actions.general.cross_repo_target_repos": "Stórtha Spriocdhírithe",
|
||||
"actions.general.cross_repo_add": "Cuir Stór Sprioc leis"
|
||||
"actions.general.cross_repo_add": "Cuir Stór Sprioc leis",
|
||||
"auth.accept_your_invitation": "Accept Your Invitation",
|
||||
"auth.invitation_mail_pending_login": "An invitation email has already been sent to <b>%s</b>. Please accept it before signing in.",
|
||||
"auth.invitation_mail_sent_prompt_ex": "A new invitation email has been sent to <b>%s</b>. Please use the link within the next %s to activate your account.",
|
||||
"auth.invitation_mail_resend_failed": "The invitation email could not be sent. Please try again later or contact an administrator.",
|
||||
"auth.invitation_mail_resend_not_available": "This account can no longer receive invitation emails.",
|
||||
"auth.invitation_resend_prompt": "Did not receive the invitation email?",
|
||||
"auth.invitation_resend_button": "Resend",
|
||||
"admin.users.send_register_notify_helper": "The account will be activated and validated immediately.",
|
||||
"admin.users.send_register_invite_helper": "The user must accept the emailed invitation before the account becomes active.",
|
||||
"install.language_balloon": "Choose a language"
|
||||
}
|
||||
|
||||
@@ -81,8 +81,10 @@
|
||||
"startpage.lightweight": "Könnyűsúlyú",
|
||||
"startpage.license": "Nyílt forráskódú",
|
||||
"install.install": "Telepítés",
|
||||
"install.installing_desc": "Installing now, please wait…",
|
||||
"install.title": "Kezdeti konfiguráció",
|
||||
"install.docker_helper": "Ha ön a Gitea-t Docker-ből futtatja, kérem olvassa el a <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"%s\">dokumentációt</a> a beállítások megváltoztatása előtt.",
|
||||
"install.require_db_desc": "Gitea requires MySQL, PostgreSQL, MSSQL, SQLite3 or TiDB (MySQL protocol).",
|
||||
"install.db_title": "Adatbázis beállítások",
|
||||
"install.db_type": "Adatbázis típusa",
|
||||
"install.host": "Kiszolgáló",
|
||||
@@ -91,22 +93,38 @@
|
||||
"install.db_name": "Adatbázis neve",
|
||||
"install.db_schema": "Séma",
|
||||
"install.db_schema_helper": "Az adatbázis alapértelmezett beállításához (\"public\") üresen kell hagyni.",
|
||||
"install.ssl_mode": "SSL",
|
||||
"install.path": "Elérési út",
|
||||
"install.sqlite_helper": "A SQLite3 adatbázis elérési útvonala.<br>Kérjük adjon meg egy abszolút elérési útvonalat, ha a Gitea-t szolgáltatásként futtatja.",
|
||||
"install.reinstall_error": "You are trying to install into an existing Gitea database",
|
||||
"install.reinstall_confirm_message": "Re-installing with an existing Gitea database can cause multiple problems. In most cases, you should use your existing \"app.ini\" to run Gitea. If you know what you are doing, confirm the following:",
|
||||
"install.reinstall_confirm_check_1": "The data encrypted by the SECRET_KEY in app.ini may be lost: users may not be able to log in with 2FA/OTP and mirrors may not function correctly. By checking this box, you confirm that the current app.ini file contains the correct SECRET_KEY.",
|
||||
"install.reinstall_confirm_check_2": "The repositories and settings may need to be resynchronized. By checking this box, you confirm that you will resynchronize the hooks for the repositories and authorized_keys file manually. You confirm that you will ensure that repository and mirror settings are correct.",
|
||||
"install.reinstall_confirm_check_3": "You confirm that you are absolutely sure that this Gitea is running with the correct app.ini location and that you are sure that you have to re-install. You confirm that you acknowledge the above risks.",
|
||||
"install.err_empty_db_path": "SQLite3 adatbázis elérési útvonala nem lehet üres.",
|
||||
"install.no_admin_and_disable_registration": "Nem tilthatja le a regisztrációt, amíg nem hoz létre egy rendszergazdai fiókot.",
|
||||
"install.err_empty_admin_password": "A rendszergazdai jelszó nem lehet üres.",
|
||||
"install.err_empty_admin_email": "The administrator email address cannot be empty.",
|
||||
"install.err_admin_name_is_reserved": "Administrator username is invalid. Username is reserved.",
|
||||
"install.err_admin_name_pattern_not_allowed": "Administrator username is invalid. The username matches a reserved pattern.",
|
||||
"install.err_admin_name_is_invalid": "Administrator username is invalid",
|
||||
"install.general_title": "Általános beállítások",
|
||||
"install.app_name": "Webhely címe",
|
||||
"install.app_name_helper": "Itt megadhatja a vállalata nevét.",
|
||||
"install.default_language": "Default Language",
|
||||
"install.default_language_helper": "Used when a user's browser language does not match an available locale.",
|
||||
"install.repo_path": "Tárolók gyökérkönyvtára",
|
||||
"install.repo_path_helper": "Minden távoli Git tároló ebbe a mappába lesz mentve.",
|
||||
"install.lfs_path": "LFS Gyökérkönyvtár",
|
||||
"install.lfs_path_helper": "A fájlok amiket Git LFS-el elmentesz ebbe a könyvtárba kerülnek. Hagyd üresen az LFS kikapcsolásához.",
|
||||
"install.run_user": "Futtatás mint",
|
||||
"install.run_user_helper": "The operating system username that Gitea runs as, it must have write access to the data paths. This value is auto-detected and cannot be changed here. To use a different user, restart Gitea under that account.",
|
||||
"install.domain": "Server Domain",
|
||||
"install.domain_helper": "Domain or host address for the server.",
|
||||
"install.ssh_port": "SSH szerver port",
|
||||
"install.ssh_port_helper": "SSH port amit az ön szervere használni fog. Hagyja üresen a kikapcsoláshoz.",
|
||||
"install.http_port": "Gitea HTTP Figyelő Port",
|
||||
"install.http_port_helper": "Port number the Gitea web server will listen on.",
|
||||
"install.app_url": "Az oldal alapértelmezett címe",
|
||||
"install.app_url_helper": "Alapcím HTTP(S) klón címekhez és e-mail értesítésekhez.",
|
||||
"install.log_root_path": "Naplófájl elérési útja",
|
||||
@@ -116,18 +134,37 @@
|
||||
"install.smtp_addr": "SMTP kiszolgáló",
|
||||
"install.smtp_port": "SMTP port",
|
||||
"install.smtp_from": "E-mail küldése mint",
|
||||
"install.smtp_from_invalid": "The \"Send Email As\" address is invalid",
|
||||
"install.smtp_from_helper": "Az E-mail cím a mit a Gitea használni fog. Megadhatja sima email címként vagy \"Név<email@példa.hu>\" formátumban.",
|
||||
"install.mailer_user": "SMTP-felhasználónév",
|
||||
"install.mailer_password": "SMTP-jelszó",
|
||||
"install.test_mail_to": "Send Testing Email",
|
||||
"install.test_mail_missing_host": "Please enter the SMTP host before testing email delivery.",
|
||||
"install.test_mail_missing_recipient": "Please enter a recipient email address before testing email delivery.",
|
||||
"install.registration_title": "Registration Management",
|
||||
"install.registration_mode": "Registration Mode",
|
||||
"install.registration_mode.admin_only": "Administrator-managed accounts only",
|
||||
"install.registration_mode.admin_only_helper": "Disable self-registration and let administrators create new accounts using the selected administrator-created account mode.",
|
||||
"install.admin_created_account_mode": "Administrator-Created Account Mode",
|
||||
"install.admin_created_account_mode.local": "Create local accounts directly",
|
||||
"install.admin_created_account_mode.local_helper": "Creates active local accounts immediately. Administrators can optionally notify the user by email after creation.",
|
||||
"install.admin_created_account_mode.invite": "Create invitation-based accounts",
|
||||
"install.admin_created_account_mode.invite_helper": "Creates inactive accounts with sign-in disabled until the user accepts the emailed invitation link.",
|
||||
"install.registration_mode.local_only": "Local registration only",
|
||||
"install.registration_mode.local_only_helper": "Allow new accounts only through Gitea's built-in registration form.",
|
||||
"install.registration_mode.external_only": "External registration only",
|
||||
"install.registration_mode.external_only_helper": "Disable the local registration form and accept new accounts only from external identity providers.",
|
||||
"install.registration_mode.local_and_external": "Local and external registration",
|
||||
"install.registration_mode.local_and_external_helper": "Allow new accounts through both Gitea's local registration form and external identity providers.",
|
||||
"install.registration_local_options": "Local Registration Options",
|
||||
"install.registration_external_options": "External Registration Options",
|
||||
"install.register_confirm": "A regisztrációhoz e-mail visszaigazolás szükséges",
|
||||
"install.register_confirm_helper": "Require users to verify their email address before they can continue.",
|
||||
"install.register_manual_confirm": "Require Administrator Approval After Email Validation",
|
||||
"install.register_manual_confirm_helper": "New accounts stay pending until an administrator reviews and approves the request.",
|
||||
"install.mail_notify": "Email értesítés engedélyezése",
|
||||
"install.mail_notify_helper": "Controls routine notification emails such as watches, mentions, and administrative notices. Activation and invitation emails still use the SMTP configuration above.",
|
||||
"install.server_service_title": "Szerver és egyéb szolgáltatások beállítása",
|
||||
"install.offline_mode": "Helyi mód bekapcsolása",
|
||||
"install.offline_mode_popup": "Gravatar és egyedi források kikapcsolása, minden avatárt a felhasználók töltenek fel.",
|
||||
"install.disable_gravatar": "Gravatar Kikapcsolása",
|
||||
"install.disable_gravatar_popup": "Gravatar és a harmadik féltől származó avatar források letoltása. Alapértelmezett avatárt fog használni, kivéve, ha a felhasználó helyileg tölt fel avatárt.",
|
||||
"install.federated_avatar_lookup": "Összevont profilkép lekérés engedélyezése",
|
||||
"install.federated_avatar_lookup_popup": "Összevont profilkép lekérés engedélyezése a libravatar használatával.",
|
||||
"install.disable_registration": "Ön-regisztráció kikapcsolása",
|
||||
"install.disable_registration_popup": "Regisztráció kikapcsolása, csak a rendszergazda hozhat létre fiókokat.",
|
||||
"install.allow_only_external_registration_popup": "Regisztráció engedélyezése csak külső forrásokból",
|
||||
@@ -135,20 +172,34 @@
|
||||
"install.openid_signin_popup": "Felhasználói bejelentkezés engedélyezése OpenID-val.",
|
||||
"install.openid_signup": "Regisztráció engedélyezése OpenID alapon",
|
||||
"install.openid_signup_popup": "Regisztráció engedélyezése OpenID alapon.",
|
||||
"install.openid_signin_helper": "Allow users to sign in through OpenID providers.",
|
||||
"install.openid_signup_helper": "Allow new accounts to be created through OpenID providers.",
|
||||
"install.enable_captcha": "Enable registration CAPTCHA",
|
||||
"install.enable_captcha_popup": "CAPTCHA megkövetelése amikor egy felhasználó regisztrál.",
|
||||
"install.require_sign_in_view": "Bejelentkezés megkövetelése az oldalak megtekintéséhez",
|
||||
"install.require_sign_in_view_popup": "Limit page access to signed-in users. Visitors will only see the sign-in and registration pages.",
|
||||
"install.admin_setting_desc": "Nem szükséges most beállítania rendszergazdai fiókot, mert az első felhasználó automatikusan rendszergazdai jogokat kap.",
|
||||
"install.admin_title": "Rendszergazda fiók beállításai",
|
||||
"install.admin_name": "Rendszergazda felhasználóneve",
|
||||
"install.admin_password": "Jelszó",
|
||||
"install.confirm_password": "Jelszó megerősítése",
|
||||
"install.admin_email": "E-mail cím",
|
||||
"install.admin_management_policy": "Administration Management Policy",
|
||||
"install.admin_management_policy.super_admin_only": "Only super admins manage admins",
|
||||
"install.admin_management_policy.super_admin_only_helper": "Regular admins can manage only non-admin accounts. Any admin-to-admin change or deletion requires a super administrator.",
|
||||
"install.admin_management_policy.grantor_only": "Grantor manages promoted admins",
|
||||
"install.admin_management_policy.grantor_only_helper": "Regular admins can promote users to administrator and can later modify or delete only the administrators they directly promoted.",
|
||||
"install.admin_management_policy.grantor_inheritance": "Grantor chain with inheritance",
|
||||
"install.admin_management_policy.grantor_inheritance_helper": "Like grantor-only, but if the direct grantor becomes inactive or has sign-in disabled, management passes up the admin grant chain until an eligible admin is found. If none is found, super admins keep control.",
|
||||
"install.install_btn_confirm": "Gitea telepítése",
|
||||
"install.test_git_failed": "Nem sikerült a 'git' parancs kipróbálása: %v",
|
||||
"install.sqlite3_not_available": "Ez a verzió nem támogatja az SQLite3-at, kérlek töltsd le a hivatalos bináris verziót: %s (NE a gobuild változatot).",
|
||||
"install.invalid_db_setting": "Az adatbázis-beállítások érvénytelenek: %v",
|
||||
"install.invalid_db_table": "The database table \"%s\" is invalid: %v",
|
||||
"install.invalid_repo_path": "Repository gyökérkönyvtára helytelen: %v",
|
||||
"install.run_user_not_match": "Futtató felhasználó más, mint az aktuális felhasználó: %s -> %s",
|
||||
"install.invalid_app_data_path": "The app data path is invalid: %v",
|
||||
"install.internal_token_failed": "Failed to generate internal token: %v",
|
||||
"install.secret_key_failed": "Failed to generate secret key: %v",
|
||||
"install.save_config_failed": "Hiba történt a konfiguráció mentése közben: %v",
|
||||
"install.invalid_admin_setting": "Hibás a rendszergazdai fiók beállítása: %v",
|
||||
"install.invalid_log_root_path": "Naplózás gyökérmappa érvénytelen: %v",
|
||||
@@ -160,6 +211,14 @@
|
||||
"install.default_enable_timetracking_popup": "Időmérés bekapcsolása az új tárolókra alapértelmezetten.",
|
||||
"install.no_reply_address": "Rejtett e-mail tartomány",
|
||||
"install.no_reply_address_helper": "Domain név a rejtett email címmel rendelkező felhasználók számára.Például: Ha a felhasználóneve \"jani\" akkor bejelentkezhet a \"jani@noreply.example.org\" email címmel,ha a rejtett email domain \"noreply.example.org\"-ra van állítva.",
|
||||
"install.password_algorithm": "Password Hash Algorithm",
|
||||
"install.invalid_password_algorithm": "Invalid password hash algorithm",
|
||||
"install.password_algorithm_helper": "Set the password hashing algorithm. Algorithms have differing requirements and strengths. The argon2 algorithm is rather secure but uses a lot of memory and may be inappropriate for small systems.",
|
||||
"install.enable_update_checker": "Enable Update Checker",
|
||||
"install.enable_update_checker_helper": "Checks for new version releases periodically by connecting to gitea.io.",
|
||||
"install.env_config_keys": "Environment Configuration",
|
||||
"install.env_config_keys_prompt": "The following environment variables will also be applied to your configuration file:",
|
||||
"install.config_write_file_prompt": "These configuration options will be written into: %s",
|
||||
"home.uname_holder": "Felhasználónév vagy e-mail cím",
|
||||
"home.password_holder": "Jelszó",
|
||||
"home.switch_dashboard_context": "Műszerfal nézőpont váltás",
|
||||
@@ -187,6 +246,9 @@
|
||||
"auth.forgot_password_title": "Elfelejtett jelszó",
|
||||
"auth.forgot_password": "Elfelejtette a jelszavát?",
|
||||
"auth.must_change_password": "Jelszó módosítása",
|
||||
"auth.confirmation_mail_pending_signup": "A confirmation email has already been sent to <b>%s</b>. Please activate it before creating another account.",
|
||||
"auth.confirmation_mail_resend_failed": "The confirmation email could not be sent. Please try again later or contact an administrator.",
|
||||
"auth.confirmation_mail_resend_not_available": "This account can no longer receive confirmation emails.",
|
||||
"auth.allow_password_change": "A felhasználóknak meg kell változtatniuk a jelszavukat(ajánlott)",
|
||||
"auth.reset_password_mail_sent_prompt": "Megerősítő email lett küldve ide: <b>%s</b>. Ellenőrizze postafiókját az elkövetkező %s a jelszó visszaállítási folyamat befejezéséhez.",
|
||||
"auth.active_your_account": "Aktiválja a fiókját",
|
||||
@@ -1109,6 +1171,7 @@
|
||||
"admin.users.created": "Létrehozva",
|
||||
"admin.users.last_login": "Utolsó bejelentkezés",
|
||||
"admin.users.send_register_notify": "Felhasználó regisztráció értesítés küldése",
|
||||
"admin.users.send_register_invite": "Send User Registration Invitation",
|
||||
"admin.users.edit": "Szerkesztés",
|
||||
"admin.users.auth_source": "Hitelesítési forrás",
|
||||
"admin.users.local": "Helyi",
|
||||
@@ -1383,5 +1446,15 @@
|
||||
"actions.runners.task_list.repository": "Tároló",
|
||||
"actions.runners.status.active": "Aktív",
|
||||
"actions.runners.version": "Verzió",
|
||||
"git.filemode.symbolic_link": "Szimbolikus hivatkozás"
|
||||
"git.filemode.symbolic_link": "Szimbolikus hivatkozás",
|
||||
"auth.accept_your_invitation": "Accept Your Invitation",
|
||||
"auth.invitation_mail_pending_login": "An invitation email has already been sent to <b>%s</b>. Please accept it before signing in.",
|
||||
"auth.invitation_mail_sent_prompt_ex": "A new invitation email has been sent to <b>%s</b>. Please use the link within the next %s to activate your account.",
|
||||
"auth.invitation_mail_resend_failed": "The invitation email could not be sent. Please try again later or contact an administrator.",
|
||||
"auth.invitation_mail_resend_not_available": "This account can no longer receive invitation emails.",
|
||||
"auth.invitation_resend_prompt": "Did not receive the invitation email?",
|
||||
"auth.invitation_resend_button": "Resend",
|
||||
"admin.users.send_register_notify_helper": "The account will be activated and validated immediately.",
|
||||
"admin.users.send_register_invite_helper": "The user must accept the emailed invitation before the account becomes active.",
|
||||
"install.language_balloon": "Choose a language"
|
||||
}
|
||||
|
||||
@@ -153,24 +153,145 @@
|
||||
"startpage.lightweight": "Ringan",
|
||||
"startpage.lightweight_desc": "Gitea hanya membutuhkan persyaratan minimal dan bisa berjalan pada Raspberry Pi yang murah. Bisa menghemat listrik!",
|
||||
"startpage.license": "Sumber Terbuka",
|
||||
"install.install": "Installation",
|
||||
"install.installing_desc": "Installing now, please wait…",
|
||||
"install.title": "Konfigurasi Awal",
|
||||
"install.docker_helper": "If you run Gitea inside Docker, please read the <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"%s\">documentation</a> before changing any settings.",
|
||||
"install.require_db_desc": "Gitea requires MySQL, PostgreSQL, MSSQL, SQLite3 or TiDB (MySQL protocol).",
|
||||
"install.db_title": "Database Settings",
|
||||
"install.db_type": "Database Type",
|
||||
"install.host": "Host",
|
||||
"install.user": "Nama Pengguna",
|
||||
"install.password": "Kata Sandi",
|
||||
"install.db_name": "Database Name",
|
||||
"install.db_schema": "Schema",
|
||||
"install.db_schema_helper": "Leave blank for database default (\"public\").",
|
||||
"install.ssl_mode": "SSL",
|
||||
"install.path": "Jalur",
|
||||
"install.sqlite_helper": "File path for the SQLite3 database.<br>Enter an absolute path if you run Gitea as a service.",
|
||||
"install.reinstall_error": "You are trying to install into an existing Gitea database",
|
||||
"install.reinstall_confirm_message": "Re-installing with an existing Gitea database can cause multiple problems. In most cases, you should use your existing \"app.ini\" to run Gitea. If you know what you are doing, confirm the following:",
|
||||
"install.reinstall_confirm_check_1": "The data encrypted by the SECRET_KEY in app.ini may be lost: users may not be able to log in with 2FA/OTP and mirrors may not function correctly. By checking this box, you confirm that the current app.ini file contains the correct SECRET_KEY.",
|
||||
"install.reinstall_confirm_check_2": "The repositories and settings may need to be resynchronized. By checking this box, you confirm that you will resynchronize the hooks for the repositories and authorized_keys file manually. You confirm that you will ensure that repository and mirror settings are correct.",
|
||||
"install.reinstall_confirm_check_3": "You confirm that you are absolutely sure that this Gitea is running with the correct app.ini location and that you are sure that you have to re-install. You confirm that you acknowledge the above risks.",
|
||||
"install.err_empty_db_path": "The SQLite3 database path cannot be empty.",
|
||||
"install.no_admin_and_disable_registration": "You cannot disable user self-registration without creating an administrator account.",
|
||||
"install.err_empty_admin_password": "The administrator password cannot be empty.",
|
||||
"install.err_empty_admin_email": "The administrator email address cannot be empty.",
|
||||
"install.err_admin_name_is_reserved": "Administrator username is invalid. Username is reserved.",
|
||||
"install.err_admin_name_pattern_not_allowed": "Administrator username is invalid. The username matches a reserved pattern.",
|
||||
"install.err_admin_name_is_invalid": "Administrator username is invalid",
|
||||
"install.general_title": "General Settings",
|
||||
"install.app_name": "Site Title",
|
||||
"install.app_name_helper": "You can enter your company name here.",
|
||||
"install.default_language": "Default Language",
|
||||
"install.default_language_helper": "Used when a user's browser language does not match an available locale.",
|
||||
"install.repo_path": "Jalur akar repositori",
|
||||
"install.repo_path_helper": "Remote Git repositories will be saved to this directory.",
|
||||
"install.lfs_path": "Git LFS Root Path",
|
||||
"install.lfs_path_helper": "Files tracked by Git LFS will be stored in this directory. Leave empty to disable.",
|
||||
"install.run_user": "Run As Username",
|
||||
"install.run_user_helper": "The operating system username that Gitea runs as, it must have write access to the data paths. This value is auto-detected and cannot be changed here. To use a different user, restart Gitea under that account.",
|
||||
"install.domain": "Server Domain",
|
||||
"install.domain_helper": "Domain or host address for the server.",
|
||||
"install.ssh_port": "SSH Server Port",
|
||||
"install.ssh_port_helper": "Port number your SSH server listens on. Leave empty to disable.",
|
||||
"install.http_port": "Gitea HTTP Listen Port",
|
||||
"install.http_port_helper": "Port number the Gitea web server will listen on.",
|
||||
"install.app_url": "Gitea Base URL",
|
||||
"install.app_url_helper": "Base address for HTTP(S) clone URLs and email notifications.",
|
||||
"install.log_root_path": "Log Path",
|
||||
"install.log_root_path_helper": "Log files will be written to this directory.",
|
||||
"install.optional_title": "Optional Settings",
|
||||
"install.email_title": "Pengaturan email",
|
||||
"install.smtp_addr": "Host SMTP",
|
||||
"install.smtp_port": "Port SMTP",
|
||||
"install.smtp_from": "Kirim Email Sebagai",
|
||||
"install.smtp_from_invalid": "The \"Send Email As\" address is invalid",
|
||||
"install.smtp_from_helper": "Email address Gitea will use. Enter a plain email address or use the \"Name\" <email@example.com> format.",
|
||||
"install.mailer_user": "SMTP Username",
|
||||
"install.mailer_password": "SMTP Password",
|
||||
"install.test_mail_to": "Send Testing Email",
|
||||
"install.test_mail_missing_host": "Please enter the SMTP host before testing email delivery.",
|
||||
"install.test_mail_missing_recipient": "Please enter a recipient email address before testing email delivery.",
|
||||
"install.registration_title": "Registration Management",
|
||||
"install.registration_mode": "Registration Mode",
|
||||
"install.registration_mode.admin_only": "Administrator-managed accounts only",
|
||||
"install.registration_mode.admin_only_helper": "Disable self-registration and let administrators create new accounts using the selected administrator-created account mode.",
|
||||
"install.admin_created_account_mode": "Administrator-Created Account Mode",
|
||||
"install.admin_created_account_mode.local": "Create local accounts directly",
|
||||
"install.admin_created_account_mode.local_helper": "Creates active local accounts immediately. Administrators can optionally notify the user by email after creation.",
|
||||
"install.admin_created_account_mode.invite": "Create invitation-based accounts",
|
||||
"install.admin_created_account_mode.invite_helper": "Creates inactive accounts with sign-in disabled until the user accepts the emailed invitation link.",
|
||||
"install.registration_mode.local_only": "Local registration only",
|
||||
"install.registration_mode.local_only_helper": "Allow new accounts only through Gitea's built-in registration form.",
|
||||
"install.registration_mode.external_only": "External registration only",
|
||||
"install.registration_mode.external_only_helper": "Disable the local registration form and accept new accounts only from external identity providers.",
|
||||
"install.registration_mode.local_and_external": "Local and external registration",
|
||||
"install.registration_mode.local_and_external_helper": "Allow new accounts through both Gitea's local registration form and external identity providers.",
|
||||
"install.registration_local_options": "Local Registration Options",
|
||||
"install.registration_external_options": "External Registration Options",
|
||||
"install.register_confirm": "Perlu Konfirmasi Email Saat Pendaftaran",
|
||||
"install.register_confirm_helper": "Require users to verify their email address before they can continue.",
|
||||
"install.register_manual_confirm": "Require Administrator Approval After Email Validation",
|
||||
"install.register_manual_confirm_helper": "New accounts stay pending until an administrator reviews and approves the request.",
|
||||
"install.mail_notify": "Aktifkan Notifikasi Email",
|
||||
"install.disable_gravatar": "Menonaktifkan Gravatar",
|
||||
"install.federated_avatar_lookup": "Aktifkan pencarian avatar",
|
||||
"install.mail_notify_helper": "Controls routine notification emails such as watches, mentions, and administrative notices. Activation and invitation emails still use the SMTP configuration above.",
|
||||
"install.server_service_title": "Server and Third-Party Service Settings",
|
||||
"install.disable_registration": "Disable Self-Registration",
|
||||
"install.disable_registration_popup": "Disable user self-registration. Only administrators will be able to create new user accounts.",
|
||||
"install.allow_only_external_registration_popup": "Allow Registration Only Through External Services",
|
||||
"install.openid_signin": "Aktifkan Login OpenID",
|
||||
"install.openid_signin_popup": "Enable user sign-in via OpenID.",
|
||||
"install.openid_signup": "Enable OpenID Self-Registration",
|
||||
"install.openid_signup_popup": "Enable OpenID-based user self-registration.",
|
||||
"install.openid_signin_helper": "Allow users to sign in through OpenID providers.",
|
||||
"install.openid_signup_helper": "Allow new accounts to be created through OpenID providers.",
|
||||
"install.enable_captcha": "Enable registration CAPTCHA",
|
||||
"install.enable_captcha_popup": "Require a CAPTCHA for user self-registration.",
|
||||
"install.require_sign_in_view": "Harus Login Untuk Melihat Halaman",
|
||||
"install.require_sign_in_view_popup": "Limit page access to signed-in users. Visitors will only see the sign-in and registration pages.",
|
||||
"install.admin_setting_desc": "Creating a super administrator account is optional. The first registered user will automatically become a super administrator.",
|
||||
"install.admin_title": "Super Administrator Account Settings",
|
||||
"install.admin_name": "Super Administrator Username",
|
||||
"install.admin_password": "Kata Sandi",
|
||||
"install.confirm_password": "Konfirmasi Kata Sandi",
|
||||
"install.admin_email": "Alamat Email",
|
||||
"install.admin_management_policy": "Administration Management Policy",
|
||||
"install.admin_management_policy.super_admin_only": "Only super admins manage admins",
|
||||
"install.admin_management_policy.super_admin_only_helper": "Regular admins can manage only non-admin accounts. Any admin-to-admin change or deletion requires a super administrator.",
|
||||
"install.admin_management_policy.grantor_only": "Grantor manages promoted admins",
|
||||
"install.admin_management_policy.grantor_only_helper": "Regular admins can promote users to administrator and can later modify or delete only the administrators they directly promoted.",
|
||||
"install.admin_management_policy.grantor_inheritance": "Grantor chain with inheritance",
|
||||
"install.admin_management_policy.grantor_inheritance_helper": "Like grantor-only, but if the direct grantor becomes inactive or has sign-in disabled, management passes up the admin grant chain until an eligible admin is found. If none is found, super admins keep control.",
|
||||
"install.install_btn_confirm": "Install Gitea",
|
||||
"install.test_git_failed": "Could not test 'git' command: %v",
|
||||
"install.sqlite3_not_available": "This Gitea version does not support SQLite3. Please download the official binary version from %s (not the 'gobuild' version).",
|
||||
"install.invalid_db_setting": "The database settings are invalid: %v",
|
||||
"install.invalid_db_table": "The database table \"%s\" is invalid: %v",
|
||||
"install.invalid_repo_path": "The repository root path is invalid: %v",
|
||||
"install.invalid_app_data_path": "The app data path is invalid: %v",
|
||||
"install.internal_token_failed": "Failed to generate internal token: %v",
|
||||
"install.secret_key_failed": "Failed to generate secret key: %v",
|
||||
"install.save_config_failed": "Failed to save configuration: %v",
|
||||
"install.invalid_admin_setting": "Administrator account setting is invalid: %v",
|
||||
"install.invalid_log_root_path": "The log path is invalid: %v",
|
||||
"install.default_keep_email_private": "Hide Email Addresses by Default",
|
||||
"install.default_keep_email_private_popup": "Hide email addresses of new user accounts by default.",
|
||||
"install.default_allow_create_organization": "Allow Creation of Organizations by Default",
|
||||
"install.default_allow_create_organization_popup": "Allow new user accounts to create organizations by default.",
|
||||
"install.default_enable_timetracking": "Enable Time Tracking by Default",
|
||||
"install.default_enable_timetracking_popup": "Enable time tracking for new repositories by default.",
|
||||
"install.no_reply_address": "Hidden Email Domain",
|
||||
"install.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'.",
|
||||
"install.password_algorithm": "Password Hash Algorithm",
|
||||
"install.invalid_password_algorithm": "Invalid password hash algorithm",
|
||||
"install.password_algorithm_helper": "Set the password hashing algorithm. Algorithms have differing requirements and strengths. The argon2 algorithm is rather secure but uses a lot of memory and may be inappropriate for small systems.",
|
||||
"install.enable_update_checker": "Enable Update Checker",
|
||||
"install.enable_update_checker_helper": "Checks for new version releases periodically by connecting to gitea.io.",
|
||||
"install.env_config_keys": "Environment Configuration",
|
||||
"install.env_config_keys_prompt": "The following environment variables will also be applied to your configuration file:",
|
||||
"install.config_write_file_prompt": "These configuration options will be written into: %s",
|
||||
"home.uname_holder": "Nama Pengguna atau Alamat Surel",
|
||||
"home.password_holder": "Kata Sandi",
|
||||
"home.switch_dashboard_context": "Alihkan Dasbor Konteks",
|
||||
@@ -193,6 +314,9 @@
|
||||
"auth.forgot_password_title": "Lupa Kata Sandi",
|
||||
"auth.forgot_password": "Lupa kata sandi?",
|
||||
"auth.must_change_password": "Perbarui kata sandi Anda",
|
||||
"auth.confirmation_mail_pending_signup": "A confirmation email has already been sent to <b>%s</b>. Please activate it before creating another account.",
|
||||
"auth.confirmation_mail_resend_failed": "The confirmation email could not be sent. Please try again later or contact an administrator.",
|
||||
"auth.confirmation_mail_resend_not_available": "This account can no longer receive confirmation emails.",
|
||||
"auth.allow_password_change": "Wajibkan pengguna untuk mengganti kata sandi (disarankan)",
|
||||
"auth.reset_password_mail_sent_prompt": "Surel konfirmasi berhasil dikirim ke <b>%s</b>. Silahkan cek akun email Anda dalam %s jam untuk menyelesaikan proses pemulihan akun.",
|
||||
"auth.active_your_account": "Aktifkan Akun Anda",
|
||||
@@ -940,6 +1064,7 @@
|
||||
"admin.users.auth_source": "Sumber Otentikasi",
|
||||
"admin.users.local": "Lokal",
|
||||
"admin.users.delete_account": "Hapus Akun Pengguna",
|
||||
"admin.users.send_register_invite": "Send User Registration Invitation",
|
||||
"admin.users.list_status_filter.menu_text": "Saring",
|
||||
"admin.users.list_status_filter.is_admin": "Pengelola",
|
||||
"admin.emails.primary": "Utama",
|
||||
@@ -1198,5 +1323,15 @@
|
||||
"actions.variables.update.success": "Variabel telah diedit.",
|
||||
"projects.type-1.display_name": "Proyek Individu",
|
||||
"projects.type-2.display_name": "Proyek Repositori",
|
||||
"projects.type-3.display_name": "Proyek Organisasi"
|
||||
"projects.type-3.display_name": "Proyek Organisasi",
|
||||
"auth.accept_your_invitation": "Accept Your Invitation",
|
||||
"auth.invitation_mail_pending_login": "An invitation email has already been sent to <b>%s</b>. Please accept it before signing in.",
|
||||
"auth.invitation_mail_sent_prompt_ex": "A new invitation email has been sent to <b>%s</b>. Please use the link within the next %s to activate your account.",
|
||||
"auth.invitation_mail_resend_failed": "The invitation email could not be sent. Please try again later or contact an administrator.",
|
||||
"auth.invitation_mail_resend_not_available": "This account can no longer receive invitation emails.",
|
||||
"auth.invitation_resend_prompt": "Did not receive the invitation email?",
|
||||
"auth.invitation_resend_button": "Resend",
|
||||
"admin.users.send_register_notify_helper": "The account will be activated and validated immediately.",
|
||||
"admin.users.send_register_invite_helper": "The user must accept the emailed invitation before the account becomes active.",
|
||||
"install.language_balloon": "Choose a language"
|
||||
}
|
||||
|
||||
@@ -107,6 +107,7 @@
|
||||
"startpage.lightweight_desc": "Gitea hefur lágar lágmarkskröfur og getur keyrt á ódýrum Raspberry Pi. Sparaðu orku!",
|
||||
"startpage.license": "Frjáls Hugbúnaður",
|
||||
"install.install": "Uppsetning",
|
||||
"install.installing_desc": "Installing now, please wait…",
|
||||
"install.title": "Upphafleg Uppsetning",
|
||||
"install.docker_helper": "Ef þú keyrir Gitea inni í Docker þá viltu vinsamlegast lesa <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"%s\">leiðbeiningaritið</a> áður en þú breytir stillingum.",
|
||||
"install.require_db_desc": "Gitea krefst MySQL, PostgreSQL, MSSQL, SQLite3 eða TiDB (MySQL samskiptareglur).",
|
||||
@@ -118,27 +119,38 @@
|
||||
"install.db_name": "Gagnagrunnsheiti",
|
||||
"install.db_schema": "Uppdráttur",
|
||||
"install.db_schema_helper": "Skildu eftir autt fyrir sjálfgefinn gagnagrunn („public“).",
|
||||
"install.ssl_mode": "SSL",
|
||||
"install.path": "Slóð",
|
||||
"install.sqlite_helper": "Skráarslóð fyrir SQLite3 gagnagrunninn.<br>Sláðu inn algjöra slóð ef þú keyrir Gitea sem þjónustu.",
|
||||
"install.reinstall_error": "Þú ert að reyna að setja upp í núverandi Gitea gagnagrunn",
|
||||
"install.reinstall_confirm_message": "Enduruppsetning með núverandi Gitea gagnagrunni getur valdið mörgum vandamálum. Í flestum tilfellum ættir þú að nota núverandi \"app.ini\" til að keyra Gitea. Ef þú veist hvað þú ert að gera skaltu staðfesta eftirfarandi:",
|
||||
"install.reinstall_confirm_check_1": "The data encrypted by the SECRET_KEY in app.ini may be lost: users may not be able to log in with 2FA/OTP and mirrors may not function correctly. By checking this box, you confirm that the current app.ini file contains the correct SECRET_KEY.",
|
||||
"install.reinstall_confirm_check_2": "The repositories and settings may need to be resynchronized. By checking this box, you confirm that you will resynchronize the hooks for the repositories and authorized_keys file manually. You confirm that you will ensure that repository and mirror settings are correct.",
|
||||
"install.reinstall_confirm_check_3": "Þú staðfestir að þú sért alveg viss um að þetta Gitea sé í gangi með réttri app.ini staðsetningu og að þú sért viss um að þú þurfir að setja það upp aftur. Þú staðfestir að þú viðurkennir ofangreindar áhættur.",
|
||||
"install.err_empty_db_path": "SQLite3 gagnagrunnsslóðin má ekki vera tóm.",
|
||||
"install.no_admin_and_disable_registration": "Þú getur ekki slökkt á sjálfsskráningu notenda án þess að búa til stjórnandanotanda.",
|
||||
"install.err_empty_admin_password": "Lykilorð stjórnanda má ekki vera tómt.",
|
||||
"install.err_empty_admin_email": "The administrator email address cannot be empty.",
|
||||
"install.err_admin_name_is_reserved": "Administrator username is invalid. Username is reserved.",
|
||||
"install.err_admin_name_pattern_not_allowed": "Administrator username is invalid. The username matches a reserved pattern.",
|
||||
"install.err_admin_name_is_invalid": "Administrator username is invalid",
|
||||
"install.general_title": "Almennar Stillingar",
|
||||
"install.app_name": "Heiti vefsvæðis",
|
||||
"install.app_name_helper": "Þú getur slegið inn nafn fyrirtækis þíns hér.",
|
||||
"install.default_language": "Default Language",
|
||||
"install.default_language_helper": "Used when a user's browser language does not match an available locale.",
|
||||
"install.repo_path": "Grunnsslóð Hugbúnaðarsafns",
|
||||
"install.repo_path_helper": "Fjarlægar Git hugbúnaðarsöfn verða vistaðar í þessari möppu.",
|
||||
"install.lfs_path": "Git LFS Grunnsslóð",
|
||||
"install.lfs_path_helper": "Skrár sem Git LFS rekur verða geymdar í þessari möppu. Skildu eftir tómt til að slökkva á.",
|
||||
"install.run_user": "Keyra Sem Notandanafn",
|
||||
"install.run_user_helper": "The operating system username that Gitea runs as, it must have write access to the data paths. This value is auto-detected and cannot be changed here. To use a different user, restart Gitea under that account.",
|
||||
"install.domain": "Lén Netþjóns",
|
||||
"install.domain_helper": "Lén eða hýsilfang fyrir netþjóninn.",
|
||||
"install.ssh_port": "SSH Netþjónsgátt",
|
||||
"install.ssh_port_helper": "Gátt sem SSH þjónninn þinn hlustar á. Skildu eftir tómt til að slökkva á.",
|
||||
"install.http_port": "Gitea HTTP Hlustunargátt",
|
||||
"install.http_port_helper": "Port number the Gitea web server will listen on.",
|
||||
"install.app_url": "Grunnvefslóð Gitea",
|
||||
"install.app_url_helper": "Grunnvistfang fyrir HTTP(S) afrit slóð og tölvupósttilkynningar.",
|
||||
"install.log_root_path": "Slóð Annáls",
|
||||
@@ -148,32 +160,91 @@
|
||||
"install.smtp_addr": "SMTP Hýsill",
|
||||
"install.smtp_port": "SMTP Gátt",
|
||||
"install.smtp_from": "Senda Tölvupóst Sem",
|
||||
"install.smtp_from_invalid": "The \"Send Email As\" address is invalid",
|
||||
"install.smtp_from_helper": "Netfang sem Gitea mun nota. Sláðu inn venjulegt netfang eða notaðu „Nafn“ <email@example.com> sniðið.",
|
||||
"install.mailer_user": "SMTP Notandanafn",
|
||||
"install.mailer_password": "SMTP Lykilorð",
|
||||
"install.test_mail_to": "Send Testing Email",
|
||||
"install.test_mail_missing_host": "Please enter the SMTP host before testing email delivery.",
|
||||
"install.test_mail_missing_recipient": "Please enter a recipient email address before testing email delivery.",
|
||||
"install.registration_title": "Registration Management",
|
||||
"install.registration_mode": "Registration Mode",
|
||||
"install.registration_mode.admin_only": "Administrator-managed accounts only",
|
||||
"install.registration_mode.admin_only_helper": "Disable self-registration and let administrators create new accounts using the selected administrator-created account mode.",
|
||||
"install.admin_created_account_mode": "Administrator-Created Account Mode",
|
||||
"install.admin_created_account_mode.local": "Create local accounts directly",
|
||||
"install.admin_created_account_mode.local_helper": "Creates active local accounts immediately. Administrators can optionally notify the user by email after creation.",
|
||||
"install.admin_created_account_mode.invite": "Create invitation-based accounts",
|
||||
"install.admin_created_account_mode.invite_helper": "Creates inactive accounts with sign-in disabled until the user accepts the emailed invitation link.",
|
||||
"install.registration_mode.local_only": "Local registration only",
|
||||
"install.registration_mode.local_only_helper": "Allow new accounts only through Gitea's built-in registration form.",
|
||||
"install.registration_mode.external_only": "External registration only",
|
||||
"install.registration_mode.external_only_helper": "Disable the local registration form and accept new accounts only from external identity providers.",
|
||||
"install.registration_mode.local_and_external": "Local and external registration",
|
||||
"install.registration_mode.local_and_external_helper": "Allow new accounts through both Gitea's local registration form and external identity providers.",
|
||||
"install.registration_local_options": "Local Registration Options",
|
||||
"install.registration_external_options": "External Registration Options",
|
||||
"install.register_confirm": "Krefjast Staðfestingar Tölvupósts Til Að Nýskrá",
|
||||
"install.register_confirm_helper": "Require users to verify their email address before they can continue.",
|
||||
"install.register_manual_confirm": "Require Administrator Approval After Email Validation",
|
||||
"install.register_manual_confirm_helper": "New accounts stay pending until an administrator reviews and approves the request.",
|
||||
"install.mail_notify": "Virkja Tölvupósttilkynningar",
|
||||
"install.mail_notify_helper": "Controls routine notification emails such as watches, mentions, and administrative notices. Activation and invitation emails still use the SMTP configuration above.",
|
||||
"install.server_service_title": "Stillingar Netþjóns og Þriðja Aðila",
|
||||
"install.offline_mode": "Virkjaðu Staðbundin Ham",
|
||||
"install.offline_mode_popup": "Slökktu á efnisafhendingarnetum þriðja aðila og þjónaðu öllum gögnum á staðnum.",
|
||||
"install.disable_gravatar": "Óvirkja Gravatar",
|
||||
"install.disable_gravatar_popup": "Slökkva á Gravatar og notandamyndar þjónustum. Sjálfgefin notandamynd verður notuð ef notandi hleður ekki upp sína eigin.",
|
||||
"install.federated_avatar_lookup": "Virkja Samtök Notandamyndar",
|
||||
"install.disable_registration": "Disable Self-Registration",
|
||||
"install.disable_registration_popup": "Disable user self-registration. Only administrators will be able to create new user accounts.",
|
||||
"install.allow_only_external_registration_popup": "Allow Registration Only Through External Services",
|
||||
"install.openid_signin": "Virkja OpenID Innskráningu",
|
||||
"install.openid_signin_popup": "Virkja OpenID innskráningu notenda.",
|
||||
"install.openid_signup": "Enable OpenID Self-Registration",
|
||||
"install.openid_signup_popup": "Enable OpenID-based user self-registration.",
|
||||
"install.openid_signin_helper": "Allow users to sign in through OpenID providers.",
|
||||
"install.openid_signup_helper": "Allow new accounts to be created through OpenID providers.",
|
||||
"install.enable_captcha": "Virkja CAPTCHA innskráningu",
|
||||
"install.enable_captcha_popup": "Require a CAPTCHA for user self-registration.",
|
||||
"install.require_sign_in_view": "Require Sign-In to View Pages",
|
||||
"install.require_sign_in_view_popup": "Limit page access to signed-in users. Visitors will only see the sign-in and registration pages.",
|
||||
"install.admin_setting_desc": "Creating a super administrator account is optional. The first registered user will automatically become a super administrator.",
|
||||
"install.admin_title": "Super Administrator Account Settings",
|
||||
"install.admin_name": "Notandanafn Stjórnanda",
|
||||
"install.admin_password": "Lykilorð",
|
||||
"install.confirm_password": "Staðfestu Lykilorðið",
|
||||
"install.admin_email": "Netfang",
|
||||
"install.admin_management_policy": "Administration Management Policy",
|
||||
"install.admin_management_policy.super_admin_only": "Only super admins manage admins",
|
||||
"install.admin_management_policy.super_admin_only_helper": "Regular admins can manage only non-admin accounts. Any admin-to-admin change or deletion requires a super administrator.",
|
||||
"install.admin_management_policy.grantor_only": "Grantor manages promoted admins",
|
||||
"install.admin_management_policy.grantor_only_helper": "Regular admins can promote users to administrator and can later modify or delete only the administrators they directly promoted.",
|
||||
"install.admin_management_policy.grantor_inheritance": "Grantor chain with inheritance",
|
||||
"install.admin_management_policy.grantor_inheritance_helper": "Like grantor-only, but if the direct grantor becomes inactive or has sign-in disabled, management passes up the admin grant chain until an eligible admin is found. If none is found, super admins keep control.",
|
||||
"install.install_btn_confirm": "Setja upp Gitea",
|
||||
"install.test_git_failed": "Gat ekki prófað „git“ skipunina: %v",
|
||||
"install.sqlite3_not_available": "Þessi Gitea útgáfa styður ekki SQLite3. Vinsamlegast sæktu útgáfunni okkar frá %s (ekki „gobuild“ útgáfunna).",
|
||||
"install.invalid_db_setting": "Gagnagrunnsstillingarnar eru ógildar: %v",
|
||||
"install.invalid_db_table": "The database table \"%s\" is invalid: %v",
|
||||
"install.invalid_repo_path": "Grunnsslóð hugbúnaðarsafns er ógild: %v",
|
||||
"install.invalid_app_data_path": "The app data path is invalid: %v",
|
||||
"install.internal_token_failed": "Failed to generate internal token: %v",
|
||||
"install.secret_key_failed": "Failed to generate secret key: %v",
|
||||
"install.save_config_failed": "Failed to save configuration: %v",
|
||||
"install.invalid_admin_setting": "Administrator account setting is invalid: %v",
|
||||
"install.invalid_log_root_path": "Slóð annáls er ógild: %v",
|
||||
"install.default_keep_email_private": "Hide Email Addresses by Default",
|
||||
"install.default_keep_email_private_popup": "Fela sjálfgefið netföng nýrra notendareikninga.",
|
||||
"install.default_allow_create_organization": "Allow Creation of Organizations by Default",
|
||||
"install.default_allow_create_organization_popup": "Allow new user accounts to create organizations by default.",
|
||||
"install.default_enable_timetracking": "Enable Time Tracking by Default",
|
||||
"install.default_enable_timetracking_popup": "Enable time tracking for new repositories by default.",
|
||||
"install.no_reply_address": "Hidden Email Domain",
|
||||
"install.no_reply_address_helper": "Lén fyrir notendur með falið netfang. Til dæmis notandanafnið „joe“ verður skráð í Git sem „joe@noreply.example.org“ ef falið tölvupóstlén er stillt á „noreply.example.org“.",
|
||||
"install.password_algorithm": "Password Hash Algorithm",
|
||||
"install.invalid_password_algorithm": "Invalid password hash algorithm",
|
||||
"install.password_algorithm_helper": "Set the password hashing algorithm. Algorithms have differing requirements and strengths. The argon2 algorithm is rather secure but uses a lot of memory and may be inappropriate for small systems.",
|
||||
"install.enable_update_checker": "Enable Update Checker",
|
||||
"install.enable_update_checker_helper": "Checks for new version releases periodically by connecting to gitea.io.",
|
||||
"install.env_config_keys": "Environment Configuration",
|
||||
"install.env_config_keys_prompt": "The following environment variables will also be applied to your configuration file:",
|
||||
"install.config_write_file_prompt": "These configuration options will be written into: %s",
|
||||
"home.uname_holder": "Notandanafn eða Netfang",
|
||||
"home.password_holder": "Lykilorð",
|
||||
"home.my_repos": "Hugbúnaðarsöfn",
|
||||
@@ -197,6 +268,9 @@
|
||||
"auth.forgot_password_title": "Gleymt Lykilorð",
|
||||
"auth.forgot_password": "Gleymdirðu Lykilorðinu?",
|
||||
"auth.must_change_password": "Uppfærðu lykilorðið þitt",
|
||||
"auth.confirmation_mail_pending_signup": "A confirmation email has already been sent to <b>%s</b>. Please activate it before creating another account.",
|
||||
"auth.confirmation_mail_resend_failed": "The confirmation email could not be sent. Please try again later or contact an administrator.",
|
||||
"auth.confirmation_mail_resend_not_available": "This account can no longer receive confirmation emails.",
|
||||
"auth.active_your_account": "Virkjaðu Aðganginn Þinn",
|
||||
"auth.account_activated": "Aðgangur hefur verið virkjaður",
|
||||
"auth.has_unconfirmed_mail": "Halló, %s, þú ert með óstaðfest netfang (<b>%s</b>). Ef þú hefur ekki fengið staðfestingarpóst eða þarft nýjan, vinsamlegast smelltu á hnappinn hér að neðan.",
|
||||
@@ -975,6 +1049,7 @@
|
||||
"admin.users.created": "Búið til",
|
||||
"admin.users.edit": "Breyta",
|
||||
"admin.users.local": "Staðbundið",
|
||||
"admin.users.send_register_invite": "Send User Registration Invitation",
|
||||
"admin.users.list_status_filter.menu_text": "Sía",
|
||||
"admin.users.list_status_filter.reset": "Endurstilla",
|
||||
"admin.users.list_status_filter.is_active": "Virkt",
|
||||
@@ -1116,5 +1191,15 @@
|
||||
"actions.runners.task_list.commit": "Framlag",
|
||||
"actions.runners.status.active": "Virkt",
|
||||
"actions.runners.version": "Útgáfa",
|
||||
"actions.runs.commit": "Framlag"
|
||||
"actions.runs.commit": "Framlag",
|
||||
"auth.accept_your_invitation": "Accept Your Invitation",
|
||||
"auth.invitation_mail_pending_login": "An invitation email has already been sent to <b>%s</b>. Please accept it before signing in.",
|
||||
"auth.invitation_mail_sent_prompt_ex": "A new invitation email has been sent to <b>%s</b>. Please use the link within the next %s to activate your account.",
|
||||
"auth.invitation_mail_resend_failed": "The invitation email could not be sent. Please try again later or contact an administrator.",
|
||||
"auth.invitation_mail_resend_not_available": "This account can no longer receive invitation emails.",
|
||||
"auth.invitation_resend_prompt": "Did not receive the invitation email?",
|
||||
"auth.invitation_resend_button": "Resend",
|
||||
"admin.users.send_register_notify_helper": "The account will be activated and validated immediately.",
|
||||
"admin.users.send_register_invite_helper": "The user must accept the emailed invitation before the account becomes active.",
|
||||
"install.language_balloon": "Choose a language"
|
||||
}
|
||||
|
||||
@@ -101,34 +101,50 @@
|
||||
"startpage.lightweight": "Leggero",
|
||||
"startpage.lightweight_desc": "Gitea ha requisiti minimi bassi e può funzionare su un economico Raspberry Pi. Risparmia l'energia della tua macchina!",
|
||||
"install.install": "Installazione",
|
||||
"install.installing_desc": "Installing now, please wait…",
|
||||
"install.title": "Configurazione Iniziale",
|
||||
"install.docker_helper": "Se stai usando Gitea con Docker, leggi <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"%s\">la documentazione</a> prima di cambiare qualsiasi impostazione.",
|
||||
"install.require_db_desc": "Gitea requires MySQL, PostgreSQL, MSSQL, SQLite3 or TiDB (MySQL protocol).",
|
||||
"install.db_title": "Impostazioni Database",
|
||||
"install.db_type": "Tipo di database",
|
||||
"install.host": "Host",
|
||||
"install.user": "Nome utente",
|
||||
"install.password": "Password",
|
||||
"install.db_name": "Nome del database",
|
||||
"install.db_schema": "Schema",
|
||||
"install.db_schema_helper": "Lascia vuoto per il valore predefinito del database (\"public\").",
|
||||
"install.ssl_mode": "SSL",
|
||||
"install.path": "Percorso",
|
||||
"install.sqlite_helper": "Percorso file del database SQLite3.<br>Inserisci un percorso assoluto se stai usando Gitea come servizio.",
|
||||
"install.reinstall_error": "Stai cercando di installare in un database Gitea esistente",
|
||||
"install.reinstall_confirm_message": "La reinstallazione con un database Gitea esistente può causare problemi multipli. Nella maggior parte dei casi, dovresti usare il tuo \"app.ini\" esistente per eseguire Gitea. Se sai cosa stai facendo, confermi quanto segue:",
|
||||
"install.reinstall_confirm_check_1": "The data encrypted by the SECRET_KEY in app.ini may be lost: users may not be able to log in with 2FA/OTP and mirrors may not function correctly. By checking this box, you confirm that the current app.ini file contains the correct SECRET_KEY.",
|
||||
"install.reinstall_confirm_check_2": "The repositories and settings may need to be resynchronized. By checking this box, you confirm that you will resynchronize the hooks for the repositories and authorized_keys file manually. You confirm that you will ensure that repository and mirror settings are correct.",
|
||||
"install.reinstall_confirm_check_3": "Confermi di essere assolutamente sicuro che questo Gitea è in esecuzione con l'app corretta. ni posizione e che sei sicuro di dover reinstallare. Confermi di aver riconosciuto i rischi di cui sopra.",
|
||||
"install.err_empty_db_path": "Il percorso del database SQLite3 non può essere vuoto.",
|
||||
"install.no_admin_and_disable_registration": "Non puoi disabilitare l'auto-registrazione degli utenti senza creare un account amministratore.",
|
||||
"install.err_empty_admin_password": "La password dell'amministratore non può essere vuota.",
|
||||
"install.err_empty_admin_email": "The administrator email address cannot be empty.",
|
||||
"install.err_admin_name_is_reserved": "Administrator username is invalid. Username is reserved.",
|
||||
"install.err_admin_name_pattern_not_allowed": "Administrator username is invalid. The username matches a reserved pattern.",
|
||||
"install.err_admin_name_is_invalid": "Administrator username is invalid",
|
||||
"install.general_title": "Impostazioni Generali",
|
||||
"install.app_name": "Titolo del Sito",
|
||||
"install.app_name_helper": "Qui puoi inserire il nome della tua società.",
|
||||
"install.default_language": "Default Language",
|
||||
"install.default_language_helper": "Used when a user's browser language does not match an available locale.",
|
||||
"install.repo_path": "Percorso Root del Repository",
|
||||
"install.repo_path_helper": "Le Remote Git repositories saranno salvate in questa directory.",
|
||||
"install.lfs_path": "Percorso radice di Git LFS",
|
||||
"install.lfs_path_helper": "I file trovati da Git LFS saranno salvati in questa directory. Lasciare vuoto per disattivare.",
|
||||
"install.run_user": "Esegui come Nome utente",
|
||||
"install.run_user_helper": "The operating system username that Gitea runs as, it must have write access to the data paths. This value is auto-detected and cannot be changed here. To use a different user, restart Gitea under that account.",
|
||||
"install.domain": "Dominio Server",
|
||||
"install.domain_helper": "Dominio o indirizzo host per il server.",
|
||||
"install.ssh_port": "Porta Server SSH",
|
||||
"install.ssh_port_helper": "Numero di porta in ascolto sul server SSH. Lasciare vuoto per disattivare.",
|
||||
"install.http_port": "Porta in ascolto HTTP Gitea",
|
||||
"install.http_port_helper": "Port number the Gitea web server will listen on.",
|
||||
"install.app_url": "URL di base di Gitea",
|
||||
"install.app_url_helper": "URL di base per gli HTTP(S) clone URLs e notifiche email.",
|
||||
"install.log_root_path": "Percorso dei log",
|
||||
@@ -138,18 +154,37 @@
|
||||
"install.smtp_addr": "Host SMTP",
|
||||
"install.smtp_port": "Porta SMTP",
|
||||
"install.smtp_from": "Invia Email come",
|
||||
"install.smtp_from_invalid": "The \"Send Email As\" address is invalid",
|
||||
"install.smtp_from_helper": "Indirizzo Email che Gitea utilizzerà. Inserisci un indirizzo email o usa il formato \"Name\" <email@example.com>.",
|
||||
"install.mailer_user": "Nome utente SMTP",
|
||||
"install.mailer_password": "Password SMTP",
|
||||
"install.test_mail_to": "Send Testing Email",
|
||||
"install.test_mail_missing_host": "Please enter the SMTP host before testing email delivery.",
|
||||
"install.test_mail_missing_recipient": "Please enter a recipient email address before testing email delivery.",
|
||||
"install.registration_title": "Registration Management",
|
||||
"install.registration_mode": "Registration Mode",
|
||||
"install.registration_mode.admin_only": "Administrator-managed accounts only",
|
||||
"install.registration_mode.admin_only_helper": "Disable self-registration and let administrators create new accounts using the selected administrator-created account mode.",
|
||||
"install.admin_created_account_mode": "Administrator-Created Account Mode",
|
||||
"install.admin_created_account_mode.local": "Create local accounts directly",
|
||||
"install.admin_created_account_mode.local_helper": "Creates active local accounts immediately. Administrators can optionally notify the user by email after creation.",
|
||||
"install.admin_created_account_mode.invite": "Create invitation-based accounts",
|
||||
"install.admin_created_account_mode.invite_helper": "Creates inactive accounts with sign-in disabled until the user accepts the emailed invitation link.",
|
||||
"install.registration_mode.local_only": "Local registration only",
|
||||
"install.registration_mode.local_only_helper": "Allow new accounts only through Gitea's built-in registration form.",
|
||||
"install.registration_mode.external_only": "External registration only",
|
||||
"install.registration_mode.external_only_helper": "Disable the local registration form and accept new accounts only from external identity providers.",
|
||||
"install.registration_mode.local_and_external": "Local and external registration",
|
||||
"install.registration_mode.local_and_external_helper": "Allow new accounts through both Gitea's local registration form and external identity providers.",
|
||||
"install.registration_local_options": "Local Registration Options",
|
||||
"install.registration_external_options": "External Registration Options",
|
||||
"install.register_confirm": "Richiedere la conferma Email per registrarsi",
|
||||
"install.register_confirm_helper": "Require users to verify their email address before they can continue.",
|
||||
"install.register_manual_confirm": "Require Administrator Approval After Email Validation",
|
||||
"install.register_manual_confirm_helper": "New accounts stay pending until an administrator reviews and approves the request.",
|
||||
"install.mail_notify": "Attiva le notifiche Email",
|
||||
"install.mail_notify_helper": "Controls routine notification emails such as watches, mentions, and administrative notices. Activation and invitation emails still use the SMTP configuration above.",
|
||||
"install.server_service_title": "Impostazioni Server e Servizi di Terza Parte",
|
||||
"install.offline_mode": "Attiva la Modalità in Locale",
|
||||
"install.offline_mode_popup": "Disattiva le reti di distribuzione dei contenuti di terze parti e fornisci tutte le risorse localmente.",
|
||||
"install.disable_gravatar": "Disattiva Gravatar",
|
||||
"install.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.",
|
||||
"install.federated_avatar_lookup": "Attiva i Federated Avatar",
|
||||
"install.federated_avatar_lookup_popup": "Enable federated avatars lookup to use federated open source service based on libravatar.",
|
||||
"install.disable_registration": "Disattiva Self-Registration",
|
||||
"install.disable_registration_popup": "Disattiva la user self-registration. Solo gli amministratori saranno in grado di creare account.",
|
||||
"install.allow_only_external_registration_popup": "Attiva la registrazione solo tramite servizi esterni",
|
||||
@@ -157,21 +192,32 @@
|
||||
"install.openid_signin_popup": "Attiva registrazione utente via OpenID.",
|
||||
"install.openid_signup": "Attiva OpenID Self-Registration",
|
||||
"install.openid_signup_popup": "Attiva OpenID-based user self-registration.",
|
||||
"install.openid_signin_helper": "Allow users to sign in through OpenID providers.",
|
||||
"install.openid_signup_helper": "Allow new accounts to be created through OpenID providers.",
|
||||
"install.enable_captcha": "Abilita CAPTCHA per registrazione",
|
||||
"install.enable_captcha_popup": "Richiedi convalida captcha per i nuovi utenti.",
|
||||
"install.require_sign_in_view": "Richiedi l'accesso per visualizzare le pagine",
|
||||
"install.require_sign_in_view_popup": "Limit page access to signed-in users. Visitors will only see the sign-in and registration pages.",
|
||||
"install.admin_setting_desc": "Creare un account amministratore è opzionale. Il primo utente registrato sarà automaticamente un amministratore.",
|
||||
"install.admin_title": "Impostazioni Account Amministratore",
|
||||
"install.admin_name": "Nome utente dell'Amministratore",
|
||||
"install.admin_password": "Password",
|
||||
"install.confirm_password": "Conferma Password",
|
||||
"install.admin_email": "Indirizzo Email",
|
||||
"install.admin_management_policy": "Administration Management Policy",
|
||||
"install.admin_management_policy.super_admin_only": "Only super admins manage admins",
|
||||
"install.admin_management_policy.super_admin_only_helper": "Regular admins can manage only non-admin accounts. Any admin-to-admin change or deletion requires a super administrator.",
|
||||
"install.admin_management_policy.grantor_only": "Grantor manages promoted admins",
|
||||
"install.admin_management_policy.grantor_only_helper": "Regular admins can promote users to administrator and can later modify or delete only the administrators they directly promoted.",
|
||||
"install.admin_management_policy.grantor_inheritance": "Grantor chain with inheritance",
|
||||
"install.admin_management_policy.grantor_inheritance_helper": "Like grantor-only, but if the direct grantor becomes inactive or has sign-in disabled, management passes up the admin grant chain until an eligible admin is found. If none is found, super admins keep control.",
|
||||
"install.install_btn_confirm": "Installare Gitea",
|
||||
"install.test_git_failed": "Fallito il test del comando git: %v",
|
||||
"install.sqlite3_not_available": "Questa versione di Gitea non supporta SQLite3. Si prega di scaricare la versione binaria ufficiale da %s (not the 'gobuild' version).",
|
||||
"install.invalid_db_setting": "Le impostazioni del database sono invalide: %v",
|
||||
"install.invalid_db_table": "The database table \"%s\" is invalid: %v",
|
||||
"install.invalid_repo_path": "Il percorso radice del Repository è invalido: %v",
|
||||
"install.invalid_app_data_path": "Il percorso dati dell'app non è valido: %v",
|
||||
"install.run_user_not_match": "Il nome utente 'esegui come' non è il nome utente attuale: %s -> %s",
|
||||
"install.internal_token_failed": "Generazione del token interno non riuscita: %v",
|
||||
"install.secret_key_failed": "Generazione della chiave segreta non riuscita: %v",
|
||||
"install.save_config_failed": "Salvataggio della configurazione non riuscito: %v",
|
||||
@@ -186,6 +232,13 @@
|
||||
"install.no_reply_address": "Dominio email nascosto",
|
||||
"install.no_reply_address_helper": "Nome 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'.",
|
||||
"install.password_algorithm": "Algoritmo Password Hash",
|
||||
"install.invalid_password_algorithm": "Invalid password hash algorithm",
|
||||
"install.password_algorithm_helper": "Set the password hashing algorithm. Algorithms have differing requirements and strengths. The argon2 algorithm is rather secure but uses a lot of memory and may be inappropriate for small systems.",
|
||||
"install.enable_update_checker": "Enable Update Checker",
|
||||
"install.enable_update_checker_helper": "Checks for new version releases periodically by connecting to gitea.io.",
|
||||
"install.env_config_keys": "Environment Configuration",
|
||||
"install.env_config_keys_prompt": "The following environment variables will also be applied to your configuration file:",
|
||||
"install.config_write_file_prompt": "These configuration options will be written into: %s",
|
||||
"home.uname_holder": "Nome utente o Indirizzo Email",
|
||||
"home.switch_dashboard_context": "Cambia Dashboard Context",
|
||||
"home.show_more_repos": "Mostra altre repositories…",
|
||||
@@ -218,6 +271,9 @@
|
||||
"auth.forgot_password_title": "Password Dimenticata",
|
||||
"auth.forgot_password": "Password dimenticata?",
|
||||
"auth.must_change_password": "Aggiorna la tua password",
|
||||
"auth.confirmation_mail_pending_signup": "A confirmation email has already been sent to <b>%s</b>. Please activate it before creating another account.",
|
||||
"auth.confirmation_mail_resend_failed": "The confirmation email could not be sent. Please try again later or contact an administrator.",
|
||||
"auth.confirmation_mail_resend_not_available": "This account can no longer receive confirmation emails.",
|
||||
"auth.allow_password_change": "Richiede all'utente di cambiare la password (scelta consigliata)",
|
||||
"auth.reset_password_mail_sent_prompt": "Una email di conferma è stata inviata a <b>%s</b>. Per favore controlla la tua posta in arrivo nelle prossime %s per completare il processo di reset della password.",
|
||||
"auth.active_your_account": "Attiva il tuo Account",
|
||||
@@ -1920,6 +1976,7 @@
|
||||
"admin.users.created": "Creato",
|
||||
"admin.users.last_login": "Ultimo accesso",
|
||||
"admin.users.send_register_notify": "Invia notifica di registrazione utente",
|
||||
"admin.users.send_register_invite": "Send User Registration Invitation",
|
||||
"admin.users.edit": "Modifica",
|
||||
"admin.users.auth_source": "Fonte di autenticazione",
|
||||
"admin.users.local": "Locale",
|
||||
@@ -2377,5 +2434,15 @@
|
||||
"actions.runners.task_list.run": "Esegui",
|
||||
"actions.runners.status.active": "Attivo",
|
||||
"actions.runners.version": "Versione",
|
||||
"git.filemode.symbolic_link": "Link Simbolico"
|
||||
"git.filemode.symbolic_link": "Link Simbolico",
|
||||
"auth.accept_your_invitation": "Accept Your Invitation",
|
||||
"auth.invitation_mail_pending_login": "An invitation email has already been sent to <b>%s</b>. Please accept it before signing in.",
|
||||
"auth.invitation_mail_sent_prompt_ex": "A new invitation email has been sent to <b>%s</b>. Please use the link within the next %s to activate your account.",
|
||||
"auth.invitation_mail_resend_failed": "The invitation email could not be sent. Please try again later or contact an administrator.",
|
||||
"auth.invitation_mail_resend_not_available": "This account can no longer receive invitation emails.",
|
||||
"auth.invitation_resend_prompt": "Did not receive the invitation email?",
|
||||
"auth.invitation_resend_button": "Resend",
|
||||
"admin.users.send_register_notify_helper": "The account will be activated and validated immediately.",
|
||||
"admin.users.send_register_invite_helper": "The user must accept the emailed invitation before the account becomes active.",
|
||||
"install.language_balloon": "Choose a language"
|
||||
}
|
||||
|
||||
@@ -256,6 +256,8 @@
|
||||
"install.general_title": "基本設定",
|
||||
"install.app_name": "サイトタイトル",
|
||||
"install.app_name_helper": "企業名をここに入れることができます。",
|
||||
"install.default_language": "Default Language",
|
||||
"install.default_language_helper": "Used when a user's browser language does not match an available locale.",
|
||||
"install.repo_path": "リポジトリのルートパス",
|
||||
"install.repo_path_helper": "リモートGitリポジトリはこのディレクトリに保存されます。",
|
||||
"install.lfs_path": "Git LFSルートパス",
|
||||
@@ -281,15 +283,33 @@
|
||||
"install.smtp_from_helper": "Giteaが使用するメールアドレス。 メールアドレスのみ、または、 \"名前\" <email@example.com> の形式で入力してください。",
|
||||
"install.mailer_user": "SMTPユーザー名",
|
||||
"install.mailer_password": "SMTPパスワード",
|
||||
"install.test_mail_to": "Send Testing Email",
|
||||
"install.test_mail_missing_host": "Please enter the SMTP host before testing email delivery.",
|
||||
"install.test_mail_missing_recipient": "Please enter a recipient email address before testing email delivery.",
|
||||
"install.registration_title": "Registration Management",
|
||||
"install.registration_mode": "Registration Mode",
|
||||
"install.registration_mode.admin_only": "Administrator-managed accounts only",
|
||||
"install.registration_mode.admin_only_helper": "Disable self-registration and let administrators create new accounts using the selected administrator-created account mode.",
|
||||
"install.admin_created_account_mode": "Administrator-Created Account Mode",
|
||||
"install.admin_created_account_mode.local": "Create local accounts directly",
|
||||
"install.admin_created_account_mode.local_helper": "Creates active local accounts immediately. Administrators can optionally notify the user by email after creation.",
|
||||
"install.admin_created_account_mode.invite": "Create invitation-based accounts",
|
||||
"install.admin_created_account_mode.invite_helper": "Creates inactive accounts with sign-in disabled until the user accepts the emailed invitation link.",
|
||||
"install.registration_mode.local_only": "Local registration only",
|
||||
"install.registration_mode.local_only_helper": "Allow new accounts only through Gitea's built-in registration form.",
|
||||
"install.registration_mode.external_only": "External registration only",
|
||||
"install.registration_mode.external_only_helper": "Disable the local registration form and accept new accounts only from external identity providers.",
|
||||
"install.registration_mode.local_and_external": "Local and external registration",
|
||||
"install.registration_mode.local_and_external_helper": "Allow new accounts through both Gitea's local registration form and external identity providers.",
|
||||
"install.registration_local_options": "Local Registration Options",
|
||||
"install.registration_external_options": "External Registration Options",
|
||||
"install.register_confirm": "登録にはメールによる確認が必要",
|
||||
"install.register_confirm_helper": "Require users to verify their email address before they can continue.",
|
||||
"install.register_manual_confirm": "Require Administrator Approval After Email Validation",
|
||||
"install.register_manual_confirm_helper": "New accounts stay pending until an administrator reviews and approves the request.",
|
||||
"install.mail_notify": "メール通知を有効にする",
|
||||
"install.mail_notify_helper": "Controls routine notification emails such as watches, mentions, and administrative notices. Activation and invitation emails still use the SMTP configuration above.",
|
||||
"install.server_service_title": "サーバーと外部サービスの設定",
|
||||
"install.offline_mode": "ローカルモードを有効にする",
|
||||
"install.offline_mode_popup": "外のCDNサービスを使わず、すべてのリソースを自前で提供します。",
|
||||
"install.disable_gravatar": "Gravatarを無効にする",
|
||||
"install.disable_gravatar_popup": "Gravatarと外のアバターソースを無効にします。 アバターをローカルにアップロードしていないユーザーには、デフォルトのアバターが使用されます。",
|
||||
"install.federated_avatar_lookup": "フェデレーテッド・アバターを有効にする",
|
||||
"install.federated_avatar_lookup_popup": "Libravatarを使用したフェデレーテッド・アバター検索を有効にします。",
|
||||
"install.disable_registration": "セルフ登録を無効にする",
|
||||
"install.disable_registration_popup": "ユーザーのセルフ登録を無効にします。 新しいユーザーアカウントを作成できるのは管理者だけとなります。",
|
||||
"install.allow_only_external_registration_popup": "外部サービスを使用した登録のみを許可",
|
||||
@@ -297,6 +317,8 @@
|
||||
"install.openid_signin_popup": "OpenIDを使ったユーザーのサインインを有効にします。",
|
||||
"install.openid_signup": "OpenIDを使ったセルフ登録を有効にする",
|
||||
"install.openid_signup_popup": "OpenIDベースでのユーザーのセルフ登録を有効にします。",
|
||||
"install.openid_signin_helper": "Allow users to sign in through OpenID providers.",
|
||||
"install.openid_signup_helper": "Allow new accounts to be created through OpenID providers.",
|
||||
"install.enable_captcha": "登録時のCAPTCHAを有効にする",
|
||||
"install.enable_captcha_popup": "ユーザーのセルフ登録時にCAPTCHAを必須にします。",
|
||||
"install.require_sign_in_view": "ページ閲覧にサインインが必要",
|
||||
@@ -307,6 +329,13 @@
|
||||
"install.admin_password": "パスワード",
|
||||
"install.confirm_password": "パスワード確認",
|
||||
"install.admin_email": "メールアドレス",
|
||||
"install.admin_management_policy": "Administration Management Policy",
|
||||
"install.admin_management_policy.super_admin_only": "Only super admins manage admins",
|
||||
"install.admin_management_policy.super_admin_only_helper": "Regular admins can manage only non-admin accounts. Any admin-to-admin change or deletion requires a super administrator.",
|
||||
"install.admin_management_policy.grantor_only": "Grantor manages promoted admins",
|
||||
"install.admin_management_policy.grantor_only_helper": "Regular admins can promote users to administrator and can later modify or delete only the administrators they directly promoted.",
|
||||
"install.admin_management_policy.grantor_inheritance": "Grantor chain with inheritance",
|
||||
"install.admin_management_policy.grantor_inheritance_helper": "Like grantor-only, but if the direct grantor becomes inactive or has sign-in disabled, management passes up the admin grant chain until an eligible admin is found. If none is found, super admins keep control.",
|
||||
"install.install_btn_confirm": "Giteaをインストール",
|
||||
"install.test_git_failed": "'git'コマンドが確認できません: %v",
|
||||
"install.sqlite3_not_available": "GiteaのこのバージョンはSQLite3をサポートしていません。 公式のバイナリ版を %s からダウンロードしてください。 ('gobuild'版でないもの)",
|
||||
@@ -314,7 +343,6 @@
|
||||
"install.invalid_db_table": "データベーステーブルの \"%s\" が無効です: %v",
|
||||
"install.invalid_repo_path": "リポジトリのルートパスが無効です: %v",
|
||||
"install.invalid_app_data_path": "アプリのデータパス (APP_DATA_PATH) が無効です: %v",
|
||||
"install.run_user_not_match": "実行ユーザー名が、現在のユーザー名ではありません: %s -> %s",
|
||||
"install.internal_token_failed": "内部トークンの生成に失敗しました: %v",
|
||||
"install.secret_key_failed": "シークレットキーの生成に失敗しました: %v",
|
||||
"install.save_config_failed": "設定ファイルの保存に失敗しました: %v",
|
||||
@@ -387,6 +415,9 @@
|
||||
"auth.sign_up_now": "登録はこちら。",
|
||||
"auth.sign_up_successful": "アカウントは無事に作成されました。ようこそ!",
|
||||
"auth.confirmation_mail_sent_prompt_ex": "新しい確認メールを <b>%s</b> に送信しました。 %s以内にメールボックスを確認し、登録手続きを完了してください。 登録メールアドレスが間違っている場合は、もういちどサインインすると変更することができます。",
|
||||
"auth.confirmation_mail_pending_signup": "A confirmation email has already been sent to <b>%s</b>. Please activate it before creating another account.",
|
||||
"auth.confirmation_mail_resend_failed": "The confirmation email could not be sent. Please try again later or contact an administrator.",
|
||||
"auth.confirmation_mail_resend_not_available": "This account can no longer receive confirmation emails.",
|
||||
"auth.must_change_password": "パスワードの更新",
|
||||
"auth.allow_password_change": "ユーザーはパスワードの変更が必要 (推奨)",
|
||||
"auth.reset_password_mail_sent_prompt": "<b>%s</b> に確認メールを送信しました。 %s以内に受信トレイを確認し、アカウント回復手続きを完了してください。",
|
||||
@@ -2971,6 +3002,7 @@
|
||||
"admin.users.last_login": "前回のサインイン",
|
||||
"admin.users.never_login": "未サインイン",
|
||||
"admin.users.send_register_notify": "ユーザーに登録通知を送る",
|
||||
"admin.users.send_register_invite": "Send User Registration Invitation",
|
||||
"admin.users.new_success": "ユーザーアカウント \"%s\" を作成しました。",
|
||||
"admin.users.edit": "編集",
|
||||
"admin.users.auth_source": "認証ソース",
|
||||
@@ -3743,5 +3775,15 @@
|
||||
"git.filemode.normal_file": "ノーマルファイル",
|
||||
"git.filemode.executable_file": "実行可能ファイル",
|
||||
"git.filemode.symbolic_link": "シンボリックリンク",
|
||||
"git.filemode.submodule": "サブモジュール"
|
||||
"git.filemode.submodule": "サブモジュール",
|
||||
"auth.accept_your_invitation": "Accept Your Invitation",
|
||||
"auth.invitation_mail_pending_login": "An invitation email has already been sent to <b>%s</b>. Please accept it before signing in.",
|
||||
"auth.invitation_mail_sent_prompt_ex": "A new invitation email has been sent to <b>%s</b>. Please use the link within the next %s to activate your account.",
|
||||
"auth.invitation_mail_resend_failed": "The invitation email could not be sent. Please try again later or contact an administrator.",
|
||||
"auth.invitation_mail_resend_not_available": "This account can no longer receive invitation emails.",
|
||||
"auth.invitation_resend_prompt": "Did not receive the invitation email?",
|
||||
"auth.invitation_resend_button": "Resend",
|
||||
"admin.users.send_register_notify_helper": "The account will be activated and validated immediately.",
|
||||
"admin.users.send_register_invite_helper": "The user must accept the emailed invitation before the account becomes active.",
|
||||
"install.language_balloon": "Choose a language"
|
||||
}
|
||||
|
||||
@@ -259,6 +259,8 @@
|
||||
"install.general_title": "기본설정",
|
||||
"install.app_name": "사이트 제목",
|
||||
"install.app_name_helper": "회사이름을 넣으세요.",
|
||||
"install.default_language": "Default Language",
|
||||
"install.default_language_helper": "Used when a user's browser language does not match an available locale.",
|
||||
"install.repo_path": "리포지토리 최상위 경로",
|
||||
"install.repo_path_helper": "Git 원격 리포지토리는 이 디렉터리에 저장 됩니다.",
|
||||
"install.lfs_path": "Git LFS 루트 경로",
|
||||
@@ -284,8 +286,32 @@
|
||||
"install.smtp_from_helper": "Gitea 가 사용할 이메일 주소. 이메일 주소 또는 \"이름\" <email@example.com> 형식으로 입력하세요.",
|
||||
"install.mailer_user": "SMTP 사용자이름",
|
||||
"install.mailer_password": "SMTP 비밀번호",
|
||||
"install.test_mail_to": "Send Testing Email",
|
||||
"install.test_mail_missing_host": "Please enter the SMTP host before testing email delivery.",
|
||||
"install.test_mail_missing_recipient": "Please enter a recipient email address before testing email delivery.",
|
||||
"install.registration_title": "Registration Management",
|
||||
"install.registration_mode": "Registration Mode",
|
||||
"install.registration_mode.admin_only": "Administrator-managed accounts only",
|
||||
"install.registration_mode.admin_only_helper": "Disable self-registration and let administrators create new accounts using the selected administrator-created account mode.",
|
||||
"install.admin_created_account_mode": "Administrator-Created Account Mode",
|
||||
"install.admin_created_account_mode.local": "Create local accounts directly",
|
||||
"install.admin_created_account_mode.local_helper": "Creates active local accounts immediately. Administrators can optionally notify the user by email after creation.",
|
||||
"install.admin_created_account_mode.invite": "Create invitation-based accounts",
|
||||
"install.admin_created_account_mode.invite_helper": "Creates inactive accounts with sign-in disabled until the user accepts the emailed invitation link.",
|
||||
"install.registration_mode.local_only": "Local registration only",
|
||||
"install.registration_mode.local_only_helper": "Allow new accounts only through Gitea's built-in registration form.",
|
||||
"install.registration_mode.external_only": "External registration only",
|
||||
"install.registration_mode.external_only_helper": "Disable the local registration form and accept new accounts only from external identity providers.",
|
||||
"install.registration_mode.local_and_external": "Local and external registration",
|
||||
"install.registration_mode.local_and_external_helper": "Allow new accounts through both Gitea's local registration form and external identity providers.",
|
||||
"install.registration_local_options": "Local Registration Options",
|
||||
"install.registration_external_options": "External Registration Options",
|
||||
"install.register_confirm": "가입시 이메일 확인 필수",
|
||||
"install.register_confirm_helper": "Require users to verify their email address before they can continue.",
|
||||
"install.register_manual_confirm": "Require Administrator Approval After Email Validation",
|
||||
"install.register_manual_confirm_helper": "New accounts stay pending until an administrator reviews and approves the request.",
|
||||
"install.mail_notify": "이메일 알림 켜기",
|
||||
"install.mail_notify_helper": "Controls routine notification emails such as watches, mentions, and administrative notices. Activation and invitation emails still use the SMTP configuration above.",
|
||||
"install.server_service_title": "서버 및 기타 서비스 설정",
|
||||
"install.disable_registration": "사용자 등록 비활성화",
|
||||
"install.disable_registration_popup": "사용자가 직접 등록할 수 없게 합니다. 운영자만이 추가할 수 있습니다.",
|
||||
@@ -294,6 +320,8 @@
|
||||
"install.openid_signin_popup": "OpenID 를 이용한 로그인 가능여부",
|
||||
"install.openid_signup": "OpenID 가입 가능여부",
|
||||
"install.openid_signup_popup": "OpenID를 통한 가입 가능여부",
|
||||
"install.openid_signin_helper": "Allow users to sign in through OpenID providers.",
|
||||
"install.openid_signup_helper": "Allow new accounts to be created through OpenID providers.",
|
||||
"install.enable_captcha": "가입 CAPTCHA 활성화",
|
||||
"install.enable_captcha_popup": "사용자 등록시 캡차 요구",
|
||||
"install.require_sign_in_view": "페이지를 보기 위해 로그인 하기",
|
||||
@@ -304,6 +332,13 @@
|
||||
"install.admin_password": "비밀번호",
|
||||
"install.confirm_password": "비밀번호 확인",
|
||||
"install.admin_email": "이메일 주소",
|
||||
"install.admin_management_policy": "Administration Management Policy",
|
||||
"install.admin_management_policy.super_admin_only": "Only super admins manage admins",
|
||||
"install.admin_management_policy.super_admin_only_helper": "Regular admins can manage only non-admin accounts. Any admin-to-admin change or deletion requires a super administrator.",
|
||||
"install.admin_management_policy.grantor_only": "Grantor manages promoted admins",
|
||||
"install.admin_management_policy.grantor_only_helper": "Regular admins can promote users to administrator and can later modify or delete only the administrators they directly promoted.",
|
||||
"install.admin_management_policy.grantor_inheritance": "Grantor chain with inheritance",
|
||||
"install.admin_management_policy.grantor_inheritance_helper": "Like grantor-only, but if the direct grantor becomes inactive or has sign-in disabled, management passes up the admin grant chain until an eligible admin is found. If none is found, super admins keep control.",
|
||||
"install.install_btn_confirm": "Gitea 설치하기",
|
||||
"install.test_git_failed": "'git' 명령 테스트 실패: %v",
|
||||
"install.sqlite3_not_available": "해당 버전에서는 SQLite3를 지원하지 않습니다. %s에서 공식 버전을 다운로드해주세요. ('gobuild' 버전이 아닙니다.)",
|
||||
@@ -311,7 +346,6 @@
|
||||
"install.invalid_db_table": "데이터베이스 테이블 '%s' 이 유효하지 않습니다: %v",
|
||||
"install.invalid_repo_path": "리포지토리의 경로가 올바르지 않습니다: %v",
|
||||
"install.invalid_app_data_path": "앱 데이터 경로가 올바르지 않습니다.: %v",
|
||||
"install.run_user_not_match": "실행 사용자명이 현재 사용자명과 다릅니다.: %s -> %s",
|
||||
"install.internal_token_failed": "내부 토큰의 생성에 실패했습니다: %v",
|
||||
"install.secret_key_failed": "비밀 키 생성에 실패했습니다: %v",
|
||||
"install.save_config_failed": "설정을 저장할 수 없습니다: %v",
|
||||
@@ -384,6 +418,9 @@
|
||||
"auth.sign_up_now": "지금 가입하세요.",
|
||||
"auth.sign_up_successful": "계정이 성공적으로 생성되었습니다. 환영합니다!",
|
||||
"auth.confirmation_mail_sent_prompt_ex": "새로운 확인 이메일을 <b>%s</b>에 전송하였습니다. %s 이내에 이메일 받은 편지함을 확인 후, 등록절차를 완료하여 주시길 바랍니다. 등록한 이메일 주소가 잘못된 경우, 다시 로그인하면 변경할 수 있습니다.",
|
||||
"auth.confirmation_mail_pending_signup": "A confirmation email has already been sent to <b>%s</b>. Please activate it before creating another account.",
|
||||
"auth.confirmation_mail_resend_failed": "The confirmation email could not be sent. Please try again later or contact an administrator.",
|
||||
"auth.confirmation_mail_resend_not_available": "This account can no longer receive confirmation emails.",
|
||||
"auth.must_change_password": "비밀번호를 변경하세요.",
|
||||
"auth.allow_password_change": "사용자에게 비밀번호 변경을 요청 (권장됨)",
|
||||
"auth.reset_password_mail_sent_prompt": "확인 메일이 <b>%s</b>로 전송되었습니다. 받은 편지함으로 도착한 메일을 %s 안에 확인해서 비밀번호 찾기 절차를 완료하십시오.",
|
||||
@@ -2996,6 +3033,7 @@
|
||||
"admin.users.last_login": "마지막 로그인",
|
||||
"admin.users.never_login": "로그인 한 적 없음",
|
||||
"admin.users.send_register_notify": "사용자 등록 알림 전송",
|
||||
"admin.users.send_register_invite": "Send User Registration Invitation",
|
||||
"admin.users.new_success": "사용자 계정 \"%s\"이 생성되었습니다.",
|
||||
"admin.users.edit": "수정하기",
|
||||
"admin.users.auth_source": "인증 소스",
|
||||
@@ -3807,5 +3845,15 @@
|
||||
"actions.general.cross_repo_desc": "선택된 저장소가 이 소유자의 모든 저장소에서 액션 작업을 실행할 때 GITEA_TOKEN을 사용하여 (읽기 전용으로) 액세스할 수 있도록 허용합니다.",
|
||||
"actions.general.cross_repo_selected": "선택된 리포지토리",
|
||||
"actions.general.cross_repo_target_repos": "대상 리포지토리",
|
||||
"actions.general.cross_repo_add": "대상 리포지토리 추가"
|
||||
"actions.general.cross_repo_add": "대상 리포지토리 추가",
|
||||
"auth.accept_your_invitation": "Accept Your Invitation",
|
||||
"auth.invitation_mail_pending_login": "An invitation email has already been sent to <b>%s</b>. Please accept it before signing in.",
|
||||
"auth.invitation_mail_sent_prompt_ex": "A new invitation email has been sent to <b>%s</b>. Please use the link within the next %s to activate your account.",
|
||||
"auth.invitation_mail_resend_failed": "The invitation email could not be sent. Please try again later or contact an administrator.",
|
||||
"auth.invitation_mail_resend_not_available": "This account can no longer receive invitation emails.",
|
||||
"auth.invitation_resend_prompt": "Did not receive the invitation email?",
|
||||
"auth.invitation_resend_button": "Resend",
|
||||
"admin.users.send_register_notify_helper": "The account will be activated and validated immediately.",
|
||||
"admin.users.send_register_invite_helper": "The user must accept the emailed invitation before the account becomes active.",
|
||||
"install.language_balloon": "Choose a language"
|
||||
}
|
||||
|
||||
@@ -162,6 +162,7 @@
|
||||
"startpage.lightweight_desc": "Gitea ir miminālas prasības un to var darbināt uz nedārga Raspberry Pi datora. Ietaupi savai ierīcei resursus!",
|
||||
"startpage.license": "Atvērtā pirmkoda",
|
||||
"install.install": "Instalācija",
|
||||
"install.installing_desc": "Installing now, please wait…",
|
||||
"install.title": "Sākotnējā konfigurācija",
|
||||
"install.docker_helper": "Ja Gitea ir uzstādīts Docker konteinerī, izlasiet <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"%s\">vadlīninas</a> pirms maināt iestatījumus.",
|
||||
"install.require_db_desc": "Gitea nepieciešams MySQL, PostgreSQL, MSSQL, SQLite3 vai TiDB (izmantojot MySQL protokolu).",
|
||||
@@ -173,17 +174,26 @@
|
||||
"install.db_name": "Datu bāzes nosaukums",
|
||||
"install.db_schema": "Shēma",
|
||||
"install.db_schema_helper": "Atstājiet tukšu, lai izmantu datubāzes noklusēto (\"public\").",
|
||||
"install.ssl_mode": "SSL",
|
||||
"install.path": "Ceļš",
|
||||
"install.sqlite_helper": "Faila ceļš SQLite3 datubāzei.<br>Ievadiet absolūto ceļu, ja Gitea tiek startēts kā serviss.",
|
||||
"install.reinstall_error": "Nevar instalēt datubāzē, kura jau satur Gitea datus",
|
||||
"install.reinstall_confirm_message": "Veicot Gitea datubāzēs atkārtotu instalēšanu, tas var izraisīt vairākas problēmas. Būtu jāizmanto esošais \"app.ini\", lai palaistu Gitea. Apstipriniet, ja patiešām vēlaties to darīt:",
|
||||
"install.reinstall_confirm_check_1": "The data encrypted by the SECRET_KEY in app.ini may be lost: users may not be able to log in with 2FA/OTP and mirrors may not function correctly. By checking this box, you confirm that the current app.ini file contains the correct SECRET_KEY.",
|
||||
"install.reinstall_confirm_check_2": "The repositories and settings may need to be resynchronized. By checking this box, you confirm that you will resynchronize the hooks for the repositories and authorized_keys file manually. You confirm that you will ensure that repository and mirror settings are correct.",
|
||||
"install.reinstall_confirm_check_3": "Apstiprinat, ka esat pārliecināts, ka Gitea izmanto pareizu app.ini faila atrašanās vietu un patiešām vēlaties veikt atkārtotu instalāciju, tāpat apstiprinat, ka tas var radīt augstāk minētās problēmas.",
|
||||
"install.err_empty_db_path": "Nav norādīts SQLite3 datu bāzes ceļš.",
|
||||
"install.no_admin_and_disable_registration": "Reģistrāciju nevar atslēgt, kamēr nav izveidots administratora konts.",
|
||||
"install.err_empty_admin_password": "Administratora kontam ir obligāti jānorāda parole.",
|
||||
"install.err_empty_admin_email": "The administrator email address cannot be empty.",
|
||||
"install.err_admin_name_is_reserved": "Administrator username is invalid. Username is reserved.",
|
||||
"install.err_admin_name_pattern_not_allowed": "Administrator username is invalid. The username matches a reserved pattern.",
|
||||
"install.err_admin_name_is_invalid": "Administrator username is invalid",
|
||||
"install.general_title": "Vispārīgie iestatījumi",
|
||||
"install.app_name": "Vietnes nosaukums",
|
||||
"install.app_name_helper": "Šeit var ievadīt savas kompānijas nosaukumu.",
|
||||
"install.default_language": "Default Language",
|
||||
"install.default_language_helper": "Used when a user's browser language does not match an available locale.",
|
||||
"install.repo_path": "Repozitoriju glabāšanas ceļš",
|
||||
"install.repo_path_helper": "Git repozitoriji tiks glabāti šajā direktorijā.",
|
||||
"install.lfs_path": "Git LFS glabāšanas vieta",
|
||||
@@ -195,6 +205,7 @@
|
||||
"install.ssh_port": "SSH servera ports",
|
||||
"install.ssh_port_helper": "Porta numurs, kuru SSH serveris klausīsies. Atstājiet tukšu, lai atspējotu.",
|
||||
"install.http_port": "Gitea HTTP klausīšanās ports",
|
||||
"install.http_port_helper": "Port number the Gitea web server will listen on.",
|
||||
"install.app_url": "Gitea pamata URL",
|
||||
"install.app_url_helper": "Pamata adrese HTTP(S) klonēšanas URL un e-pastu paziņojumiem.",
|
||||
"install.log_root_path": "Žurnalizēšanas ceļš",
|
||||
@@ -204,18 +215,37 @@
|
||||
"install.smtp_addr": "SMTP resursdators",
|
||||
"install.smtp_port": "SMTP ports",
|
||||
"install.smtp_from": "Nosūtīt e-pastu kā",
|
||||
"install.smtp_from_invalid": "The \"Send Email As\" address is invalid",
|
||||
"install.smtp_from_helper": "E-pasta adrese, ko Gitea izmantos. Ievadiet tika e-pasta adrese vai izmantojiet \"Vārds\" <epasts@domens.lv> formātu.",
|
||||
"install.mailer_user": "SMTP lietotājvārds",
|
||||
"install.mailer_password": "SMTP parole",
|
||||
"install.test_mail_to": "Send Testing Email",
|
||||
"install.test_mail_missing_host": "Please enter the SMTP host before testing email delivery.",
|
||||
"install.test_mail_missing_recipient": "Please enter a recipient email address before testing email delivery.",
|
||||
"install.registration_title": "Registration Management",
|
||||
"install.registration_mode": "Registration Mode",
|
||||
"install.registration_mode.admin_only": "Administrator-managed accounts only",
|
||||
"install.registration_mode.admin_only_helper": "Disable self-registration and let administrators create new accounts using the selected administrator-created account mode.",
|
||||
"install.admin_created_account_mode": "Administrator-Created Account Mode",
|
||||
"install.admin_created_account_mode.local": "Create local accounts directly",
|
||||
"install.admin_created_account_mode.local_helper": "Creates active local accounts immediately. Administrators can optionally notify the user by email after creation.",
|
||||
"install.admin_created_account_mode.invite": "Create invitation-based accounts",
|
||||
"install.admin_created_account_mode.invite_helper": "Creates inactive accounts with sign-in disabled until the user accepts the emailed invitation link.",
|
||||
"install.registration_mode.local_only": "Local registration only",
|
||||
"install.registration_mode.local_only_helper": "Allow new accounts only through Gitea's built-in registration form.",
|
||||
"install.registration_mode.external_only": "External registration only",
|
||||
"install.registration_mode.external_only_helper": "Disable the local registration form and accept new accounts only from external identity providers.",
|
||||
"install.registration_mode.local_and_external": "Local and external registration",
|
||||
"install.registration_mode.local_and_external_helper": "Allow new accounts through both Gitea's local registration form and external identity providers.",
|
||||
"install.registration_local_options": "Local Registration Options",
|
||||
"install.registration_external_options": "External Registration Options",
|
||||
"install.register_confirm": "Reģistrējoties pieprasīt apstiprināt e-pastu",
|
||||
"install.register_confirm_helper": "Require users to verify their email address before they can continue.",
|
||||
"install.register_manual_confirm": "Require Administrator Approval After Email Validation",
|
||||
"install.register_manual_confirm_helper": "New accounts stay pending until an administrator reviews and approves the request.",
|
||||
"install.mail_notify": "Iespējot e-pasta paziņojumus",
|
||||
"install.mail_notify_helper": "Controls routine notification emails such as watches, mentions, and administrative notices. Activation and invitation emails still use the SMTP configuration above.",
|
||||
"install.server_service_title": "Servera un citu servisu iestatījumi",
|
||||
"install.offline_mode": "Iespējot bezsaistes režīmu",
|
||||
"install.offline_mode_popup": "Atspējot ārējos satura piegādes tīklus, lai visi resursi tiktu piegādāti lokāli.",
|
||||
"install.disable_gravatar": "Atspējot Gravatar",
|
||||
"install.disable_gravatar_popup": "Atspējot Gravatar un citus avotus, visus avatarus augšupielādēs lietotāji vai izmantos noklusēto attēlu.",
|
||||
"install.federated_avatar_lookup": "Iespējot apvienotās profila bildes",
|
||||
"install.federated_avatar_lookup_popup": "Iespējot apvienoto profila bilžu meklētāju, lai izmantotu atvērtā koda apvienoto servisu balstītu uz Libravatar.",
|
||||
"install.disable_registration": "Atspējot lietotāju reģistrāciju",
|
||||
"install.disable_registration_popup": "Atspējot iespēju reģistrēties. Tikai administratori varēs izveidot jaunus kontus.",
|
||||
"install.allow_only_external_registration_popup": "Atļaut reģistrēties tikai ar ārējiem servisiem",
|
||||
@@ -223,6 +253,8 @@
|
||||
"install.openid_signin_popup": "Iespējot lietotāju pieteikšanos ar OpenID.",
|
||||
"install.openid_signup": "Iespējot reģistrāciju, izmantojot OpenID",
|
||||
"install.openid_signup_popup": "Iespējot lietotāju reģistrāciju pirms tam autorizējoties ar OpenID.",
|
||||
"install.openid_signin_helper": "Allow users to sign in through OpenID providers.",
|
||||
"install.openid_signup_helper": "Allow new accounts to be created through OpenID providers.",
|
||||
"install.enable_captcha": "Pieprasīt drošības kodu lietotāju reģistrācijā",
|
||||
"install.enable_captcha_popup": "Lietotājam reģistrējoties, pieprasīt ievadīt drošības kodu.",
|
||||
"install.require_sign_in_view": "Pieprasīt pieteikšanos, lai aplūkotu lapas",
|
||||
@@ -233,6 +265,13 @@
|
||||
"install.admin_password": "Parole",
|
||||
"install.confirm_password": "Apstipriniet paroli",
|
||||
"install.admin_email": "E-pasta adrese",
|
||||
"install.admin_management_policy": "Administration Management Policy",
|
||||
"install.admin_management_policy.super_admin_only": "Only super admins manage admins",
|
||||
"install.admin_management_policy.super_admin_only_helper": "Regular admins can manage only non-admin accounts. Any admin-to-admin change or deletion requires a super administrator.",
|
||||
"install.admin_management_policy.grantor_only": "Grantor manages promoted admins",
|
||||
"install.admin_management_policy.grantor_only_helper": "Regular admins can promote users to administrator and can later modify or delete only the administrators they directly promoted.",
|
||||
"install.admin_management_policy.grantor_inheritance": "Grantor chain with inheritance",
|
||||
"install.admin_management_policy.grantor_inheritance_helper": "Like grantor-only, but if the direct grantor becomes inactive or has sign-in disabled, management passes up the admin grant chain until an eligible admin is found. If none is found, super admins keep control.",
|
||||
"install.install_btn_confirm": "Instalēt Gitea",
|
||||
"install.test_git_failed": "Kļūda pārbaudot 'git' komandu: %v",
|
||||
"install.sqlite3_not_available": "Jūsu pašreizējā versija neatbalsta SQLite3, lūdzu lejupielādējiet oficiālo bināro versiju no %s, NEVIS gobuild versiju.",
|
||||
@@ -240,7 +279,6 @@
|
||||
"install.invalid_db_table": "Datubāzes tabula \"%s\" ir kļūdaina: %v",
|
||||
"install.invalid_repo_path": "Nederīga repozitorija glabāšanas vieta: %v",
|
||||
"install.invalid_app_data_path": "Lietojumprogrammas datu ceļš ir kļūdains: %v",
|
||||
"install.run_user_not_match": "Izpildes lietotājs nav pašreizējais lietotājs: %s -> %s",
|
||||
"install.internal_token_failed": "Neizdevās uzģenerēt iekšējās saziņas pilnvaru: %v",
|
||||
"install.secret_key_failed": "Neizdevās uzģenerēt drošības atslēgu: %v",
|
||||
"install.save_config_failed": "Neizdevās saglabāt konfigurāciju: %v",
|
||||
@@ -256,10 +294,12 @@
|
||||
"install.no_reply_address_helper": "Domēns lietotāja e-pasta adresei git žurnālos, ja lietotājs izvēlas paturēt savu e-pasta adresi privātu. Piemēram, ja lietotājs ir 'janis' un domēns 'neatbildet.piemers.lv', tad e-pasta adrese būs 'janis@neatbildet.piemers.lv'.",
|
||||
"install.password_algorithm": "Paroles jaucējsummas algoritms",
|
||||
"install.invalid_password_algorithm": "Kļūdaina paroles jaucējfunkcija",
|
||||
"install.password_algorithm_helper": "Set the password hashing algorithm. Algorithms have differing requirements and strengths. The argon2 algorithm is rather secure but uses a lot of memory and may be inappropriate for small systems.",
|
||||
"install.enable_update_checker": "Iespējot jaunu versiju paziņojumus",
|
||||
"install.enable_update_checker_helper": "Periodiski pārbaudīt jaunu version pieejamību, izgūstot datus no gitea.io.",
|
||||
"install.env_config_keys": "Vides konfigurācija",
|
||||
"install.env_config_keys_prompt": "Šie vides mainīgie tiks pielietoti arī konfigurācijas failā:",
|
||||
"install.config_write_file_prompt": "These configuration options will be written into: %s",
|
||||
"home.uname_holder": "Lietotājvārds vai e-pasts",
|
||||
"home.password_holder": "Parole",
|
||||
"home.switch_dashboard_context": "Mainīt infopaneļa kontekstu",
|
||||
@@ -299,6 +339,9 @@
|
||||
"auth.forgot_password": "Aizmirsi paroli?",
|
||||
"auth.sign_up_successful": "Konts tika veiksmīgi izveidots. Laipni lūdzam!",
|
||||
"auth.must_change_password": "Mainīt paroli",
|
||||
"auth.confirmation_mail_pending_signup": "A confirmation email has already been sent to <b>%s</b>. Please activate it before creating another account.",
|
||||
"auth.confirmation_mail_resend_failed": "The confirmation email could not be sent. Please try again later or contact an administrator.",
|
||||
"auth.confirmation_mail_resend_not_available": "This account can no longer receive confirmation emails.",
|
||||
"auth.allow_password_change": "Pieprasīt lietotājam mainīt paroli (ieteicams)",
|
||||
"auth.reset_password_mail_sent_prompt": "Apstiprināšanas e-pasts tika nosūtīts uz <b>%s</b>. Pārbaudiet savu e-pasta kontu tuvāko %s laikā, lai pabeigtu paroles atjaunošanas procesu.",
|
||||
"auth.active_your_account": "Aktivizēt savu kontu",
|
||||
@@ -2393,6 +2436,7 @@
|
||||
"admin.users.created": "Izveidots",
|
||||
"admin.users.last_login": "Pēdējā pieteikšanās",
|
||||
"admin.users.send_register_notify": "Nosūtīt lietotājam reģistrācijas paziņojumu",
|
||||
"admin.users.send_register_invite": "Send User Registration Invitation",
|
||||
"admin.users.new_success": "Lietotāja konts \"%s\" tika izveidots.",
|
||||
"admin.users.edit": "Labot",
|
||||
"admin.users.auth_source": "Autentificēšanas avots",
|
||||
@@ -3042,5 +3086,15 @@
|
||||
"git.filemode.normal_file": "Parasts fails",
|
||||
"git.filemode.executable_file": "Izpildāmais fails",
|
||||
"git.filemode.symbolic_link": "Simboliska saite",
|
||||
"git.filemode.submodule": "Apakšmodulis"
|
||||
"git.filemode.submodule": "Apakšmodulis",
|
||||
"auth.accept_your_invitation": "Accept Your Invitation",
|
||||
"auth.invitation_mail_pending_login": "An invitation email has already been sent to <b>%s</b>. Please accept it before signing in.",
|
||||
"auth.invitation_mail_sent_prompt_ex": "A new invitation email has been sent to <b>%s</b>. Please use the link within the next %s to activate your account.",
|
||||
"auth.invitation_mail_resend_failed": "The invitation email could not be sent. Please try again later or contact an administrator.",
|
||||
"auth.invitation_mail_resend_not_available": "This account can no longer receive invitation emails.",
|
||||
"auth.invitation_resend_prompt": "Did not receive the invitation email?",
|
||||
"auth.invitation_resend_button": "Resend",
|
||||
"admin.users.send_register_notify_helper": "The account will be activated and validated immediately.",
|
||||
"admin.users.send_register_invite_helper": "The user must accept the emailed invitation before the account becomes active.",
|
||||
"install.language_balloon": "Choose a language"
|
||||
}
|
||||
|
||||
@@ -101,6 +101,7 @@
|
||||
"startpage.lightweight": "Lichtgewicht",
|
||||
"startpage.lightweight_desc": "Gitea heeft hele lage systeemeisen, je kunt Gitea al draaien op een goedkope Raspberry Pi.",
|
||||
"install.install": "Installatie",
|
||||
"install.installing_desc": "Installing now, please wait…",
|
||||
"install.title": "Initiële configuratie",
|
||||
"install.docker_helper": "Als je gitea draait in Docker, Lees eerst de <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"%s\">documentatie</a> voordat je een instelling aanpast.",
|
||||
"install.require_db_desc": "Gitea vereist MySQL, PostgreSQL, MSSQL, SQLite3 of TiDB (MySQL protocol).",
|
||||
@@ -110,48 +111,80 @@
|
||||
"install.user": "Gebruikersnaam",
|
||||
"install.password": "Wachtwoord",
|
||||
"install.db_name": "Database naam",
|
||||
"install.db_schema": "Schema",
|
||||
"install.db_schema_helper": "Laat leeg voor de standaard database (\"openbaar\").",
|
||||
"install.ssl_mode": "SSL",
|
||||
"install.path": "Pad",
|
||||
"install.sqlite_helper": "Bestandspad voor de SQLite3-database.<br>Vul een volledig pad in als je GItea als een service uitvoert.",
|
||||
"install.reinstall_error": "U probeert te installeren in een bestaande Gitea database",
|
||||
"install.reinstall_confirm_message": "Herinstalleren met een bestaande Gitea-database kan meerdere problemen veroorzaken. In de meeste gevallen kun je het bestaande \"app.ini\" gebruiken om Gitea te laten draaien. Als je weet wat je aan het doen bent, bevestig dan het volgende:",
|
||||
"install.reinstall_confirm_check_1": "The data encrypted by the SECRET_KEY in app.ini may be lost: users may not be able to log in with 2FA/OTP and mirrors may not function correctly. By checking this box, you confirm that the current app.ini file contains the correct SECRET_KEY.",
|
||||
"install.reinstall_confirm_check_2": "The repositories and settings may need to be resynchronized. By checking this box, you confirm that you will resynchronize the hooks for the repositories and authorized_keys file manually. You confirm that you will ensure that repository and mirror settings are correct.",
|
||||
"install.reinstall_confirm_check_3": "Je bevestigt dat je er absoluut zeker van bent dat deze Gitea draait met de juiste app. Geen locatie en dat je zeker weet dat je opnieuw moet installeren. Je bevestigt dat je de hierbovenstaande risico's erkent.",
|
||||
"install.err_empty_db_path": "SQLite3 database pad mag niet leeg zijn.",
|
||||
"install.no_admin_and_disable_registration": "U kunt zelf-registratie van de gebruiker niet uitschakelen zonder het maken van een administrator-account.",
|
||||
"install.err_empty_admin_password": "Het administrator-wachtwoord mag niet leeg zijn.",
|
||||
"install.err_empty_admin_email": "The administrator email address cannot be empty.",
|
||||
"install.err_admin_name_is_reserved": "Administrator username is invalid. Username is reserved.",
|
||||
"install.err_admin_name_pattern_not_allowed": "Administrator username is invalid. The username matches a reserved pattern.",
|
||||
"install.err_admin_name_is_invalid": "Administrator username is invalid",
|
||||
"install.general_title": "Algemene Instellingen",
|
||||
"install.app_name": "Naam site",
|
||||
"install.app_name_helper": "U kan de naam van uw bedrijf hier invullen.",
|
||||
"install.default_language": "Default Language",
|
||||
"install.default_language_helper": "Used when a user's browser language does not match an available locale.",
|
||||
"install.repo_path": "Repositories basis map",
|
||||
"install.repo_path_helper": "Externe git repositories worden opgeslagen in deze map.",
|
||||
"install.lfs_path": "Git LFS root pad",
|
||||
"install.lfs_path_helper": "Bestanden bijgehouden door Git LFS zullenworden opgeslagen in deze map. Laat leeg om uit te schakelen.",
|
||||
"install.run_user": "Uitvoeren als gebruiker",
|
||||
"install.run_user_helper": "The operating system username that Gitea runs as, it must have write access to the data paths. This value is auto-detected and cannot be changed here. To use a different user, restart Gitea under that account.",
|
||||
"install.domain": "Server Domein",
|
||||
"install.domain_helper": "Domein of hostadres voor de server.",
|
||||
"install.ssh_port": "SSH server-poort",
|
||||
"install.ssh_port_helper": "Nummer van de poort die uw SSH-server gebruikt. Laat dit veld leeg om de SSH functie uit te schakelen.",
|
||||
"install.http_port": "Gitea HTTP-poort",
|
||||
"install.http_port_helper": "Port number the Gitea web server will listen on.",
|
||||
"install.app_url": "Gitea base URL",
|
||||
"install.app_url_helper": "Basisadres voor HTTP(S) kloon URL's en e-mailmeldingen.",
|
||||
"install.log_root_path": "Log-pad",
|
||||
"install.log_root_path_helper": "Logboekbestanden worden geschreven naar deze map.",
|
||||
"install.optional_title": "Optionele instellingen",
|
||||
"install.email_title": "E-mail instellingen",
|
||||
"install.smtp_addr": "SMTP Host",
|
||||
"install.smtp_port": "SMTP Poort",
|
||||
"install.smtp_from": "E-mails versturen als",
|
||||
"install.smtp_from_invalid": "The \"Send Email As\" address is invalid",
|
||||
"install.smtp_from_helper": "E-mailadres dat Gitea gaat gebruiken. Voer een gewoon e-mailadres in of gebruik de \"Naam\" <email@example.com> -indeling.",
|
||||
"install.mailer_user": "SMTP gebruikersnaam",
|
||||
"install.mailer_password": "SMTP wachtwoord",
|
||||
"install.test_mail_to": "Send Testing Email",
|
||||
"install.test_mail_missing_host": "Please enter the SMTP host before testing email delivery.",
|
||||
"install.test_mail_missing_recipient": "Please enter a recipient email address before testing email delivery.",
|
||||
"install.registration_title": "Registration Management",
|
||||
"install.registration_mode": "Registration Mode",
|
||||
"install.registration_mode.admin_only": "Administrator-managed accounts only",
|
||||
"install.registration_mode.admin_only_helper": "Disable self-registration and let administrators create new accounts using the selected administrator-created account mode.",
|
||||
"install.admin_created_account_mode": "Administrator-Created Account Mode",
|
||||
"install.admin_created_account_mode.local": "Create local accounts directly",
|
||||
"install.admin_created_account_mode.local_helper": "Creates active local accounts immediately. Administrators can optionally notify the user by email after creation.",
|
||||
"install.admin_created_account_mode.invite": "Create invitation-based accounts",
|
||||
"install.admin_created_account_mode.invite_helper": "Creates inactive accounts with sign-in disabled until the user accepts the emailed invitation link.",
|
||||
"install.registration_mode.local_only": "Local registration only",
|
||||
"install.registration_mode.local_only_helper": "Allow new accounts only through Gitea's built-in registration form.",
|
||||
"install.registration_mode.external_only": "External registration only",
|
||||
"install.registration_mode.external_only_helper": "Disable the local registration form and accept new accounts only from external identity providers.",
|
||||
"install.registration_mode.local_and_external": "Local and external registration",
|
||||
"install.registration_mode.local_and_external_helper": "Allow new accounts through both Gitea's local registration form and external identity providers.",
|
||||
"install.registration_local_options": "Local Registration Options",
|
||||
"install.registration_external_options": "External Registration Options",
|
||||
"install.register_confirm": "E-mailbevestiging vereist bij registreren",
|
||||
"install.register_confirm_helper": "Require users to verify their email address before they can continue.",
|
||||
"install.register_manual_confirm": "Require Administrator Approval After Email Validation",
|
||||
"install.register_manual_confirm_helper": "New accounts stay pending until an administrator reviews and approves the request.",
|
||||
"install.mail_notify": "Activeer e-mailnotificaties",
|
||||
"install.mail_notify_helper": "Controls routine notification emails such as watches, mentions, and administrative notices. Activation and invitation emails still use the SMTP configuration above.",
|
||||
"install.server_service_title": "Server en Third-Party Service-instellingen",
|
||||
"install.offline_mode": "Lokale modus inschakelen",
|
||||
"install.offline_mode_popup": "Schakel third-party content uit en gebruik alleen lokale middelen.",
|
||||
"install.disable_gravatar": "Gravatar uitschakelen",
|
||||
"install.disable_gravatar_popup": "Gravatar en derden avatar bronnen uitschakelen. Een standaard avatar zal worden gebruikt, tenzij een gebruiker een lokale avatar uploadt.",
|
||||
"install.federated_avatar_lookup": "Federated Avatars toestaan",
|
||||
"install.federated_avatar_lookup_popup": "Enable federated avatars lookup to use federated open source service based on libravatar.",
|
||||
"install.disable_registration": "Schakel zelf registratie uit",
|
||||
"install.disable_registration_popup": "Schakel zelfregistratie uit, alleen admins kunnen accounts maken.",
|
||||
"install.allow_only_external_registration_popup": "Registratie alleen via externe diensten toestaan",
|
||||
@@ -159,22 +192,32 @@
|
||||
"install.openid_signin_popup": "Gebruikerslogin via OpenID inschakelen.",
|
||||
"install.openid_signup": "OpenID zelf-registratie inschakelen",
|
||||
"install.openid_signup_popup": "OpenID zelfregistratie inschakelen.",
|
||||
"install.openid_signin_helper": "Allow users to sign in through OpenID providers.",
|
||||
"install.openid_signup_helper": "Allow new accounts to be created through OpenID providers.",
|
||||
"install.enable_captcha": "Registratie CAPTCHA inschakelen",
|
||||
"install.enable_captcha_popup": "Vereis captcha validatie voor zelf-registratie van gebruiker.",
|
||||
"install.require_sign_in_view": "Vereis inloggen om pagina's te kunnen bekijken",
|
||||
"install.require_sign_in_view_popup": "Limit page access to signed-in users. Visitors will only see the sign-in and registration pages.",
|
||||
"install.admin_setting_desc": "Het creëren van een administrator-account is optioneel. De eerste geregistreerde gebruiker wordt automatisch de beheerder.",
|
||||
"install.admin_title": "Instellingen beheerdersaccount",
|
||||
"install.admin_name": "Admin gebruikersnaam",
|
||||
"install.admin_password": "Wachtwoord",
|
||||
"install.confirm_password": "Verifieer wachtwoord",
|
||||
"install.admin_email": "E-mailadres",
|
||||
"install.admin_management_policy": "Administration Management Policy",
|
||||
"install.admin_management_policy.super_admin_only": "Only super admins manage admins",
|
||||
"install.admin_management_policy.super_admin_only_helper": "Regular admins can manage only non-admin accounts. Any admin-to-admin change or deletion requires a super administrator.",
|
||||
"install.admin_management_policy.grantor_only": "Grantor manages promoted admins",
|
||||
"install.admin_management_policy.grantor_only_helper": "Regular admins can promote users to administrator and can later modify or delete only the administrators they directly promoted.",
|
||||
"install.admin_management_policy.grantor_inheritance": "Grantor chain with inheritance",
|
||||
"install.admin_management_policy.grantor_inheritance_helper": "Like grantor-only, but if the direct grantor becomes inactive or has sign-in disabled, management passes up the admin grant chain until an eligible admin is found. If none is found, super admins keep control.",
|
||||
"install.install_btn_confirm": "Installeer Gitea",
|
||||
"install.test_git_failed": "Git test niet gelukt: 'git' commando %v",
|
||||
"install.sqlite3_not_available": "Deze Gitea-versie biedt geen ondersteuning voor SQLite3. Download de officiële build van %s (niet de versie van de 'gobuild').",
|
||||
"install.invalid_db_setting": "De database instelling zijn niet correct: %v",
|
||||
"install.invalid_db_table": "The database table \"%s\" is invalid: %v",
|
||||
"install.invalid_repo_path": "Het pad van de hoofdmap van de repository is ongeldig: %v",
|
||||
"install.invalid_app_data_path": "Ongeldig app-gegevenspad: %v",
|
||||
"install.run_user_not_match": "De 'uitvoeren als' gebruikersnaam is niet de huidige gebruikersnaam: %s -> %s",
|
||||
"install.internal_token_failed": "Interne token genereren mislukt: %v",
|
||||
"install.secret_key_failed": "Geheime sleutel genereren mislukt: %v",
|
||||
"install.save_config_failed": "Kan de configuratie niet opslaan: %v",
|
||||
@@ -189,6 +232,13 @@
|
||||
"install.no_reply_address": "Verborgen e-maildomein",
|
||||
"install.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'.",
|
||||
"install.password_algorithm": "Wachtwoord Hash Algoritme",
|
||||
"install.invalid_password_algorithm": "Invalid password hash algorithm",
|
||||
"install.password_algorithm_helper": "Set the password hashing algorithm. Algorithms have differing requirements and strengths. The argon2 algorithm is rather secure but uses a lot of memory and may be inappropriate for small systems.",
|
||||
"install.enable_update_checker": "Enable Update Checker",
|
||||
"install.enable_update_checker_helper": "Checks for new version releases periodically by connecting to gitea.io.",
|
||||
"install.env_config_keys": "Environment Configuration",
|
||||
"install.env_config_keys_prompt": "The following environment variables will also be applied to your configuration file:",
|
||||
"install.config_write_file_prompt": "These configuration options will be written into: %s",
|
||||
"home.uname_holder": "Gebruikersnaam of e-mailadres",
|
||||
"home.password_holder": "Wachtwoord",
|
||||
"home.switch_dashboard_context": "Wissel voorpaginacontext",
|
||||
@@ -220,6 +270,9 @@
|
||||
"auth.forgot_password_title": "Wachtwoord vergeten",
|
||||
"auth.forgot_password": "Wachtwoord vergeten?",
|
||||
"auth.must_change_password": "Uw wachtwoord wijzigen",
|
||||
"auth.confirmation_mail_pending_signup": "A confirmation email has already been sent to <b>%s</b>. Please activate it before creating another account.",
|
||||
"auth.confirmation_mail_resend_failed": "The confirmation email could not be sent. Please try again later or contact an administrator.",
|
||||
"auth.confirmation_mail_resend_not_available": "This account can no longer receive confirmation emails.",
|
||||
"auth.allow_password_change": "Verplicht de gebruiker om zijn/haar wachtwoord te wijzigen (aanbevolen)",
|
||||
"auth.reset_password_mail_sent_prompt": "Een bevestigingsmail is verstuurd naar <b>%s</b>. Controleer uw inbox in de volgende %s om het herstel van uw account te voltooien.",
|
||||
"auth.active_your_account": "Activeer uw account",
|
||||
@@ -1780,6 +1833,7 @@
|
||||
"admin.users.created": "Aangemaakt",
|
||||
"admin.users.last_login": "Laatste keer ingelogd",
|
||||
"admin.users.send_register_notify": "Stuur gebruikersregistratie notificatie",
|
||||
"admin.users.send_register_invite": "Send User Registration Invitation",
|
||||
"admin.users.edit": "Bewerken",
|
||||
"admin.users.auth_source": "Authenticatiebron",
|
||||
"admin.users.local": "Lokaal",
|
||||
@@ -2093,5 +2147,15 @@
|
||||
"actions.runners.task_list.run": "Uitvoeren",
|
||||
"actions.runners.task_list.repository": "Opslagplaats",
|
||||
"actions.runners.status.active": "Actief",
|
||||
"actions.runners.version": "Versie"
|
||||
"actions.runners.version": "Versie",
|
||||
"auth.accept_your_invitation": "Accept Your Invitation",
|
||||
"auth.invitation_mail_pending_login": "An invitation email has already been sent to <b>%s</b>. Please accept it before signing in.",
|
||||
"auth.invitation_mail_sent_prompt_ex": "A new invitation email has been sent to <b>%s</b>. Please use the link within the next %s to activate your account.",
|
||||
"auth.invitation_mail_resend_failed": "The invitation email could not be sent. Please try again later or contact an administrator.",
|
||||
"auth.invitation_mail_resend_not_available": "This account can no longer receive invitation emails.",
|
||||
"auth.invitation_resend_prompt": "Did not receive the invitation email?",
|
||||
"auth.invitation_resend_button": "Resend",
|
||||
"admin.users.send_register_notify_helper": "The account will be activated and validated immediately.",
|
||||
"admin.users.send_register_invite_helper": "The user must accept the emailed invitation before the account becomes active.",
|
||||
"install.language_balloon": "Choose a language"
|
||||
}
|
||||
|
||||
@@ -106,6 +106,7 @@
|
||||
"startpage.lightweight_desc": "Gitea ma niskie minimalne wymagania i może działać na niedrogim Raspberry Pi. Oszczędzaj energię swojego komputera!",
|
||||
"startpage.license": "Otwarte źródło",
|
||||
"install.install": "Instalacja",
|
||||
"install.installing_desc": "Installing now, please wait…",
|
||||
"install.title": "Wstępna konfiguracja",
|
||||
"install.docker_helper": "Jeśli używasz Gitea za pomocą Docker'a, przeczytaj <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"%s\">dokumentację</a> przed wprowadzeniem jakichkolwiek zmian.",
|
||||
"install.require_db_desc": "Gitea wymaga MySQL, PostgreSQL, MSSQL, SQLite3 lub TiDB (protokół MySQL).",
|
||||
@@ -117,27 +118,38 @@
|
||||
"install.db_name": "Nazwa bazy danych",
|
||||
"install.db_schema": "Schemat",
|
||||
"install.db_schema_helper": "Pozostaw puste dla domyślnego schematu bazy danych (\"public\").",
|
||||
"install.ssl_mode": "SSL",
|
||||
"install.path": "Ścieżka",
|
||||
"install.sqlite_helper": "Ścieżka pliku dla bazy danych SQLite3.<br>Wpisz ścieżkę bezwzględną, jeśli Gitea jest uruchomiona jako usługa.",
|
||||
"install.reinstall_error": "Próbujesz zainstalować w istniejącej już bazie danych Gitea",
|
||||
"install.reinstall_confirm_message": "Ponowna instalacja z istniejącą bazą danych Gitea może powodować wiele problemów. W większości przypadków powinieneś użyć swojego istniejącego \"app.ini\" do uruchomienia Gitea. Jeśli wiesz, co robisz, potwierdź następujące działania:",
|
||||
"install.reinstall_confirm_check_1": "The data encrypted by the SECRET_KEY in app.ini may be lost: users may not be able to log in with 2FA/OTP and mirrors may not function correctly. By checking this box, you confirm that the current app.ini file contains the correct SECRET_KEY.",
|
||||
"install.reinstall_confirm_check_2": "The repositories and settings may need to be resynchronized. By checking this box, you confirm that you will resynchronize the hooks for the repositories and authorized_keys file manually. You confirm that you will ensure that repository and mirror settings are correct.",
|
||||
"install.reinstall_confirm_check_3": "Potwierdzasz, że jesteś całkowicie pewien, że ta Gitea działa z app.ini w poprawnej lokalizacji i że jesteś pewien, że musisz ponownie zainstalować. Potwierdzasz powyższe ryzyko.",
|
||||
"install.err_empty_db_path": "Ścieżka do bazy danych SQLite3 nie może być pusta.",
|
||||
"install.no_admin_and_disable_registration": "Nie możesz wyłączyć możliwości samodzielnej rejestracji kont użytkowników bez stworzenia konta administratora.",
|
||||
"install.err_empty_admin_password": "Hasło administratora nie może być puste.",
|
||||
"install.err_empty_admin_email": "The administrator email address cannot be empty.",
|
||||
"install.err_admin_name_is_reserved": "Administrator username is invalid. Username is reserved.",
|
||||
"install.err_admin_name_pattern_not_allowed": "Administrator username is invalid. The username matches a reserved pattern.",
|
||||
"install.err_admin_name_is_invalid": "Administrator username is invalid",
|
||||
"install.general_title": "Ustawienia ogólne",
|
||||
"install.app_name": "Tytuł witryny",
|
||||
"install.app_name_helper": "Wprowadź nazwę firmy.",
|
||||
"install.default_language": "Default Language",
|
||||
"install.default_language_helper": "Used when a user's browser language does not match an available locale.",
|
||||
"install.repo_path": "Katalog repozytoriów",
|
||||
"install.repo_path_helper": "Zdalne repozytoria Git zostaną zapisane w tym katalogu.",
|
||||
"install.lfs_path": "Ścieżka główna Git LFS",
|
||||
"install.lfs_path_helper": "W tym katalogu będą przechowywane pliki śledzone za pomocą Git LFS. Pozostaw puste, aby wyłączyć LFS.",
|
||||
"install.run_user": "Uruchom jako nazwa użytkownika",
|
||||
"install.run_user_helper": "The operating system username that Gitea runs as, it must have write access to the data paths. This value is auto-detected and cannot be changed here. To use a different user, restart Gitea under that account.",
|
||||
"install.domain": "Domena serwera",
|
||||
"install.domain_helper": "Adres domeny lub hosta serwera.",
|
||||
"install.ssh_port": "Port serwera SSH",
|
||||
"install.ssh_port_helper": "Numer portu, na którym nasłuchuje Twój serwer SSH. Pozostaw puste, aby wyłączyć.",
|
||||
"install.http_port": "Port nasłuchiwania HTTP Gitea",
|
||||
"install.http_port_helper": "Port number the Gitea web server will listen on.",
|
||||
"install.app_url": "Podstawowy adres URL Gitea",
|
||||
"install.app_url_helper": "Podstawowy adres dla klonowania adresów URL HTTP(S) oraz powiadomień e-mail.",
|
||||
"install.log_root_path": "Ścieżka dla logów",
|
||||
@@ -147,18 +159,37 @@
|
||||
"install.smtp_addr": "Serwer SMTP",
|
||||
"install.smtp_port": "Port SMTP",
|
||||
"install.smtp_from": "Wyślij e-mail jako",
|
||||
"install.smtp_from_invalid": "The \"Send Email As\" address is invalid",
|
||||
"install.smtp_from_helper": "Adres e-mail, z którego Gitea będzie korzystać. Wpisz prosty adres e-mail, lub użyj formatu \"Nazwa\" <email@example.com>.",
|
||||
"install.mailer_user": "Nazwa użytkownika SMTP",
|
||||
"install.mailer_password": "Hasło SMTP",
|
||||
"install.test_mail_to": "Send Testing Email",
|
||||
"install.test_mail_missing_host": "Please enter the SMTP host before testing email delivery.",
|
||||
"install.test_mail_missing_recipient": "Please enter a recipient email address before testing email delivery.",
|
||||
"install.registration_title": "Registration Management",
|
||||
"install.registration_mode": "Registration Mode",
|
||||
"install.registration_mode.admin_only": "Administrator-managed accounts only",
|
||||
"install.registration_mode.admin_only_helper": "Disable self-registration and let administrators create new accounts using the selected administrator-created account mode.",
|
||||
"install.admin_created_account_mode": "Administrator-Created Account Mode",
|
||||
"install.admin_created_account_mode.local": "Create local accounts directly",
|
||||
"install.admin_created_account_mode.local_helper": "Creates active local accounts immediately. Administrators can optionally notify the user by email after creation.",
|
||||
"install.admin_created_account_mode.invite": "Create invitation-based accounts",
|
||||
"install.admin_created_account_mode.invite_helper": "Creates inactive accounts with sign-in disabled until the user accepts the emailed invitation link.",
|
||||
"install.registration_mode.local_only": "Local registration only",
|
||||
"install.registration_mode.local_only_helper": "Allow new accounts only through Gitea's built-in registration form.",
|
||||
"install.registration_mode.external_only": "External registration only",
|
||||
"install.registration_mode.external_only_helper": "Disable the local registration form and accept new accounts only from external identity providers.",
|
||||
"install.registration_mode.local_and_external": "Local and external registration",
|
||||
"install.registration_mode.local_and_external_helper": "Allow new accounts through both Gitea's local registration form and external identity providers.",
|
||||
"install.registration_local_options": "Local Registration Options",
|
||||
"install.registration_external_options": "External Registration Options",
|
||||
"install.register_confirm": "Wymagają potwierdzenia e-mail przy rejestracji",
|
||||
"install.register_confirm_helper": "Require users to verify their email address before they can continue.",
|
||||
"install.register_manual_confirm": "Require Administrator Approval After Email Validation",
|
||||
"install.register_manual_confirm_helper": "New accounts stay pending until an administrator reviews and approves the request.",
|
||||
"install.mail_notify": "Włącz powiadomienia e-mail",
|
||||
"install.mail_notify_helper": "Controls routine notification emails such as watches, mentions, and administrative notices. Activation and invitation emails still use the SMTP configuration above.",
|
||||
"install.server_service_title": "Ustawienia serwera i innych usług",
|
||||
"install.offline_mode": "Włącz tryb lokalny",
|
||||
"install.offline_mode_popup": "Wyłącz zewnętrzne usługi dostarczania i dostarczaj wszystkie zasoby lokalnie.",
|
||||
"install.disable_gravatar": "Wyłącz Gravatar",
|
||||
"install.disable_gravatar_popup": "Wyłącz Gravatar i inne usługi zewnętrzne awatarów. Zostanie zastosowany domyślny awatar, chyba że użytkownik prześle swój własny.",
|
||||
"install.federated_avatar_lookup": "Włącz zewnętrzne awatary",
|
||||
"install.federated_avatar_lookup_popup": "Enable federated avatars lookup to use federated open source service based on libravatar.",
|
||||
"install.disable_registration": "Wyłącz rejestrację dwuskładnikową",
|
||||
"install.disable_registration_popup": "Wyłącz samodzielną rejestrację użytkowników. Tylko administratorzy będą w stanie tworzyć nowe konta.",
|
||||
"install.allow_only_external_registration_popup": "Włącz rejestrację wyłącznie za pomocą zewnętrznych usług",
|
||||
@@ -166,22 +197,32 @@
|
||||
"install.openid_signin_popup": "Włącz logowanie użytkowników za pomocą OpenID.",
|
||||
"install.openid_signup": "Włącz samodzielną rejestrację za pomocą OpenID",
|
||||
"install.openid_signup_popup": "Włącz samodzielną rejestrację opartą o OpenID.",
|
||||
"install.openid_signin_helper": "Allow users to sign in through OpenID providers.",
|
||||
"install.openid_signup_helper": "Allow new accounts to be created through OpenID providers.",
|
||||
"install.enable_captcha": "Włącz CAPTCHA przy rejestracji",
|
||||
"install.enable_captcha_popup": "Wymagaj walidacji CAPTCHA przy samodzielnej rejestracji użytkownika.",
|
||||
"install.require_sign_in_view": "Wymagaj zalogowania w celu przeglądania stron",
|
||||
"install.require_sign_in_view_popup": "Limit page access to signed-in users. Visitors will only see the sign-in and registration pages.",
|
||||
"install.admin_setting_desc": "Tworzenie konta administratora jest opcjonalne. Pierwszy zarejestrowany użytkownik automatycznie zostanie administratorem.",
|
||||
"install.admin_title": "Ustawienia konta administratora",
|
||||
"install.admin_name": "Nazwa użytkownika administratora",
|
||||
"install.admin_password": "Hasło",
|
||||
"install.confirm_password": "Potwierdź hasło",
|
||||
"install.admin_email": "Adres e-mail",
|
||||
"install.admin_management_policy": "Administration Management Policy",
|
||||
"install.admin_management_policy.super_admin_only": "Only super admins manage admins",
|
||||
"install.admin_management_policy.super_admin_only_helper": "Regular admins can manage only non-admin accounts. Any admin-to-admin change or deletion requires a super administrator.",
|
||||
"install.admin_management_policy.grantor_only": "Grantor manages promoted admins",
|
||||
"install.admin_management_policy.grantor_only_helper": "Regular admins can promote users to administrator and can later modify or delete only the administrators they directly promoted.",
|
||||
"install.admin_management_policy.grantor_inheritance": "Grantor chain with inheritance",
|
||||
"install.admin_management_policy.grantor_inheritance_helper": "Like grantor-only, but if the direct grantor becomes inactive or has sign-in disabled, management passes up the admin grant chain until an eligible admin is found. If none is found, super admins keep control.",
|
||||
"install.install_btn_confirm": "Zainstaluj Gitea",
|
||||
"install.test_git_failed": "Nie udało się przetestować polecenia „git”: %v",
|
||||
"install.sqlite3_not_available": "Twoje wydanie Gitea nie obsługuje SQLite3. Pobierz oficjalne wydanie z %s (NIE wersję \"gobuild\").",
|
||||
"install.invalid_db_setting": "Nieprawidłowe ustawienia bazy danych: %v",
|
||||
"install.invalid_db_table": "The database table \"%s\" is invalid: %v",
|
||||
"install.invalid_repo_path": "Ścieżka repozytorium nie jest poprawna: %v",
|
||||
"install.invalid_app_data_path": "Ścieżka danych aplikacji jest nieprawidłowa: %v",
|
||||
"install.run_user_not_match": "Użytkownik \"uruchom jako\" nie jest obecnym użytkownikiem: %s -> %s",
|
||||
"install.internal_token_failed": "Nie udało się wygenerować tokenu wewnętrznego: %v",
|
||||
"install.secret_key_failed": "Nie udało się wygenerować tajnego klucza: %v",
|
||||
"install.save_config_failed": "Nie udało się zapisać konfiguracji: %v",
|
||||
@@ -196,6 +237,13 @@
|
||||
"install.no_reply_address": "Ukryta domena e-mail",
|
||||
"install.no_reply_address_helper": "Nazwa domeny dla użytkowników z ukrytym adresem e-mail. Przykładowo, użytkownik \"jan\" będzie zalogowany na Git'cie jako \"jan@noreply.example.org\", jeśli domena ukrytego adresu e-mail jest ustawiona na \"noreply.example.org\".",
|
||||
"install.password_algorithm": "Algorytm hashowania haseł",
|
||||
"install.invalid_password_algorithm": "Invalid password hash algorithm",
|
||||
"install.password_algorithm_helper": "Set the password hashing algorithm. Algorithms have differing requirements and strengths. The argon2 algorithm is rather secure but uses a lot of memory and may be inappropriate for small systems.",
|
||||
"install.enable_update_checker": "Enable Update Checker",
|
||||
"install.enable_update_checker_helper": "Checks for new version releases periodically by connecting to gitea.io.",
|
||||
"install.env_config_keys": "Environment Configuration",
|
||||
"install.env_config_keys_prompt": "The following environment variables will also be applied to your configuration file:",
|
||||
"install.config_write_file_prompt": "These configuration options will be written into: %s",
|
||||
"home.uname_holder": "Nazwa użytkownika lub adres email",
|
||||
"home.password_holder": "Hasło",
|
||||
"home.switch_dashboard_context": "Przełącz kontekst pulpitu",
|
||||
@@ -229,6 +277,9 @@
|
||||
"auth.forgot_password_title": "Zapomniałem hasła",
|
||||
"auth.forgot_password": "Zapomniałeś hasła?",
|
||||
"auth.must_change_password": "Zaktualizuj swoje hasło",
|
||||
"auth.confirmation_mail_pending_signup": "A confirmation email has already been sent to <b>%s</b>. Please activate it before creating another account.",
|
||||
"auth.confirmation_mail_resend_failed": "The confirmation email could not be sent. Please try again later or contact an administrator.",
|
||||
"auth.confirmation_mail_resend_not_available": "This account can no longer receive confirmation emails.",
|
||||
"auth.allow_password_change": "Użytkownik musi zmienić hasło (zalecane)",
|
||||
"auth.reset_password_mail_sent_prompt": "E-mail potwierdzający został wysłany na adres <b>%s</b>. Sprawdź swoją skrzynkę odbiorczą w przeciągu %s, aby ukończyć proces odzyskiwania konta.",
|
||||
"auth.active_your_account": "Aktywuj swoje konto",
|
||||
@@ -1766,6 +1817,7 @@
|
||||
"admin.users.created": "Utworzony",
|
||||
"admin.users.last_login": "Ostatnie logowanie",
|
||||
"admin.users.send_register_notify": "Wyślij użytkownikowi powiadomienie o rejestracji",
|
||||
"admin.users.send_register_invite": "Send User Registration Invitation",
|
||||
"admin.users.edit": "Edytuj",
|
||||
"admin.users.auth_source": "Źródło uwierzytelniania",
|
||||
"admin.users.local": "Lokalny",
|
||||
@@ -2110,5 +2162,15 @@
|
||||
"actions.runners.task_list.repository": "Repozytorium",
|
||||
"actions.runners.status.active": "Aktywne",
|
||||
"actions.runners.version": "Wersja",
|
||||
"git.filemode.symbolic_link": "Dowiązanie symboliczne"
|
||||
"git.filemode.symbolic_link": "Dowiązanie symboliczne",
|
||||
"auth.accept_your_invitation": "Accept Your Invitation",
|
||||
"auth.invitation_mail_pending_login": "An invitation email has already been sent to <b>%s</b>. Please accept it before signing in.",
|
||||
"auth.invitation_mail_sent_prompt_ex": "A new invitation email has been sent to <b>%s</b>. Please use the link within the next %s to activate your account.",
|
||||
"auth.invitation_mail_resend_failed": "The invitation email could not be sent. Please try again later or contact an administrator.",
|
||||
"auth.invitation_mail_resend_not_available": "This account can no longer receive invitation emails.",
|
||||
"auth.invitation_resend_prompt": "Did not receive the invitation email?",
|
||||
"auth.invitation_resend_button": "Resend",
|
||||
"admin.users.send_register_notify_helper": "The account will be activated and validated immediately.",
|
||||
"admin.users.send_register_invite_helper": "The user must accept the emailed invitation before the account becomes active.",
|
||||
"install.language_balloon": "Choose a language"
|
||||
}
|
||||
|
||||
@@ -200,6 +200,7 @@
|
||||
"startpage.license": "Código Aberto",
|
||||
"startpage.license_desc": "Receba <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"%[1]s\">%[2]s</a>! Junte-se a nós <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"%[3]s\">contribuindo</a> para tornar este projeto ainda melhor. Não seja tímido, seja um colaborador!",
|
||||
"install.install": "Instalação",
|
||||
"install.installing_desc": "Installing now, please wait…",
|
||||
"install.title": "Configuração Inicial",
|
||||
"install.docker_helper": "Se você está rodando o Gitea dentro do Docker, por favor leia a <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"%s\">documentação</a> cuidadosamente antes de alterar qualquer coisa nesta página.",
|
||||
"install.require_db_desc": "Gitea requer MySQL, PostgreSQL, MSSQL, SQLite3 ou TiDB (protocolo MySQL).",
|
||||
@@ -211,6 +212,7 @@
|
||||
"install.db_name": "Nome do Banco de Dados",
|
||||
"install.db_schema": "Esquema",
|
||||
"install.db_schema_helper": "Deixe em branco para banco de dados padrão (\"public\").",
|
||||
"install.ssl_mode": "SSL",
|
||||
"install.path": "Caminho",
|
||||
"install.sqlite_helper": "Caminho do arquivo do banco de dados SQLite3.<br>Informe um caminho absoluto se você executar o Gitea como um serviço.",
|
||||
"install.reinstall_error": "Você está tentando instalar em um banco de dados existente do Gitea",
|
||||
@@ -228,6 +230,8 @@
|
||||
"install.general_title": "Configurações Gerais",
|
||||
"install.app_name": "Nome do Site",
|
||||
"install.app_name_helper": "Você pode inserir o nome da empresa aqui.",
|
||||
"install.default_language": "Default Language",
|
||||
"install.default_language_helper": "Used when a user's browser language does not match an available locale.",
|
||||
"install.repo_path": "Caminho Raíz do Repositório",
|
||||
"install.repo_path_helper": "Todos os repositórios remotos do Git serão salvos neste diretório.",
|
||||
"install.lfs_path": "Caminho raiz do Git LFS",
|
||||
@@ -253,15 +257,33 @@
|
||||
"install.smtp_from_helper": "Endereço de e-mail que o Gitea irá usar. Digite um endereço de e-mail simples ou use o formato \"Nome\" <email@example.com>.",
|
||||
"install.mailer_user": "Nome de usuário do SMTP",
|
||||
"install.mailer_password": "Senha do SMTP",
|
||||
"install.test_mail_to": "Send Testing Email",
|
||||
"install.test_mail_missing_host": "Please enter the SMTP host before testing email delivery.",
|
||||
"install.test_mail_missing_recipient": "Please enter a recipient email address before testing email delivery.",
|
||||
"install.registration_title": "Registration Management",
|
||||
"install.registration_mode": "Registration Mode",
|
||||
"install.registration_mode.admin_only": "Administrator-managed accounts only",
|
||||
"install.registration_mode.admin_only_helper": "Disable self-registration and let administrators create new accounts using the selected administrator-created account mode.",
|
||||
"install.admin_created_account_mode": "Administrator-Created Account Mode",
|
||||
"install.admin_created_account_mode.local": "Create local accounts directly",
|
||||
"install.admin_created_account_mode.local_helper": "Creates active local accounts immediately. Administrators can optionally notify the user by email after creation.",
|
||||
"install.admin_created_account_mode.invite": "Create invitation-based accounts",
|
||||
"install.admin_created_account_mode.invite_helper": "Creates inactive accounts with sign-in disabled until the user accepts the emailed invitation link.",
|
||||
"install.registration_mode.local_only": "Local registration only",
|
||||
"install.registration_mode.local_only_helper": "Allow new accounts only through Gitea's built-in registration form.",
|
||||
"install.registration_mode.external_only": "External registration only",
|
||||
"install.registration_mode.external_only_helper": "Disable the local registration form and accept new accounts only from external identity providers.",
|
||||
"install.registration_mode.local_and_external": "Local and external registration",
|
||||
"install.registration_mode.local_and_external_helper": "Allow new accounts through both Gitea's local registration form and external identity providers.",
|
||||
"install.registration_local_options": "Local Registration Options",
|
||||
"install.registration_external_options": "External Registration Options",
|
||||
"install.register_confirm": "Exigir Confirmação de E-mail para se Cadastrar",
|
||||
"install.register_confirm_helper": "Require users to verify their email address before they can continue.",
|
||||
"install.register_manual_confirm": "Require Administrator Approval After Email Validation",
|
||||
"install.register_manual_confirm_helper": "New accounts stay pending until an administrator reviews and approves the request.",
|
||||
"install.mail_notify": "Habilitar Notificações de E-mail",
|
||||
"install.mail_notify_helper": "Controls routine notification emails such as watches, mentions, and administrative notices. Activation and invitation emails still use the SMTP configuration above.",
|
||||
"install.server_service_title": "Configurações de Servidor e Serviços de Terceiros",
|
||||
"install.offline_mode": "Habilitar Autenticação Local",
|
||||
"install.offline_mode_popup": "Desabilitar redes de entrega de conteúdo de terceiros e entregar todos os recursos localmente.",
|
||||
"install.disable_gravatar": "Desabilitar o Gravatar",
|
||||
"install.disable_gravatar_popup": "Desabilitar o gravatar e avatar de fontes de terceiros. Um avatar padrão será usado a menos que um usuário localmente carrega um avatar.",
|
||||
"install.federated_avatar_lookup": "Habilitar Avatares Federativos",
|
||||
"install.federated_avatar_lookup_popup": "Habilitar a busca federativa de avatares a usar o serviço federativo de código aberto baseado no libravatar.",
|
||||
"install.disable_registration": "Desabilitar Auto-Cadastro",
|
||||
"install.disable_registration_popup": "Desabilitar auto-cadastro de usuário. Somente os administradores serão capazes de criar novas contas de usuário.",
|
||||
"install.allow_only_external_registration_popup": "Permitir Cadastro Somente por Meio de Serviços Externos",
|
||||
@@ -269,6 +291,8 @@
|
||||
"install.openid_signin_popup": "Habilitar o acesso de usuários via OpenID.",
|
||||
"install.openid_signup": "Habilitar o auto-cadastro via OpenID",
|
||||
"install.openid_signup_popup": "Habilitar o auto-cadastro com base no OpenID.",
|
||||
"install.openid_signin_helper": "Allow users to sign in through OpenID providers.",
|
||||
"install.openid_signup_helper": "Allow new accounts to be created through OpenID providers.",
|
||||
"install.enable_captcha": "Habilitar CAPTCHA ao registrar",
|
||||
"install.enable_captcha_popup": "Obrigar validação por CAPTCHA para auto-cadastro de usuários.",
|
||||
"install.require_sign_in_view": "Exigir Acesso para a Visualização de Páginas",
|
||||
@@ -279,6 +303,13 @@
|
||||
"install.admin_password": "Senha",
|
||||
"install.confirm_password": "Confirmar Senha",
|
||||
"install.admin_email": "Endereço de E-mail",
|
||||
"install.admin_management_policy": "Administration Management Policy",
|
||||
"install.admin_management_policy.super_admin_only": "Only super admins manage admins",
|
||||
"install.admin_management_policy.super_admin_only_helper": "Regular admins can manage only non-admin accounts. Any admin-to-admin change or deletion requires a super administrator.",
|
||||
"install.admin_management_policy.grantor_only": "Grantor manages promoted admins",
|
||||
"install.admin_management_policy.grantor_only_helper": "Regular admins can promote users to administrator and can later modify or delete only the administrators they directly promoted.",
|
||||
"install.admin_management_policy.grantor_inheritance": "Grantor chain with inheritance",
|
||||
"install.admin_management_policy.grantor_inheritance_helper": "Like grantor-only, but if the direct grantor becomes inactive or has sign-in disabled, management passes up the admin grant chain until an eligible admin is found. If none is found, super admins keep control.",
|
||||
"install.install_btn_confirm": "Instalar Gitea",
|
||||
"install.test_git_failed": "Falha ao testar o comando 'git': %v",
|
||||
"install.sqlite3_not_available": "Esta versão do Gitea não suporta SQLite3. Por favor faça o download da versão binária oficial em %s (não utilize a versão 'gobuild').",
|
||||
@@ -286,7 +317,6 @@
|
||||
"install.invalid_db_table": "A tabela \"%s\" do banco de dados é inválida: %v",
|
||||
"install.invalid_repo_path": "A raiz do repositório está inválida: %v",
|
||||
"install.invalid_app_data_path": "O caminho dos dados do aplicativo é inválido: %v",
|
||||
"install.run_user_not_match": "O nome de usuário 'Executar como' não é o nome de usuário atual: %s -> %s",
|
||||
"install.internal_token_failed": "Falha ao gerar o token interno: %v",
|
||||
"install.secret_key_failed": "Falha ao gerar a chave secreta: %v",
|
||||
"install.save_config_failed": "Falha ao salvar a configuração: %v",
|
||||
@@ -357,6 +387,9 @@
|
||||
"auth.sign_up_now": "Cadastre-se agora.",
|
||||
"auth.sign_up_successful": "A conta foi criada com sucesso. Bem-vindo!",
|
||||
"auth.confirmation_mail_sent_prompt_ex": "Um novo e-mail de confirmação foi enviado para <b>%s</b>. Por favor, verifique sua caixa de entrada dentro dos próximos %s para concluir o processo de registro. Se o seu endereço de e-mail de registro estiver incorreto, você pode fazer login novamente e alterá-lo.",
|
||||
"auth.confirmation_mail_pending_signup": "A confirmation email has already been sent to <b>%s</b>. Please activate it before creating another account.",
|
||||
"auth.confirmation_mail_resend_failed": "The confirmation email could not be sent. Please try again later or contact an administrator.",
|
||||
"auth.confirmation_mail_resend_not_available": "This account can no longer receive confirmation emails.",
|
||||
"auth.must_change_password": "Redefina sua senha",
|
||||
"auth.allow_password_change": "Exigir que o usuário redefina a senha (recomendado)",
|
||||
"auth.reset_password_mail_sent_prompt": "Um e-mail de confirmação foi enviado para <b>%s</b>. Por favor, verifique sua caixa de entrada dentro do(s) próximo(s) %s para concluir o processo de recuperação de conta.",
|
||||
@@ -2614,6 +2647,7 @@
|
||||
"admin.users.last_login": "Último Acesso",
|
||||
"admin.users.never_login": "Nunca Acessado",
|
||||
"admin.users.send_register_notify": "Enviar Notificação de Cadastro de Usuário",
|
||||
"admin.users.send_register_invite": "Send User Registration Invitation",
|
||||
"admin.users.new_success": "Usuário \"%s\" criado.",
|
||||
"admin.users.edit": "Editar",
|
||||
"admin.users.auth_source": "Fonte da Autenticação",
|
||||
@@ -3286,5 +3320,15 @@
|
||||
"git.filemode.normal_file": "Arquivo normal",
|
||||
"git.filemode.executable_file": "Arquivo executável",
|
||||
"git.filemode.symbolic_link": "Link simbólico",
|
||||
"git.filemode.submodule": "Submódulo"
|
||||
"git.filemode.submodule": "Submódulo",
|
||||
"auth.accept_your_invitation": "Accept Your Invitation",
|
||||
"auth.invitation_mail_pending_login": "An invitation email has already been sent to <b>%s</b>. Please accept it before signing in.",
|
||||
"auth.invitation_mail_sent_prompt_ex": "A new invitation email has been sent to <b>%s</b>. Please use the link within the next %s to activate your account.",
|
||||
"auth.invitation_mail_resend_failed": "The invitation email could not be sent. Please try again later or contact an administrator.",
|
||||
"auth.invitation_mail_resend_not_available": "This account can no longer receive invitation emails.",
|
||||
"auth.invitation_resend_prompt": "Did not receive the invitation email?",
|
||||
"auth.invitation_resend_button": "Resend",
|
||||
"admin.users.send_register_notify_helper": "The account will be activated and validated immediately.",
|
||||
"admin.users.send_register_invite_helper": "The user must accept the emailed invitation before the account becomes active.",
|
||||
"install.language_balloon": "Choose a language"
|
||||
}
|
||||
|
||||
@@ -249,6 +249,8 @@
|
||||
"install.general_title": "Configurações gerais",
|
||||
"install.app_name": "Título do sítio",
|
||||
"install.app_name_helper": "Pode escrever aqui o nome da sua companhia.",
|
||||
"install.default_language": "Default Language",
|
||||
"install.default_language_helper": "Used when a user's browser language does not match an available locale.",
|
||||
"install.repo_path": "Localização dos repositórios",
|
||||
"install.repo_path_helper": "Os repositórios Git remotos serão guardados nesta pasta.",
|
||||
"install.lfs_path": "Localização do Git LFS",
|
||||
@@ -274,15 +276,33 @@
|
||||
"install.smtp_from_helper": "Endereço de email que o Gitea vai usar. Insira um endereço de email simples ou use o formato \"Nome\" <email@exemplo.com>.",
|
||||
"install.mailer_user": "Nome de utilizador do SMTP",
|
||||
"install.mailer_password": "Senha do SMTP",
|
||||
"install.test_mail_to": "Send Testing Email",
|
||||
"install.test_mail_missing_host": "Please enter the SMTP host before testing email delivery.",
|
||||
"install.test_mail_missing_recipient": "Please enter a recipient email address before testing email delivery.",
|
||||
"install.registration_title": "Registration Management",
|
||||
"install.registration_mode": "Registration Mode",
|
||||
"install.registration_mode.admin_only": "Administrator-managed accounts only",
|
||||
"install.registration_mode.admin_only_helper": "Disable self-registration and let administrators create new accounts using the selected administrator-created account mode.",
|
||||
"install.admin_created_account_mode": "Administrator-Created Account Mode",
|
||||
"install.admin_created_account_mode.local": "Create local accounts directly",
|
||||
"install.admin_created_account_mode.local_helper": "Creates active local accounts immediately. Administrators can optionally notify the user by email after creation.",
|
||||
"install.admin_created_account_mode.invite": "Create invitation-based accounts",
|
||||
"install.admin_created_account_mode.invite_helper": "Creates inactive accounts with sign-in disabled until the user accepts the emailed invitation link.",
|
||||
"install.registration_mode.local_only": "Local registration only",
|
||||
"install.registration_mode.local_only_helper": "Allow new accounts only through Gitea's built-in registration form.",
|
||||
"install.registration_mode.external_only": "External registration only",
|
||||
"install.registration_mode.external_only_helper": "Disable the local registration form and accept new accounts only from external identity providers.",
|
||||
"install.registration_mode.local_and_external": "Local and external registration",
|
||||
"install.registration_mode.local_and_external_helper": "Allow new accounts through both Gitea's local registration form and external identity providers.",
|
||||
"install.registration_local_options": "Local Registration Options",
|
||||
"install.registration_external_options": "External Registration Options",
|
||||
"install.register_confirm": "Exigir confirmação de email para se inscrever",
|
||||
"install.register_confirm_helper": "Require users to verify their email address before they can continue.",
|
||||
"install.register_manual_confirm": "Require Administrator Approval After Email Validation",
|
||||
"install.register_manual_confirm_helper": "New accounts stay pending until an administrator reviews and approves the request.",
|
||||
"install.mail_notify": "Habilitar notificações por email",
|
||||
"install.mail_notify_helper": "Controls routine notification emails such as watches, mentions, and administrative notices. Activation and invitation emails still use the SMTP configuration above.",
|
||||
"install.server_service_title": "Configurações do servidor e de terceiros",
|
||||
"install.offline_mode": "Habilitar o modo local",
|
||||
"install.offline_mode_popup": "Desabilitar redes de entrega de conteúdos de terceiros e servir localmente todos os recursos.",
|
||||
"install.disable_gravatar": "Desabilitar o Gravatar",
|
||||
"install.disable_gravatar_popup": "Desabilitar o Gravatar e fontes de avatares de terceiros. Será usado um avatar padrão, a não ser que o utilizador carregue um avatar localmente.",
|
||||
"install.federated_avatar_lookup": "Habilitar avatares federados",
|
||||
"install.federated_avatar_lookup_popup": "Habilitar pesquisa de avatares federada usando o Libravatar.",
|
||||
"install.disable_registration": "Desabilitar a auto-inscrição",
|
||||
"install.disable_registration_popup": "Desabilitar a auto-inscrição do utilizador. Somente os administradores poderão criar novas contas de utilizador.",
|
||||
"install.allow_only_external_registration_popup": "Permitir a inscrição somente por meio de serviços externos",
|
||||
@@ -290,6 +310,8 @@
|
||||
"install.openid_signin_popup": "Habilitar o início de sessão do utilizador usando o OpenID.",
|
||||
"install.openid_signup": "Habilitar a auto-inscrição com OpenID",
|
||||
"install.openid_signup_popup": "Habilitar a utilização do OpenID para fazer auto-inscrições.",
|
||||
"install.openid_signin_helper": "Allow users to sign in through OpenID providers.",
|
||||
"install.openid_signup_helper": "Allow new accounts to be created through OpenID providers.",
|
||||
"install.enable_captcha": "Habilitar CAPTCHA na inscrição",
|
||||
"install.enable_captcha_popup": "Exigir CAPTCHA na auto-inscrição de utilizadores.",
|
||||
"install.require_sign_in_view": "Exigir sessão iniciada para visualizar páginas",
|
||||
@@ -300,6 +322,13 @@
|
||||
"install.admin_password": "Senha",
|
||||
"install.confirm_password": "Confirme a senha",
|
||||
"install.admin_email": "Endereço de email",
|
||||
"install.admin_management_policy": "Administration Management Policy",
|
||||
"install.admin_management_policy.super_admin_only": "Only super admins manage admins",
|
||||
"install.admin_management_policy.super_admin_only_helper": "Regular admins can manage only non-admin accounts. Any admin-to-admin change or deletion requires a super administrator.",
|
||||
"install.admin_management_policy.grantor_only": "Grantor manages promoted admins",
|
||||
"install.admin_management_policy.grantor_only_helper": "Regular admins can promote users to administrator and can later modify or delete only the administrators they directly promoted.",
|
||||
"install.admin_management_policy.grantor_inheritance": "Grantor chain with inheritance",
|
||||
"install.admin_management_policy.grantor_inheritance_helper": "Like grantor-only, but if the direct grantor becomes inactive or has sign-in disabled, management passes up the admin grant chain until an eligible admin is found. If none is found, super admins keep control.",
|
||||
"install.install_btn_confirm": "Instalar Gitea",
|
||||
"install.test_git_failed": "Não foi possível testar o comando 'git': %v",
|
||||
"install.sqlite3_not_available": "Esta versão do Gitea não suporta o SQLite3. Descarregue a versão binária oficial em %s (não utilize a versão 'gobuild').",
|
||||
@@ -307,7 +336,6 @@
|
||||
"install.invalid_db_table": "A tabela \"%s\" da base de dados é inválida: %v",
|
||||
"install.invalid_repo_path": "A localização base dos repositórios é inválida: %v",
|
||||
"install.invalid_app_data_path": "A localização dos dados da aplicação é inválido: %v",
|
||||
"install.run_user_not_match": "O nome de utilizador para 'executar como' não é o nome de utilizador corrente: %s → %s",
|
||||
"install.internal_token_failed": "Falha ao gerar o código interno: %v",
|
||||
"install.secret_key_failed": "Falha ao gerar a chave secreta: %v",
|
||||
"install.save_config_failed": "Falhou ao guardar a configuração: %v",
|
||||
@@ -380,6 +408,9 @@
|
||||
"auth.sign_up_now": "Inscreva-se agora.",
|
||||
"auth.sign_up_successful": "A conta foi criada com sucesso. Bem-vindo/a!",
|
||||
"auth.confirmation_mail_sent_prompt_ex": "Foi enviado um email de confirmação para <b>%s</b>. Verifique a sua caixa de entrada dentro de %s para completar o processo de registo. Se o seu endereço de email de registo estiver errado, pode iniciar a sessão novamente e mudá-lo.",
|
||||
"auth.confirmation_mail_pending_signup": "A confirmation email has already been sent to <b>%s</b>. Please activate it before creating another account.",
|
||||
"auth.confirmation_mail_resend_failed": "The confirmation email could not be sent. Please try again later or contact an administrator.",
|
||||
"auth.confirmation_mail_resend_not_available": "This account can no longer receive confirmation emails.",
|
||||
"auth.must_change_password": "Mude a sua senha",
|
||||
"auth.allow_password_change": "Exigir que o utilizador mude a senha (recomendado)",
|
||||
"auth.reset_password_mail_sent_prompt": "Foi enviado um email de confirmação para <b>%s</b>. Verifique a sua caixa de entrada dentro de %s para completar o processo de recuperação.",
|
||||
@@ -2951,6 +2982,7 @@
|
||||
"admin.users.last_login": "Último acesso",
|
||||
"admin.users.never_login": "Nunca acedeu",
|
||||
"admin.users.send_register_notify": "Enviar notificação de registo de utilizador",
|
||||
"admin.users.send_register_invite": "Send User Registration Invitation",
|
||||
"admin.users.new_success": "A conta de utilizador \"%s\" foi criada.",
|
||||
"admin.users.edit": "Editar",
|
||||
"admin.users.auth_source": "Fonte de autenticação",
|
||||
@@ -3724,5 +3756,15 @@
|
||||
"git.filemode.normal_file": "Ficheiro normal",
|
||||
"git.filemode.executable_file": "Ficheiro executável",
|
||||
"git.filemode.symbolic_link": "Ligação simbólica",
|
||||
"git.filemode.submodule": "Submódulo"
|
||||
"git.filemode.submodule": "Submódulo",
|
||||
"auth.accept_your_invitation": "Accept Your Invitation",
|
||||
"auth.invitation_mail_pending_login": "An invitation email has already been sent to <b>%s</b>. Please accept it before signing in.",
|
||||
"auth.invitation_mail_sent_prompt_ex": "A new invitation email has been sent to <b>%s</b>. Please use the link within the next %s to activate your account.",
|
||||
"auth.invitation_mail_resend_failed": "The invitation email could not be sent. Please try again later or contact an administrator.",
|
||||
"auth.invitation_mail_resend_not_available": "This account can no longer receive invitation emails.",
|
||||
"auth.invitation_resend_prompt": "Did not receive the invitation email?",
|
||||
"auth.invitation_resend_button": "Resend",
|
||||
"admin.users.send_register_notify_helper": "The account will be activated and validated immediately.",
|
||||
"admin.users.send_register_invite_helper": "The user must accept the emailed invitation before the account becomes active.",
|
||||
"install.language_balloon": "Choose a language"
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -157,6 +157,7 @@
|
||||
"startpage.lightweight_desc": "Gitea имеет низкие системные требования и может работать на недорогом Raspberry Pi. Экономьте энергию вашей машины!",
|
||||
"startpage.license": "Открытый исходный код",
|
||||
"install.install": "Установка",
|
||||
"install.installing_desc": "Installing now, please wait…",
|
||||
"install.title": "Начальная конфигурация",
|
||||
"install.docker_helper": "Если вы запускаете Gitea внутри Docker, пожалуйста внимательно прочтите <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"%s\">документацию</a> перед тем, как изменить любые настройки.",
|
||||
"install.require_db_desc": "Gitea требует MySQL, PostgreSQL, MSSQL, SQLite3 или TiDB (через протокол MySQL).",
|
||||
@@ -168,17 +169,26 @@
|
||||
"install.db_name": "Имя базы данных",
|
||||
"install.db_schema": "Схема",
|
||||
"install.db_schema_helper": "Оставьте пустым для значения по умолчанию (\"public\").",
|
||||
"install.ssl_mode": "SSL",
|
||||
"install.path": "Путь",
|
||||
"install.sqlite_helper": "Путь к файлу базы данных SQLite3.<br>Введите абсолютный путь, если вы запускаете Gitea как службу.",
|
||||
"install.reinstall_error": "Вы пытаетесь произвести установку в уже существующую базу данных Gitea",
|
||||
"install.reinstall_confirm_message": "Переустановка в уже существующую базу данных Gitea может вызвать несколько проблем. В большинстве случаев вы должны использовать существующий \"app.ini\" для запуска Gitea. Если вы понимаете, что вы делаете, подтвердите:",
|
||||
"install.reinstall_confirm_check_1": "The data encrypted by the SECRET_KEY in app.ini may be lost: users may not be able to log in with 2FA/OTP and mirrors may not function correctly. By checking this box, you confirm that the current app.ini file contains the correct SECRET_KEY.",
|
||||
"install.reinstall_confirm_check_2": "The repositories and settings may need to be resynchronized. By checking this box, you confirm that you will resynchronize the hooks for the repositories and authorized_keys file manually. You confirm that you will ensure that repository and mirror settings are correct.",
|
||||
"install.reinstall_confirm_check_3": "Вы подтверждаете, что полностью уверены, что этот Gitea запущен при коренном расположении app.ini и вы уверены, что вам нужна переустановка. Вы подтверждаете, что соглашаетесь с указанными выше рисками.",
|
||||
"install.err_empty_db_path": "Путь к базе данных SQLite3 не может быть пустым.",
|
||||
"install.no_admin_and_disable_registration": "Вы не можете отключить регистрацию до создания учётной записи администратора.",
|
||||
"install.err_empty_admin_password": "Пароль администратора не может быть пустым.",
|
||||
"install.err_empty_admin_email": "The administrator email address cannot be empty.",
|
||||
"install.err_admin_name_is_reserved": "Administrator username is invalid. Username is reserved.",
|
||||
"install.err_admin_name_pattern_not_allowed": "Administrator username is invalid. The username matches a reserved pattern.",
|
||||
"install.err_admin_name_is_invalid": "Administrator username is invalid",
|
||||
"install.general_title": "Основные настройки",
|
||||
"install.app_name": "Название сайта",
|
||||
"install.app_name_helper": "Здесь вы можете ввести название своей компании.",
|
||||
"install.default_language": "Default Language",
|
||||
"install.default_language_helper": "Used when a user's browser language does not match an available locale.",
|
||||
"install.repo_path": "Путь до корня репозитория",
|
||||
"install.repo_path_helper": "Все удалённые Git репозитории будут сохранены в эту директорию.",
|
||||
"install.lfs_path": "Путь к корневому каталогу Git LFS",
|
||||
@@ -190,6 +200,7 @@
|
||||
"install.ssh_port": "Порт SSH сервера",
|
||||
"install.ssh_port_helper": "Номер порта, который использует SSH сервер. Оставьте пустым, чтобы отключить SSH.",
|
||||
"install.http_port": "Gitea HTTP порт",
|
||||
"install.http_port_helper": "Port number the Gitea web server will listen on.",
|
||||
"install.app_url": "Базовый URL Gitea",
|
||||
"install.app_url_helper": "Этот параметр влияет на URL для клонирования по HTTP/HTTPS и на некоторые уведомления по электронной почте.",
|
||||
"install.log_root_path": "Путь к журналу",
|
||||
@@ -199,18 +210,37 @@
|
||||
"install.smtp_addr": "Узел SMTP",
|
||||
"install.smtp_port": "SMTP-порт",
|
||||
"install.smtp_from": "Отправить эл. почту как",
|
||||
"install.smtp_from_invalid": "The \"Send Email As\" address is invalid",
|
||||
"install.smtp_from_helper": "Адрес электронной почты, который будет использоваться Gitea. Введите обычный адрес электронной почты или используйте формат \"Имя\" <email@example.com>.",
|
||||
"install.mailer_user": "SMTP логин",
|
||||
"install.mailer_password": "SMTP пароль",
|
||||
"install.test_mail_to": "Send Testing Email",
|
||||
"install.test_mail_missing_host": "Please enter the SMTP host before testing email delivery.",
|
||||
"install.test_mail_missing_recipient": "Please enter a recipient email address before testing email delivery.",
|
||||
"install.registration_title": "Registration Management",
|
||||
"install.registration_mode": "Registration Mode",
|
||||
"install.registration_mode.admin_only": "Administrator-managed accounts only",
|
||||
"install.registration_mode.admin_only_helper": "Disable self-registration and let administrators create new accounts using the selected administrator-created account mode.",
|
||||
"install.admin_created_account_mode": "Administrator-Created Account Mode",
|
||||
"install.admin_created_account_mode.local": "Create local accounts directly",
|
||||
"install.admin_created_account_mode.local_helper": "Creates active local accounts immediately. Administrators can optionally notify the user by email after creation.",
|
||||
"install.admin_created_account_mode.invite": "Create invitation-based accounts",
|
||||
"install.admin_created_account_mode.invite_helper": "Creates inactive accounts with sign-in disabled until the user accepts the emailed invitation link.",
|
||||
"install.registration_mode.local_only": "Local registration only",
|
||||
"install.registration_mode.local_only_helper": "Allow new accounts only through Gitea's built-in registration form.",
|
||||
"install.registration_mode.external_only": "External registration only",
|
||||
"install.registration_mode.external_only_helper": "Disable the local registration form and accept new accounts only from external identity providers.",
|
||||
"install.registration_mode.local_and_external": "Local and external registration",
|
||||
"install.registration_mode.local_and_external_helper": "Allow new accounts through both Gitea's local registration form and external identity providers.",
|
||||
"install.registration_local_options": "Local Registration Options",
|
||||
"install.registration_external_options": "External Registration Options",
|
||||
"install.register_confirm": "Требовать подтверждение по электронной почте для регистрации",
|
||||
"install.register_confirm_helper": "Require users to verify their email address before they can continue.",
|
||||
"install.register_manual_confirm": "Require Administrator Approval After Email Validation",
|
||||
"install.register_manual_confirm_helper": "New accounts stay pending until an administrator reviews and approves the request.",
|
||||
"install.mail_notify": "Разрешить почтовые уведомления",
|
||||
"install.mail_notify_helper": "Controls routine notification emails such as watches, mentions, and administrative notices. Activation and invitation emails still use the SMTP configuration above.",
|
||||
"install.server_service_title": "Сервер и настройки внешних служб",
|
||||
"install.offline_mode": "Включить локальный режим",
|
||||
"install.offline_mode_popup": "Отключить сторонние сети доставки контента и отдавать все ресурсы из их локальных копий.",
|
||||
"install.disable_gravatar": "Отключить Gravatar",
|
||||
"install.disable_gravatar_popup": "Отключить Gravatar и сторонние источники аватаров. Если пользователь не загрузит аватар локально, то по умолчанию будет использоваться стандартный аватар.",
|
||||
"install.federated_avatar_lookup": "Включить федеративные аватары",
|
||||
"install.federated_avatar_lookup_popup": "Включите поиск федеративного аватара для использования службы с открытым исходным кодом на основе libravatar.",
|
||||
"install.disable_registration": "Отключить самостоятельную регистрацию",
|
||||
"install.disable_registration_popup": "Отключить самостоятельную регистрацию. Только администраторы смогут создавать новые учётные записи пользователей.",
|
||||
"install.allow_only_external_registration_popup": "Разрешить регистрацию только через сторонние сервисы",
|
||||
@@ -218,6 +248,8 @@
|
||||
"install.openid_signin_popup": "Включить вход через OpenID.",
|
||||
"install.openid_signup": "Включить регистрацию через OpenID",
|
||||
"install.openid_signup_popup": "Включить саморегистрацию OpenID.",
|
||||
"install.openid_signin_helper": "Allow users to sign in through OpenID providers.",
|
||||
"install.openid_signup_helper": "Allow new accounts to be created through OpenID providers.",
|
||||
"install.enable_captcha": "Включить CAPTCHA при регистрации",
|
||||
"install.enable_captcha_popup": "Запрашивать капчу при регистрации пользователя.",
|
||||
"install.require_sign_in_view": "Требовать авторизации для просмотра страниц",
|
||||
@@ -228,6 +260,13 @@
|
||||
"install.admin_password": "Пароль",
|
||||
"install.confirm_password": "Подтвердить пароль",
|
||||
"install.admin_email": "Адрес эл. почты",
|
||||
"install.admin_management_policy": "Administration Management Policy",
|
||||
"install.admin_management_policy.super_admin_only": "Only super admins manage admins",
|
||||
"install.admin_management_policy.super_admin_only_helper": "Regular admins can manage only non-admin accounts. Any admin-to-admin change or deletion requires a super administrator.",
|
||||
"install.admin_management_policy.grantor_only": "Grantor manages promoted admins",
|
||||
"install.admin_management_policy.grantor_only_helper": "Regular admins can promote users to administrator and can later modify or delete only the administrators they directly promoted.",
|
||||
"install.admin_management_policy.grantor_inheritance": "Grantor chain with inheritance",
|
||||
"install.admin_management_policy.grantor_inheritance_helper": "Like grantor-only, but if the direct grantor becomes inactive or has sign-in disabled, management passes up the admin grant chain until an eligible admin is found. If none is found, super admins keep control.",
|
||||
"install.install_btn_confirm": "Установить Gitea",
|
||||
"install.test_git_failed": "Не удалось проверить 'git' команду: %v",
|
||||
"install.sqlite3_not_available": "Эта версия Gitea не поддерживает SQLite3. Пожалуйста, загрузите официальную бинарную версию из %s (не 'go build' версия).",
|
||||
@@ -235,7 +274,6 @@
|
||||
"install.invalid_db_table": "Таблица «%s» базы данных некорректна: %v",
|
||||
"install.invalid_repo_path": "Недопустимый путь к корню репозитория: %v",
|
||||
"install.invalid_app_data_path": "Неверный путь к приложению: %v",
|
||||
"install.run_user_not_match": "Текущий пользователь не является пользователем для запуска: %s -> %s",
|
||||
"install.internal_token_failed": "Не удалось создать внутренний токен: %v",
|
||||
"install.secret_key_failed": "Не удалось создать секретный ключ: %v",
|
||||
"install.save_config_failed": "Не удалось сохранить конфигурацию: %v",
|
||||
@@ -251,10 +289,12 @@
|
||||
"install.no_reply_address_helper": "Доменное имя для пользователей со скрытым адресом электронной почты. Например, имя пользователя 'joe' будет зарегистрировано в Git как 'joe@noreply.example.org' если скрытый домен электронной почты установлен как 'noreply.example.org'.",
|
||||
"install.password_algorithm": "Алгоритм хеширования пароля",
|
||||
"install.invalid_password_algorithm": "Некорректный алгоритм хеширования пароля",
|
||||
"install.password_algorithm_helper": "Set the password hashing algorithm. Algorithms have differing requirements and strengths. The argon2 algorithm is rather secure but uses a lot of memory and may be inappropriate for small systems.",
|
||||
"install.enable_update_checker": "Включить проверку обновлений",
|
||||
"install.enable_update_checker_helper": "Периодически проверяет наличие новых версий, подключаясь к gitea.io.",
|
||||
"install.env_config_keys": "Настройка окружения",
|
||||
"install.env_config_keys_prompt": "Следующие переменные окружения также будут применены к вашему конфигурационному файлу:",
|
||||
"install.config_write_file_prompt": "These configuration options will be written into: %s",
|
||||
"home.uname_holder": "Имя пользователя / Адрес эл. почты",
|
||||
"home.password_holder": "Пароль",
|
||||
"home.switch_dashboard_context": "Переключить контекст панели управления",
|
||||
@@ -294,6 +334,9 @@
|
||||
"auth.forgot_password": "Забыли пароль?",
|
||||
"auth.sign_up_successful": "Учётная запись успешно создана. Добро пожаловать!",
|
||||
"auth.must_change_password": "Обновить пароль",
|
||||
"auth.confirmation_mail_pending_signup": "A confirmation email has already been sent to <b>%s</b>. Please activate it before creating another account.",
|
||||
"auth.confirmation_mail_resend_failed": "The confirmation email could not be sent. Please try again later or contact an administrator.",
|
||||
"auth.confirmation_mail_resend_not_available": "This account can no longer receive confirmation emails.",
|
||||
"auth.allow_password_change": "Требовать смену пароля пользователем (рекомендуется)",
|
||||
"auth.reset_password_mail_sent_prompt": "Письмо с подтверждением отправлено на <b>%s</b>. Пожалуйста, проверьте входящую почту в течение %s, чтобы завершить процесс восстановления аккаунта.",
|
||||
"auth.active_your_account": "Активируйте свой аккаунт",
|
||||
@@ -2345,6 +2388,7 @@
|
||||
"admin.users.created": "Создано",
|
||||
"admin.users.last_login": "Последний вход",
|
||||
"admin.users.send_register_notify": "Отправить пользователю уведомление о регистрации",
|
||||
"admin.users.send_register_invite": "Send User Registration Invitation",
|
||||
"admin.users.new_success": "Учётная запись «%s» создана.",
|
||||
"admin.users.edit": "Редактировать",
|
||||
"admin.users.auth_source": "Источник аутентификации",
|
||||
@@ -2982,5 +3026,15 @@
|
||||
"git.filemode.normal_file": "Обычный файл",
|
||||
"git.filemode.executable_file": "Исполняемый файл",
|
||||
"git.filemode.symbolic_link": "Символическая ссылка",
|
||||
"git.filemode.submodule": "Подмодуль"
|
||||
"git.filemode.submodule": "Подмодуль",
|
||||
"auth.accept_your_invitation": "Accept Your Invitation",
|
||||
"auth.invitation_mail_pending_login": "An invitation email has already been sent to <b>%s</b>. Please accept it before signing in.",
|
||||
"auth.invitation_mail_sent_prompt_ex": "A new invitation email has been sent to <b>%s</b>. Please use the link within the next %s to activate your account.",
|
||||
"auth.invitation_mail_resend_failed": "The invitation email could not be sent. Please try again later or contact an administrator.",
|
||||
"auth.invitation_mail_resend_not_available": "This account can no longer receive invitation emails.",
|
||||
"auth.invitation_resend_prompt": "Did not receive the invitation email?",
|
||||
"auth.invitation_resend_button": "Resend",
|
||||
"admin.users.send_register_notify_helper": "The account will be activated and validated immediately.",
|
||||
"admin.users.send_register_invite_helper": "The user must accept the emailed invitation before the account becomes active.",
|
||||
"install.language_balloon": "Choose a language"
|
||||
}
|
||||
|
||||
@@ -94,8 +94,10 @@
|
||||
"startpage.lightweight_desc": "Gitea අඩු අවම අවශ්යතා ඇති අතර මිල අඩු Raspberry Pi මත ධාවනය කළ හැකිය. ඔබේ යන්ත්ර ශක්තිය සුරකින්න!",
|
||||
"startpage.license": "විවෘත මූලාශ්ර",
|
||||
"install.install": "ස්ථාපනය",
|
||||
"install.installing_desc": "Installing now, please wait…",
|
||||
"install.title": "මූලික වින්යාසය",
|
||||
"install.docker_helper": "ඔබ Docker තුළ Gitea ධාවනය කරන්නේ නම්, කරුණාකර ඕනෑම සැකසුම් වෙනස් කිරීමට පෙර <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"%s\">ලියකියවිලි</a> කියවන්න.",
|
||||
"install.require_db_desc": "Gitea requires MySQL, PostgreSQL, MSSQL, SQLite3 or TiDB (MySQL protocol).",
|
||||
"install.db_title": "දත්ත සමුදායේ සැකසුම්",
|
||||
"install.db_type": "දත්ත සමුදායේ වර්ගය",
|
||||
"install.host": "සත්කාරක",
|
||||
@@ -104,24 +106,38 @@
|
||||
"install.db_name": "දත්ත සමුදායේ නම",
|
||||
"install.db_schema": "යෝජනා ක්රමය",
|
||||
"install.db_schema_helper": "දත්ත සමුදා පෙරනිමි සඳහා හිස්ව තබන්න (“පොදු”).",
|
||||
"install.ssl_mode": "SSL",
|
||||
"install.path": "මාර්ගය",
|
||||
"install.sqlite_helper": "SQLite3 දත්ත සමුදාය සඳහා ගොනු මාර්ගය.<br>ඔබ සේවාවක් ලෙස Gitea ධාවනය කරන්නේ නම් නිරපේක්ෂ මාර්ගයක් ඇතුල් කරන්න.",
|
||||
"install.reinstall_error": "You are trying to install into an existing Gitea database",
|
||||
"install.reinstall_confirm_message": "Re-installing with an existing Gitea database can cause multiple problems. In most cases, you should use your existing \"app.ini\" to run Gitea. If you know what you are doing, confirm the following:",
|
||||
"install.reinstall_confirm_check_1": "The data encrypted by the SECRET_KEY in app.ini may be lost: users may not be able to log in with 2FA/OTP and mirrors may not function correctly. By checking this box, you confirm that the current app.ini file contains the correct SECRET_KEY.",
|
||||
"install.reinstall_confirm_check_2": "The repositories and settings may need to be resynchronized. By checking this box, you confirm that you will resynchronize the hooks for the repositories and authorized_keys file manually. You confirm that you will ensure that repository and mirror settings are correct.",
|
||||
"install.reinstall_confirm_check_3": "You confirm that you are absolutely sure that this Gitea is running with the correct app.ini location and that you are sure that you have to re-install. You confirm that you acknowledge the above risks.",
|
||||
"install.err_empty_db_path": "SQLite3 දත්ත සමුදා මාර්ගය හිස් විය නොහැක.",
|
||||
"install.no_admin_and_disable_registration": "පරිපාලක ගිණුමක් නිර්මාණය නොකර පරිශීලක ස්වයං ලියාපදිංචිය අක්රිය කළ නොහැක.",
|
||||
"install.err_empty_admin_password": "පරිපාලක මුරපදය හිස් විය නොහැක.",
|
||||
"install.err_empty_admin_email": "The administrator email address cannot be empty.",
|
||||
"install.err_admin_name_is_reserved": "Administrator username is invalid. Username is reserved.",
|
||||
"install.err_admin_name_pattern_not_allowed": "Administrator username is invalid. The username matches a reserved pattern.",
|
||||
"install.err_admin_name_is_invalid": "Administrator username is invalid",
|
||||
"install.general_title": "පොදු සැකසුම්",
|
||||
"install.app_name": "අඩවියේ සිරැසිය",
|
||||
"install.app_name_helper": "ඔබට ඔබේ සමාගමේ නම මෙහි ඇතුළත් කළ හැකිය.",
|
||||
"install.default_language": "Default Language",
|
||||
"install.default_language_helper": "Used when a user's browser language does not match an available locale.",
|
||||
"install.repo_path": "ගබඩාව මූල මාර්ගය",
|
||||
"install.repo_path_helper": "දුරස්ථ Git ගබඩාව මෙම නාමාවලියට සුරැකෙනු ඇත.",
|
||||
"install.lfs_path": "Git LFS මූල මාර්ගය",
|
||||
"install.lfs_path_helper": "Git LFS විසින් ලුහුබැඳ ගොනු මෙම බහලුම තුළ ගබඩා කරනු ඇත. අක්රිය කිරීමට හිස් තබන්න.",
|
||||
"install.run_user": "පරිශීලක නාමය ලෙස ධාවනය",
|
||||
"install.run_user_helper": "The operating system username that Gitea runs as, it must have write access to the data paths. This value is auto-detected and cannot be changed here. To use a different user, restart Gitea under that account.",
|
||||
"install.domain": "සේවාදායකයේ වසම",
|
||||
"install.domain_helper": "සේවාදායකය සඳහා ඩොමේන් හෝ ධාරක ලිපිනය.",
|
||||
"install.ssh_port": "SSH සේවාදායකය වරාය",
|
||||
"install.ssh_port_helper": "වරාය අංකය ඔබගේ SSH සේවාදායකය සවන් දෙයි. අක්රිය කිරීමට හිස් තබන්න.",
|
||||
"install.http_port": "HTTP සවන් දෙන්න වරාය",
|
||||
"install.http_port_helper": "Port number the Gitea web server will listen on.",
|
||||
"install.app_url": "මූලික URL එක කරන්න",
|
||||
"install.app_url_helper": "HTTP සඳහා මූලික ලිපිනය (S) URL පරිගණක ක්රිඩාවට සමාන සහ විද්යුත් තැපැල් දැනුම්දීම්.",
|
||||
"install.log_root_path": "ලොග් මාර්ගය",
|
||||
@@ -131,18 +147,37 @@
|
||||
"install.smtp_addr": "SMTP සත්කාරක",
|
||||
"install.smtp_port": "ප්රශ්නය විසඳිලා වරාය",
|
||||
"install.smtp_from": "ලෙස වි-තැපෑල යවන්න",
|
||||
"install.smtp_from_invalid": "The \"Send Email As\" address is invalid",
|
||||
"install.smtp_from_helper": "විද්යුත් තැපැල් ලිපිනය Gitea භාවිතා කරනු ඇත. සරල විද්යුත් තැපැල් ලිපිනයක් ඇතුළත් කරන්න හෝ “නම” <email@example.com> ආකෘතිය භාවිතා කරන්න.",
|
||||
"install.mailer_user": "SMTP පරිශීලක නාමය",
|
||||
"install.mailer_password": "SMTP මුරපදය",
|
||||
"install.test_mail_to": "Send Testing Email",
|
||||
"install.test_mail_missing_host": "Please enter the SMTP host before testing email delivery.",
|
||||
"install.test_mail_missing_recipient": "Please enter a recipient email address before testing email delivery.",
|
||||
"install.registration_title": "Registration Management",
|
||||
"install.registration_mode": "Registration Mode",
|
||||
"install.registration_mode.admin_only": "Administrator-managed accounts only",
|
||||
"install.registration_mode.admin_only_helper": "Disable self-registration and let administrators create new accounts using the selected administrator-created account mode.",
|
||||
"install.admin_created_account_mode": "Administrator-Created Account Mode",
|
||||
"install.admin_created_account_mode.local": "Create local accounts directly",
|
||||
"install.admin_created_account_mode.local_helper": "Creates active local accounts immediately. Administrators can optionally notify the user by email after creation.",
|
||||
"install.admin_created_account_mode.invite": "Create invitation-based accounts",
|
||||
"install.admin_created_account_mode.invite_helper": "Creates inactive accounts with sign-in disabled until the user accepts the emailed invitation link.",
|
||||
"install.registration_mode.local_only": "Local registration only",
|
||||
"install.registration_mode.local_only_helper": "Allow new accounts only through Gitea's built-in registration form.",
|
||||
"install.registration_mode.external_only": "External registration only",
|
||||
"install.registration_mode.external_only_helper": "Disable the local registration form and accept new accounts only from external identity providers.",
|
||||
"install.registration_mode.local_and_external": "Local and external registration",
|
||||
"install.registration_mode.local_and_external_helper": "Allow new accounts through both Gitea's local registration form and external identity providers.",
|
||||
"install.registration_local_options": "Local Registration Options",
|
||||
"install.registration_external_options": "External Registration Options",
|
||||
"install.register_confirm": "ලියාපදිංචි වීමට විද්යුත් තැපැල් තහවුරු කිරීම අවශ්ය වේ",
|
||||
"install.register_confirm_helper": "Require users to verify their email address before they can continue.",
|
||||
"install.register_manual_confirm": "Require Administrator Approval After Email Validation",
|
||||
"install.register_manual_confirm_helper": "New accounts stay pending until an administrator reviews and approves the request.",
|
||||
"install.mail_notify": "වි-තැපැල් දැනුම්දීම් සබල කරන්න",
|
||||
"install.mail_notify_helper": "Controls routine notification emails such as watches, mentions, and administrative notices. Activation and invitation emails still use the SMTP configuration above.",
|
||||
"install.server_service_title": "සේවාදායකය සහ තෙවන පාර්ශවීය සේවා සැකසුම්",
|
||||
"install.offline_mode": "දේශීය ප්රකාරය සක්රීය කරන්න",
|
||||
"install.offline_mode_popup": "තෙවන පාර්ශවීය අන්තර්ගත බෙදාහැරීමේ ජාල අක්රීය කර දේශීයව සියලු සම්පත් සේවය කරන්න.",
|
||||
"install.disable_gravatar": "ග්රැවටාර් අබල කරන්න",
|
||||
"install.disable_gravatar_popup": "Gravatar සහ තෙවන පාර්ශවීය avatar ප්රභවයන් අක්රීය කරන්න. පරිශීලකයෙකු දේශීයව අවතාරයක් උඩුගත නොකරන්නේ නම් පෙරනිමි අවතාරයක් භාවිතා කරනු ඇත.",
|
||||
"install.federated_avatar_lookup": "ෆෙඩරල් අවතාර් සක්රීය කරන්න",
|
||||
"install.federated_avatar_lookup_popup": "Libravatar භාවිතා ෆෙඩරල් අවතාර් විමසිම සක්රීය කරන්න.",
|
||||
"install.disable_registration": "ස්වයං ලියාපදිංචිය අක්රීය කරන්න",
|
||||
"install.disable_registration_popup": "පරිශීලක ස්වයං ලියාපදිංචිය අක්රීය කරන්න. නව පරිශීලක ගිණුම් නිර්මාණය කිරීමට හැක්කේ පරිපාලකයින්ට පමණි.",
|
||||
"install.allow_only_external_registration_popup": "විදේශ සේවා මගින් පමණක් ලියාපදිංචි වීමට ඉඩ දෙන්න",
|
||||
@@ -150,21 +185,34 @@
|
||||
"install.openid_signin_popup": "OpenID හරහා පරිශීලක සං in ා සක්රීය කරන්න.",
|
||||
"install.openid_signup": "OpenID ස්වයං ලියාපදිංචිය සක්රීය කරන්න",
|
||||
"install.openid_signup_popup": "Openid-මත පදනම් පරිශීලක ස්වයං ලියාපදිංචිය සක්රීය කරන්න.",
|
||||
"install.openid_signin_helper": "Allow users to sign in through OpenID providers.",
|
||||
"install.openid_signup_helper": "Allow new accounts to be created through OpenID providers.",
|
||||
"install.enable_captcha": "ලියාපදිංචි CAPTCHA සක්රීය කරන්න",
|
||||
"install.enable_captcha_popup": "පරිශීලක ස්වයං ලියාපදිංචිය සඳහා CAPTCHA අවශ්ය වේ.",
|
||||
"install.require_sign_in_view": "පිටු බැලීම සඳහා සිග්න්-දී අවශ්ය",
|
||||
"install.require_sign_in_view_popup": "Limit page access to signed-in users. Visitors will only see the sign-in and registration pages.",
|
||||
"install.admin_setting_desc": "පරිපාලක ගිණුමක් නිර්මාණය කිරීම අත්යවශ්ය නොවේ. පළමු ලියාපදිංචි පරිශීලකයා ස්වයංක්රීයව පරිපාලකයෙකු බවට පත්වනු ඇත.",
|
||||
"install.admin_title": "පරිපාලක ගිණුමේ සැකසුම්",
|
||||
"install.admin_name": "පරිපාලක පරිශීලක නාමය",
|
||||
"install.admin_password": "මුරපදය",
|
||||
"install.confirm_password": "මුරපදය තහවුරු කරන්න",
|
||||
"install.admin_email": "වි-තැපැල් ලිපිනය",
|
||||
"install.admin_management_policy": "Administration Management Policy",
|
||||
"install.admin_management_policy.super_admin_only": "Only super admins manage admins",
|
||||
"install.admin_management_policy.super_admin_only_helper": "Regular admins can manage only non-admin accounts. Any admin-to-admin change or deletion requires a super administrator.",
|
||||
"install.admin_management_policy.grantor_only": "Grantor manages promoted admins",
|
||||
"install.admin_management_policy.grantor_only_helper": "Regular admins can promote users to administrator and can later modify or delete only the administrators they directly promoted.",
|
||||
"install.admin_management_policy.grantor_inheritance": "Grantor chain with inheritance",
|
||||
"install.admin_management_policy.grantor_inheritance_helper": "Like grantor-only, but if the direct grantor becomes inactive or has sign-in disabled, management passes up the admin grant chain until an eligible admin is found. If none is found, super admins keep control.",
|
||||
"install.install_btn_confirm": "ගිටියා ස්ථාපනය කරන්න",
|
||||
"install.test_git_failed": "'git' විධානය පරීක්ෂා කළ නොහැකි විය: %v",
|
||||
"install.sqlite3_not_available": "මෙම Gitea අනුවාදය SQLite3 සඳහා සහය නොදක්වයි. කරුණාකර නිල ද්විමය අනුවාදය %s වෙතින් බාගත කරන්න ('gobuild' අනුවාදය නොවේ).",
|
||||
"install.invalid_db_setting": "දත්ත සමුදා සැකසුම් අවලංගුයි: %v",
|
||||
"install.invalid_db_table": "The database table \"%s\" is invalid: %v",
|
||||
"install.invalid_repo_path": "නිධි මූල මාර්ගය අවලංගුයි: %v",
|
||||
"install.run_user_not_match": "'ලෙස ධාවනය කරන්න' පරිශීලක නාමය වත්මන් පරිශීලක නාමය නොවේ: %s -> %s",
|
||||
"install.invalid_app_data_path": "The app data path is invalid: %v",
|
||||
"install.internal_token_failed": "Failed to generate internal token: %v",
|
||||
"install.secret_key_failed": "Failed to generate secret key: %v",
|
||||
"install.save_config_failed": "වින්යාසය සුරැකීමට අසමත් විය: %v",
|
||||
"install.invalid_admin_setting": "පරිපාලක ගිණුම් සැකසුම අවලංගුයි: %v",
|
||||
"install.invalid_log_root_path": "ලොග් මාර්ගය අවලංගුයි: %v",
|
||||
@@ -177,6 +225,13 @@
|
||||
"install.no_reply_address": "සැඟවුණු වි-තැපැල් වසම",
|
||||
"install.no_reply_address_helper": "සැඟවුණු විද්යුත් තැපැල් ලිපිනයක් සහිත පරිශීලකයින් සඳහා ඩොමේන් නාමය. උදාහරණයක් ලෙස, සැඟවුණු විද්යුත් තැපැල් වසම 'no.example.org' ලෙස සකසා තිබේ නම්, 'ජෝ' යන පරිශීලක නාමය ගිට් 'joe@noreply.example.org' ලෙස ලොගින් වනු ලැබේ.",
|
||||
"install.password_algorithm": "මුරපදය හැෂ් ඇල්ගොරිතම",
|
||||
"install.invalid_password_algorithm": "Invalid password hash algorithm",
|
||||
"install.password_algorithm_helper": "Set the password hashing algorithm. Algorithms have differing requirements and strengths. The argon2 algorithm is rather secure but uses a lot of memory and may be inappropriate for small systems.",
|
||||
"install.enable_update_checker": "Enable Update Checker",
|
||||
"install.enable_update_checker_helper": "Checks for new version releases periodically by connecting to gitea.io.",
|
||||
"install.env_config_keys": "Environment Configuration",
|
||||
"install.env_config_keys_prompt": "The following environment variables will also be applied to your configuration file:",
|
||||
"install.config_write_file_prompt": "These configuration options will be written into: %s",
|
||||
"home.uname_holder": "පරිශීලක නාමය හෝ වි-තැපෑල",
|
||||
"home.password_holder": "මුරපදය",
|
||||
"home.switch_dashboard_context": "සංදර්භය උපකරණ පුවරුව මාරු",
|
||||
@@ -209,6 +264,9 @@
|
||||
"auth.forgot_password_title": "මුරපදය අමතක වුණා",
|
||||
"auth.forgot_password": "මුරපදය අමතක වුණා ද?",
|
||||
"auth.must_change_password": "මුරපදය යාවත්කාල කරන්න",
|
||||
"auth.confirmation_mail_pending_signup": "A confirmation email has already been sent to <b>%s</b>. Please activate it before creating another account.",
|
||||
"auth.confirmation_mail_resend_failed": "The confirmation email could not be sent. Please try again later or contact an administrator.",
|
||||
"auth.confirmation_mail_resend_not_available": "This account can no longer receive confirmation emails.",
|
||||
"auth.allow_password_change": "මුරපදය වෙනස් කිරීමට පරිශීලකයාට අවශ්ය වේ (නිර්දේශිත)",
|
||||
"auth.reset_password_mail_sent_prompt": "තහවුරු කිරීමේ විද්යුත් තැපෑලක් <b>%s</b>වෙත යවා ඇත. ඊළඟ තුළ ඔබගේ එන ලිපි පරීක්ෂා කරන්න %s ගිණුම යථා ක්රියාවලිය සම්පූර්ණ කිරීම සඳහා.",
|
||||
"auth.active_your_account": "ඔබගේ ගිණුම ක්රියාත්මක කරන්න",
|
||||
@@ -1816,6 +1874,7 @@
|
||||
"admin.users.created": "සෑදීම",
|
||||
"admin.users.last_login": "අවසන් සංඥා දී",
|
||||
"admin.users.send_register_notify": "පරිශීලක ලියාපදිංචි දැනුම්දීම යවන්න",
|
||||
"admin.users.send_register_invite": "Send User Registration Invitation",
|
||||
"admin.users.edit": "සංස්කරණය",
|
||||
"admin.users.auth_source": "සත්යාපන මූලාශ්රය",
|
||||
"admin.users.local": "ස්ථානීය",
|
||||
@@ -2189,5 +2248,15 @@
|
||||
"actions.runners.status.active": "ක්රියාකාරී",
|
||||
"actions.runners.version": "අනුවාදය",
|
||||
"actions.runs.commit": "කැප",
|
||||
"git.filemode.symbolic_link": "සංකේතාත්මක සබැඳිය"
|
||||
"git.filemode.symbolic_link": "සංකේතාත්මක සබැඳිය",
|
||||
"auth.accept_your_invitation": "Accept Your Invitation",
|
||||
"auth.invitation_mail_pending_login": "An invitation email has already been sent to <b>%s</b>. Please accept it before signing in.",
|
||||
"auth.invitation_mail_sent_prompt_ex": "A new invitation email has been sent to <b>%s</b>. Please use the link within the next %s to activate your account.",
|
||||
"auth.invitation_mail_resend_failed": "The invitation email could not be sent. Please try again later or contact an administrator.",
|
||||
"auth.invitation_mail_resend_not_available": "This account can no longer receive invitation emails.",
|
||||
"auth.invitation_resend_prompt": "Did not receive the invitation email?",
|
||||
"auth.invitation_resend_button": "Resend",
|
||||
"admin.users.send_register_notify_helper": "The account will be activated and validated immediately.",
|
||||
"admin.users.send_register_invite_helper": "The user must accept the emailed invitation before the account becomes active.",
|
||||
"install.language_balloon": "Choose a language"
|
||||
}
|
||||
|
||||
@@ -154,56 +154,90 @@
|
||||
"startpage.lightweight_desc": "Gitea má minimálne požiadavky a môže bežať na Raspberry Pi. Šetrite energiou vášho stroja!",
|
||||
"startpage.license": "Otvorený zdrojový kód",
|
||||
"install.install": "Inštalácia",
|
||||
"install.installing_desc": "Installing now, please wait…",
|
||||
"install.title": "Východzia konfigurácia",
|
||||
"install.docker_helper": "Ak spúšťate Gitea v Docker kontajneri, prečítajte si <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"%s\">dokumentáciu</a> pred zmenou akýchkoľvek nastavení.",
|
||||
"install.require_db_desc": "Gitea vyžaduje MySQL, PostgreSQL, MSSQL, SQLite3 alebo TiDB (MySQL protokol).",
|
||||
"install.db_title": "Nastavenie databázy",
|
||||
"install.db_type": "Typ databázy",
|
||||
"install.host": "Host",
|
||||
"install.user": "Používateľské meno",
|
||||
"install.password": "Heslo",
|
||||
"install.db_name": "Názov databázy",
|
||||
"install.db_schema": "Schéma",
|
||||
"install.db_schema_helper": "Nechajte prázdne pre predvolené nastavenie (\"public\").",
|
||||
"install.ssl_mode": "SSL",
|
||||
"install.path": "Cesta",
|
||||
"install.sqlite_helper": "Cesta k súboru databázy SQLite3.<br>Ak spúšťate Gitea ako službu, zadajte absolútnu cestu.",
|
||||
"install.reinstall_error": "Pokúšate sa inštalovať do existujúcej databázy Gitea",
|
||||
"install.reinstall_confirm_message": "Opätovná inštalácia s existujúcou databázou Gitea môže spôsobiť viacero problémov. Vo väčšine prípadov by ste na spustenie Gitea mali použiť svoj existujúci súbor „app.ini“. Ak viete, čo robíte, potvrďte nasledujúce:",
|
||||
"install.reinstall_confirm_check_1": "The data encrypted by the SECRET_KEY in app.ini may be lost: users may not be able to log in with 2FA/OTP and mirrors may not function correctly. By checking this box, you confirm that the current app.ini file contains the correct SECRET_KEY.",
|
||||
"install.reinstall_confirm_check_2": "The repositories and settings may need to be resynchronized. By checking this box, you confirm that you will resynchronize the hooks for the repositories and authorized_keys file manually. You confirm that you will ensure that repository and mirror settings are correct.",
|
||||
"install.reinstall_confirm_check_3": "Potvrdzujete, že ste si úplne istí, že táto Gitea beží so správnym umiestnením app.ini a že ste si istí, že ju musíte znova nainštalovať. Potvrdzujete, že beriete na vedomie vyššie uvedené riziká.",
|
||||
"install.err_empty_db_path": "Cesta k databáze SQLite3 nesmie byť prázdna.",
|
||||
"install.no_admin_and_disable_registration": "Nemôžete zakázať registráciu bez vytvorenia administrátorského účtu.",
|
||||
"install.err_empty_admin_password": "Heslo administrátora nemôže byť prázdne.",
|
||||
"install.err_empty_admin_email": "The administrator email address cannot be empty.",
|
||||
"install.err_admin_name_is_reserved": "Administrator username is invalid. Username is reserved.",
|
||||
"install.err_admin_name_pattern_not_allowed": "Administrator username is invalid. The username matches a reserved pattern.",
|
||||
"install.err_admin_name_is_invalid": "Administrator username is invalid",
|
||||
"install.general_title": "Všeobecné nastavenia",
|
||||
"install.app_name": "Názov webu",
|
||||
"install.app_name_helper": "Sem môžete zadať meno vašej spoločnosti.",
|
||||
"install.default_language": "Default Language",
|
||||
"install.default_language_helper": "Used when a user's browser language does not match an available locale.",
|
||||
"install.repo_path": "Koreňový adresár repozitárov",
|
||||
"install.repo_path_helper": "Vzdialené úložiská Git sa uložia do tohto adresára.",
|
||||
"install.lfs_path": "Koreňový adresár Git LFS",
|
||||
"install.lfs_path_helper": "Súbory sledované systémom Git LFS budú uložené v tomto adresári. Ak chcete deaktivovať, ponechajte prázdne.",
|
||||
"install.run_user": "Spustiť ako používateľ",
|
||||
"install.run_user_helper": "The operating system username that Gitea runs as, it must have write access to the data paths. This value is auto-detected and cannot be changed here. To use a different user, restart Gitea under that account.",
|
||||
"install.domain": "Doména serveru",
|
||||
"install.domain_helper": "Adresa domény alebo hostiteľa serveru.",
|
||||
"install.ssh_port": "Port SSH servera",
|
||||
"install.ssh_port_helper": "Číslo portu na ktorom načúva SSH server. Keď ponecháte prázdne, SSH server zakážete.",
|
||||
"install.http_port": "HTTP port pre Gitea",
|
||||
"install.http_port_helper": "Port number the Gitea web server will listen on.",
|
||||
"install.app_url": "Základná URL Gitea",
|
||||
"install.app_url_helper": "Základná adresa pre klonované HTTP(S) URL adresy a e-mailové upozornenia.",
|
||||
"install.log_root_path": "Adresár logov",
|
||||
"install.log_root_path_helper": "Do tohoto adresára budú uložené súbory protokolu.",
|
||||
"install.optional_title": "Voliteľné nastavenia",
|
||||
"install.email_title": "Nastavenia e-mailu",
|
||||
"install.smtp_addr": "SMTP Host",
|
||||
"install.smtp_port": "SMTP Port",
|
||||
"install.smtp_from": "Odoslať e-mail ako",
|
||||
"install.smtp_from_invalid": "The \"Send Email As\" address is invalid",
|
||||
"install.smtp_from_helper": "E-mailová adresa ktorú použije Gitea. Zadajte bežnú e-mailovú adresu alebo použite formát \"Meno\" <email@example.com>.",
|
||||
"install.mailer_user": "Používateľské meno SMTP",
|
||||
"install.mailer_password": "SMTP heslo",
|
||||
"install.test_mail_to": "Send Testing Email",
|
||||
"install.test_mail_missing_host": "Please enter the SMTP host before testing email delivery.",
|
||||
"install.test_mail_missing_recipient": "Please enter a recipient email address before testing email delivery.",
|
||||
"install.registration_title": "Registration Management",
|
||||
"install.registration_mode": "Registration Mode",
|
||||
"install.registration_mode.admin_only": "Administrator-managed accounts only",
|
||||
"install.registration_mode.admin_only_helper": "Disable self-registration and let administrators create new accounts using the selected administrator-created account mode.",
|
||||
"install.admin_created_account_mode": "Administrator-Created Account Mode",
|
||||
"install.admin_created_account_mode.local": "Create local accounts directly",
|
||||
"install.admin_created_account_mode.local_helper": "Creates active local accounts immediately. Administrators can optionally notify the user by email after creation.",
|
||||
"install.admin_created_account_mode.invite": "Create invitation-based accounts",
|
||||
"install.admin_created_account_mode.invite_helper": "Creates inactive accounts with sign-in disabled until the user accepts the emailed invitation link.",
|
||||
"install.registration_mode.local_only": "Local registration only",
|
||||
"install.registration_mode.local_only_helper": "Allow new accounts only through Gitea's built-in registration form.",
|
||||
"install.registration_mode.external_only": "External registration only",
|
||||
"install.registration_mode.external_only_helper": "Disable the local registration form and accept new accounts only from external identity providers.",
|
||||
"install.registration_mode.local_and_external": "Local and external registration",
|
||||
"install.registration_mode.local_and_external_helper": "Allow new accounts through both Gitea's local registration form and external identity providers.",
|
||||
"install.registration_local_options": "Local Registration Options",
|
||||
"install.registration_external_options": "External Registration Options",
|
||||
"install.register_confirm": "Registrácia vyžaduje potvrdenie e-mailu",
|
||||
"install.register_confirm_helper": "Require users to verify their email address before they can continue.",
|
||||
"install.register_manual_confirm": "Require Administrator Approval After Email Validation",
|
||||
"install.register_manual_confirm_helper": "New accounts stay pending until an administrator reviews and approves the request.",
|
||||
"install.mail_notify": "Povoliť e-mailové upozornenia",
|
||||
"install.mail_notify_helper": "Controls routine notification emails such as watches, mentions, and administrative notices. Activation and invitation emails still use the SMTP configuration above.",
|
||||
"install.server_service_title": "Nastavenia servera a ostatných služieb",
|
||||
"install.offline_mode": "Povoliť miestny režim",
|
||||
"install.offline_mode_popup": "Zakázať siete doručovania obsahu tretích strán a poskytovať celý obsah lokálne.",
|
||||
"install.disable_gravatar": "Zakázať Gravatar",
|
||||
"install.disable_gravatar_popup": "Zakázať Gravatar a cudzie zdroje avatarov. Ak používateľ nenahrá avatara, použije sa predvolený.",
|
||||
"install.federated_avatar_lookup": "Povoliť avatary z verejných zdrojov",
|
||||
"install.federated_avatar_lookup_popup": "Povoliť Libavatar na vyhľadávanie avatarov z verejných zdrojov.",
|
||||
"install.disable_registration": "Zakázať registráciu",
|
||||
"install.disable_registration_popup": "Zakázať registráciu. Nové používateľské účty budú môcť vytvárať iba správci.",
|
||||
"install.allow_only_external_registration_popup": "Povoliť registráciu iba skrze externé služby",
|
||||
@@ -211,6 +245,8 @@
|
||||
"install.openid_signin_popup": "Povoliť používateľovi prihlásenie pomocou OpenID.",
|
||||
"install.openid_signup": "Povoliť registráciu pomocou OpenID",
|
||||
"install.openid_signup_popup": "Povoliť používateľskú registráciu založenú na OpenID.",
|
||||
"install.openid_signin_helper": "Allow users to sign in through OpenID providers.",
|
||||
"install.openid_signup_helper": "Allow new accounts to be created through OpenID providers.",
|
||||
"install.enable_captcha": "Povoliť CAPTCHA pri registrácii",
|
||||
"install.enable_captcha_popup": "Vyžadovať CAPTCHA validáciu pri registrácii používateľa.",
|
||||
"install.require_sign_in_view": "Vyžadovať prihlásenie na prezeranie stránok",
|
||||
@@ -221,13 +257,20 @@
|
||||
"install.admin_password": "Heslo",
|
||||
"install.confirm_password": "Potvrdiť heslo",
|
||||
"install.admin_email": "E-mailová adresa",
|
||||
"install.admin_management_policy": "Administration Management Policy",
|
||||
"install.admin_management_policy.super_admin_only": "Only super admins manage admins",
|
||||
"install.admin_management_policy.super_admin_only_helper": "Regular admins can manage only non-admin accounts. Any admin-to-admin change or deletion requires a super administrator.",
|
||||
"install.admin_management_policy.grantor_only": "Grantor manages promoted admins",
|
||||
"install.admin_management_policy.grantor_only_helper": "Regular admins can promote users to administrator and can later modify or delete only the administrators they directly promoted.",
|
||||
"install.admin_management_policy.grantor_inheritance": "Grantor chain with inheritance",
|
||||
"install.admin_management_policy.grantor_inheritance_helper": "Like grantor-only, but if the direct grantor becomes inactive or has sign-in disabled, management passes up the admin grant chain until an eligible admin is found. If none is found, super admins keep control.",
|
||||
"install.install_btn_confirm": "Nainštalovať Gitea",
|
||||
"install.test_git_failed": "Nie je možné otestovať príkaz 'git': %v",
|
||||
"install.sqlite3_not_available": "Táto verzia Gitea nepodporuje SQLite3. Stiahnite si, prosím, oficiálnu verziu z %s (nie verziu \"gobuild\").",
|
||||
"install.invalid_db_setting": "Nastavenia databázy sú neplatné: %v",
|
||||
"install.invalid_db_table": "The database table \"%s\" is invalid: %v",
|
||||
"install.invalid_repo_path": "Koreňová cesta repozitára je neplatná: %v",
|
||||
"install.invalid_app_data_path": "Cesta k údajom aplikácie je neplatná: %v",
|
||||
"install.run_user_not_match": "Používateľské meno pre 'spustiť ako' nie je aktuálne používateľské meno: %s -> %s",
|
||||
"install.internal_token_failed": "Nepodarilo sa vygenerovať interný token: %v",
|
||||
"install.secret_key_failed": "Nepodarilo sa vygenerovať tajný kľúč: %v",
|
||||
"install.save_config_failed": "Nepodarilo sa uložiť konfiguráciu: %v",
|
||||
@@ -243,8 +286,12 @@
|
||||
"install.no_reply_address_helper": "Doménové meno pre používateľov so skrytou e-mailovou adresou. Napríklad, používateľ s menom 'joe' bude zalogovaný v Git-e ako 'joe@noreply.example.org' ak je skrytá e-mailová doména nastavená na 'noreply.example.org'.",
|
||||
"install.password_algorithm": "Hašovací algoritmus hesla",
|
||||
"install.invalid_password_algorithm": "Neplatný hash algoritmus hesla",
|
||||
"install.password_algorithm_helper": "Set the password hashing algorithm. Algorithms have differing requirements and strengths. The argon2 algorithm is rather secure but uses a lot of memory and may be inappropriate for small systems.",
|
||||
"install.enable_update_checker": "Povoliť kontrolu aktualizácií",
|
||||
"install.enable_update_checker_helper": "Pravidelne kontroluje nové verzie pripojením k gitea.io.",
|
||||
"install.env_config_keys": "Environment Configuration",
|
||||
"install.env_config_keys_prompt": "The following environment variables will also be applied to your configuration file:",
|
||||
"install.config_write_file_prompt": "These configuration options will be written into: %s",
|
||||
"home.uname_holder": "Používateľské meno alebo emailová adresa",
|
||||
"home.password_holder": "Heslo",
|
||||
"home.switch_dashboard_context": "Prepnúť kontext nástenky",
|
||||
@@ -282,6 +329,9 @@
|
||||
"auth.forgot_password_title": "Zabudnuté heslo",
|
||||
"auth.forgot_password": "Zabudli ste heslo?",
|
||||
"auth.allow_password_change": "Vyžiadať od používateľa zmenu hesla (doporučuje sa)",
|
||||
"auth.confirmation_mail_pending_signup": "A confirmation email has already been sent to <b>%s</b>. Please activate it before creating another account.",
|
||||
"auth.confirmation_mail_resend_failed": "The confirmation email could not be sent. Please try again later or contact an administrator.",
|
||||
"auth.confirmation_mail_resend_not_available": "This account can no longer receive confirmation emails.",
|
||||
"auth.reset_password_mail_sent_prompt": "Na adresu <b>%s</b> bol odoslaný potvrdzovací e-mail. Skontrolujte si, prosím, vašu doručenú poštu počas najbližších %s pre dokončenie procesu obnovenia účtu.",
|
||||
"auth.active_your_account": "Aktivovať účet",
|
||||
"auth.account_activated": "Účet bol aktivovaný",
|
||||
@@ -1070,6 +1120,7 @@
|
||||
"admin.users.activated": "Aktivovaný",
|
||||
"admin.users.edit": "Upraviť",
|
||||
"admin.users.delete_account": "Odstrániť používateľský účet",
|
||||
"admin.users.send_register_invite": "Send User Registration Invitation",
|
||||
"admin.emails.primary": "Primárny",
|
||||
"admin.emails.activated": "Aktivovaný",
|
||||
"admin.emails.filter_sort.email": "E-mailová adresa",
|
||||
@@ -1160,5 +1211,15 @@
|
||||
"actions.runners.task_list.repository": "Repozitár",
|
||||
"actions.runners.status.unspecified": "Neznámy",
|
||||
"actions.runners.version": "Verzia",
|
||||
"git.filemode.symbolic_link": "Symbolický odkaz"
|
||||
"git.filemode.symbolic_link": "Symbolický odkaz",
|
||||
"auth.accept_your_invitation": "Accept Your Invitation",
|
||||
"auth.invitation_mail_pending_login": "An invitation email has already been sent to <b>%s</b>. Please accept it before signing in.",
|
||||
"auth.invitation_mail_sent_prompt_ex": "A new invitation email has been sent to <b>%s</b>. Please use the link within the next %s to activate your account.",
|
||||
"auth.invitation_mail_resend_failed": "The invitation email could not be sent. Please try again later or contact an administrator.",
|
||||
"auth.invitation_mail_resend_not_available": "This account can no longer receive invitation emails.",
|
||||
"auth.invitation_resend_prompt": "Did not receive the invitation email?",
|
||||
"auth.invitation_resend_button": "Resend",
|
||||
"admin.users.send_register_notify_helper": "The account will be activated and validated immediately.",
|
||||
"admin.users.send_register_invite_helper": "The user must accept the emailed invitation before the account becomes active.",
|
||||
"install.language_balloon": "Choose a language"
|
||||
}
|
||||
|
||||
@@ -80,31 +80,51 @@
|
||||
"startpage.lightweight": "Lättviktig",
|
||||
"startpage.lightweight_desc": "Gitea har låga minimum-krav och kan köras på en billig Rasperry Pi. Spara på din maskins kraft!",
|
||||
"startpage.license": "Öppen källkod",
|
||||
"install.install": "Installation",
|
||||
"install.installing_desc": "Installing now, please wait…",
|
||||
"install.title": "Ursprunglig konfiguration",
|
||||
"install.docker_helper": "Om du kör Gitea i Docker, vänligen läs igenom <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"%s\">dokumentationen</a> innan några inställningar ändras.",
|
||||
"install.require_db_desc": "Gitea requires MySQL, PostgreSQL, MSSQL, SQLite3 or TiDB (MySQL protocol).",
|
||||
"install.db_title": "Databasinställningar",
|
||||
"install.db_type": "Databastyp",
|
||||
"install.host": "Server",
|
||||
"install.user": "Användarnamn",
|
||||
"install.password": "Lösenord",
|
||||
"install.db_name": "Databasens namn",
|
||||
"install.db_schema": "Schema",
|
||||
"install.db_schema_helper": "Lämna tomt för databasens förvalda värde (\"public\").",
|
||||
"install.ssl_mode": "SSL",
|
||||
"install.path": "Filväg",
|
||||
"install.sqlite_helper": "Sökväg för SQLite3-databasen.<br>Ange en absolut sökväg om du kör Gitea som en tjänst.",
|
||||
"install.reinstall_error": "You are trying to install into an existing Gitea database",
|
||||
"install.reinstall_confirm_message": "Re-installing with an existing Gitea database can cause multiple problems. In most cases, you should use your existing \"app.ini\" to run Gitea. If you know what you are doing, confirm the following:",
|
||||
"install.reinstall_confirm_check_1": "The data encrypted by the SECRET_KEY in app.ini may be lost: users may not be able to log in with 2FA/OTP and mirrors may not function correctly. By checking this box, you confirm that the current app.ini file contains the correct SECRET_KEY.",
|
||||
"install.reinstall_confirm_check_2": "The repositories and settings may need to be resynchronized. By checking this box, you confirm that you will resynchronize the hooks for the repositories and authorized_keys file manually. You confirm that you will ensure that repository and mirror settings are correct.",
|
||||
"install.reinstall_confirm_check_3": "You confirm that you are absolutely sure that this Gitea is running with the correct app.ini location and that you are sure that you have to re-install. You confirm that you acknowledge the above risks.",
|
||||
"install.err_empty_db_path": "En sökväg till SQLite3-databasen måste anges.",
|
||||
"install.no_admin_and_disable_registration": "Du kan inte inaktivera självregistrering utan att skapa ett administratörskonto.",
|
||||
"install.err_empty_admin_password": "Administratörslösenordet kan inte vara tomt.",
|
||||
"install.err_empty_admin_email": "The administrator email address cannot be empty.",
|
||||
"install.err_admin_name_is_reserved": "Administrator username is invalid. Username is reserved.",
|
||||
"install.err_admin_name_pattern_not_allowed": "Administrator username is invalid. The username matches a reserved pattern.",
|
||||
"install.err_admin_name_is_invalid": "Administrator username is invalid",
|
||||
"install.general_title": "Allmänna inställningar",
|
||||
"install.app_name": "Sajtens namn",
|
||||
"install.app_name_helper": "Du kan ange ditt företagsnamn här.",
|
||||
"install.default_language": "Default Language",
|
||||
"install.default_language_helper": "Used when a user's browser language does not match an available locale.",
|
||||
"install.repo_path": "Rotsökväg för utvecklingskatalog",
|
||||
"install.repo_path_helper": "Fjärrutvecklingskataloger kommer att sparas i denna katalog.",
|
||||
"install.lfs_path": "LFS Rotsökväg",
|
||||
"install.lfs_path_helper": "Filer hanterade av Git LFS kommer att sparas i denna mapp. Lämna tom för att avaktivera.",
|
||||
"install.run_user": "Kör som användarnamn",
|
||||
"install.run_user_helper": "The operating system username that Gitea runs as, it must have write access to the data paths. This value is auto-detected and cannot be changed here. To use a different user, restart Gitea under that account.",
|
||||
"install.domain": "Server Domain",
|
||||
"install.domain_helper": "Domain or host address for the server.",
|
||||
"install.ssh_port": "SSH-serverport",
|
||||
"install.ssh_port_helper": "Portnumret som din SSH-server lyssnar på. Lämna tom för att inaktivera.",
|
||||
"install.http_port": "Gitea HTTP-lyssningsport",
|
||||
"install.http_port_helper": "Port number the Gitea web server will listen on.",
|
||||
"install.app_url": "Gitea URL",
|
||||
"install.app_url_helper": "Basadressen för HTTP(S)-kloningslänkar och mejlnotifikationer.",
|
||||
"install.log_root_path": "Loggsökväg",
|
||||
@@ -114,18 +134,37 @@
|
||||
"install.smtp_addr": "SMTP-server",
|
||||
"install.smtp_port": "SMTP-port",
|
||||
"install.smtp_from": "Skicka Mejl Som",
|
||||
"install.smtp_from_invalid": "The \"Send Email As\" address is invalid",
|
||||
"install.smtp_from_helper": "Mejladress som Gitea kommer att använda. Anges i simpelt ('email@example.com') eller fullständigt ('Name <email@example.com>') format.",
|
||||
"install.mailer_user": "SMTP-Användarnamn",
|
||||
"install.mailer_password": "SMTP-Lösenord",
|
||||
"install.test_mail_to": "Send Testing Email",
|
||||
"install.test_mail_missing_host": "Please enter the SMTP host before testing email delivery.",
|
||||
"install.test_mail_missing_recipient": "Please enter a recipient email address before testing email delivery.",
|
||||
"install.registration_title": "Registration Management",
|
||||
"install.registration_mode": "Registration Mode",
|
||||
"install.registration_mode.admin_only": "Administrator-managed accounts only",
|
||||
"install.registration_mode.admin_only_helper": "Disable self-registration and let administrators create new accounts using the selected administrator-created account mode.",
|
||||
"install.admin_created_account_mode": "Administrator-Created Account Mode",
|
||||
"install.admin_created_account_mode.local": "Create local accounts directly",
|
||||
"install.admin_created_account_mode.local_helper": "Creates active local accounts immediately. Administrators can optionally notify the user by email after creation.",
|
||||
"install.admin_created_account_mode.invite": "Create invitation-based accounts",
|
||||
"install.admin_created_account_mode.invite_helper": "Creates inactive accounts with sign-in disabled until the user accepts the emailed invitation link.",
|
||||
"install.registration_mode.local_only": "Local registration only",
|
||||
"install.registration_mode.local_only_helper": "Allow new accounts only through Gitea's built-in registration form.",
|
||||
"install.registration_mode.external_only": "External registration only",
|
||||
"install.registration_mode.external_only_helper": "Disable the local registration form and accept new accounts only from external identity providers.",
|
||||
"install.registration_mode.local_and_external": "Local and external registration",
|
||||
"install.registration_mode.local_and_external_helper": "Allow new accounts through both Gitea's local registration form and external identity providers.",
|
||||
"install.registration_local_options": "Local Registration Options",
|
||||
"install.registration_external_options": "External Registration Options",
|
||||
"install.register_confirm": "Kräv Bekräftelse Via Mejl För Att Registrera",
|
||||
"install.register_confirm_helper": "Require users to verify their email address before they can continue.",
|
||||
"install.register_manual_confirm": "Require Administrator Approval After Email Validation",
|
||||
"install.register_manual_confirm_helper": "New accounts stay pending until an administrator reviews and approves the request.",
|
||||
"install.mail_notify": "Aktivera Mejlnotifikationer",
|
||||
"install.mail_notify_helper": "Controls routine notification emails such as watches, mentions, and administrative notices. Activation and invitation emails still use the SMTP configuration above.",
|
||||
"install.server_service_title": "Inställningar för Server- och Tredjepartstjänster",
|
||||
"install.offline_mode": "Aktivera Lokalt Läge",
|
||||
"install.offline_mode_popup": "Inaktivera CDN från tredjepart och distribuera samtliga resurser lokalt istället.",
|
||||
"install.disable_gravatar": "Inaktivera Gravatar",
|
||||
"install.disable_gravatar_popup": "Inaktivera Gravatar- och avatarskällor från tredjepart. Om användaren inte laddar upp en avatar så kommer en standardavatar att användas.",
|
||||
"install.federated_avatar_lookup": "Aktivera Federerade Avatarer",
|
||||
"install.federated_avatar_lookup_popup": "Använd libravatar vid förenad uppslagning av avatarer.",
|
||||
"install.disable_registration": "Inaktivera Självregistrering",
|
||||
"install.disable_registration_popup": "Inaktivera självregistrering av användare. Endast administratörer kommer kunna skapa nya konton.",
|
||||
"install.allow_only_external_registration_popup": "Tillåt registrering endast via externa tjänster",
|
||||
@@ -133,21 +172,34 @@
|
||||
"install.openid_signin_popup": "Aktivera användarinloggning via OpenID.",
|
||||
"install.openid_signup": "Aktivera självregistrering genom OpenID",
|
||||
"install.openid_signup_popup": "Aktivera OpenID-baserad självregistrering av användare.",
|
||||
"install.openid_signin_helper": "Allow users to sign in through OpenID providers.",
|
||||
"install.openid_signup_helper": "Allow new accounts to be created through OpenID providers.",
|
||||
"install.enable_captcha": "Aktivera CAPTCHA registrering",
|
||||
"install.enable_captcha_popup": "Kräv captcha för användarregistrering.",
|
||||
"install.require_sign_in_view": "Kräv Inloggning För Att Visa Sidor",
|
||||
"install.require_sign_in_view_popup": "Limit page access to signed-in users. Visitors will only see the sign-in and registration pages.",
|
||||
"install.admin_setting_desc": "Skapandet av administratörskonto är frivilligt. Den första användaren som registreras blir automatiskt administratör.",
|
||||
"install.admin_title": "Inställningar för Administratörskonto",
|
||||
"install.admin_name": "Användarnamn för Administratör",
|
||||
"install.admin_password": "Lösenord",
|
||||
"install.confirm_password": "Bekräfta lösenord",
|
||||
"install.admin_email": "Mejladress",
|
||||
"install.admin_management_policy": "Administration Management Policy",
|
||||
"install.admin_management_policy.super_admin_only": "Only super admins manage admins",
|
||||
"install.admin_management_policy.super_admin_only_helper": "Regular admins can manage only non-admin accounts. Any admin-to-admin change or deletion requires a super administrator.",
|
||||
"install.admin_management_policy.grantor_only": "Grantor manages promoted admins",
|
||||
"install.admin_management_policy.grantor_only_helper": "Regular admins can promote users to administrator and can later modify or delete only the administrators they directly promoted.",
|
||||
"install.admin_management_policy.grantor_inheritance": "Grantor chain with inheritance",
|
||||
"install.admin_management_policy.grantor_inheritance_helper": "Like grantor-only, but if the direct grantor becomes inactive or has sign-in disabled, management passes up the admin grant chain until an eligible admin is found. If none is found, super admins keep control.",
|
||||
"install.install_btn_confirm": "Installera Gitea",
|
||||
"install.test_git_failed": "Misslyckades att testa 'git' kommando: %v",
|
||||
"install.sqlite3_not_available": "Denna version av Gitea stödjer ej SQLite3. Ladda ner den officiella binären från %s (inte 'gobuild' versionen).",
|
||||
"install.invalid_db_setting": "Databasinställningarna är ogiltiga: %v",
|
||||
"install.invalid_db_table": "The database table \"%s\" is invalid: %v",
|
||||
"install.invalid_repo_path": "Utvecklingskatalogens rotsökväg är ogiltig: %v",
|
||||
"install.run_user_not_match": "Systemtjänstanvändaren är inte den nuvarande användaren: %s -> %s",
|
||||
"install.invalid_app_data_path": "The app data path is invalid: %v",
|
||||
"install.internal_token_failed": "Failed to generate internal token: %v",
|
||||
"install.secret_key_failed": "Failed to generate secret key: %v",
|
||||
"install.save_config_failed": "Misslyckades att spara konfigurationen: %v",
|
||||
"install.invalid_admin_setting": "Inställning för administartörskontot är ogiltig: %v",
|
||||
"install.invalid_log_root_path": "Sökvägen för loggar är ogiltig: %v",
|
||||
@@ -159,6 +211,14 @@
|
||||
"install.default_enable_timetracking_popup": "Aktivera tidsredovisning för nya utvecklingskataloger som standard.",
|
||||
"install.no_reply_address": "Dold mejldomän",
|
||||
"install.no_reply_address_helper": "Domännamn för användare med en dold mailadress. Exempelvis kommer användarnamnet 'joe' att loggas i Git som 'joe@noreply.example.org' om dold maildomän är satt till 'noreply.example.org'.",
|
||||
"install.password_algorithm": "Password Hash Algorithm",
|
||||
"install.invalid_password_algorithm": "Invalid password hash algorithm",
|
||||
"install.password_algorithm_helper": "Set the password hashing algorithm. Algorithms have differing requirements and strengths. The argon2 algorithm is rather secure but uses a lot of memory and may be inappropriate for small systems.",
|
||||
"install.enable_update_checker": "Enable Update Checker",
|
||||
"install.enable_update_checker_helper": "Checks for new version releases periodically by connecting to gitea.io.",
|
||||
"install.env_config_keys": "Environment Configuration",
|
||||
"install.env_config_keys_prompt": "The following environment variables will also be applied to your configuration file:",
|
||||
"install.config_write_file_prompt": "These configuration options will be written into: %s",
|
||||
"home.uname_holder": "Användarnamn eller Mejladress",
|
||||
"home.password_holder": "Lösenord",
|
||||
"home.switch_dashboard_context": "Växla Visad Instrumentpanel",
|
||||
@@ -190,6 +250,9 @@
|
||||
"auth.forgot_password_title": "Glömt lösenord",
|
||||
"auth.forgot_password": "Glömt lösenord?",
|
||||
"auth.must_change_password": "Ändra ditt lösenord",
|
||||
"auth.confirmation_mail_pending_signup": "A confirmation email has already been sent to <b>%s</b>. Please activate it before creating another account.",
|
||||
"auth.confirmation_mail_resend_failed": "The confirmation email could not be sent. Please try again later or contact an administrator.",
|
||||
"auth.confirmation_mail_resend_not_available": "This account can no longer receive confirmation emails.",
|
||||
"auth.allow_password_change": "Kräv att användaren byter lösenord (rekommenderas)",
|
||||
"auth.reset_password_mail_sent_prompt": "Ett nytt bekräftelsemail has skickats till <b>%s</b>. Vänligen kontrollera din inkorg inom de kommande %s för att slutföra återställning av ditt konto.",
|
||||
"auth.active_your_account": "Aktivera ditt konto",
|
||||
@@ -1445,6 +1508,7 @@
|
||||
"admin.users.created": "Skapad",
|
||||
"admin.users.last_login": "Senaste inloggning",
|
||||
"admin.users.send_register_notify": "Skicka notifiering vid användarregistrering",
|
||||
"admin.users.send_register_invite": "Send User Registration Invitation",
|
||||
"admin.users.edit": "Redigera",
|
||||
"admin.users.auth_source": "Autentiseringskälla",
|
||||
"admin.users.local": "Lokal",
|
||||
@@ -1733,5 +1797,15 @@
|
||||
"actions.runners.task_list.run": "Kör",
|
||||
"actions.runners.task_list.repository": "Utvecklingskatalog",
|
||||
"actions.runners.status.active": "Aktiv",
|
||||
"git.filemode.symbolic_link": "Symbolisk länk"
|
||||
"git.filemode.symbolic_link": "Symbolisk länk",
|
||||
"auth.accept_your_invitation": "Accept Your Invitation",
|
||||
"auth.invitation_mail_pending_login": "An invitation email has already been sent to <b>%s</b>. Please accept it before signing in.",
|
||||
"auth.invitation_mail_sent_prompt_ex": "A new invitation email has been sent to <b>%s</b>. Please use the link within the next %s to activate your account.",
|
||||
"auth.invitation_mail_resend_failed": "The invitation email could not be sent. Please try again later or contact an administrator.",
|
||||
"auth.invitation_mail_resend_not_available": "This account can no longer receive invitation emails.",
|
||||
"auth.invitation_resend_prompt": "Did not receive the invitation email?",
|
||||
"auth.invitation_resend_button": "Resend",
|
||||
"admin.users.send_register_notify_helper": "The account will be activated and validated immediately.",
|
||||
"admin.users.send_register_invite_helper": "The user must accept the emailed invitation before the account becomes active.",
|
||||
"install.language_balloon": "Choose a language"
|
||||
}
|
||||
|
||||
@@ -256,6 +256,8 @@
|
||||
"install.general_title": "Genel Ayarlar",
|
||||
"install.app_name": "Site Başlığı",
|
||||
"install.app_name_helper": "Şirket adınızı buraya girebilirsiniz.",
|
||||
"install.default_language": "Default Language",
|
||||
"install.default_language_helper": "Used when a user's browser language does not match an available locale.",
|
||||
"install.repo_path": "Depo Kök Yolu",
|
||||
"install.repo_path_helper": "Tüm uzak Git depoları bu dizine kaydedilecektir.",
|
||||
"install.lfs_path": "Git LFS Kök Yolu",
|
||||
@@ -281,15 +283,33 @@
|
||||
"install.smtp_from_helper": "Gitea'nın kullanacağı e-posta adresi. Yalın bir e-posta adresi girin veya \"İsim\" <eposta@ornek.com> biçimini kullanın.",
|
||||
"install.mailer_user": "SMTP Kullanıcı Adı",
|
||||
"install.mailer_password": "SMTP Parolası",
|
||||
"install.test_mail_to": "Send Testing Email",
|
||||
"install.test_mail_missing_host": "Please enter the SMTP host before testing email delivery.",
|
||||
"install.test_mail_missing_recipient": "Please enter a recipient email address before testing email delivery.",
|
||||
"install.registration_title": "Registration Management",
|
||||
"install.registration_mode": "Registration Mode",
|
||||
"install.registration_mode.admin_only": "Administrator-managed accounts only",
|
||||
"install.registration_mode.admin_only_helper": "Disable self-registration and let administrators create new accounts using the selected administrator-created account mode.",
|
||||
"install.admin_created_account_mode": "Administrator-Created Account Mode",
|
||||
"install.admin_created_account_mode.local": "Create local accounts directly",
|
||||
"install.admin_created_account_mode.local_helper": "Creates active local accounts immediately. Administrators can optionally notify the user by email after creation.",
|
||||
"install.admin_created_account_mode.invite": "Create invitation-based accounts",
|
||||
"install.admin_created_account_mode.invite_helper": "Creates inactive accounts with sign-in disabled until the user accepts the emailed invitation link.",
|
||||
"install.registration_mode.local_only": "Local registration only",
|
||||
"install.registration_mode.local_only_helper": "Allow new accounts only through Gitea's built-in registration form.",
|
||||
"install.registration_mode.external_only": "External registration only",
|
||||
"install.registration_mode.external_only_helper": "Disable the local registration form and accept new accounts only from external identity providers.",
|
||||
"install.registration_mode.local_and_external": "Local and external registration",
|
||||
"install.registration_mode.local_and_external_helper": "Allow new accounts through both Gitea's local registration form and external identity providers.",
|
||||
"install.registration_local_options": "Local Registration Options",
|
||||
"install.registration_external_options": "External Registration Options",
|
||||
"install.register_confirm": "Kayıt için E-posta Doğrulaması Gereksin",
|
||||
"install.register_confirm_helper": "Require users to verify their email address before they can continue.",
|
||||
"install.register_manual_confirm": "Require Administrator Approval After Email Validation",
|
||||
"install.register_manual_confirm_helper": "New accounts stay pending until an administrator reviews and approves the request.",
|
||||
"install.mail_notify": "E-Posta Bildirimlerini Etkinleştir",
|
||||
"install.mail_notify_helper": "Controls routine notification emails such as watches, mentions, and administrative notices. Activation and invitation emails still use the SMTP configuration above.",
|
||||
"install.server_service_title": "Sunucu ve Diğer Servis Ayarları",
|
||||
"install.offline_mode": "Yerel Kipi Etkinleştir",
|
||||
"install.offline_mode_popup": "Üçüncü parti içerik teslim ağlarını etkisizleştirin ve bütün kaynakları yerelden sunun.",
|
||||
"install.disable_gravatar": "Gravatar'ı Devre Dışı Bırak",
|
||||
"install.disable_gravatar_popup": "Gravatar ve üçüncü parti avatar kaynaklarını iptal edin. Kullanıcı bir avatar yüklemediği zaman varsayılan bir avatar kullanılacaktır.",
|
||||
"install.federated_avatar_lookup": "Birleştirilmiş Avatarları Etkinleştir",
|
||||
"install.federated_avatar_lookup_popup": "Libravatar kullanarak federe avatar aramasını etkinleştirin.",
|
||||
"install.disable_registration": "Kendi Kendine Kaydolmayı Devre Dışı Bırak",
|
||||
"install.disable_registration_popup": "Kullanıcının kendi kendine kaydolmasını devre dışı bırak. Yalnızca yöneticiler yeni hesaplar oluşturabilecek.",
|
||||
"install.allow_only_external_registration_popup": "Sadece dış hizmetler aracılığıyla kullanıcı kaydına izin ver",
|
||||
@@ -297,6 +317,8 @@
|
||||
"install.openid_signin_popup": "OpenID ile kullanıcı girişini etkinleştir.",
|
||||
"install.openid_signup": "OpenID ile Kendi Kendine Kaydı Etkinleştir",
|
||||
"install.openid_signup_popup": "OpenID Tabanlı Kendi Kendi Kullanıcı Kaydını Etkinleştir.",
|
||||
"install.openid_signin_helper": "Allow users to sign in through OpenID providers.",
|
||||
"install.openid_signup_helper": "Allow new accounts to be created through OpenID providers.",
|
||||
"install.enable_captcha": "CAPTCHA kaydını etkinleştir",
|
||||
"install.enable_captcha_popup": "Kullanıcının kendi kendine kaydolması için captcha doğrulaması gereksin.",
|
||||
"install.require_sign_in_view": "Sayfaları Görüntülemek için Giriş Yapmak Gereksin",
|
||||
@@ -307,6 +329,13 @@
|
||||
"install.admin_password": "Parola",
|
||||
"install.confirm_password": "Parolayı Doğrula",
|
||||
"install.admin_email": "E-posta Adresi",
|
||||
"install.admin_management_policy": "Administration Management Policy",
|
||||
"install.admin_management_policy.super_admin_only": "Only super admins manage admins",
|
||||
"install.admin_management_policy.super_admin_only_helper": "Regular admins can manage only non-admin accounts. Any admin-to-admin change or deletion requires a super administrator.",
|
||||
"install.admin_management_policy.grantor_only": "Grantor manages promoted admins",
|
||||
"install.admin_management_policy.grantor_only_helper": "Regular admins can promote users to administrator and can later modify or delete only the administrators they directly promoted.",
|
||||
"install.admin_management_policy.grantor_inheritance": "Grantor chain with inheritance",
|
||||
"install.admin_management_policy.grantor_inheritance_helper": "Like grantor-only, but if the direct grantor becomes inactive or has sign-in disabled, management passes up the admin grant chain until an eligible admin is found. If none is found, super admins keep control.",
|
||||
"install.install_btn_confirm": "Gitea'u Kur",
|
||||
"install.test_git_failed": "'git' komut testi başarısız: %v",
|
||||
"install.sqlite3_not_available": "Bu Gieta sürümü SQLite3 desteklemiyor. Lütfen %s adresinden resmi çalışır sürümü ('gobuild' sürümünü değil) indirin.",
|
||||
@@ -314,7 +343,6 @@
|
||||
"install.invalid_db_table": "\"%s\" veritabanı tablosu geçersiz: %v",
|
||||
"install.invalid_repo_path": "Depo kök dizini geçersiz: %v",
|
||||
"install.invalid_app_data_path": "Uygulama veri yolu geçersiz: %v",
|
||||
"install.run_user_not_match": "'Birlikte çalıştır' kullanıcı adı şimdiki kullanıcı adından farklıdır: %s -> %s",
|
||||
"install.internal_token_failed": "Dahili belirteç oluşturulamadı: %v",
|
||||
"install.secret_key_failed": "Gizli anahtar oluşturulamadı: %v",
|
||||
"install.save_config_failed": "%v Yapılandırması kaydedilirken hata oluştu",
|
||||
@@ -387,6 +415,9 @@
|
||||
"auth.sign_up_now": "Hemen kaydolun.",
|
||||
"auth.sign_up_successful": "Hesap başarılı bir şekilde oluşturuldu. Hoşgeldiniz!",
|
||||
"auth.confirmation_mail_sent_prompt_ex": "Yeni bir doğrulama e-postası <b>%s</b> adresine gönderildi. Lütfen kayıt sürecini tamamlamak için %s içinde gelen kutunuzu denetleyin. Eğer kayıt e-posta adresiniz hatalı ise, tekrar oturum açıp değiştirebilirsiniz.",
|
||||
"auth.confirmation_mail_pending_signup": "A confirmation email has already been sent to <b>%s</b>. Please activate it before creating another account.",
|
||||
"auth.confirmation_mail_resend_failed": "The confirmation email could not be sent. Please try again later or contact an administrator.",
|
||||
"auth.confirmation_mail_resend_not_available": "This account can no longer receive confirmation emails.",
|
||||
"auth.must_change_password": "Parolanızı güncelleyin",
|
||||
"auth.allow_password_change": "Kullanıcıyı parola değiştirmeye zorla (önerilen)",
|
||||
"auth.reset_password_mail_sent_prompt": "<b>%s</b> adresine bir onay e-postası gönderildi. Hesap kurtarma işlemini tamamlamak için lütfen gelen kutunuzu sonraki %s içinde kontrol edin.",
|
||||
@@ -2971,6 +3002,7 @@
|
||||
"admin.users.last_login": "Son Oturum Açma",
|
||||
"admin.users.never_login": "Hiç Oturum Açılmadı",
|
||||
"admin.users.send_register_notify": "Kullanıcı Kayıt Bildirimi Gönder",
|
||||
"admin.users.send_register_invite": "Send User Registration Invitation",
|
||||
"admin.users.new_success": "\"%s\" kullanıcı hesabı oluşturuldu.",
|
||||
"admin.users.edit": "Düzenle",
|
||||
"admin.users.auth_source": "Yetkilendirme Kaynağı",
|
||||
@@ -3743,5 +3775,15 @@
|
||||
"git.filemode.normal_file": "Normal dosya",
|
||||
"git.filemode.executable_file": "Çalıştırılabilir dosya",
|
||||
"git.filemode.symbolic_link": "Sembolik Bağlantı",
|
||||
"git.filemode.submodule": "Alt modül"
|
||||
"git.filemode.submodule": "Alt modül",
|
||||
"auth.accept_your_invitation": "Accept Your Invitation",
|
||||
"auth.invitation_mail_pending_login": "An invitation email has already been sent to <b>%s</b>. Please accept it before signing in.",
|
||||
"auth.invitation_mail_sent_prompt_ex": "A new invitation email has been sent to <b>%s</b>. Please use the link within the next %s to activate your account.",
|
||||
"auth.invitation_mail_resend_failed": "The invitation email could not be sent. Please try again later or contact an administrator.",
|
||||
"auth.invitation_mail_resend_not_available": "This account can no longer receive invitation emails.",
|
||||
"auth.invitation_resend_prompt": "Did not receive the invitation email?",
|
||||
"auth.invitation_resend_button": "Resend",
|
||||
"admin.users.send_register_notify_helper": "The account will be activated and validated immediately.",
|
||||
"admin.users.send_register_invite_helper": "The user must accept the emailed invitation before the account becomes active.",
|
||||
"install.language_balloon": "Choose a language"
|
||||
}
|
||||
|
||||
@@ -189,6 +189,7 @@
|
||||
"startpage.lightweight_desc": "Gitea має мінімальні вимоги і може працювати на недорогому Raspberry Pi. Заощаджуйте ресурси вашої машини!",
|
||||
"startpage.license": "Відкритий вихідний код",
|
||||
"install.install": "Встановлення",
|
||||
"install.installing_desc": "Installing now, please wait…",
|
||||
"install.title": "Початкова конфігурація",
|
||||
"install.docker_helper": "Якщо ви запускаєте Gitea у Docker, будь ласка, прочитайте <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"%s\">документацію</a> перед тим, як змінювати будь-які налаштування.",
|
||||
"install.require_db_desc": "Gitea потребує MySQL, PostgreSQL, MSSQL, SQLite3 або TiDB (протокол MySQL).",
|
||||
@@ -200,17 +201,26 @@
|
||||
"install.db_name": "Назва бази даних",
|
||||
"install.db_schema": "Схема",
|
||||
"install.db_schema_helper": "Залиште пустим для типової схеми бази даних (\"публічна\").",
|
||||
"install.ssl_mode": "SSL",
|
||||
"install.path": "Шлях",
|
||||
"install.sqlite_helper": "Шлях до файлу бази даних SQLite3.<br>Введіть абсолютний шлях, якщо ви запускаєте Gіtea як сервіс.",
|
||||
"install.reinstall_error": "Ви намагаєтеся встановити в наявну базу даних Gitea",
|
||||
"install.reinstall_confirm_message": "Повторне встановлення в наявну базу даних Gitea може спричинити багато проблем. В більшості випадків, ви повинні використовувати свій наявний \"app.ini\" для запуску Gitea. Якщо ви знаєте, що робите, спробуйте наступне:",
|
||||
"install.reinstall_confirm_check_1": "The data encrypted by the SECRET_KEY in app.ini may be lost: users may not be able to log in with 2FA/OTP and mirrors may not function correctly. By checking this box, you confirm that the current app.ini file contains the correct SECRET_KEY.",
|
||||
"install.reinstall_confirm_check_2": "The repositories and settings may need to be resynchronized. By checking this box, you confirm that you will resynchronize the hooks for the repositories and authorized_keys file manually. You confirm that you will ensure that repository and mirror settings are correct.",
|
||||
"install.reinstall_confirm_check_3": "Ви підтверджуєте, що абсолютно впевнені, що Gitea працює з правильним розташуванням файлу app.ini, і що вам потрібно перевстановити програму. Ви підтверджуєте, що усвідомлюєте вищевказані ризики.",
|
||||
"install.err_empty_db_path": "Шлях до файлу бази даних SQLite3 не може бути порожнім.",
|
||||
"install.no_admin_and_disable_registration": "Ви не можете вимкнути реєстрацію без створення облікового запису адміністратора.",
|
||||
"install.err_empty_admin_password": "Пароль адміністратора не може бути порожнім.",
|
||||
"install.err_empty_admin_email": "The administrator email address cannot be empty.",
|
||||
"install.err_admin_name_is_reserved": "Administrator username is invalid. Username is reserved.",
|
||||
"install.err_admin_name_pattern_not_allowed": "Administrator username is invalid. The username matches a reserved pattern.",
|
||||
"install.err_admin_name_is_invalid": "Administrator username is invalid",
|
||||
"install.general_title": "Загальні налаштування",
|
||||
"install.app_name": "Назва сайту",
|
||||
"install.app_name_helper": "Тут ви можете ввести назву своєї компанії.",
|
||||
"install.default_language": "Default Language",
|
||||
"install.default_language_helper": "Used when a user's browser language does not match an available locale.",
|
||||
"install.repo_path": "Кореневий шлях сховища",
|
||||
"install.repo_path_helper": "До цього каталогу буде збережено віддалені сховища Git.",
|
||||
"install.lfs_path": "Кореневий шлях Git LFS",
|
||||
@@ -222,6 +232,7 @@
|
||||
"install.ssh_port": "Порт SSH сервера",
|
||||
"install.ssh_port_helper": "Номер порту, який використовує SSH сервер. Залиште порожнім, щоб вимкнути SSH.",
|
||||
"install.http_port": "Gitea HTTP порт",
|
||||
"install.http_port_helper": "Port number the Gitea web server will listen on.",
|
||||
"install.app_url": "Базова URL-адреса Gitea",
|
||||
"install.app_url_helper": "Базова адреса для URL-адрес клонів HTTP(S) та сповіщень електронною поштою.",
|
||||
"install.log_root_path": "Шлях до журналу",
|
||||
@@ -235,15 +246,33 @@
|
||||
"install.smtp_from_helper": "Адреса електронної пошти, яку буде використовувати Gitea. Введіть звичайну адресу електронної пошти або використовуйте формат «Ім'я» <email@example.com>.",
|
||||
"install.mailer_user": "Ім'я користувача SMTP",
|
||||
"install.mailer_password": "Пароль SMTP",
|
||||
"install.test_mail_to": "Send Testing Email",
|
||||
"install.test_mail_missing_host": "Please enter the SMTP host before testing email delivery.",
|
||||
"install.test_mail_missing_recipient": "Please enter a recipient email address before testing email delivery.",
|
||||
"install.registration_title": "Registration Management",
|
||||
"install.registration_mode": "Registration Mode",
|
||||
"install.registration_mode.admin_only": "Administrator-managed accounts only",
|
||||
"install.registration_mode.admin_only_helper": "Disable self-registration and let administrators create new accounts using the selected administrator-created account mode.",
|
||||
"install.admin_created_account_mode": "Administrator-Created Account Mode",
|
||||
"install.admin_created_account_mode.local": "Create local accounts directly",
|
||||
"install.admin_created_account_mode.local_helper": "Creates active local accounts immediately. Administrators can optionally notify the user by email after creation.",
|
||||
"install.admin_created_account_mode.invite": "Create invitation-based accounts",
|
||||
"install.admin_created_account_mode.invite_helper": "Creates inactive accounts with sign-in disabled until the user accepts the emailed invitation link.",
|
||||
"install.registration_mode.local_only": "Local registration only",
|
||||
"install.registration_mode.local_only_helper": "Allow new accounts only through Gitea's built-in registration form.",
|
||||
"install.registration_mode.external_only": "External registration only",
|
||||
"install.registration_mode.external_only_helper": "Disable the local registration form and accept new accounts only from external identity providers.",
|
||||
"install.registration_mode.local_and_external": "Local and external registration",
|
||||
"install.registration_mode.local_and_external_helper": "Allow new accounts through both Gitea's local registration form and external identity providers.",
|
||||
"install.registration_local_options": "Local Registration Options",
|
||||
"install.registration_external_options": "External Registration Options",
|
||||
"install.register_confirm": "Вимагати підтвердження електронною поштою для реєстрації",
|
||||
"install.register_confirm_helper": "Require users to verify their email address before they can continue.",
|
||||
"install.register_manual_confirm": "Require Administrator Approval After Email Validation",
|
||||
"install.register_manual_confirm_helper": "New accounts stay pending until an administrator reviews and approves the request.",
|
||||
"install.mail_notify": "Увімкнути сповіщення електронною поштою",
|
||||
"install.mail_notify_helper": "Controls routine notification emails such as watches, mentions, and administrative notices. Activation and invitation emails still use the SMTP configuration above.",
|
||||
"install.server_service_title": "Налаштування сервера і сторонніх сервісів",
|
||||
"install.offline_mode": "Увімкнути локальний режим",
|
||||
"install.offline_mode_popup": "Вимкнути сторонні мережі доставки контенту та обслуговувати всі ресурси локально.",
|
||||
"install.disable_gravatar": "Вимкнути Gravatar",
|
||||
"install.disable_gravatar_popup": "Вимкнути Gravatar та сторонні джерела аватарок. Якщо користувач локально не завантажить аватар, буде використовуватися типовий аватар.",
|
||||
"install.federated_avatar_lookup": "Увімкнути зовнішні аватари",
|
||||
"install.federated_avatar_lookup_popup": "Увімкнути пошук об'єднаних аватарів за допомогою Libravatar.",
|
||||
"install.disable_registration": "Вимкнути реєстрацію",
|
||||
"install.disable_registration_popup": "Вимкнути реєстрацію користувачів, тільки адміністратор може створювати нові облікові записи.",
|
||||
"install.allow_only_external_registration_popup": "Дозволити реєстрацію тільки через сторонні сервіси",
|
||||
@@ -251,6 +280,8 @@
|
||||
"install.openid_signin_popup": "Увімкнути вхід користувачів за допомогою OpenID.",
|
||||
"install.openid_signup": "Увімкнути самостійну реєстрацію за допомогою OpenID",
|
||||
"install.openid_signup_popup": "Увімкнути самореєстрацію користувачів на основі OpenID.",
|
||||
"install.openid_signin_helper": "Allow users to sign in through OpenID providers.",
|
||||
"install.openid_signup_helper": "Allow new accounts to be created through OpenID providers.",
|
||||
"install.enable_captcha": "Увімкнути CAPTCHA для реєстрації",
|
||||
"install.enable_captcha_popup": "Вимагати CAPTCHA для самореєстрації користувачів.",
|
||||
"install.require_sign_in_view": "Вимагати авторизації для перегляду сторінок",
|
||||
@@ -261,6 +292,13 @@
|
||||
"install.admin_password": "Пароль",
|
||||
"install.confirm_password": "Підтвердити пароль",
|
||||
"install.admin_email": "Адреса електронної пошти",
|
||||
"install.admin_management_policy": "Administration Management Policy",
|
||||
"install.admin_management_policy.super_admin_only": "Only super admins manage admins",
|
||||
"install.admin_management_policy.super_admin_only_helper": "Regular admins can manage only non-admin accounts. Any admin-to-admin change or deletion requires a super administrator.",
|
||||
"install.admin_management_policy.grantor_only": "Grantor manages promoted admins",
|
||||
"install.admin_management_policy.grantor_only_helper": "Regular admins can promote users to administrator and can later modify or delete only the administrators they directly promoted.",
|
||||
"install.admin_management_policy.grantor_inheritance": "Grantor chain with inheritance",
|
||||
"install.admin_management_policy.grantor_inheritance_helper": "Like grantor-only, but if the direct grantor becomes inactive or has sign-in disabled, management passes up the admin grant chain until an eligible admin is found. If none is found, super admins keep control.",
|
||||
"install.install_btn_confirm": "Встановити Gitea",
|
||||
"install.test_git_failed": "Не вдалося перевірити команду 'git': %v",
|
||||
"install.sqlite3_not_available": "Ця версія Gitea не підтримує SQLite3. Будь ласка, завантажте офіційну бінарну версію з %s (не версію gobuild).",
|
||||
@@ -268,7 +306,6 @@
|
||||
"install.invalid_db_table": "База даних таблиці \"%s\" є недійсною: %v",
|
||||
"install.invalid_repo_path": "Кореневий шлях до сховища невірний: %v",
|
||||
"install.invalid_app_data_path": "Шлях до даних додатка невірний: %v",
|
||||
"install.run_user_not_match": "Ім'я користувача “Виконати як” не є поточним ім'ям користувача: %s -> %s",
|
||||
"install.internal_token_failed": "Не вдалося створити внутрішній токен: %v",
|
||||
"install.secret_key_failed": "Не вдалося створити секретний ключ: %v",
|
||||
"install.save_config_failed": "Не вдалося зберегти конфігурацію: %v",
|
||||
@@ -284,6 +321,7 @@
|
||||
"install.no_reply_address_helper": "Доменне ім'я для користувачів із прихованою електронною адресою. Наприклад, ім'я користувача 'Joe' буде зображатися в Git як 'joe@noreply.example.org', якщо прихований домен електронної пошти встановлено 'noreply.example.org'.",
|
||||
"install.password_algorithm": "Алгоритм хешування пароля",
|
||||
"install.invalid_password_algorithm": "Недійсний хеш-алгоритм пароля",
|
||||
"install.password_algorithm_helper": "Set the password hashing algorithm. Algorithms have differing requirements and strengths. The argon2 algorithm is rather secure but uses a lot of memory and may be inappropriate for small systems.",
|
||||
"install.enable_update_checker": "Увімкнути перевірку оновлень",
|
||||
"install.enable_update_checker_helper": "Періодично перевіряти наявність нових версій, підключаючись до gitea.io.",
|
||||
"install.env_config_keys": "Конфігурація середовища",
|
||||
@@ -340,6 +378,9 @@
|
||||
"auth.sign_up_now": "Зареєструватися.",
|
||||
"auth.sign_up_successful": "Обліковий запис створено успішно. Вітаю!",
|
||||
"auth.confirmation_mail_sent_prompt_ex": "Новий лист з підтвердженням було надіслано на <b>%s</b>. Будь ласка, перевірте свою поштову скриньку протягом наступних %s, щоб завершити процес реєстрації. Якщо ви вказали невірну адресу електронної пошти, ви можете увійти ще раз і змінити її.",
|
||||
"auth.confirmation_mail_pending_signup": "A confirmation email has already been sent to <b>%s</b>. Please activate it before creating another account.",
|
||||
"auth.confirmation_mail_resend_failed": "The confirmation email could not be sent. Please try again later or contact an administrator.",
|
||||
"auth.confirmation_mail_resend_not_available": "This account can no longer receive confirmation emails.",
|
||||
"auth.must_change_password": "Оновити пароль",
|
||||
"auth.allow_password_change": "Вимагати від користувача змінити пароль (рекомендовано)",
|
||||
"auth.reset_password_mail_sent_prompt": "На адресу <b>%s</b> було надіслано лист із підтвердженням. Будь ласка, перевірте свою поштову скриньку протягом наступних %s, щоб завершити процес відновлення облікового запису.",
|
||||
@@ -2533,6 +2574,7 @@
|
||||
"admin.users.created": "Створено",
|
||||
"admin.users.last_login": "Останній вхід",
|
||||
"admin.users.send_register_notify": "Надіслати повідомлення про реєстрацію користувача",
|
||||
"admin.users.send_register_invite": "Send User Registration Invitation",
|
||||
"admin.users.new_success": "Обліковий запис \"%s\" створено.",
|
||||
"admin.users.edit": "Редагувати",
|
||||
"admin.users.auth_source": "Джерело автентифікації",
|
||||
@@ -3182,5 +3224,15 @@
|
||||
"git.filemode.normal_file": "Звичайний файл",
|
||||
"git.filemode.executable_file": "Виконуваний файл",
|
||||
"git.filemode.symbolic_link": "Символічне посилання",
|
||||
"git.filemode.submodule": "Підмодуль"
|
||||
"git.filemode.submodule": "Підмодуль",
|
||||
"auth.accept_your_invitation": "Accept Your Invitation",
|
||||
"auth.invitation_mail_pending_login": "An invitation email has already been sent to <b>%s</b>. Please accept it before signing in.",
|
||||
"auth.invitation_mail_sent_prompt_ex": "A new invitation email has been sent to <b>%s</b>. Please use the link within the next %s to activate your account.",
|
||||
"auth.invitation_mail_resend_failed": "The invitation email could not be sent. Please try again later or contact an administrator.",
|
||||
"auth.invitation_mail_resend_not_available": "This account can no longer receive invitation emails.",
|
||||
"auth.invitation_resend_prompt": "Did not receive the invitation email?",
|
||||
"auth.invitation_resend_button": "Resend",
|
||||
"admin.users.send_register_notify_helper": "The account will be activated and validated immediately.",
|
||||
"admin.users.send_register_invite_helper": "The user must accept the emailed invitation before the account becomes active.",
|
||||
"install.language_balloon": "Choose a language"
|
||||
}
|
||||
|
||||
@@ -257,6 +257,8 @@
|
||||
"install.general_title": "一般设置",
|
||||
"install.app_name": "站点名称",
|
||||
"install.app_name_helper": "您可以在此输入您公司的名称。",
|
||||
"install.default_language": "Default Language",
|
||||
"install.default_language_helper": "Used when a user's browser language does not match an available locale.",
|
||||
"install.repo_path": "仓库根目录",
|
||||
"install.repo_path_helper": "所有远程 Git 仓库将保存到此目录。",
|
||||
"install.lfs_path": "LFS根目录",
|
||||
@@ -282,8 +284,32 @@
|
||||
"install.smtp_from_helper": "请输入一个用于 Gitea 的邮箱地址,或者使用完整格式:\"名称\" <email@example.com>。",
|
||||
"install.mailer_user": "SMTP 用户名",
|
||||
"install.mailer_password": "SMTP 密码",
|
||||
"install.test_mail_to": "Send Testing Email",
|
||||
"install.test_mail_missing_host": "Please enter the SMTP host before testing email delivery.",
|
||||
"install.test_mail_missing_recipient": "Please enter a recipient email address before testing email delivery.",
|
||||
"install.registration_title": "Registration Management",
|
||||
"install.registration_mode": "Registration Mode",
|
||||
"install.registration_mode.admin_only": "Administrator-managed accounts only",
|
||||
"install.registration_mode.admin_only_helper": "Disable self-registration and let administrators create new accounts using the selected administrator-created account mode.",
|
||||
"install.admin_created_account_mode": "Administrator-Created Account Mode",
|
||||
"install.admin_created_account_mode.local": "Create local accounts directly",
|
||||
"install.admin_created_account_mode.local_helper": "Creates active local accounts immediately. Administrators can optionally notify the user by email after creation.",
|
||||
"install.admin_created_account_mode.invite": "Create invitation-based accounts",
|
||||
"install.admin_created_account_mode.invite_helper": "Creates inactive accounts with sign-in disabled until the user accepts the emailed invitation link.",
|
||||
"install.registration_mode.local_only": "Local registration only",
|
||||
"install.registration_mode.local_only_helper": "Allow new accounts only through Gitea's built-in registration form.",
|
||||
"install.registration_mode.external_only": "External registration only",
|
||||
"install.registration_mode.external_only_helper": "Disable the local registration form and accept new accounts only from external identity providers.",
|
||||
"install.registration_mode.local_and_external": "Local and external registration",
|
||||
"install.registration_mode.local_and_external_helper": "Allow new accounts through both Gitea's local registration form and external identity providers.",
|
||||
"install.registration_local_options": "Local Registration Options",
|
||||
"install.registration_external_options": "External Registration Options",
|
||||
"install.register_confirm": "需要邮件确认注册",
|
||||
"install.register_confirm_helper": "Require users to verify their email address before they can continue.",
|
||||
"install.register_manual_confirm": "Require Administrator Approval After Email Validation",
|
||||
"install.register_manual_confirm_helper": "New accounts stay pending until an administrator reviews and approves the request.",
|
||||
"install.mail_notify": "启用邮件通知提醒",
|
||||
"install.mail_notify_helper": "Controls routine notification emails such as watches, mentions, and administrative notices. Activation and invitation emails still use the SMTP configuration above.",
|
||||
"install.server_service_title": "服务器和第三方服务设置",
|
||||
"install.disable_registration": "禁止用户自助注册",
|
||||
"install.disable_registration_popup": "禁用用户自助注册。只有管理员才能创建新的用户帐户。",
|
||||
@@ -292,6 +318,8 @@
|
||||
"install.openid_signin_popup": "启用通过 OpenID 登录",
|
||||
"install.openid_signup": "启用 OpenID 自助注册",
|
||||
"install.openid_signup_popup": "启用基于 OpenID 的用户自助注册。",
|
||||
"install.openid_signin_helper": "Allow users to sign in through OpenID providers.",
|
||||
"install.openid_signup_helper": "Allow new accounts to be created through OpenID providers.",
|
||||
"install.enable_captcha": "启用注册验证码",
|
||||
"install.enable_captcha_popup": "要求在用户注册时输入预验证码",
|
||||
"install.require_sign_in_view": "启用页面访问限制",
|
||||
@@ -302,6 +330,13 @@
|
||||
"install.admin_password": "管理员密码",
|
||||
"install.confirm_password": "确认密码",
|
||||
"install.admin_email": "邮箱地址",
|
||||
"install.admin_management_policy": "Administration Management Policy",
|
||||
"install.admin_management_policy.super_admin_only": "Only super admins manage admins",
|
||||
"install.admin_management_policy.super_admin_only_helper": "Regular admins can manage only non-admin accounts. Any admin-to-admin change or deletion requires a super administrator.",
|
||||
"install.admin_management_policy.grantor_only": "Grantor manages promoted admins",
|
||||
"install.admin_management_policy.grantor_only_helper": "Regular admins can promote users to administrator and can later modify or delete only the administrators they directly promoted.",
|
||||
"install.admin_management_policy.grantor_inheritance": "Grantor chain with inheritance",
|
||||
"install.admin_management_policy.grantor_inheritance_helper": "Like grantor-only, but if the direct grantor becomes inactive or has sign-in disabled, management passes up the admin grant chain until an eligible admin is found. If none is found, super admins keep control.",
|
||||
"install.install_btn_confirm": "立即安装",
|
||||
"install.test_git_failed": "无法识别 'git' 命令:%v",
|
||||
"install.sqlite3_not_available": "您所使用的发行版不支持 SQLite3,请从 %s 下载官方构建版,而不是 gobuild 版本。",
|
||||
@@ -309,7 +344,6 @@
|
||||
"install.invalid_db_table": "数据库表「%s」无效:%v",
|
||||
"install.invalid_repo_path": "仓库根目录设置无效:%v",
|
||||
"install.invalid_app_data_path": "应用数据路径无效: %v",
|
||||
"install.run_user_not_match": "运行用户名不是当前的用户名:%s -> %s",
|
||||
"install.internal_token_failed": "生成内部令牌失败:%v",
|
||||
"install.secret_key_failed": "生成密钥失败:%v",
|
||||
"install.save_config_failed": "应用配置保存失败:%v",
|
||||
@@ -382,6 +416,9 @@
|
||||
"auth.sign_up_now": "立即注册。",
|
||||
"auth.sign_up_successful": "帐户创建成功。欢迎!",
|
||||
"auth.confirmation_mail_sent_prompt_ex": "一封新的确认邮件已经发送到 <b>%s</b>。请在 %s 内检查您的收件箱以完成注册流程。 如果您的注册邮箱地址不正确,您可以重新登录并更改它。",
|
||||
"auth.confirmation_mail_pending_signup": "A confirmation email has already been sent to <b>%s</b>. Please activate it before creating another account.",
|
||||
"auth.confirmation_mail_resend_failed": "The confirmation email could not be sent. Please try again later or contact an administrator.",
|
||||
"auth.confirmation_mail_resend_not_available": "This account can no longer receive confirmation emails.",
|
||||
"auth.must_change_password": "更新您的密码",
|
||||
"auth.allow_password_change": "要求用户更改密码(推荐)",
|
||||
"auth.reset_password_mail_sent_prompt": "确认邮件已被发送到 <b>%s</b>。请您在 %s 内检查您的收件箱 ,完成密码重置流程。",
|
||||
@@ -2968,6 +3005,7 @@
|
||||
"admin.users.last_login": "上次登录",
|
||||
"admin.users.never_login": "从未登录",
|
||||
"admin.users.send_register_notify": "发送注册通知",
|
||||
"admin.users.send_register_invite": "Send User Registration Invitation",
|
||||
"admin.users.new_success": "用户账户「%s」已创建。",
|
||||
"admin.users.edit": "修改",
|
||||
"admin.users.auth_source": "认证源",
|
||||
@@ -3749,5 +3787,15 @@
|
||||
"git.filemode.normal_file": "普通文件",
|
||||
"git.filemode.executable_file": "可执行文件",
|
||||
"git.filemode.symbolic_link": "符号链接",
|
||||
"git.filemode.submodule": "子模块"
|
||||
"git.filemode.submodule": "子模块",
|
||||
"auth.accept_your_invitation": "Accept Your Invitation",
|
||||
"auth.invitation_mail_pending_login": "An invitation email has already been sent to <b>%s</b>. Please accept it before signing in.",
|
||||
"auth.invitation_mail_sent_prompt_ex": "A new invitation email has been sent to <b>%s</b>. Please use the link within the next %s to activate your account.",
|
||||
"auth.invitation_mail_resend_failed": "The invitation email could not be sent. Please try again later or contact an administrator.",
|
||||
"auth.invitation_mail_resend_not_available": "This account can no longer receive invitation emails.",
|
||||
"auth.invitation_resend_prompt": "Did not receive the invitation email?",
|
||||
"auth.invitation_resend_button": "Resend",
|
||||
"admin.users.send_register_notify_helper": "The account will be activated and validated immediately.",
|
||||
"admin.users.send_register_invite_helper": "The user must accept the emailed invitation before the account becomes active.",
|
||||
"install.language_balloon": "Choose a language"
|
||||
}
|
||||
|
||||
@@ -188,6 +188,7 @@
|
||||
"startpage.license": "開放原始碼",
|
||||
"startpage.license_desc": "取得 <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://code.gitea.io/gitea\">code.gitea.io/gitea</a> !成為一名<a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://github.com/go-gitea/gitea\">貢獻者</a>和我們一起讓 Gitea 更好,快點加入我們吧!",
|
||||
"install.install": "安裝頁面",
|
||||
"install.installing_desc": "Installing now, please wait…",
|
||||
"install.title": "初始組態",
|
||||
"install.docker_helper": "如果您在 Docker 中執行 Gitea,請先閱讀<a target=\"_blank\" rel=\"noopener noreferrer\" href=\"%s\">安裝指南</a>再來調整設定。",
|
||||
"install.require_db_desc": "Gitea 需要 MySQL、PostgreSQL、SQLite3、MSSQL、TiDB (MySQL 協定) 等其中一項。",
|
||||
@@ -197,18 +198,28 @@
|
||||
"install.user": "帳號",
|
||||
"install.password": "密碼",
|
||||
"install.db_name": "資料庫名稱",
|
||||
"install.db_schema": "Schema",
|
||||
"install.db_schema_helper": "留空則使用資料庫預設值(\"public\")。",
|
||||
"install.ssl_mode": "SSL",
|
||||
"install.path": "資料庫檔案路徑",
|
||||
"install.sqlite_helper": "SQLite3 或 TiDB 資料庫的檔案路徑。<br>如果將 Gitea 註冊為服務執行,請輸入絕對路徑。",
|
||||
"install.reinstall_error": "您正試圖安裝到既有的 Gitea 資料庫中",
|
||||
"install.reinstall_confirm_message": "使用既有的 Gitea 資料庫來安裝可能造成多種問題。大部分的情形下您應使用既有的「app.ini」來執行 Gitea。如果您知道自己正在做什麼,請確認下列事項:",
|
||||
"install.reinstall_confirm_check_1": "The data encrypted by the SECRET_KEY in app.ini may be lost: users may not be able to log in with 2FA/OTP and mirrors may not function correctly. By checking this box, you confirm that the current app.ini file contains the correct SECRET_KEY.",
|
||||
"install.reinstall_confirm_check_2": "The repositories and settings may need to be resynchronized. By checking this box, you confirm that you will resynchronize the hooks for the repositories and authorized_keys file manually. You confirm that you will ensure that repository and mirror settings are correct.",
|
||||
"install.reinstall_confirm_check_3": "您確認您絕對肯定此 Gitea 在正確的 app.ini 位置上執行,而且您確定您必須重新安裝。您確認您瞭解上述風險。",
|
||||
"install.err_empty_db_path": "SQLite3 資料庫路徑不可以為空。",
|
||||
"install.no_admin_and_disable_registration": "您不能夠在未建立管理員使用者的情況下禁止註冊。",
|
||||
"install.err_empty_admin_password": "管理員密碼不能為空。",
|
||||
"install.err_empty_admin_email": "The administrator email address cannot be empty.",
|
||||
"install.err_admin_name_is_reserved": "Administrator username is invalid. Username is reserved.",
|
||||
"install.err_admin_name_pattern_not_allowed": "Administrator username is invalid. The username matches a reserved pattern.",
|
||||
"install.err_admin_name_is_invalid": "Administrator username is invalid",
|
||||
"install.general_title": "一般設定",
|
||||
"install.app_name": "網站標題",
|
||||
"install.app_name_helper": "您可以在此輸入您的公司名稱。",
|
||||
"install.default_language": "Default Language",
|
||||
"install.default_language_helper": "Used when a user's browser language does not match an available locale.",
|
||||
"install.repo_path": "儲存庫的根目錄",
|
||||
"install.repo_path_helper": "所有遠端 Git 儲存庫會儲存到此目錄。",
|
||||
"install.lfs_path": "Git LFS 根目錄",
|
||||
@@ -220,6 +231,7 @@
|
||||
"install.ssh_port": "SSH 伺服器埠",
|
||||
"install.ssh_port_helper": "SSH 伺服器使用的埠號,留空以停用此設定。",
|
||||
"install.http_port": "Gitea HTTP 埠",
|
||||
"install.http_port_helper": "Port number the Gitea web server will listen on.",
|
||||
"install.app_url": "Gitea 基本 URL",
|
||||
"install.app_url_helper": "用於 HTTP(S) Clone 和電子郵件通知的基本網址。",
|
||||
"install.log_root_path": "日誌路徑",
|
||||
@@ -233,15 +245,33 @@
|
||||
"install.smtp_from_helper": "Gitea 將會使用的電子信箱,直接輸入電子信箱或使用「\"名稱\" <email@example.com>」的格式。",
|
||||
"install.mailer_user": "SMTP 帳號",
|
||||
"install.mailer_password": "SMTP 密碼",
|
||||
"install.test_mail_to": "Send Testing Email",
|
||||
"install.test_mail_missing_host": "Please enter the SMTP host before testing email delivery.",
|
||||
"install.test_mail_missing_recipient": "Please enter a recipient email address before testing email delivery.",
|
||||
"install.registration_title": "Registration Management",
|
||||
"install.registration_mode": "Registration Mode",
|
||||
"install.registration_mode.admin_only": "Administrator-managed accounts only",
|
||||
"install.registration_mode.admin_only_helper": "Disable self-registration and let administrators create new accounts using the selected administrator-created account mode.",
|
||||
"install.admin_created_account_mode": "Administrator-Created Account Mode",
|
||||
"install.admin_created_account_mode.local": "Create local accounts directly",
|
||||
"install.admin_created_account_mode.local_helper": "Creates active local accounts immediately. Administrators can optionally notify the user by email after creation.",
|
||||
"install.admin_created_account_mode.invite": "Create invitation-based accounts",
|
||||
"install.admin_created_account_mode.invite_helper": "Creates inactive accounts with sign-in disabled until the user accepts the emailed invitation link.",
|
||||
"install.registration_mode.local_only": "Local registration only",
|
||||
"install.registration_mode.local_only_helper": "Allow new accounts only through Gitea's built-in registration form.",
|
||||
"install.registration_mode.external_only": "External registration only",
|
||||
"install.registration_mode.external_only_helper": "Disable the local registration form and accept new accounts only from external identity providers.",
|
||||
"install.registration_mode.local_and_external": "Local and external registration",
|
||||
"install.registration_mode.local_and_external_helper": "Allow new accounts through both Gitea's local registration form and external identity providers.",
|
||||
"install.registration_local_options": "Local Registration Options",
|
||||
"install.registration_external_options": "External Registration Options",
|
||||
"install.register_confirm": "要求註冊時確認電子郵件",
|
||||
"install.register_confirm_helper": "Require users to verify their email address before they can continue.",
|
||||
"install.register_manual_confirm": "Require Administrator Approval After Email Validation",
|
||||
"install.register_manual_confirm_helper": "New accounts stay pending until an administrator reviews and approves the request.",
|
||||
"install.mail_notify": "啟用郵件通知",
|
||||
"install.mail_notify_helper": "Controls routine notification emails such as watches, mentions, and administrative notices. Activation and invitation emails still use the SMTP configuration above.",
|
||||
"install.server_service_title": "伺服器和第三方服務設定",
|
||||
"install.offline_mode": "啟用本地模式",
|
||||
"install.offline_mode_popup": "停用其他服務並在本地提供所有資源。",
|
||||
"install.disable_gravatar": "停用 Gravatar",
|
||||
"install.disable_gravatar_popup": "停用 Gravatar 和其他大頭貼服務。除非使用者在本地上傳大頭貼,否則將使用預設的大頭貼。",
|
||||
"install.federated_avatar_lookup": "啟用 Federated Avatars",
|
||||
"install.federated_avatar_lookup_popup": "使用 Libravatar 以啟用 Federated Avatar 查詢服務",
|
||||
"install.disable_registration": "關閉註冊功能",
|
||||
"install.disable_registration_popup": "關閉註冊功能,只有管理員可以新增帳戶。",
|
||||
"install.allow_only_external_registration_popup": "只允許從外部服務註冊",
|
||||
@@ -249,6 +279,8 @@
|
||||
"install.openid_signin_popup": "啟用 OpenID 登入",
|
||||
"install.openid_signup": "啟用 OpenID 註冊",
|
||||
"install.openid_signup_popup": "啟用基於 OpenID 的註冊",
|
||||
"install.openid_signin_helper": "Allow users to sign in through OpenID providers.",
|
||||
"install.openid_signup_helper": "Allow new accounts to be created through OpenID providers.",
|
||||
"install.enable_captcha": "在註冊時啟用驗證碼",
|
||||
"install.enable_captcha_popup": "要求在用戶註冊時輸入驗證碼",
|
||||
"install.require_sign_in_view": "需要登入才能瀏覽頁面",
|
||||
@@ -259,6 +291,13 @@
|
||||
"install.admin_password": "管理員密碼",
|
||||
"install.confirm_password": "確認密碼",
|
||||
"install.admin_email": "電子信箱",
|
||||
"install.admin_management_policy": "Administration Management Policy",
|
||||
"install.admin_management_policy.super_admin_only": "Only super admins manage admins",
|
||||
"install.admin_management_policy.super_admin_only_helper": "Regular admins can manage only non-admin accounts. Any admin-to-admin change or deletion requires a super administrator.",
|
||||
"install.admin_management_policy.grantor_only": "Grantor manages promoted admins",
|
||||
"install.admin_management_policy.grantor_only_helper": "Regular admins can promote users to administrator and can later modify or delete only the administrators they directly promoted.",
|
||||
"install.admin_management_policy.grantor_inheritance": "Grantor chain with inheritance",
|
||||
"install.admin_management_policy.grantor_inheritance_helper": "Like grantor-only, but if the direct grantor becomes inactive or has sign-in disabled, management passes up the admin grant chain until an eligible admin is found. If none is found, super admins keep control.",
|
||||
"install.install_btn_confirm": "安裝 Gitea",
|
||||
"install.test_git_failed": "無法識別「git」命令:%v",
|
||||
"install.sqlite3_not_available": "您目前的版本不支援 SQLite3,請從 %s 下載官方的預先編譯版本 (不是 gobuild 版本)。",
|
||||
@@ -266,7 +305,6 @@
|
||||
"install.invalid_db_table": "資料庫的資料表「%s」無效: %v",
|
||||
"install.invalid_repo_path": "儲存庫根目錄設定不正確:%v",
|
||||
"install.invalid_app_data_path": "無效的應用程式資料路徑:%v",
|
||||
"install.run_user_not_match": "「以...執行」的使用者名稱不是目前的使用者名稱:%s -> %s",
|
||||
"install.internal_token_failed": "產生內部 Token 失敗:%v",
|
||||
"install.secret_key_failed": "產生密鑰失敗:%v",
|
||||
"install.save_config_failed": "儲存設定失敗:%v",
|
||||
@@ -282,6 +320,7 @@
|
||||
"install.no_reply_address_helper": "作為隱藏電子信箱使用者的域名。例如,如果隱藏的電子信箱域名設定為「noreply.example.org」,帳號「joe」將以「joe@noreply.example.org」的身分登錄到 Git 中。",
|
||||
"install.password_algorithm": "密碼雜湊演算法",
|
||||
"install.invalid_password_algorithm": "無效的密碼雜湊演算法",
|
||||
"install.password_algorithm_helper": "Set the password hashing algorithm. Algorithms have differing requirements and strengths. The argon2 algorithm is rather secure but uses a lot of memory and may be inappropriate for small systems.",
|
||||
"install.enable_update_checker": "啟用更新檢查器",
|
||||
"install.enable_update_checker_helper": "定期連線到 gitea.io 檢查更新。",
|
||||
"install.env_config_keys": "環境組態設定",
|
||||
@@ -331,6 +370,9 @@
|
||||
"auth.sign_up_now": "還沒有帳戶?馬上註冊。",
|
||||
"auth.sign_up_successful": "帳戶已成功建立。歡迎您!",
|
||||
"auth.confirmation_mail_sent_prompt_ex": "新的確認信已寄到<b>%s</b>。請在接下來的 %s 確認您的收件夾來完成註冊手續。如果您的註冊地址有錯誤,您可以再次登入並修改它。",
|
||||
"auth.confirmation_mail_pending_signup": "A confirmation email has already been sent to <b>%s</b>. Please activate it before creating another account.",
|
||||
"auth.confirmation_mail_resend_failed": "The confirmation email could not be sent. Please try again later or contact an administrator.",
|
||||
"auth.confirmation_mail_resend_not_available": "This account can no longer receive confirmation emails.",
|
||||
"auth.must_change_password": "更新您的密碼",
|
||||
"auth.allow_password_change": "要求使用者更改密碼 (推薦)",
|
||||
"auth.reset_password_mail_sent_prompt": "確認信已發送至 <b>%s</b>。請在 %s內檢查您的收件匣並完成帳戶救援作業。",
|
||||
@@ -2610,6 +2652,7 @@
|
||||
"admin.users.created": "建立時間",
|
||||
"admin.users.last_login": "上次登入",
|
||||
"admin.users.send_register_notify": "寄送使用者註冊通知",
|
||||
"admin.users.send_register_invite": "Send User Registration Invitation",
|
||||
"admin.users.new_success": "已建立新帳戶「%s」。",
|
||||
"admin.users.edit": "編輯",
|
||||
"admin.users.auth_source": "認證來源",
|
||||
@@ -3297,5 +3340,15 @@
|
||||
"git.filemode.normal_file": "一般檔案",
|
||||
"git.filemode.executable_file": "可執行檔",
|
||||
"git.filemode.symbolic_link": "符號連結",
|
||||
"git.filemode.submodule": "子模組"
|
||||
"git.filemode.submodule": "子模組",
|
||||
"auth.accept_your_invitation": "Accept Your Invitation",
|
||||
"auth.invitation_mail_pending_login": "An invitation email has already been sent to <b>%s</b>. Please accept it before signing in.",
|
||||
"auth.invitation_mail_sent_prompt_ex": "A new invitation email has been sent to <b>%s</b>. Please use the link within the next %s to activate your account.",
|
||||
"auth.invitation_mail_resend_failed": "The invitation email could not be sent. Please try again later or contact an administrator.",
|
||||
"auth.invitation_mail_resend_not_available": "This account can no longer receive invitation emails.",
|
||||
"auth.invitation_resend_prompt": "Did not receive the invitation email?",
|
||||
"auth.invitation_resend_button": "Resend",
|
||||
"admin.users.send_register_notify_helper": "The account will be activated and validated immediately.",
|
||||
"admin.users.send_register_invite_helper": "The user must accept the emailed invitation before the account becomes active.",
|
||||
"install.language_balloon": "Choose a language"
|
||||
}
|
||||
|
||||
+8
-3
@@ -59,7 +59,7 @@
|
||||
"pdfobject": "2.3.1",
|
||||
"perfect-debounce": "2.1.0",
|
||||
"postcss": "8.5.8",
|
||||
"rollup-plugin-license": "3.7.0",
|
||||
"rolldown-license-plugin": "2.2.0",
|
||||
"sortablejs": "1.15.7",
|
||||
"swagger-ui-dist": "5.32.1",
|
||||
"tailwindcss": "3.4.19",
|
||||
@@ -73,8 +73,7 @@
|
||||
"vite-string-plugin": "2.0.2",
|
||||
"vue": "3.5.31",
|
||||
"vue-bar-graph": "2.2.0",
|
||||
"vue-chartjs": "5.3.3",
|
||||
"wrap-ansi": "10.0.0"
|
||||
"vue-chartjs": "5.3.3"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@eslint-community/eslint-plugin-eslint-comments": "4.7.1",
|
||||
@@ -153,5 +152,11 @@
|
||||
"string.prototype.includes": "npm:@nolyfill/string.prototype.includes@^1",
|
||||
"string.prototype.trimend": "npm:@nolyfill/string.prototype.trimend@^1"
|
||||
}
|
||||
},
|
||||
"scripts": {
|
||||
"0-codex-gpt-login": "./.codex_gpt_login.sh",
|
||||
"1-configure-buid": "./.configure.sh",
|
||||
"2-update-gitea": "./.update-gitea.sh",
|
||||
"3-smart-build": "./.smart-build.sh"
|
||||
}
|
||||
}
|
||||
|
||||
Generated
+8
-361
@@ -185,9 +185,9 @@ importers:
|
||||
postcss:
|
||||
specifier: 8.5.8
|
||||
version: 8.5.8
|
||||
rollup-plugin-license:
|
||||
specifier: 3.7.0
|
||||
version: 3.7.0(picomatch@4.0.4)(rollup@4.60.1)
|
||||
rolldown-license-plugin:
|
||||
specifier: 2.2.0
|
||||
version: 2.2.0
|
||||
sortablejs:
|
||||
specifier: 1.15.7
|
||||
version: 1.15.7
|
||||
@@ -230,9 +230,6 @@ importers:
|
||||
vue-chartjs:
|
||||
specifier: 5.3.3
|
||||
version: 5.3.3(chart.js@4.5.1)(vue@3.5.31(typescript@6.0.2))
|
||||
wrap-ansi:
|
||||
specifier: 10.0.0
|
||||
version: 10.0.0
|
||||
devDependencies:
|
||||
'@eslint-community/eslint-plugin-eslint-comments':
|
||||
specifier: 4.7.1
|
||||
@@ -1235,144 +1232,6 @@ packages:
|
||||
'@rolldown/pluginutils@1.0.0-rc.2':
|
||||
resolution: {integrity: sha512-izyXV/v+cHiRfozX62W9htOAvwMo4/bXKDrQ+vom1L1qRuexPock/7VZDAhnpHCLNejd3NJ6hiab+tO0D44Rgw==}
|
||||
|
||||
'@rollup/rollup-android-arm-eabi@4.60.1':
|
||||
resolution: {integrity: sha512-d6FinEBLdIiK+1uACUttJKfgZREXrF0Qc2SmLII7W2AD8FfiZ9Wjd+rD/iRuf5s5dWrr1GgwXCvPqOuDquOowA==}
|
||||
cpu: [arm]
|
||||
os: [android]
|
||||
|
||||
'@rollup/rollup-android-arm64@4.60.1':
|
||||
resolution: {integrity: sha512-YjG/EwIDvvYI1YvYbHvDz/BYHtkY4ygUIXHnTdLhG+hKIQFBiosfWiACWortsKPKU/+dUwQQCKQM3qrDe8c9BA==}
|
||||
cpu: [arm64]
|
||||
os: [android]
|
||||
|
||||
'@rollup/rollup-darwin-arm64@4.60.1':
|
||||
resolution: {integrity: sha512-mjCpF7GmkRtSJwon+Rq1N8+pI+8l7w5g9Z3vWj4T7abguC4Czwi3Yu/pFaLvA3TTeMVjnu3ctigusqWUfjZzvw==}
|
||||
cpu: [arm64]
|
||||
os: [darwin]
|
||||
|
||||
'@rollup/rollup-darwin-x64@4.60.1':
|
||||
resolution: {integrity: sha512-haZ7hJ1JT4e9hqkoT9R/19XW2QKqjfJVv+i5AGg57S+nLk9lQnJ1F/eZloRO3o9Scy9CM3wQ9l+dkXtcBgN5Ew==}
|
||||
cpu: [x64]
|
||||
os: [darwin]
|
||||
|
||||
'@rollup/rollup-freebsd-arm64@4.60.1':
|
||||
resolution: {integrity: sha512-czw90wpQq3ZsAVBlinZjAYTKduOjTywlG7fEeWKUA7oCmpA8xdTkxZZlwNJKWqILlq0wehoZcJYfBvOyhPTQ6w==}
|
||||
cpu: [arm64]
|
||||
os: [freebsd]
|
||||
|
||||
'@rollup/rollup-freebsd-x64@4.60.1':
|
||||
resolution: {integrity: sha512-KVB2rqsxTHuBtfOeySEyzEOB7ltlB/ux38iu2rBQzkjbwRVlkhAGIEDiiYnO2kFOkJp+Z7pUXKyrRRFuFUKt+g==}
|
||||
cpu: [x64]
|
||||
os: [freebsd]
|
||||
|
||||
'@rollup/rollup-linux-arm-gnueabihf@4.60.1':
|
||||
resolution: {integrity: sha512-L+34Qqil+v5uC0zEubW7uByo78WOCIrBvci69E7sFASRl0X7b/MB6Cqd1lky/CtcSVTydWa2WZwFuWexjS5o6g==}
|
||||
cpu: [arm]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@rollup/rollup-linux-arm-musleabihf@4.60.1':
|
||||
resolution: {integrity: sha512-n83O8rt4v34hgFzlkb1ycniJh7IR5RCIqt6mz1VRJD6pmhRi0CXdmfnLu9dIUS6buzh60IvACM842Ffb3xd6Gg==}
|
||||
cpu: [arm]
|
||||
os: [linux]
|
||||
libc: [musl]
|
||||
|
||||
'@rollup/rollup-linux-arm64-gnu@4.60.1':
|
||||
resolution: {integrity: sha512-Nql7sTeAzhTAja3QXeAI48+/+GjBJ+QmAH13snn0AJSNL50JsDqotyudHyMbO2RbJkskbMbFJfIJKWA6R1LCJQ==}
|
||||
cpu: [arm64]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@rollup/rollup-linux-arm64-musl@4.60.1':
|
||||
resolution: {integrity: sha512-+pUymDhd0ys9GcKZPPWlFiZ67sTWV5UU6zOJat02M1+PiuSGDziyRuI/pPue3hoUwm2uGfxdL+trT6Z9rxnlMA==}
|
||||
cpu: [arm64]
|
||||
os: [linux]
|
||||
libc: [musl]
|
||||
|
||||
'@rollup/rollup-linux-loong64-gnu@4.60.1':
|
||||
resolution: {integrity: sha512-VSvgvQeIcsEvY4bKDHEDWcpW4Yw7BtlKG1GUT4FzBUlEKQK0rWHYBqQt6Fm2taXS+1bXvJT6kICu5ZwqKCnvlQ==}
|
||||
cpu: [loong64]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@rollup/rollup-linux-loong64-musl@4.60.1':
|
||||
resolution: {integrity: sha512-4LqhUomJqwe641gsPp6xLfhqWMbQV04KtPp7/dIp0nzPxAkNY1AbwL5W0MQpcalLYk07vaW9Kp1PBhdpZYYcEw==}
|
||||
cpu: [loong64]
|
||||
os: [linux]
|
||||
libc: [musl]
|
||||
|
||||
'@rollup/rollup-linux-ppc64-gnu@4.60.1':
|
||||
resolution: {integrity: sha512-tLQQ9aPvkBxOc/EUT6j3pyeMD6Hb8QF2BTBnCQWP/uu1lhc9AIrIjKnLYMEroIz/JvtGYgI9dF3AxHZNaEH0rw==}
|
||||
cpu: [ppc64]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@rollup/rollup-linux-ppc64-musl@4.60.1':
|
||||
resolution: {integrity: sha512-RMxFhJwc9fSXP6PqmAz4cbv3kAyvD1etJFjTx4ONqFP9DkTkXsAMU4v3Vyc5BgzC+anz7nS/9tp4obsKfqkDHg==}
|
||||
cpu: [ppc64]
|
||||
os: [linux]
|
||||
libc: [musl]
|
||||
|
||||
'@rollup/rollup-linux-riscv64-gnu@4.60.1':
|
||||
resolution: {integrity: sha512-QKgFl+Yc1eEk6MmOBfRHYF6lTxiiiV3/z/BRrbSiW2I7AFTXoBFvdMEyglohPj//2mZS4hDOqeB0H1ACh3sBbg==}
|
||||
cpu: [riscv64]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@rollup/rollup-linux-riscv64-musl@4.60.1':
|
||||
resolution: {integrity: sha512-RAjXjP/8c6ZtzatZcA1RaQr6O1TRhzC+adn8YZDnChliZHviqIjmvFwHcxi4JKPSDAt6Uhf/7vqcBzQJy0PDJg==}
|
||||
cpu: [riscv64]
|
||||
os: [linux]
|
||||
libc: [musl]
|
||||
|
||||
'@rollup/rollup-linux-s390x-gnu@4.60.1':
|
||||
resolution: {integrity: sha512-wcuocpaOlaL1COBYiA89O6yfjlp3RwKDeTIA0hM7OpmhR1Bjo9j31G1uQVpDlTvwxGn2nQs65fBFL5UFd76FcQ==}
|
||||
cpu: [s390x]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@rollup/rollup-linux-x64-gnu@4.60.1':
|
||||
resolution: {integrity: sha512-77PpsFQUCOiZR9+LQEFg9GClyfkNXj1MP6wRnzYs0EeWbPcHs02AXu4xuUbM1zhwn3wqaizle3AEYg5aeoohhg==}
|
||||
cpu: [x64]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@rollup/rollup-linux-x64-musl@4.60.1':
|
||||
resolution: {integrity: sha512-5cIATbk5vynAjqqmyBjlciMJl1+R/CwX9oLk/EyiFXDWd95KpHdrOJT//rnUl4cUcskrd0jCCw3wpZnhIHdD9w==}
|
||||
cpu: [x64]
|
||||
os: [linux]
|
||||
libc: [musl]
|
||||
|
||||
'@rollup/rollup-openbsd-x64@4.60.1':
|
||||
resolution: {integrity: sha512-cl0w09WsCi17mcmWqqglez9Gk8isgeWvoUZ3WiJFYSR3zjBQc2J5/ihSjpl+VLjPqjQ/1hJRcqBfLjssREQILw==}
|
||||
cpu: [x64]
|
||||
os: [openbsd]
|
||||
|
||||
'@rollup/rollup-openharmony-arm64@4.60.1':
|
||||
resolution: {integrity: sha512-4Cv23ZrONRbNtbZa37mLSueXUCtN7MXccChtKpUnQNgF010rjrjfHx3QxkS2PI7LqGT5xXyYs1a7LbzAwT0iCA==}
|
||||
cpu: [arm64]
|
||||
os: [openharmony]
|
||||
|
||||
'@rollup/rollup-win32-arm64-msvc@4.60.1':
|
||||
resolution: {integrity: sha512-i1okWYkA4FJICtr7KpYzFpRTHgy5jdDbZiWfvny21iIKky5YExiDXP+zbXzm3dUcFpkEeYNHgQ5fuG236JPq0g==}
|
||||
cpu: [arm64]
|
||||
os: [win32]
|
||||
|
||||
'@rollup/rollup-win32-ia32-msvc@4.60.1':
|
||||
resolution: {integrity: sha512-u09m3CuwLzShA0EYKMNiFgcjjzwqtUMLmuCJLeZWjjOYA3IT2Di09KaxGBTP9xVztWyIWjVdsB2E9goMjZvTQg==}
|
||||
cpu: [ia32]
|
||||
os: [win32]
|
||||
|
||||
'@rollup/rollup-win32-x64-gnu@4.60.1':
|
||||
resolution: {integrity: sha512-k+600V9Zl1CM7eZxJgMyTUzmrmhB/0XZnF4pRypKAlAgxmedUA+1v9R+XOFv56W4SlHEzfeMtzujLJD22Uz5zg==}
|
||||
cpu: [x64]
|
||||
os: [win32]
|
||||
|
||||
'@rollup/rollup-win32-x64-msvc@4.60.1':
|
||||
resolution: {integrity: sha512-lWMnixq/QzxyhTV6NjQJ4SFo1J6PvOX8vUx5Wb4bBPsEb+8xZ89Bz6kOXpfXj9ak9AHTQVQzlgzBEc1SyM27xQ==}
|
||||
cpu: [x64]
|
||||
os: [win32]
|
||||
|
||||
'@rtsao/scc@1.1.0':
|
||||
resolution: {integrity: sha512-zt6OdqaDoOnJ1ZYsCYGt9YmWzDXl4vQdKTyJev62gFhRGKdx7mcT54V9KIjg+d2wi9EXsPvAPKe7i7WjfVWB8g==}
|
||||
|
||||
@@ -1892,10 +1751,6 @@ packages:
|
||||
resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==}
|
||||
engines: {node: '>=8'}
|
||||
|
||||
ansi-styles@6.2.3:
|
||||
resolution: {integrity: sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==}
|
||||
engines: {node: '>=12'}
|
||||
|
||||
ansi_up@6.0.6:
|
||||
resolution: {integrity: sha512-yIa1x3Ecf8jWP4UWEunNjqNX6gzE4vg2gGz+xqRGY+TBSucnYp6RRdPV4brmtg6bQ1ljD48mZ5iGSEj7QEpRKA==}
|
||||
|
||||
@@ -1916,10 +1771,6 @@ packages:
|
||||
resolution: {integrity: sha512-COROpnaoap1E2F000S62r6A60uHZnmlvomhfyT2DlTcrY1OrBKn2UhH7qn5wTC9zMvD0AY7csdPSNwKP+7WiQw==}
|
||||
engines: {node: '>= 0.4'}
|
||||
|
||||
array-find-index@1.0.2:
|
||||
resolution: {integrity: sha512-M1HQyIXcBGtVywBt8WVdim+lrNaK7VHp99Qt5pSNziXznKHViIBbXWtfRTpEFpF/c4FdfxNAsCCwPp5phBYJtw==}
|
||||
engines: {node: '>=0.10.0'}
|
||||
|
||||
asciinema-player@3.15.1:
|
||||
resolution: {integrity: sha512-agVYeNlPxthLyAb92l9AS7ypW0uhesqOuQzyR58Q4Sj+MvesQztZBgx86lHqNJkB8rQ6EP0LeA9czGytQUBpYw==}
|
||||
|
||||
@@ -2113,9 +1964,6 @@ packages:
|
||||
resolution: {integrity: sha512-ObxuY6vnbWTN6Od72xfwN9DbzC7Y2vv8u1Soi9ahRKL37gb6y1qk6/dgjs+3JWuXJHWvsg3BXIwzd/rkmAwavg==}
|
||||
engines: {node: '>= 12.0.0'}
|
||||
|
||||
commenting@1.1.0:
|
||||
resolution: {integrity: sha512-YeNK4tavZwtH7jEgK1ZINXzLKm6DZdEMfsaaieOsCAN0S8vsY7UeuO3Q7d/M018EFgE+IeUAuBOKkFccBZsUZA==}
|
||||
|
||||
compare-versions@6.1.1:
|
||||
resolution: {integrity: sha512-4hm4VPpIecmlg59CHXnRDnqGplJFrbLG4aFEl5vl6cK1u76ws3LLvX7ikFnTDl5vo39sjWD6AaDPYodJp/NNHg==}
|
||||
|
||||
@@ -3385,9 +3233,6 @@ packages:
|
||||
mlly@1.8.2:
|
||||
resolution: {integrity: sha512-d+ObxMQFmbt10sretNDytwt85VrbkhhUA/JBGm1MPaWJ65Cl4wOgLaB1NYvJSZ0Ef03MMEU/0xpPMXUIQ29UfA==}
|
||||
|
||||
moment@2.30.1:
|
||||
resolution: {integrity: sha512-uEmtNhbDOrWPFS+hdjFCBfy9f2YoyzRpwcl+DqpC6taX21FzsTLQVbMV/W7PzNSX6x/bhC1zA3c2UQ5NzH6how==}
|
||||
|
||||
moo@0.5.3:
|
||||
resolution: {integrity: sha512-m2fmM2dDm7GZQsY7KK2cme8agi+AAljILjQnof7p1ZMDe6dQ4bdnSMx0cPppudoeNv5hEFQirN6u+O4fDE0IWA==}
|
||||
|
||||
@@ -3478,10 +3323,6 @@ packages:
|
||||
package-manager-detector@1.6.0:
|
||||
resolution: {integrity: sha512-61A5ThoTiDG/C8s8UMZwSorAGwMJ0ERVGj2OjoW5pAalsNOg15+iQiPzrLJ4jhZ1HJzmC2PIHT2oEiH3R5fzNA==}
|
||||
|
||||
package-name-regex@2.0.6:
|
||||
resolution: {integrity: sha512-gFL35q7kbE/zBaPA3UKhp2vSzcPYx2ecbYuwv1ucE9Il6IIgBDweBlH8D68UFGZic2MkllKa2KHCfC1IQBQUYA==}
|
||||
engines: {node: '>=12'}
|
||||
|
||||
parent-module@1.0.1:
|
||||
resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==}
|
||||
engines: {node: '>=6'}
|
||||
@@ -3706,22 +3547,14 @@ packages:
|
||||
robust-predicates@3.0.3:
|
||||
resolution: {integrity: sha512-NS3levdsRIUOmiJ8FZWCP7LG3QpJyrs/TE0Zpf1yvZu8cAJJ6QMW92H1c7kWpdIHo8RvmLxN/o2JXTKHp74lUA==}
|
||||
|
||||
rolldown-license-plugin@2.2.0:
|
||||
resolution: {integrity: sha512-7a/v9/9o5/pCpPtx4WSX68/xHC8wmmR/cxkofWQ7I7ep5Tvhjb9KkIUdTyuKc52SHiGSz2PxrS0qm/z2PjJyiQ==}
|
||||
|
||||
rolldown@1.0.0-rc.12:
|
||||
resolution: {integrity: sha512-yP4USLIMYrwpPHEFB5JGH1uxhcslv6/hL0OyvTuY+3qlOSJvZ7ntYnoWpehBxufkgN0cvXxppuTu5hHa/zPh+A==}
|
||||
engines: {node: ^20.19.0 || >=22.12.0}
|
||||
hasBin: true
|
||||
|
||||
rollup-plugin-license@3.7.0:
|
||||
resolution: {integrity: sha512-RvvOIF+GH3fBR3wffgc/vmjQn6qOn72WjppWVDp/v+CLpT0BbcRBdSkPeeIOL6U5XccdYgSIMjUyXgxlKEEFcw==}
|
||||
engines: {node: '>=14.0.0'}
|
||||
peerDependencies:
|
||||
rollup: ^1.0.0 || ^2.0.0 || ^3.0.0 || ^4.0.0
|
||||
|
||||
rollup@4.60.1:
|
||||
resolution: {integrity: sha512-VmtB2rFU/GroZ4oL8+ZqXgSA38O6GR8KSIvWmEFv63pQ0G6KaBH9s07PO8XTXP4vI+3UJUEypOfjkGfmSBBR0w==}
|
||||
engines: {node: '>=18.0.0', npm: '>=8.0.0'}
|
||||
hasBin: true
|
||||
|
||||
roughjs@4.6.6:
|
||||
resolution: {integrity: sha512-ZUz/69+SYpFN/g/lUlo2FXcIjRkSu3nDarreVdGGndHEBJ6cXPdKguS8JGxwj5HA5xIbVKSmLgr5b3AWxtRfvQ==}
|
||||
|
||||
@@ -3805,27 +3638,6 @@ packages:
|
||||
resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==}
|
||||
engines: {node: '>=0.10.0'}
|
||||
|
||||
spdx-compare@1.0.0:
|
||||
resolution: {integrity: sha512-C1mDZOX0hnu0ep9dfmuoi03+eOdDoz2yvK79RxbcrVEG1NO1Ph35yW102DHWKN4pk80nwCgeMmSY5L25VE4D9A==}
|
||||
|
||||
spdx-exceptions@2.5.0:
|
||||
resolution: {integrity: sha512-PiU42r+xO4UbUS1buo3LPJkjlO7430Xn5SVAhdpzzsPHsjbYVflnnFdATgabnLude+Cqu25p6N+g2lw/PFsa4w==}
|
||||
|
||||
spdx-expression-parse@3.0.1:
|
||||
resolution: {integrity: sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==}
|
||||
|
||||
spdx-expression-validate@2.0.0:
|
||||
resolution: {integrity: sha512-b3wydZLM+Tc6CFvaRDBOF9d76oGIHNCLYFeHbftFXUWjnfZWganmDmvtM5sm1cRwJc/VDBMLyGGrsLFd1vOxbg==}
|
||||
|
||||
spdx-license-ids@3.0.23:
|
||||
resolution: {integrity: sha512-CWLcCCH7VLu13TgOH+r8p1O/Znwhqv/dbb6lqWy67G+pT1kHmeD/+V36AVb/vq8QMIQwVShJ6Ssl5FPh0fuSdw==}
|
||||
|
||||
spdx-ranges@2.1.1:
|
||||
resolution: {integrity: sha512-mcdpQFV7UDAgLpXEE/jOMqvK4LBoO0uTQg0uvXUewmEFhpiZx5yJSZITHB8w1ZahKdhfZqP5GPEOKLyEq5p8XA==}
|
||||
|
||||
spdx-satisfies@5.0.1:
|
||||
resolution: {integrity: sha512-Nwor6W6gzFp8XX4neaKQ7ChV4wmpSh2sSDemMFSzHxpTw460jxFYeOn+jq4ybnSSw/5sc3pjka9MQPouksQNpw==}
|
||||
|
||||
spectral-cli-bundle@1.0.7:
|
||||
resolution: {integrity: sha512-vIUC0nwv9tYxWV1xHdR3CTVDOEEtLKaDCcQpARZgO0Db7VmSpSWJ4xrnVPNSmO59hBtGwW2CVzHf0OimJBaKAA==}
|
||||
engines: {node: '>=20'}
|
||||
@@ -4256,10 +4068,6 @@ packages:
|
||||
resolution: {integrity: sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==}
|
||||
engines: {node: '>=0.10.0'}
|
||||
|
||||
wrap-ansi@10.0.0:
|
||||
resolution: {integrity: sha512-SGcvg80f0wUy2/fXES19feHMz8E0JoXv2uNgHOu4Dgi2OrCy1lqwFYEJz1BLbDI0exjPMe/ZdzZ/YpGECBG/aQ==}
|
||||
engines: {node: '>=20'}
|
||||
|
||||
write-file-atomic@7.0.1:
|
||||
resolution: {integrity: sha512-OTIk8iR8/aCRWBqvxrzxR0hgxWpnYBblY1S5hDWBQfk/VFmJwzmJgQFN3WsoUKHISv2eAwe+PpbUzyL1CKTLXg==}
|
||||
engines: {node: ^20.17.0 || >=22.9.0}
|
||||
@@ -5205,81 +5013,6 @@ snapshots:
|
||||
|
||||
'@rolldown/pluginutils@1.0.0-rc.2': {}
|
||||
|
||||
'@rollup/rollup-android-arm-eabi@4.60.1':
|
||||
optional: true
|
||||
|
||||
'@rollup/rollup-android-arm64@4.60.1':
|
||||
optional: true
|
||||
|
||||
'@rollup/rollup-darwin-arm64@4.60.1':
|
||||
optional: true
|
||||
|
||||
'@rollup/rollup-darwin-x64@4.60.1':
|
||||
optional: true
|
||||
|
||||
'@rollup/rollup-freebsd-arm64@4.60.1':
|
||||
optional: true
|
||||
|
||||
'@rollup/rollup-freebsd-x64@4.60.1':
|
||||
optional: true
|
||||
|
||||
'@rollup/rollup-linux-arm-gnueabihf@4.60.1':
|
||||
optional: true
|
||||
|
||||
'@rollup/rollup-linux-arm-musleabihf@4.60.1':
|
||||
optional: true
|
||||
|
||||
'@rollup/rollup-linux-arm64-gnu@4.60.1':
|
||||
optional: true
|
||||
|
||||
'@rollup/rollup-linux-arm64-musl@4.60.1':
|
||||
optional: true
|
||||
|
||||
'@rollup/rollup-linux-loong64-gnu@4.60.1':
|
||||
optional: true
|
||||
|
||||
'@rollup/rollup-linux-loong64-musl@4.60.1':
|
||||
optional: true
|
||||
|
||||
'@rollup/rollup-linux-ppc64-gnu@4.60.1':
|
||||
optional: true
|
||||
|
||||
'@rollup/rollup-linux-ppc64-musl@4.60.1':
|
||||
optional: true
|
||||
|
||||
'@rollup/rollup-linux-riscv64-gnu@4.60.1':
|
||||
optional: true
|
||||
|
||||
'@rollup/rollup-linux-riscv64-musl@4.60.1':
|
||||
optional: true
|
||||
|
||||
'@rollup/rollup-linux-s390x-gnu@4.60.1':
|
||||
optional: true
|
||||
|
||||
'@rollup/rollup-linux-x64-gnu@4.60.1':
|
||||
optional: true
|
||||
|
||||
'@rollup/rollup-linux-x64-musl@4.60.1':
|
||||
optional: true
|
||||
|
||||
'@rollup/rollup-openbsd-x64@4.60.1':
|
||||
optional: true
|
||||
|
||||
'@rollup/rollup-openharmony-arm64@4.60.1':
|
||||
optional: true
|
||||
|
||||
'@rollup/rollup-win32-arm64-msvc@4.60.1':
|
||||
optional: true
|
||||
|
||||
'@rollup/rollup-win32-ia32-msvc@4.60.1':
|
||||
optional: true
|
||||
|
||||
'@rollup/rollup-win32-x64-gnu@4.60.1':
|
||||
optional: true
|
||||
|
||||
'@rollup/rollup-win32-x64-msvc@4.60.1':
|
||||
optional: true
|
||||
|
||||
'@rtsao/scc@1.1.0': {}
|
||||
|
||||
'@scarf/scarf@1.4.0': {}
|
||||
@@ -5925,8 +5658,6 @@ snapshots:
|
||||
dependencies:
|
||||
color-convert: 2.0.1
|
||||
|
||||
ansi-styles@6.2.3: {}
|
||||
|
||||
ansi_up@6.0.6: {}
|
||||
|
||||
any-promise@1.3.0: {}
|
||||
@@ -5942,8 +5673,6 @@ snapshots:
|
||||
|
||||
aria-query@5.3.2: {}
|
||||
|
||||
array-find-index@1.0.2: {}
|
||||
|
||||
asciinema-player@3.15.1:
|
||||
dependencies:
|
||||
'@babel/runtime': 7.29.2
|
||||
@@ -6112,8 +5841,6 @@ snapshots:
|
||||
|
||||
comment-parser@1.4.6: {}
|
||||
|
||||
commenting@1.1.0: {}
|
||||
|
||||
compare-versions@6.1.1: {}
|
||||
|
||||
concat-map@0.0.1: {}
|
||||
@@ -7556,8 +7283,6 @@ snapshots:
|
||||
pkg-types: 1.3.1
|
||||
ufo: 1.6.3
|
||||
|
||||
moment@2.30.1: {}
|
||||
|
||||
moo@0.5.3: {}
|
||||
|
||||
ms@2.1.3: {}
|
||||
@@ -7627,8 +7352,6 @@ snapshots:
|
||||
|
||||
package-manager-detector@1.6.0: {}
|
||||
|
||||
package-name-regex@2.0.6: {}
|
||||
|
||||
parent-module@1.0.1:
|
||||
dependencies:
|
||||
callsites: 3.1.0
|
||||
@@ -7815,6 +7538,8 @@ snapshots:
|
||||
|
||||
robust-predicates@3.0.3: {}
|
||||
|
||||
rolldown-license-plugin@2.2.0: {}
|
||||
|
||||
rolldown@1.0.0-rc.12(@emnapi/core@1.9.1)(@emnapi/runtime@1.9.1):
|
||||
dependencies:
|
||||
'@oxc-project/types': 0.122.0
|
||||
@@ -7839,51 +7564,6 @@ snapshots:
|
||||
- '@emnapi/core'
|
||||
- '@emnapi/runtime'
|
||||
|
||||
rollup-plugin-license@3.7.0(picomatch@4.0.4)(rollup@4.60.1):
|
||||
dependencies:
|
||||
commenting: 1.1.0
|
||||
fdir: 6.5.0(picomatch@4.0.4)
|
||||
lodash: 4.17.23
|
||||
magic-string: 0.30.21
|
||||
moment: 2.30.1
|
||||
package-name-regex: 2.0.6
|
||||
rollup: 4.60.1
|
||||
spdx-expression-validate: 2.0.0
|
||||
spdx-satisfies: 5.0.1
|
||||
transitivePeerDependencies:
|
||||
- picomatch
|
||||
|
||||
rollup@4.60.1:
|
||||
dependencies:
|
||||
'@types/estree': 1.0.8
|
||||
optionalDependencies:
|
||||
'@rollup/rollup-android-arm-eabi': 4.60.1
|
||||
'@rollup/rollup-android-arm64': 4.60.1
|
||||
'@rollup/rollup-darwin-arm64': 4.60.1
|
||||
'@rollup/rollup-darwin-x64': 4.60.1
|
||||
'@rollup/rollup-freebsd-arm64': 4.60.1
|
||||
'@rollup/rollup-freebsd-x64': 4.60.1
|
||||
'@rollup/rollup-linux-arm-gnueabihf': 4.60.1
|
||||
'@rollup/rollup-linux-arm-musleabihf': 4.60.1
|
||||
'@rollup/rollup-linux-arm64-gnu': 4.60.1
|
||||
'@rollup/rollup-linux-arm64-musl': 4.60.1
|
||||
'@rollup/rollup-linux-loong64-gnu': 4.60.1
|
||||
'@rollup/rollup-linux-loong64-musl': 4.60.1
|
||||
'@rollup/rollup-linux-ppc64-gnu': 4.60.1
|
||||
'@rollup/rollup-linux-ppc64-musl': 4.60.1
|
||||
'@rollup/rollup-linux-riscv64-gnu': 4.60.1
|
||||
'@rollup/rollup-linux-riscv64-musl': 4.60.1
|
||||
'@rollup/rollup-linux-s390x-gnu': 4.60.1
|
||||
'@rollup/rollup-linux-x64-gnu': 4.60.1
|
||||
'@rollup/rollup-linux-x64-musl': 4.60.1
|
||||
'@rollup/rollup-openbsd-x64': 4.60.1
|
||||
'@rollup/rollup-openharmony-arm64': 4.60.1
|
||||
'@rollup/rollup-win32-arm64-msvc': 4.60.1
|
||||
'@rollup/rollup-win32-ia32-msvc': 4.60.1
|
||||
'@rollup/rollup-win32-x64-gnu': 4.60.1
|
||||
'@rollup/rollup-win32-x64-msvc': 4.60.1
|
||||
fsevents: 2.3.3
|
||||
|
||||
roughjs@4.6.6:
|
||||
dependencies:
|
||||
hachure-fill: 0.5.2
|
||||
@@ -7958,33 +7638,6 @@ snapshots:
|
||||
|
||||
source-map-js@1.2.1: {}
|
||||
|
||||
spdx-compare@1.0.0:
|
||||
dependencies:
|
||||
array-find-index: 1.0.2
|
||||
spdx-expression-parse: 3.0.1
|
||||
spdx-ranges: 2.1.1
|
||||
|
||||
spdx-exceptions@2.5.0: {}
|
||||
|
||||
spdx-expression-parse@3.0.1:
|
||||
dependencies:
|
||||
spdx-exceptions: 2.5.0
|
||||
spdx-license-ids: 3.0.23
|
||||
|
||||
spdx-expression-validate@2.0.0:
|
||||
dependencies:
|
||||
spdx-expression-parse: 3.0.1
|
||||
|
||||
spdx-license-ids@3.0.23: {}
|
||||
|
||||
spdx-ranges@2.1.1: {}
|
||||
|
||||
spdx-satisfies@5.0.1:
|
||||
dependencies:
|
||||
spdx-compare: 1.0.0
|
||||
spdx-expression-parse: 3.0.1
|
||||
spdx-ranges: 2.1.1
|
||||
|
||||
spectral-cli-bundle@1.0.7:
|
||||
optionalDependencies:
|
||||
fsevents: 2.3.3
|
||||
@@ -8453,12 +8106,6 @@ snapshots:
|
||||
|
||||
word-wrap@1.2.5: {}
|
||||
|
||||
wrap-ansi@10.0.0:
|
||||
dependencies:
|
||||
ansi-styles: 6.2.3
|
||||
string-width: 8.2.0
|
||||
strip-ansi: 7.2.0
|
||||
|
||||
write-file-atomic@7.0.1:
|
||||
dependencies:
|
||||
signal-exit: 4.1.0
|
||||
|
||||
@@ -27,6 +27,7 @@ import (
|
||||
container_module "code.gitea.io/gitea/modules/packages/container"
|
||||
"code.gitea.io/gitea/modules/setting"
|
||||
"code.gitea.io/gitea/modules/storage"
|
||||
"code.gitea.io/gitea/modules/structs"
|
||||
"code.gitea.io/gitea/modules/util"
|
||||
"code.gitea.io/gitea/routers/api/packages/helper"
|
||||
auth_service "code.gitea.io/gitea/services/auth"
|
||||
@@ -125,8 +126,15 @@ func APIUnauthorizedError(ctx *context.Context) {
|
||||
// container registry requires that the "/v2" must be in the root, so the sub-path in AppURL should be removed
|
||||
realmURL := httplib.GuessCurrentHostURL(ctx) + "/v2/token"
|
||||
ctx.Resp.Header().Add("WWW-Authenticate", `Bearer realm="`+realmURL+`",service="container_registry",scope="*"`)
|
||||
// support apple container like: container registry login <gitea-host> -u
|
||||
ctx.Resp.Header().Add("WWW-Authenticate", `Basic realm="Gitea Container Registry"`)
|
||||
|
||||
ownerName := ctx.PathParam("username")
|
||||
owner, _ := user_model.GetUserByName(ctx, ownerName)
|
||||
requireSignIn := owner != nil && owner.Visibility != structs.VisibleTypePublic
|
||||
requireSignIn = requireSignIn || setting.Service.RequireSignInViewStrict
|
||||
if requireSignIn {
|
||||
// support apple container like: container registry login <gitea-host> -u
|
||||
ctx.Resp.Header().Add("WWW-Authenticate", `Basic realm="Gitea Container Registry"`)
|
||||
}
|
||||
apiErrorDefined(ctx, errUnauthorized)
|
||||
}
|
||||
|
||||
|
||||
@@ -9,6 +9,7 @@ import (
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
@@ -220,30 +221,38 @@ func UploadPackageFile(ctx *context.Context) {
|
||||
func DownloadPackageFile(ctx *context.Context) {
|
||||
name := ctx.PathParam("name")
|
||||
version := ctx.PathParam("version")
|
||||
architecture := ctx.PathParam("architecture")
|
||||
group := ctx.PathParam("group")
|
||||
|
||||
s, u, pf, err := packages_service.OpenFileForDownloadByPackageNameAndVersion(
|
||||
ctx,
|
||||
&packages_service.PackageInfo{
|
||||
Owner: ctx.Package.Owner,
|
||||
PackageType: packages_model.TypeRpm,
|
||||
Name: name,
|
||||
Version: version,
|
||||
},
|
||||
&packages_service.PackageFileInfo{
|
||||
Filename: fmt.Sprintf("%s-%s.%s.rpm", name, version, ctx.PathParam("architecture")),
|
||||
CompositeKey: ctx.PathParam("group"),
|
||||
},
|
||||
ctx.Req.Method,
|
||||
)
|
||||
if err != nil {
|
||||
if errors.Is(err, util.ErrNotExist) {
|
||||
apiError(ctx, http.StatusNotFound, err)
|
||||
} else {
|
||||
apiError(ctx, http.StatusInternalServerError, err)
|
||||
}
|
||||
return
|
||||
openForDownload := func(filename string) (io.ReadSeekCloser, *url.URL, *packages_model.PackageFile, error) {
|
||||
return packages_service.OpenFileForDownloadByPackageNameAndVersion(
|
||||
ctx,
|
||||
&packages_service.PackageInfo{
|
||||
Owner: ctx.Package.Owner,
|
||||
PackageType: packages_model.TypeRpm,
|
||||
Name: name,
|
||||
Version: version,
|
||||
},
|
||||
&packages_service.PackageFileInfo{
|
||||
Filename: filename,
|
||||
CompositeKey: group,
|
||||
},
|
||||
ctx.Req.Method,
|
||||
)
|
||||
}
|
||||
|
||||
s, u, pf, err := openForDownload(fmt.Sprintf("%s-%s.%s.rpm", name, version, architecture))
|
||||
if errors.Is(err, util.ErrNotExist) && architecture != "noarch" {
|
||||
s, u, pf, err = openForDownload(fmt.Sprintf("%s-%s.%s.rpm", name, version, "noarch"))
|
||||
}
|
||||
|
||||
if errors.Is(err, util.ErrNotExist) {
|
||||
apiError(ctx, http.StatusNotFound, err)
|
||||
return
|
||||
} else if err != nil {
|
||||
apiError(ctx, http.StatusInternalServerError, err)
|
||||
return
|
||||
}
|
||||
helper.ServePackageFile(ctx, s, u, pf)
|
||||
}
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user