Merge remote-tracking branch 'upstream/main'
26
.drone.yml
|
@ -25,7 +25,7 @@ steps:
|
|||
- make deps-frontend
|
||||
|
||||
- name: deps-backend
|
||||
image: golang:1.18
|
||||
image: golang:1.19
|
||||
pull: always
|
||||
commands:
|
||||
- make deps-backend
|
||||
|
@ -88,7 +88,7 @@ steps:
|
|||
depends_on: [deps-frontend]
|
||||
|
||||
- name: checks-backend
|
||||
image: golang:1.18
|
||||
image: golang:1.19
|
||||
commands:
|
||||
- make checks-backend
|
||||
depends_on: [deps-backend]
|
||||
|
@ -122,7 +122,7 @@ steps:
|
|||
path: /go
|
||||
|
||||
- name: build-backend-arm64
|
||||
image: golang:1.18
|
||||
image: golang:1.19
|
||||
environment:
|
||||
GO111MODULE: on
|
||||
GOPROXY: https://goproxy.io
|
||||
|
@ -138,7 +138,7 @@ steps:
|
|||
path: /go
|
||||
|
||||
- name: build-backend-windows
|
||||
image: golang:1.18
|
||||
image: golang:1.19
|
||||
environment:
|
||||
GO111MODULE: on
|
||||
GOPROXY: https://goproxy.io
|
||||
|
@ -153,7 +153,7 @@ steps:
|
|||
path: /go
|
||||
|
||||
- name: build-backend-386
|
||||
image: golang:1.18
|
||||
image: golang:1.19
|
||||
environment:
|
||||
GO111MODULE: on
|
||||
GOPROXY: https://goproxy.io
|
||||
|
@ -243,7 +243,7 @@ steps:
|
|||
- pull_request
|
||||
|
||||
- name: deps-backend
|
||||
image: golang:1.18
|
||||
image: golang:1.19
|
||||
pull: always
|
||||
commands:
|
||||
- make deps-backend
|
||||
|
@ -360,7 +360,7 @@ steps:
|
|||
path: /go
|
||||
|
||||
- name: generate-coverage
|
||||
image: golang:1.18
|
||||
image: golang:1.19
|
||||
commands:
|
||||
- make coverage
|
||||
environment:
|
||||
|
@ -436,7 +436,7 @@ steps:
|
|||
- pull_request
|
||||
|
||||
- name: deps-backend
|
||||
image: golang:1.18
|
||||
image: golang:1.19
|
||||
pull: always
|
||||
commands:
|
||||
- make deps-backend
|
||||
|
@ -578,7 +578,7 @@ trigger:
|
|||
|
||||
steps:
|
||||
- name: download
|
||||
image: golang:1.18
|
||||
image: golang:1.19
|
||||
pull: always
|
||||
commands:
|
||||
- timeout -s ABRT 40m make generate-license generate-gitignore
|
||||
|
@ -640,7 +640,7 @@ steps:
|
|||
- make deps-frontend
|
||||
|
||||
- name: deps-backend
|
||||
image: golang:1.18
|
||||
image: golang:1.19
|
||||
pull: always
|
||||
commands:
|
||||
- make deps-backend
|
||||
|
@ -649,7 +649,7 @@ steps:
|
|||
path: /go
|
||||
|
||||
- name: static
|
||||
image: techknowlogick/xgo:go-1.18.x
|
||||
image: techknowlogick/xgo:go-1.19.x
|
||||
pull: always
|
||||
commands:
|
||||
# Upgrade to node 18 once https://github.com/techknowlogick/xgo/issues/163 is resolved
|
||||
|
@ -760,7 +760,7 @@ steps:
|
|||
- make deps-frontend
|
||||
|
||||
- name: deps-backend
|
||||
image: golang:1.18
|
||||
image: golang:1.19
|
||||
pull: always
|
||||
commands:
|
||||
- make deps-backend
|
||||
|
@ -769,7 +769,7 @@ steps:
|
|||
path: /go
|
||||
|
||||
- name: static
|
||||
image: techknowlogick/xgo:go-1.18.x
|
||||
image: techknowlogick/xgo:go-1.19.x
|
||||
pull: always
|
||||
commands:
|
||||
# Upgrade to node 18 once https://github.com/techknowlogick/xgo/issues/163 is resolved
|
||||
|
|
|
@ -30,7 +30,7 @@ overrides:
|
|||
env:
|
||||
worker: true
|
||||
rules:
|
||||
no-restricted-globals: [2, addEventListener, blur, close, closed, confirm, defaultStatus, defaultstatus, error, event, external, find, focus, frameElement, frames, history, innerHeight, innerWidth, isFinite, isNaN, length, location, locationbar, menubar, moveBy, moveTo, name, onblur, onerror, onfocus, onload, onresize, onunload, open, opener, opera, outerHeight, outerWidth, pageXOffset, pageYOffset, parent, print, removeEventListener, resizeBy, resizeTo, screen, screenLeft, screenTop, screenX, screenY, scroll, scrollbars, scrollBy, scrollTo, scrollX, scrollY, status, statusbar, stop, toolbar, top]
|
||||
no-restricted-globals: [2, addEventListener, blur, close, closed, confirm, defaultStatus, defaultstatus, error, event, external, find, focus, frameElement, frames, history, innerHeight, innerWidth, isFinite, isNaN, length, locationbar, menubar, moveBy, moveTo, name, onblur, onerror, onfocus, onload, onresize, onunload, open, opener, opera, outerHeight, outerWidth, pageXOffset, pageYOffset, parent, print, removeEventListener, resizeBy, resizeTo, screen, screenLeft, screenTop, screenX, screenY, scroll, scrollbars, scrollBy, scrollTo, scrollX, scrollY, status, statusbar, stop, toolbar, top]
|
||||
- files: ["build/generate-images.js"]
|
||||
rules:
|
||||
import/no-unresolved: [0]
|
||||
|
@ -109,7 +109,7 @@ rules:
|
|||
import/no-extraneous-dependencies: [2]
|
||||
import/no-import-module-exports: [0]
|
||||
import/no-internal-modules: [0]
|
||||
import/no-mutable-exports: [2]
|
||||
import/no-mutable-exports: [0]
|
||||
import/no-named-as-default-member: [0]
|
||||
import/no-named-as-default: [2]
|
||||
import/no-named-default: [0]
|
||||
|
@ -121,7 +121,7 @@ rules:
|
|||
import/no-restricted-paths: [0]
|
||||
import/no-self-import: [2]
|
||||
import/no-unassigned-import: [0]
|
||||
import/no-unresolved: [2, {commonjs: true}]
|
||||
import/no-unresolved: [2, {commonjs: true, ignore: ["\\?.+$"]}]
|
||||
import/no-unused-modules: [2, {unusedExports: true}]
|
||||
import/no-useless-path-segments: [2, {commonjs: true}]
|
||||
import/no-webpack-loader-syntax: [2]
|
||||
|
@ -211,7 +211,7 @@ rules:
|
|||
no-compare-neg-zero: [2]
|
||||
no-cond-assign: [2, except-parens]
|
||||
no-confusing-arrow: [0]
|
||||
no-console: [1, {allow: [info, warn, error]}]
|
||||
no-console: [1, {allow: [debug, info, warn, error]}]
|
||||
no-const-assign: [2]
|
||||
no-constant-binary-expression: [2]
|
||||
no-constant-condition: [0]
|
||||
|
@ -287,7 +287,7 @@ rules:
|
|||
no-redeclare: [2]
|
||||
no-regex-spaces: [2]
|
||||
no-restricted-exports: [0]
|
||||
no-restricted-globals: [2, addEventListener, blur, close, closed, confirm, defaultStatus, defaultstatus, error, event, external, find, focus, frameElement, frames, history, innerHeight, innerWidth, isFinite, isNaN, length, location, locationbar, menubar, moveBy, moveTo, name, onblur, onerror, onfocus, onload, onresize, onunload, open, opener, opera, outerHeight, outerWidth, pageXOffset, pageYOffset, parent, print, removeEventListener, resizeBy, resizeTo, screen, screenLeft, screenTop, screenX, screenY, scroll, scrollbars, scrollBy, scrollTo, scrollX, scrollY, self, status, statusbar, stop, toolbar, top]
|
||||
no-restricted-globals: [2, addEventListener, blur, close, closed, confirm, defaultStatus, defaultstatus, error, event, external, find, focus, frameElement, frames, history, innerHeight, innerWidth, isFinite, isNaN, length, location, locationbar, menubar, moveBy, moveTo, name, onblur, onerror, onfocus, onload, onresize, onunload, open, opener, opera, outerHeight, outerWidth, pageXOffset, pageYOffset, parent, print, removeEventListener, resizeBy, resizeTo, screen, screenLeft, screenTop, screenX, screenY, scroll, scrollbars, scrollBy, scrollTo, scrollX, scrollY, self, status, statusbar, stop, toolbar, top, __dirname, __filename]
|
||||
no-restricted-imports: [0]
|
||||
no-restricted-syntax: [2, WithStatement, ForInStatement, LabeledStatement]
|
||||
no-return-assign: [0]
|
||||
|
@ -321,7 +321,7 @@ rules:
|
|||
no-unused-labels: [2]
|
||||
no-unused-private-class-members: [2]
|
||||
no-unused-vars: [2, {args: all, argsIgnorePattern: ^_, varsIgnorePattern: ^_, caughtErrorsIgnorePattern: ^_, destructuredArrayIgnorePattern: ^_, ignoreRestSiblings: false}]
|
||||
no-use-before-define: [2, nofunc]
|
||||
no-use-before-define: [2, {functions: false, classes: true, variables: true, allowNamedExports: true}]
|
||||
no-useless-backreference: [0]
|
||||
no-useless-call: [2]
|
||||
no-useless-catch: [2]
|
||||
|
@ -347,7 +347,7 @@ rules:
|
|||
padded-blocks: [2, never]
|
||||
padding-line-between-statements: [0]
|
||||
prefer-arrow-callback: [2, {allowNamedFunctions: true, allowUnboundThis: true}]
|
||||
prefer-const: [2, {destructuring: all}]
|
||||
prefer-const: [2, {destructuring: all, ignoreReadBeforeAssign: true}]
|
||||
prefer-destructuring: [0]
|
||||
prefer-exponentiation-operator: [2]
|
||||
prefer-named-capture-group: [0]
|
||||
|
@ -449,7 +449,7 @@ rules:
|
|||
unicorn/no-new-array: [0]
|
||||
unicorn/no-new-buffer: [0]
|
||||
unicorn/no-null: [0]
|
||||
unicorn/no-object-as-default-parameter: [2]
|
||||
unicorn/no-object-as-default-parameter: [0]
|
||||
unicorn/no-process-exit: [0]
|
||||
unicorn/no-reduce: [2]
|
||||
unicorn/no-static-only-class: [2]
|
||||
|
@ -475,7 +475,7 @@ rules:
|
|||
unicorn/prefer-array-index-of: [2]
|
||||
unicorn/prefer-array-some: [2]
|
||||
unicorn/prefer-at: [0]
|
||||
unicorn/prefer-code-point: [2]
|
||||
unicorn/prefer-code-point: [0]
|
||||
unicorn/prefer-dataset: [2]
|
||||
unicorn/prefer-date-now: [2]
|
||||
unicorn/prefer-default-parameters: [0]
|
||||
|
|
|
@ -29,7 +29,7 @@ linters:
|
|||
fast: false
|
||||
|
||||
run:
|
||||
go: 1.18
|
||||
go: 1.19
|
||||
timeout: 10m
|
||||
skip-dirs:
|
||||
- node_modules
|
||||
|
@ -75,7 +75,7 @@ linters-settings:
|
|||
- name: modifies-value-receiver
|
||||
gofumpt:
|
||||
extra-rules: true
|
||||
lang-version: "1.18"
|
||||
lang-version: "1.19"
|
||||
depguard:
|
||||
# TODO: use depguard to replace import checks in gitea-vet
|
||||
list-type: denylist
|
||||
|
|
308
CHANGELOG.md
|
@ -4,6 +4,314 @@ This changelog goes through all the changes that have been made in each release
|
|||
without substantial changes to our git log; to see the highlights of what has
|
||||
been added to each release, please refer to the [blog](https://blog.gitea.io).
|
||||
|
||||
## [1.17.0](https://github.com/go-gitea/gitea/releases/tag/v1.17.0) - 2022-07-30
|
||||
|
||||
* BREAKING
|
||||
* Require go1.18 for Gitea 1.17 (#19918)
|
||||
* Make AppDataPath absolute against the AppWorkPath if it is not (#19815)
|
||||
* Nuke the incorrect permission report on /api/v1/notifications (#19761)
|
||||
* Refactor git module, make Gitea use internal git config (#19732)
|
||||
* Remove `RequireHighlightJS` field, update plantuml example. (#19615)
|
||||
* Increase minimal required git version to 2.0 (#19577)
|
||||
* Add a directory prefix `gitea-src-VERSION` to release-tar-file (#19396)
|
||||
* Use "main" as default branch name (#19354)
|
||||
* Make cron task no notice on success (#19221)
|
||||
* Add pam account authorization check (#19040)
|
||||
* Show messages for users if the ROOT_URL is wrong, show JavaScript errors (#18971)
|
||||
* Refactor mirror code & fix StartToMirror (#18904)
|
||||
* Remove deprecated SSH ciphers from default (#18697)
|
||||
* Add the possibility to allow the user to have a favicon which differs from the main logo (#18542)
|
||||
* Update reserved usernames list (#18438)
|
||||
* Support custom ACME provider (#18340)
|
||||
* Change initial TrustModel to committer (#18335)
|
||||
* Update HTTP status codes (#18063)
|
||||
* Upgrade Alpine from 3.13 to 3.15 (#18050)
|
||||
* Restrict email address validation (#17688)
|
||||
* Refactor Router Logger (#17308)
|
||||
* SECURITY
|
||||
* Use git.HOME_PATH for Git HOME directory (#20114) (#20293)
|
||||
* Add write check for creating Commit Statuses (#20332) (#20333)
|
||||
* Remove deprecated SSH ciphers from default (#18697)
|
||||
* FEDERATION
|
||||
* Return statistic information for nodeinfo (#19561)
|
||||
* Add Webfinger endpoint (#19462)
|
||||
* Store the foreign ID of issues during migration (#18446)
|
||||
* FEATURES
|
||||
* Automatically render wiki TOC (#19873)
|
||||
* Adding button to link accounts from user settings (#19792)
|
||||
* Allow set default merge style while creating repo (#19751)
|
||||
* Auto merge pull requests when all checks succeeded (#9307 & #19648)
|
||||
* Improve reviewing PR UX (#19612)
|
||||
* Add support for rendering console output with colors (#19497)
|
||||
* Add Helm Chart registry (#19406)
|
||||
* Add Goroutine stack inspector to admin/monitor (#19207)
|
||||
* RSS/Atom support for Orgs & Repos (#17714 & #19055)
|
||||
* Add button for issue deletion (#19032)
|
||||
* Allow to mark files in a PR as viewed (#19007)
|
||||
* Add Index to comment for migrations and mirroring (#18806)
|
||||
* Add health check endpoint (#18465)
|
||||
* Add packagist webhook (#18224)
|
||||
* Add "Allow edits from maintainer" feature (#18002)
|
||||
* Add apply-patch, basic revert and cherry-pick functionality (#17902)
|
||||
* Add Package Registry (#16510)
|
||||
* Add LDAP group sync to Teams (#16299)
|
||||
* Pause queues (#15928)
|
||||
* Added auto-save whitespace behavior if it changed manually (#15566)
|
||||
* Find files in repo (#15028)
|
||||
* Provide configuration to allow camo-media proxying (#12802)
|
||||
* API
|
||||
* Add endpoint to serve blob or LFS file content (#19689)
|
||||
* Add endpoint to check if team has repo access (#19540)
|
||||
* More commit info (#19252)
|
||||
* Allow to create file on empty repo (#19224)
|
||||
* Allow removing issues (#18879)
|
||||
* Add endpoint to query collaborators permission for a repository (#18761)
|
||||
* Return primary language and repository language stats API URL (#18396)
|
||||
* Implement http signatures support for the API (#17565)
|
||||
* ENHANCEMENTS
|
||||
* Make notification bell more prominent on mobile (#20108, #20236, #20251) (#20269)
|
||||
* Adjust max-widths for the repository file table (#20243) (#20247)
|
||||
* Display full name (#20171) (#20246)
|
||||
* Add dbconsistency checks for Stopwatches (#20010)
|
||||
* Add fetch.writeCommitGraph to gitconfig (#20006)
|
||||
* Add fgprof pprof profiler (#20005)
|
||||
* Move agit dependency (#19998)
|
||||
* Empty log queue on flush and close (#19994)
|
||||
* Remove tab/TabName usage where it's not needed (#19973)
|
||||
* Improve file header on mobile (#19945)
|
||||
* Move issues related files into models/issues (#19931)
|
||||
* Add breaking email restrictions checker in doctor (#19903)
|
||||
* Improve UX on modal for deleting an access token (#19894)
|
||||
* Add alt text to logo (#19892)
|
||||
* Move some code into models/git (#19879)
|
||||
* Remove customized (unmaintained) dropdown, improve aria a11y for dropdown (#19861)
|
||||
* Make user profile image show full image on mobile (#19840)
|
||||
* Replace blue button and label classes with primary (#19763)
|
||||
* Remove fomantic progress module (#19760)
|
||||
* Allows repo search to match against "owner/repo" pattern strings (#19754)
|
||||
* Move org functions (#19753)
|
||||
* Move almost all functions' parameter db.Engine to context.Context (#19748)
|
||||
* Show source/target branches on PR's list (#19747)
|
||||
* Use http.StatusTemporaryRedirect(307) when serve avatar directly (#19739)
|
||||
* Add doctor orphan check for orphaned pull requests without an existing base repo (#19731)
|
||||
* Make Ctrl+Enter (quick submit) work for issue comment and wiki editor (#19729)
|
||||
* Update go-chi/cache to utilize Ping() (#19719)
|
||||
* Improve commit list/view on mobile (#19712)
|
||||
* Move some repository related code into sub package (#19711)
|
||||
* Use a better OlderThan for DeleteInactiveUsers (#19693)
|
||||
* Introduce eslint-plugin-jquery (#19690)
|
||||
* Tidy up `<head>` template (#19678)
|
||||
* Calculate filename hash only once (#19654)
|
||||
* Simplify `IsVendor` (#19626)
|
||||
* Add "Reference" section to Issue view sidebar (#19609)
|
||||
* Only set CanColorStdout / CanColorStderr to true if the stdout/stderr is a terminal (#19581)
|
||||
* Use for a repo action one database transaction (#19576)
|
||||
* Simplify loops to copy (#19569)
|
||||
* Added X-Mailer header to outgoing emails (#19562)
|
||||
* use middleware to open gitRepo (#19559)
|
||||
* Mute link in diff header (#19556)
|
||||
* Improve UI on mobile (#19546)
|
||||
* Fix Pull Request comment filename word breaks (#19535)
|
||||
* Permalink files In PR diff (#19534)
|
||||
* PullService lock via pullID (#19520)
|
||||
* Make repository file list useable on mobile (#19515)
|
||||
* more context for models (#19511)
|
||||
* Refactor readme file renderer (#19502)
|
||||
* By default force vertical tabs on mobile (#19486)
|
||||
* Github style following followers (#19482)
|
||||
* Improve action table indices (#19472)
|
||||
* Use horizontal tabs for repo header on mobile (#19468)
|
||||
* pass gitRepo down since its used for main repo and wiki (#19461)
|
||||
* Admin should not delete himself (#19423)
|
||||
* Use queue instead of memory queue in webhook send service (#19390)
|
||||
* Simplify the code to get issue count (#19380)
|
||||
* Add commit status popup to issuelist (#19375)
|
||||
* Add RSS Feed buttons to Repo, User and Org pages (#19370)
|
||||
* Add logic to switch between source/rendered on Markdown (#19356)
|
||||
* Move some helper files out of models (#19355)
|
||||
* Move access and repo permission to models/perm/access (#19350)
|
||||
* Disallow selecting the text of buttons (#19330)
|
||||
* Allow custom redirect for landing page (#19324)
|
||||
* Remove dependent on session auth for api/v1 routers (#19321)
|
||||
* Never use /api/v1 from Gitea UI Pages (#19318)
|
||||
* Remove legacy unmaintained packages, refactor to support change default locale (#19308)
|
||||
* Move milestone to models/issues/ (#19278)
|
||||
* Configure OpenSSH log level via Environment in Docker (#19274)
|
||||
* Move reaction to models/issues/ (#19264)
|
||||
* Make git.OpenRepository accept Context (#19260)
|
||||
* Move some issue methods as functions (#19255)
|
||||
* Show last cron messages on monitor page (#19223)
|
||||
* New cron task: delete old system notices (#19219)
|
||||
* Add Redis Sentinel Authentication Support (#19213)
|
||||
* Add auto logging of goroutine pid label (#19212)
|
||||
* Set OpenGraph title to DisplayName in profile pages (#19206)
|
||||
* Add pprof labels in processes and for lifecycles (#19202)
|
||||
* Let web and API routes have different auth methods group (#19168)
|
||||
* Move init repository related functions to modules (#19159)
|
||||
* Feeds: render markdown to html (#19058)
|
||||
* Allow users to self-request a PR review (#19030)
|
||||
* Allow render HTML with css/js external links (#19017)
|
||||
* Fix script compatiable with OpenWrt (#19000)
|
||||
* Support ignore all santize for external renderer (#18984)
|
||||
* Add note to GPG key response if user has no keys (#18961)
|
||||
* Improve Stopwatch behavior (#18930)
|
||||
* Improve mirror iterator (#18928)
|
||||
* Uncapitalize errors (#18915)
|
||||
* Prevent Stats Indexer reporting error if repo dir missing (#18870)
|
||||
* Refactor SecToTime() function (#18863)
|
||||
* Replace deprecated String.prototype.substr() with String.prototype.slice() (#18796)
|
||||
* Move deletebeans into models/db (#18781)
|
||||
* Fix display time of milestones (#18753)
|
||||
* Add config option to disable "Update branch by rebase" (#18745)
|
||||
* Display template path of current page in dev mode (#18717)
|
||||
* Add number in queue status to monitor page (#18712)
|
||||
* Change git.cmd to RunWithContext (#18693)
|
||||
* Refactor i18n, use Locale to provide i18n/translation related functions (#18648)
|
||||
* Delete old git.NewCommand() and use it as git.NewCommandContext() (#18552)
|
||||
* Move organization related structs into sub package (#18518)
|
||||
* Warn at startup if the provided `SCRIPT_TYPE` is not on the PATH (#18467)
|
||||
* Use `CryptoRandomBytes` instead of `CryptoRandomString` (#18439)
|
||||
* Use explicit jQuery import, remove unused eslint globals (#18435)
|
||||
* Allow to filter repositories by language in explore, user and organization repositories lists (#18430)
|
||||
* Use base32 for 2FA scratch token (#18384)
|
||||
* Unexport var git.GlobalCommandArgs (#18376)
|
||||
* Don't underline commit status icon on hover (#18372)
|
||||
* Always use git command but not os.Command (#18363)
|
||||
* Switch to non-deprecation setting (#18358)
|
||||
* Set the LastModified header for raw files (#18356)
|
||||
* Refactor jwt.StandardClaims to RegisteredClaims (#18344)
|
||||
* Enable deprecation error for v1.17.0 (#18341)
|
||||
* Refactor httplib (#18338)
|
||||
* Limit max-height of CodeMirror editors for issue comment and wiki (#18271)
|
||||
* Validate migration files (#18203)
|
||||
* Format with gofumpt (#18184)
|
||||
* Allow custom default merge message with .gitea/default_merge_message/<merge_style>_TEMPLATE.md (#18177)
|
||||
* Prettify number of issues (#17760)
|
||||
* Add a "admin user generate-access-token" subcommand (#17722)
|
||||
* Custom regexp external issues (#17624)
|
||||
* Add smtp password to install page (#17564)
|
||||
* Add config options to hide issue events (#17414)
|
||||
* Prevent double click new issue/pull/comment button (#16157)
|
||||
* Show issue assignee on project board (#15232)
|
||||
* BUGFIXES
|
||||
* WebAuthn CredentialID field needs to be increased in size (#20530) (#20555)
|
||||
* Ensure that all unmerged files are merged when conflict checking (#20528) (#20536)
|
||||
* Stop logging EOFs and exit(1)s in ssh handler (#20476) (#20529)
|
||||
* Add labels to two buttons that were missing them (#20419) (#20524)
|
||||
* Fix ROOT_URL detection for URLs without trailing slash (#20502) (#20503)
|
||||
* Dismiss prior pull reviews if done via web in review dismiss (#20197) (#20407)
|
||||
* Allow RSA 2047 bit keys (#20272) (#20396)
|
||||
* Add missing return for when topic isn't found (#20351) (#20395)
|
||||
* Fix commit status icon when in subdirectory (#20285) (#20385)
|
||||
* Initialize cron last (#20373) (#20384)
|
||||
* Set target on create release with existing tag (#20381) (#20382)
|
||||
* Update xorm.io/xorm to fix a interpreting db column sizes issue on 32bit systems (#20371) (#20372)
|
||||
* Make sure `repo_dir` is an empty directory or doesn't exist before 'dump-repo' (#20205) (#20370)
|
||||
* Prevent context deadline error propagation in GetCommitsInfo (#20346) (#20361)
|
||||
* Correctly handle draft releases without a tag (#20314) (#20335)
|
||||
* Prevent "empty" scrollbars on Firefox (#20294) (#20308)
|
||||
* Refactor SSH init code, fix directory creation for TrustedUserCAKeys file (#20299) (#20306)
|
||||
* Bump goldmark to v1.4.13 (#20300) (#20301)
|
||||
* Do not create empty ".ssh" directory when loading config (#20289) (#20298)
|
||||
* Fix NPE when using non-numeric (#20277) (#20278)
|
||||
* Store read access in access for team repositories (#20275) (#20276)
|
||||
* EscapeFilter the group dn membership (#20200) (#20254)
|
||||
* Only show Followers that current user can access (#20220) (#20252)
|
||||
* Update Bluemonday to v1.0.19 (#20199) (#20209)
|
||||
* Refix indices on actions table (#20158) (#20198)
|
||||
* Check if project has the same repository id with issue when assign project to issue (#20133) (#20188)
|
||||
* Fix remove file on initial comment (#20127) (#20128)
|
||||
* Catch the error before the response is processed by goth (#20000) (#20102)
|
||||
* Dashboard feed respect setting.UI.FeedPagingNum again (#20094) (#20099)
|
||||
* Alter hook_task TEXT fields to LONGTEXT (#20038) (#20041)
|
||||
* Respond with a 401 on git push when password isn't changed yet (#20026) (#20027)
|
||||
* Return 404 when tag is broken (#20017) (#20024)
|
||||
* Alter hook_task TEXT fields to LONGTEXT (#20038) (#20041)
|
||||
* Respond with a 401 on git push when password isn't changed yet (#20026) (#20027)
|
||||
* Return 404 when tag is broken (#20017) (#20024)
|
||||
* Write Commit-Graphs in RepositoryDumper (#20004)
|
||||
* Use DisplayName() instead of FullName in Oauth Provider (#19991)
|
||||
* Don't buffer doctor logger (#19982)
|
||||
* Always try to fetch repo for mirrors (#19975)
|
||||
* Uppercase first languages letters (#19965)
|
||||
* Fix cli command restore-repo: "units" should be parsed as StringSlice (#19953)
|
||||
* Ensure minimum mirror interval is reported on settings page (#19895)
|
||||
* Exclude Archived repos from Dashboard Milestones (#19882)
|
||||
* gitconfig: set safe.directory = * (#19870)
|
||||
* Prevent NPE on update mirror settings (#19864)
|
||||
* Only return valid stopwatches to the EventSource (#19863)
|
||||
* Prevent NPE whilst migrating if there is a team request review (#19855)
|
||||
* Fix inconsistency in doctor output (#19836)
|
||||
* Fix release tag for webhook (#19830)
|
||||
* Add title attribute to dependencies in sidebar (#19807)
|
||||
* Estimate Action Count in Statistics (#19775)
|
||||
* Do not update user stars numbers unless fix is specified (#19750)
|
||||
* Improved ref comment link when origin is body/title (#19741)
|
||||
* Fix nodeinfo caching and prevent NPE if cache non-existent (#19721)
|
||||
* Fix duplicate entry error when add team member (#19702)
|
||||
* Fix sending empty notifications (#19589)
|
||||
* Update image URL for Discord webhook (#19536)
|
||||
* Don't let repo clone URL overflow (#19517)
|
||||
* Allow commit status popup on /pulls page (#19507)
|
||||
* Fix two UI bugs: JS error in imagediff.js, 500 error in diff/compare.tmpl (#19494)
|
||||
* Fix logging of Transfer API (#19456)
|
||||
* Fix panic in teams API when requesting members (#19360)
|
||||
* Refactor CSRF protection modules, make sure CSRF tokens can be up-to-date. (#19337)
|
||||
* An attempt to sync a non-mirror repo must give 400 (Bad Request) (#19300)
|
||||
* Move checks for pulls before merge into own function (#19271)
|
||||
* Fix `contrib/upgrade.sh` (#19222)
|
||||
* Set the default branch for repositories generated from templates (#19136)
|
||||
* Fix EasyMDE error when input Enter (#19004)
|
||||
* Don't clean up hardcoded `tmp` (#18983)
|
||||
* Delete related notifications on issue deletion too (#18953)
|
||||
* Fix trace log to show value instead of pointers (#18926)
|
||||
* Fix behavior or checkbox submission. (#18851)
|
||||
* Add `ContextUser` (#18798)
|
||||
* Fix some mirror bugs (#18649)
|
||||
* Quote MAKE to prevent path expansion with space error (#18622)
|
||||
* Preserve users if restoring a repository on the same Gitea instance (#18604)
|
||||
* Fix non-ASCII search on database (#18437)
|
||||
* Automatically pause queue if index service is unavailable (#15066)
|
||||
* TESTING
|
||||
* Allow postgres integration tests to run over unix pipe (#19875)
|
||||
* Prevent intermittent NPE in queue tests (#19301)
|
||||
* Add test for importing pull requests in gitea uploader for migrations (#18752)
|
||||
* Remove redundant comparison in repo dump/restore (#18660)
|
||||
* More repo dump/restore tests, including pull requests (#18621)
|
||||
* Add test coverage for original author conversion during migrations (#18506)
|
||||
* TRANSLATION
|
||||
* Update issue_no_dependencies description (#19112)
|
||||
* Refactor webhooks i18n (#18380)
|
||||
* BUILD
|
||||
* Use alpine 3.16 (#19797)
|
||||
* Require node 14.0 (#19451)
|
||||
* DOCS
|
||||
* Update documents (git/fomantic/db, etc) (#19868)
|
||||
* Update the ROOT documentation and error messages (#19832)
|
||||
* Update document to use FHS `/usr/local/bin/gitea` instead of `/app/...` for Docker (#19794)
|
||||
* Update documentation to disable duration settings with -1 instead of 0 (#19647)
|
||||
* Add warning to set SENDMAIL_ARGS to -- (#19102)
|
||||
* Update nginx reverse proxy docs (#18922)
|
||||
* Add example to render html files (#18736)
|
||||
* Make SSH passtrough documentation better (#18687)
|
||||
* Changelog 1.16.0 & 1.15.11 (#18468 & #18455) (#18470)
|
||||
* Update the SSH passthrough documentation (#18366)
|
||||
* Add `contrib/upgrade.sh` (#18286)
|
||||
* MISC
|
||||
* Fix aria for logo (#19955)
|
||||
* In code search, get code unit accessible repos in one (main) query (#19764)
|
||||
* Add tooltip to pending PR comments (#19662)
|
||||
* Improve sync performance for pull-mirrors (#19125)
|
||||
* Improve dashboard's repo list performance (#18963)
|
||||
* Avoid database lookups for `DescriptionHTML` (#18924)
|
||||
* Remove CodeMirror dependencies (#18911)
|
||||
* Disable unnecessary mirroring elements (#18527)
|
||||
* Disable unnecessary OpenID/OAuth2 elements (#18491)
|
||||
* Disable unnecessary GitHooks elements (#18485)
|
||||
* Change some logging levels (#18421)
|
||||
* Prevent showing webauthn error for every time visiting `/user/settings/security` (#18385)
|
||||
* Use correct translation key for errors (#18342)
|
||||
|
||||
## [1.16.9](https://github.com/go-gitea/gitea/releases/tag/v1.16.9) - 2022-07-12
|
||||
|
||||
* SECURITY
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#Build stage
|
||||
FROM golang:1.18-alpine3.16 AS build-env
|
||||
FROM golang:1.19-alpine3.16 AS build-env
|
||||
|
||||
ARG GOPROXY
|
||||
ENV GOPROXY ${GOPROXY:-direct}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#Build stage
|
||||
FROM golang:1.18-alpine3.16 AS build-env
|
||||
FROM golang:1.19-alpine3.16 AS build-env
|
||||
|
||||
ARG GOPROXY
|
||||
ENV GOPROXY ${GOPROXY:-direct}
|
||||
|
|
2
Makefile
|
@ -23,7 +23,7 @@ SHASUM ?= shasum -a 256
|
|||
HAS_GO = $(shell hash $(GO) > /dev/null 2>&1 && echo "GO" || echo "NOGO" )
|
||||
COMMA := ,
|
||||
|
||||
XGO_VERSION := go-1.18.x
|
||||
XGO_VERSION := go-1.19.x
|
||||
|
||||
AIR_PACKAGE ?= github.com/cosmtrek/air@v1.40.4
|
||||
EDITORCONFIG_CHECKER_PACKAGE ?= github.com/editorconfig-checker/editorconfig-checker/cmd/editorconfig-checker@2.5.0
|
||||
|
|
|
@ -14,6 +14,7 @@ import (
|
|||
"code.gitea.io/gitea/models/db"
|
||||
"code.gitea.io/gitea/models/migrations"
|
||||
"code.gitea.io/gitea/modules/doctor"
|
||||
"code.gitea.io/gitea/modules/git"
|
||||
"code.gitea.io/gitea/modules/log"
|
||||
"code.gitea.io/gitea/modules/setting"
|
||||
|
||||
|
@ -124,13 +125,18 @@ func runRecreateTable(ctx *cli.Context) error {
|
|||
}
|
||||
|
||||
func runDoctor(ctx *cli.Context) error {
|
||||
stdCtx, cancel := installSignals()
|
||||
defer cancel()
|
||||
|
||||
// some doctor sub-commands need to use git command
|
||||
if err := git.InitFull(stdCtx); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Silence the default loggers
|
||||
log.DelNamedLogger("console")
|
||||
log.DelNamedLogger(log.DEFAULT)
|
||||
|
||||
stdCtx, cancel := installSignals()
|
||||
defer cancel()
|
||||
|
||||
// Now setup our own
|
||||
logFile := ctx.String("log-file")
|
||||
if !ctx.IsSet("log-file") {
|
||||
|
|
|
@ -80,7 +80,6 @@ func runPR() {
|
|||
setting.RunUser = curUser.Username
|
||||
|
||||
log.Printf("[PR] Loading fixtures data ...\n")
|
||||
gitea_git.CheckLFSVersion()
|
||||
//models.LoadConfigs()
|
||||
/*
|
||||
setting.Database.Type = "sqlite3"
|
||||
|
|
|
@ -698,9 +698,11 @@ ROUTER = console
|
|||
;; Enable captcha validation for registration
|
||||
;ENABLE_CAPTCHA = false
|
||||
;;
|
||||
;; Type of captcha you want to use. Options: image, recaptcha, hcaptcha
|
||||
;; Type of captcha you want to use. Options: image, recaptcha, hcaptcha, mcaptcha.
|
||||
;CAPTCHA_TYPE = image
|
||||
;;
|
||||
;; Change this to use recaptcha.net or other recaptcha service
|
||||
;RECAPTCHA_URL = https://www.google.com/recaptcha/
|
||||
;; Enable recaptcha to use Google's recaptcha service
|
||||
;; Go to https://www.google.com/recaptcha/admin to sign up for a key
|
||||
;RECAPTCHA_SECRET =
|
||||
|
@ -710,8 +712,13 @@ ROUTER = console
|
|||
;HCAPTCHA_SECRET =
|
||||
;HCAPTCHA_SITEKEY =
|
||||
;;
|
||||
;; Change this to use recaptcha.net or other recaptcha service
|
||||
;RECAPTCHA_URL = https://www.google.com/recaptcha/
|
||||
;; Change this to use demo.mcaptcha.org or your self-hosted mcaptcha.org instance.
|
||||
;MCAPTCHA_URL = https://demo.mcaptcha.org
|
||||
;;
|
||||
;; Go to your configured mCaptcha instance and register a sitekey
|
||||
;; and use your account's secret.
|
||||
;MCAPTCHA_SECRET =
|
||||
;MCAPTCHA_SITEKEY =
|
||||
;;
|
||||
;; Default value for KeepEmailPrivate
|
||||
;; Each new user will get the value of this setting copied into their profile
|
||||
|
@ -1083,7 +1090,7 @@ ROUTER = console
|
|||
;EXPLORE_PAGING_NUM = 20
|
||||
;;
|
||||
;; Number of issues that are displayed on one page
|
||||
;ISSUE_PAGING_NUM = 10
|
||||
;ISSUE_PAGING_NUM = 20
|
||||
;;
|
||||
;; Number of maximum commits displayed in one activity feed
|
||||
;FEED_MAX_COMMIT_NUM = 5
|
||||
|
@ -1496,6 +1503,11 @@ ROUTER = console
|
|||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;;
|
||||
;; NOTICE: this section is for Gitea 1.18 and later. If you are using Gitea 1.17 or older,
|
||||
;; please refer to
|
||||
;; https://github.com/go-gitea/gitea/blob/release/v1.17/custom/conf/app.example.ini
|
||||
;; https://github.com/go-gitea/gitea/blob/release/v1.17/docs/content/doc/advanced/config-cheat-sheet.en-us.md
|
||||
;;
|
||||
;ENABLED = false
|
||||
;;
|
||||
;; Buffer length of channel, keep it as it is if you don't know what it is.
|
||||
|
@ -1509,12 +1521,12 @@ ROUTER = console
|
|||
;; - dummy: send email messages to the log as a testing phase.
|
||||
;; If your provider does not explicitly say which protocol it uses but does provide a port,
|
||||
;; you can set SMTP_PORT instead and this will be inferred.
|
||||
;; (Before 1.18, this was controlled via MAILER_TYPE and IS_TLS_ENABLED.)
|
||||
;; (Before 1.18, see the notice, this was controlled via MAILER_TYPE and IS_TLS_ENABLED.)
|
||||
;PROTOCOL =
|
||||
;;
|
||||
;; Mail server address, e.g. smtp.gmail.com.
|
||||
;; For smtp+unix, this should be a path to a unix socket instead.
|
||||
;; (Before 1.18, this was combined with SMTP_PORT as HOST.)
|
||||
;; (Before 1.18, see the notice, this was combined with SMTP_PORT as HOST.)
|
||||
;SMTP_ADDR =
|
||||
;;
|
||||
;; Mail server port. Common ports are:
|
||||
|
|
|
@ -20,8 +20,9 @@ params:
|
|||
website: https://docs.gitea.io
|
||||
version: 1.16.9
|
||||
minGoVersion: 1.18
|
||||
goVersion: 1.18
|
||||
goVersion: 1.19
|
||||
minNodeVersion: 14
|
||||
search: nav
|
||||
|
||||
outputs:
|
||||
home:
|
||||
|
|
|
@ -172,7 +172,7 @@ The following configuration set `Content-Type: application/vnd.android.package-a
|
|||
## UI (`ui`)
|
||||
|
||||
- `EXPLORE_PAGING_NUM`: **20**: Number of repositories that are shown in one explore page.
|
||||
- `ISSUE_PAGING_NUM`: **10**: Number of issues that are shown in one page (for all pages that list issues).
|
||||
- `ISSUE_PAGING_NUM`: **20**: Number of issues that are shown in one page (for all pages that list issues, milestones, projects).
|
||||
- `MEMBERS_PAGING_NUM`: **20**: Number of members that are shown in organization members.
|
||||
- `FEED_MAX_COMMIT_NUM`: **5**: Number of maximum commits shown in one activity feed.
|
||||
- `FEED_PAGING_NUM`: **20**: Number of items that are displayed in home feed.
|
||||
|
@ -296,8 +296,8 @@ The following configuration set `Content-Type: application/vnd.android.package-a
|
|||
- `MINIMUM_KEY_SIZE_CHECK`: **true**: Indicate whether to check minimum key size with corresponding type.
|
||||
|
||||
- `OFFLINE_MODE`: **false**: Disables use of CDN for static files and Gravatar for profile pictures.
|
||||
- `CERT_FILE`: **https/cert.pem**: Cert file path used for HTTPS. When chaining, the server certificate must come first, then intermediate CA certificates (if any). This is ignored if `ENABLE_ACME=true`. From 1.11 paths are relative to `CUSTOM_PATH`.
|
||||
- `KEY_FILE`: **https/key.pem**: Key file path used for HTTPS. This is ignored if `ENABLE_ACME=true`. From 1.11 paths are relative to `CUSTOM_PATH`.
|
||||
- `CERT_FILE`: **https/cert.pem**: Cert file path used for HTTPS. When chaining, the server certificate must come first, then intermediate CA certificates (if any). This is ignored if `ENABLE_ACME=true`. Paths are relative to `CUSTOM_PATH`.
|
||||
- `KEY_FILE`: **https/key.pem**: Key file path used for HTTPS. This is ignored if `ENABLE_ACME=true`. Paths are relative to `CUSTOM_PATH`.
|
||||
- `STATIC_ROOT_PATH`: **./**: Upper level of template and static files path.
|
||||
- `APP_DATA_PATH`: **data** (**/data/gitea** on docker): Default path for application data.
|
||||
- `STATIC_CACHE_TIME`: **6h**: Web browser cache time for static resources on `custom/`, `public/` and all uploaded avatars. Note that this cache is disabled when `RUN_MODE` is "dev".
|
||||
|
@ -438,11 +438,11 @@ Configuration at `[queue]` will set defaults for queues with overrides for indiv
|
|||
- `MAX_ATTEMPTS`: **10**: Maximum number of attempts to create the wrapped queue
|
||||
- `TIMEOUT`: **GRACEFUL_HAMMER_TIME + 30s**: Timeout the creation of the wrapped queue if it takes longer than this to create.
|
||||
- Queues by default come with a dynamically scaling worker pool. The following settings configure this:
|
||||
- `WORKERS`: **0** (v1.14 and before: **1**): Number of initial workers for the queue.
|
||||
- `WORKERS`: **0**: Number of initial workers for the queue.
|
||||
- `MAX_WORKERS`: **10**: Maximum number of worker go-routines for the queue.
|
||||
- `BLOCK_TIMEOUT`: **1s**: If the queue blocks for this time, boost the number of workers - the `BLOCK_TIMEOUT` will then be doubled before boosting again whilst the boost is ongoing.
|
||||
- `BOOST_TIMEOUT`: **5m**: Boost workers will timeout after this long.
|
||||
- `BOOST_WORKERS`: **1** (v1.14 and before: **5**): This many workers will be added to the worker pool if there is a boost.
|
||||
- `BOOST_WORKERS`: **1**: This many workers will be added to the worker pool if there is a boost.
|
||||
|
||||
Gitea creates the following non-unique queues:
|
||||
|
||||
|
@ -579,13 +579,16 @@ Certain queues have defaults that override the defaults set in `[queue]` (this o
|
|||
provided email rather than a generated email.
|
||||
- `ENABLE_CAPTCHA`: **false**: Enable this to use captcha validation for registration.
|
||||
- `REQUIRE_EXTERNAL_REGISTRATION_CAPTCHA`: **false**: Enable this to force captcha validation
|
||||
even for External Accounts (i.e. GitHub, OpenID Connect, etc). You must `ENABLE_CAPTCHA` also.
|
||||
- `CAPTCHA_TYPE`: **image**: \[image, recaptcha, hcaptcha\]
|
||||
even for External Accounts (i.e. GitHub, OpenID Connect, etc). You also must enable `ENABLE_CAPTCHA`.
|
||||
- `CAPTCHA_TYPE`: **image**: \[image, recaptcha, hcaptcha, mcaptcha\]
|
||||
- `RECAPTCHA_SECRET`: **""**: Go to https://www.google.com/recaptcha/admin to get a secret for recaptcha.
|
||||
- `RECAPTCHA_SITEKEY`: **""**: Go to https://www.google.com/recaptcha/admin to get a sitekey for recaptcha.
|
||||
- `RECAPTCHA_URL`: **https://www.google.com/recaptcha/**: Set the recaptcha url - allows the use of recaptcha net.
|
||||
- `HCAPTCHA_SECRET`: **""**: Sign up at https://www.hcaptcha.com/ to get a secret for hcaptcha.
|
||||
- `HCAPTCHA_SITEKEY`: **""**: Sign up at https://www.hcaptcha.com/ to get a sitekey for hcaptcha.
|
||||
- `MCAPTCHA_SECRET`: **""**: Go to your mCaptcha instance to get a secret for mCaptcha.
|
||||
- `MCAPTCHA_SITEKEY`: **""**: Go to your mCaptcha instance to get a sitekey for mCaptcha.
|
||||
- `MCAPTCHA_URL` **https://demo.mcaptcha.org/**: Set the mCaptcha URL.
|
||||
- `DEFAULT_KEEP_EMAIL_PRIVATE`: **false**: By default set users to keep their email address private.
|
||||
- `DEFAULT_ALLOW_CREATE_ORGANIZATION`: **true**: Allow new users to create organizations by default.
|
||||
- `DEFAULT_USER_IS_RESTRICTED`: **false**: Give new users restricted permissions by default
|
||||
|
@ -631,7 +634,7 @@ Define allowed algorithms and their minimum key length (use -1 to disable a type
|
|||
|
||||
- `QUEUE_LENGTH`: **1000**: Hook task queue length. Use caution when editing this value.
|
||||
- `DELIVER_TIMEOUT`: **5**: Delivery timeout (sec) for shooting webhooks.
|
||||
- `ALLOWED_HOST_LIST`: **external**: Since 1.15.7. Default to `*` for 1.15.x, `external` for 1.16 and later. Webhook can only call allowed hosts for security reasons. Comma separated list.
|
||||
- `ALLOWED_HOST_LIST`: **external**: Webhook can only call allowed hosts for security reasons. Comma separated list.
|
||||
- Built-in networks:
|
||||
- `loopback`: 127.0.0.0/8 for IPv4 and ::1/128 for IPv6, localhost is included.
|
||||
- `private`: RFC 1918 (10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16) and RFC 4193 (FC00::/7). Also called LAN/Intranet.
|
||||
|
@ -646,6 +649,12 @@ Define allowed algorithms and their minimum key length (use -1 to disable a type
|
|||
|
||||
## Mailer (`mailer`)
|
||||
|
||||
⚠️ This section is for Gitea 1.18 and later. If you are using Gitea 1.17 or older,
|
||||
please refer to
|
||||
[Gitea 1.17 app.ini example](https://github.com/go-gitea/gitea/blob/release/v1.17/custom/conf/app.example.ini)
|
||||
and
|
||||
[Gitea 1.17 configuration document](https://github.com/go-gitea/gitea/blob/release/v1.17/docs/content/doc/advanced/config-cheat-sheet.en-us.md)
|
||||
|
||||
- `ENABLED`: **false**: Enable to use a mail service.
|
||||
- `PROTOCOL`: **\<empty\>**: Mail server protocol. One of "smtp", "smtps", "smtp+startls", "smtp+unix", "sendmail", "dummy". _Before 1.18, this was inferred from a combination of `MAILER_TYPE` and `IS_TLS_ENABLED`._
|
||||
- SMTP family, if your provider does not explicitly say which protocol it uses but does provide a port, you can set SMTP_PORT instead and this will be inferred.
|
||||
|
|
|
@ -15,7 +15,14 @@ menu:
|
|||
|
||||
# 配置说明
|
||||
|
||||
这是针对Gitea配置文件的说明,你可以了解Gitea的强大配置。需要说明的是,你的所有改变请修改 `custom/conf/app.ini` 文件而不是源文件。所有默认值可以通过 [app.example.ini](https://github.com/go-gitea/gitea/blob/master/custom/conf/app.example.ini) 查看到。如果你发现 `%(X)s` 这样的内容,请查看 [ini](https://github.com/go-ini/ini/#recursive-values) 这里的说明。标注了 :exclamation: 的配置项表明除非你真的理解这个配置项的意义,否则最好使用默认值。
|
||||
这是针对Gitea配置文件的说明,你可以了解Gitea的强大配置。需要说明的是,你的所有改变请修改 `custom/conf/app.ini` 文件而不是源文件。
|
||||
所有默认值可以通过 [app.example.ini](https://github.com/go-gitea/gitea/blob/master/custom/conf/app.example.ini) 查看到。
|
||||
如果你发现 `%(X)s` 这样的内容,请查看 [ini](https://github.com/go-ini/ini/#recursive-values) 这里的说明。
|
||||
标注了 :exclamation: 的配置项表明除非你真的理解这个配置项的意义,否则最好使用默认值。
|
||||
|
||||
## ⚠️时效性警告⚠️
|
||||
|
||||
此文档的内容可能过于陈旧或者错误,请参考英文文档。
|
||||
|
||||
{{< toc >}}
|
||||
|
||||
|
|
|
@ -105,6 +105,18 @@ curl -X POST "http://localhost:4000/api/v1/repos/test1/test1/issues" \
|
|||
As mentioned above, the token used is the same one you would use in
|
||||
the `token=` string in a GET request.
|
||||
|
||||
## Pagination
|
||||
|
||||
The API supports pagination. The `page` and `limit` parameters are used to specify the page number and the number of items per page. As well, the `Link` header is returned with the next, previous, and last page links if there are more than one pages. The `x-total-count` is also returned to indicate the total number of items.
|
||||
|
||||
```sh
|
||||
curl -v "http://localhost/api/v1/repos/search?limit=1"
|
||||
...
|
||||
< link: <http://localhost/api/v1/repos/search?limit=1&page=2>; rel="next",<http://localhost/api/v1/repos/search?limit=1&page=5252>; rel="last"
|
||||
...
|
||||
< x-total-count: 5252
|
||||
```
|
||||
|
||||
## API Guide:
|
||||
|
||||
API Reference guide is auto-generated by swagger and available on:
|
||||
|
|
|
@ -46,7 +46,7 @@ _表格中的符号含义:_
|
|||
| Git 驱动的集成化 wiki | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✘ |
|
||||
| 部署令牌 | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
|
||||
| 仓库写权限令牌 | ✓ | ✘ | ✓ | ✓ | ✓ | ✘ | ✓ |
|
||||
| 内置容器 Registry | ✘ | ✘ | ✘ | ✓ | ✓ | ✘ | ✘ |
|
||||
| 内置容器 Registry | ✓ | ✘ | ✘ | ✓ | ✓ | ✘ | ✘ |
|
||||
| 外部 Git 镜像 | ✓ | ✓ | ✘ | ✘ | ✓ | ✓ | ✓ |
|
||||
| WebAuthn (2FA) | ✓ | ✘ | ✓ | ✓ | ✓ | ✓ | ? |
|
||||
| 内置 CI/CD | ✘ | ✘ | ✘ | ✓ | ✓ | ✘ | ✘ |
|
||||
|
@ -62,7 +62,7 @@ _表格中的符号含义:_
|
|||
| Git LFS 2.0 | ✓ | ✘ | ✓ | ✓ | ✓ | ⁄ | ✓ |
|
||||
| 组织里程碑 | ✘ | ✘ | ✘ | ✓ | ✓ | ✘ | ✘ |
|
||||
| 细粒度用户角色 (例如 Code, Issues, Wiki) | ✓ | ✘ | ✘ | ✓ | ✓ | ✘ | ✘ |
|
||||
| 提交人的身份验证 | ✘ | ✘ | ? | ✓ | ✓ | ✓ | ✘ |
|
||||
| 提交人的身份验证 | ⁄ | ✘ | ? | ✓ | ✓ | ✓ | ✘ |
|
||||
| GPG 签名的提交 | ✓ | ✘ | ✓ | ✓ | ✓ | ✓ | ✓ |
|
||||
| SSH 签名的提交 | ✓ | ✘ | ✘ | ✘ | ✘ | ? | ? |
|
||||
| 拒绝未用通过验证的提交 | ✓ | ✘ | ✓ | ✓ | ✓ | ✘ | ✓ |
|
||||
|
@ -71,6 +71,7 @@ _表格中的符号含义:_
|
|||
| 建立新分支 | ✓ | ✘ | ✓ | ✓ | ✓ | ✘ | ✘ |
|
||||
| 在线代码编辑 | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
|
||||
| 提交的统计图表 | ✓ | ✘ | ✓ | ✓ | ✓ | ✓ | ✓ |
|
||||
| 模板仓库 | ✓ | ✘ | ✓ | ✘ | ✓ | ✓ | ✘ |
|
||||
|
||||
#### Issue 管理
|
||||
|
||||
|
@ -84,9 +85,9 @@ _表格中的符号含义:_
|
|||
| 关联的 issues | ✘ | ✘ | ⁄ | ✘ | ✓ | ✘ | ✘ |
|
||||
| 私密 issues | ✘ | ✘ | ✘ | ✓ | ✓ | ✘ | ✘ |
|
||||
| 评论反馈 | ✓ | ✘ | ✓ | ✓ | ✓ | ✘ | ✘ |
|
||||
| 锁定讨论 | ✘ | ✘ | ✓ | ✓ | ✓ | ✘ | ✘ |
|
||||
| 锁定讨论 | ✓ | ✘ | ✓ | ✓ | ✓ | ✘ | ✘ |
|
||||
| Issue 批量处理 | ✓ | ✘ | ✓ | ✓ | ✓ | ✘ | ✘ |
|
||||
| Issue 看板 | ✘ | ✘ | ✘ | ✓ | ✓ | ✘ | ✘ |
|
||||
| Issue 看板 | ✓ | ✘ | ✘ | ✓ | ✓ | ✘ | ✘ |
|
||||
| 从 issues 创建分支 | ✘ | ✘ | ✘ | ✓ | ✓ | ✘ | ✘ |
|
||||
| Issue 搜索 | ✓ | ✘ | ✓ | ✓ | ✓ | ✓ | ✘ |
|
||||
| 全局 Issue 搜索 | ✘ | ✘ | ✓ | ✓ | ✓ | ✓ | ✘ |
|
||||
|
@ -108,6 +109,7 @@ _表格中的符号含义:_
|
|||
| 回退某些 commits 或 merge request | ✘ | ✘ | ✓ | ✓ | ✓ | ✓ | ✘ |
|
||||
| Pull/Merge requests 模板 | ✓ | ✓ | ✓ | ✓ | ✓ | ✘ | ✘ |
|
||||
| 查看 Cherry-picking 的更改 | ✘ | ✘ | ✘ | ✓ | ✓ | ✘ | ✘ |
|
||||
| 下载 Patch | ✓ | ✘ | ✓ | ✓ | ✓ | / | ✘ |
|
||||
|
||||
#### 第三方集成
|
||||
|
||||
|
@ -124,4 +126,5 @@ _表格中的符号含义:_
|
|||
| 二次验证 (2FA) | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✘ |
|
||||
| 集成 Mattermost/Slack | ✓ | ✓ | ⁄ | ✓ | ✓ | ⁄ | ✓ |
|
||||
| 集成 Discord | ✓ | ✓ | ✓ | ✓ | ✓ | ✘ | ✘ |
|
||||
| 集成 Microsoft Teams | ✓ | ✘ | ✓ | ✓ | ✓ | ✓ | ✘ |
|
||||
| 显示外部 CI/CD 的状态 | ✓ | ✘ | ✓ | ✓ | ✓ | ✓ | ✓ |
|
||||
|
|
|
@ -0,0 +1,18 @@
|
|||
---
|
||||
date: "2019-11-12T16:00:00+02:00"
|
||||
title: "Search"
|
||||
slug: "search"
|
||||
weight: 4
|
||||
toc: false
|
||||
draft: false
|
||||
sitemap:
|
||||
priority : 0.1
|
||||
layout: "search"
|
||||
---
|
||||
|
||||
|
||||
This file exists solely to respond to /search URL with the related `search` layout template.
|
||||
|
||||
No content shown here is rendered, all content is based in the template layouts/doc/search.html
|
||||
|
||||
Setting a very low sitemap priority will tell search engines this is not important content.
|
|
@ -5,12 +5,6 @@ slug: "search"
|
|||
weight: 4
|
||||
toc: false
|
||||
draft: false
|
||||
menu:
|
||||
sidebar:
|
||||
parent: "help"
|
||||
name: "Search"
|
||||
weight: 4
|
||||
identifier: "search"
|
||||
sitemap:
|
||||
priority : 0.1
|
||||
layout: "search"
|
||||
|
|
|
@ -5,12 +5,6 @@ slug: "search"
|
|||
weight: 4
|
||||
toc: false
|
||||
draft: false
|
||||
menu:
|
||||
sidebar:
|
||||
parent: "help"
|
||||
name: "Chercher"
|
||||
weight: 4
|
||||
identifier: "search"
|
||||
sitemap:
|
||||
priority : 0.1
|
||||
layout: "search"
|
||||
|
|
|
@ -0,0 +1,18 @@
|
|||
---
|
||||
date: "2019-11-12T16:00:00+02:00"
|
||||
title: "Search"
|
||||
slug: "search"
|
||||
weight: 4
|
||||
toc: false
|
||||
draft: false
|
||||
sitemap:
|
||||
priority : 0.1
|
||||
layout: "search"
|
||||
---
|
||||
|
||||
|
||||
This file exists solely to respond to /search URL with the related `search` layout template.
|
||||
|
||||
No content shown here is rendered, all content is based in the template layouts/doc/search.html
|
||||
|
||||
Setting a very low sitemap priority will tell search engines this is not important content.
|
|
@ -0,0 +1,18 @@
|
|||
---
|
||||
date: "2019-11-12T16:00:00+02:00"
|
||||
title: "Search"
|
||||
slug: "search"
|
||||
weight: 4
|
||||
toc: false
|
||||
draft: false
|
||||
sitemap:
|
||||
priority : 0.1
|
||||
layout: "search"
|
||||
---
|
||||
|
||||
|
||||
This file exists solely to respond to /search URL with the related `search` layout template.
|
||||
|
||||
No content shown here is rendered, all content is based in the template layouts/doc/search.html
|
||||
|
||||
Setting a very low sitemap priority will tell search engines this is not important content.
|
|
@ -5,12 +5,6 @@ slug: "search"
|
|||
weight: 4
|
||||
toc: false
|
||||
draft: false
|
||||
menu:
|
||||
sidebar:
|
||||
parent: "help"
|
||||
name: "搜索"
|
||||
weight: 4
|
||||
identifier: "search"
|
||||
sitemap:
|
||||
priority : 0.1
|
||||
layout: "search"
|
||||
|
|
|
@ -5,12 +5,6 @@ slug: "search"
|
|||
weight: 4
|
||||
toc: false
|
||||
draft: false
|
||||
menu:
|
||||
sidebar:
|
||||
parent: "help"
|
||||
name: "搜尋"
|
||||
weight: 4
|
||||
identifier: "search"
|
||||
sitemap:
|
||||
priority : 0.1
|
||||
layout: "search"
|
||||
|
|
|
@ -27,7 +27,7 @@ To authenticate to the Package Registry, you need to provide [custom HTTP header
|
|||
## Publish a package
|
||||
|
||||
To publish a generic package perform a HTTP PUT operation with the package content in the request body.
|
||||
You cannot publish a package if a package of the same name and version already exists. You must delete the existing package first.
|
||||
You cannot publish a file with the same name twice to a package. You must delete the existing package version first.
|
||||
|
||||
```
|
||||
PUT https://gitea.example.com/api/packages/{owner}/generic/{package_name}/{package_version}/{file_name}
|
||||
|
@ -36,9 +36,9 @@ PUT https://gitea.example.com/api/packages/{owner}/generic/{package_name}/{packa
|
|||
| Parameter | Description |
|
||||
| ----------------- | ----------- |
|
||||
| `owner` | The owner of the package. |
|
||||
| `package_name` | The package name. It can contain only lowercase letters (`a-z`), uppercase letter (`A-Z`), numbers (`0-9`), dots (`.`), hyphens (`-`), or underscores (`_`). |
|
||||
| `package_version` | The package version, a non-empty string. |
|
||||
| `file_name` | The filename. It can contain only lowercase letters (`a-z`), uppercase letter (`A-Z`), numbers (`0-9`), dots (`.`), hyphens (`-`), or underscores (`_`). |
|
||||
| `package_name` | The package name. It can contain only lowercase letters (`a-z`), uppercase letter (`A-Z`), numbers (`0-9`), dots (`.`), hyphens (`-`), pluses (`+`), or underscores (`_`). |
|
||||
| `package_version` | The package version, a non-empty string without trailing or leading whitespaces. |
|
||||
| `file_name` | The filename. It can contain only lowercase letters (`a-z`), uppercase letter (`A-Z`), numbers (`0-9`), dots (`.`), hyphens (`-`), pluses (`+`), or underscores (`_`). |
|
||||
|
||||
Example request using HTTP Basic authentication:
|
||||
|
||||
|
@ -55,7 +55,8 @@ The server reponds with the following HTTP Status codes.
|
|||
| HTTP Status Code | Meaning |
|
||||
| ----------------- | ------- |
|
||||
| `201 Created` | The package has been published. |
|
||||
| `400 Bad Request` | The package name and/or version are invalid or a package with the same name and version already exist. |
|
||||
| `400 Bad Request` | The package name and/or version and/or file name are invalid. |
|
||||
| `409 Conflict` | A file with the same name exist already in the package. |
|
||||
|
||||
## Download a package
|
||||
|
||||
|
@ -80,3 +81,67 @@ Example request using HTTP Basic authentication:
|
|||
curl --user your_username:your_token_or_password \
|
||||
https://gitea.example.com/api/packages/testuser/generic/test_package/1.0.0/file.bin
|
||||
```
|
||||
|
||||
The server reponds with the following HTTP Status codes.
|
||||
|
||||
| HTTP Status Code | Meaning |
|
||||
| ----------------- | ------- |
|
||||
| `200 OK` | Success |
|
||||
| `404 Not Found` | The package or file was not found. |
|
||||
|
||||
## Delete a package
|
||||
|
||||
To delete a generic package perform a HTTP DELETE operation. This will delete all files of this version.
|
||||
|
||||
```
|
||||
DELETE https://gitea.example.com/api/packages/{owner}/generic/{package_name}/{package_version}
|
||||
```
|
||||
|
||||
| Parameter | Description |
|
||||
| ----------------- | ----------- |
|
||||
| `owner` | The owner of the package. |
|
||||
| `package_name` | The package name. |
|
||||
| `package_version` | The package version. |
|
||||
|
||||
Example request using HTTP Basic authentication:
|
||||
|
||||
```shell
|
||||
curl --user your_username:your_token_or_password -X DELETE \
|
||||
https://gitea.example.com/api/packages/testuser/generic/test_package/1.0.0
|
||||
```
|
||||
|
||||
The server reponds with the following HTTP Status codes.
|
||||
|
||||
| HTTP Status Code | Meaning |
|
||||
| ----------------- | ------- |
|
||||
| `204 No Content` | Success |
|
||||
| `404 Not Found` | The package was not found. |
|
||||
|
||||
## Delete a package file
|
||||
|
||||
To delete a file of a generic package perform a HTTP DELETE operation. This will delete the package version too if there is no file left.
|
||||
|
||||
```
|
||||
DELETE https://gitea.example.com/api/packages/{owner}/generic/{package_name}/{package_version}/{filename}
|
||||
```
|
||||
|
||||
| Parameter | Description |
|
||||
| ----------------- | ----------- |
|
||||
| `owner` | The owner of the package. |
|
||||
| `package_name` | The package name. |
|
||||
| `package_version` | The package version. |
|
||||
| `filename` | The filename. |
|
||||
|
||||
Example request using HTTP Basic authentication:
|
||||
|
||||
```shell
|
||||
curl --user your_username:your_token_or_password -X DELETE \
|
||||
https://gitea.example.com/api/packages/testuser/generic/test_package/1.0.0/file.bin
|
||||
```
|
||||
|
||||
The server reponds with the following HTTP Status codes.
|
||||
|
||||
| HTTP Status Code | Meaning |
|
||||
| ----------------- | ------- |
|
||||
| `204 No Content` | Success |
|
||||
| `404 Not Found` | The package or file was not found. |
|
||||
|
|
|
@ -81,6 +81,16 @@ To publish a package simply run:
|
|||
mvn deploy
|
||||
```
|
||||
|
||||
If you want to publish a prebuild package to the registry, you can use [`mvn deploy:deploy-file`](https://maven.apache.org/plugins/maven-deploy-plugin/deploy-file-mojo.html):
|
||||
|
||||
```shell
|
||||
mvn deploy:deploy-file -Durl=https://gitea.example.com/api/packages/{owner}/maven -DrepositoryId=gitea -Dfile=/path/to/package.jar
|
||||
```
|
||||
|
||||
| Parameter | Description |
|
||||
| -------------- | ----------- |
|
||||
| `owner` | The owner of the package. |
|
||||
|
||||
You cannot publish a package if a package of the same name and version already exists. You must delete the existing package first.
|
||||
|
||||
## Install a package
|
||||
|
|
|
@ -67,6 +67,26 @@ npm publish
|
|||
|
||||
You cannot publish a package if a package of the same name and version already exists. You must delete the existing package first.
|
||||
|
||||
## Unpublish a package
|
||||
|
||||
Delete a package by running the following command:
|
||||
|
||||
```shell
|
||||
npm unpublish {package_name}[@{package_version}]
|
||||
```
|
||||
|
||||
| Parameter | Description |
|
||||
| ----------------- | ----------- |
|
||||
| `package_name` | The package name. |
|
||||
| `package_version` | The package version. |
|
||||
|
||||
For example:
|
||||
|
||||
```shell
|
||||
npm unpublish @test/test_package
|
||||
npm unpublish @test/test_package@1.0.0
|
||||
```
|
||||
|
||||
## Install a package
|
||||
|
||||
To install a package from the package registry, execute the following command:
|
||||
|
@ -113,6 +133,7 @@ The tag name must not be a valid version. All tag names which are parsable as a
|
|||
npm install
|
||||
npm ci
|
||||
npm publish
|
||||
npm unpublish
|
||||
npm dist-tag
|
||||
npm view
|
||||
```
|
||||
|
|
|
@ -47,6 +47,8 @@ For example:
|
|||
dotnet nuget add source --name gitea --username testuser --password password123 https://gitea.example.com/api/packages/testuser/nuget/index.json
|
||||
```
|
||||
|
||||
You can add the source without credentials and use the [`--api-key`](https://docs.microsoft.com/en-us/dotnet/core/tools/dotnet-nuget-push) parameter when publishing packages. In this case you need to provide a [personal access token]({{< relref "doc/developers/api-usage.en-us.md#authentication" >}}).
|
||||
|
||||
## Publish a package
|
||||
|
||||
Publish a package by running the following command:
|
||||
|
|
|
@ -34,6 +34,7 @@ The following package managers are currently supported:
|
|||
| [Maven]({{< relref "doc/packages/maven.en-us.md" >}}) | Java | `mvn`, `gradle` |
|
||||
| [npm]({{< relref "doc/packages/npm.en-us.md" >}}) | JavaScript | `npm`, `yarn` |
|
||||
| [NuGet]({{< relref "doc/packages/nuget.en-us.md" >}}) | .NET | `nuget` |
|
||||
| [Pub]({{< relref "doc/packages/pub.en-us.md" >}}) | Dart | `dart`, `flutter` |
|
||||
| [PyPI]({{< relref "doc/packages/pypi.en-us.md" >}}) | Python | `pip`, `twine` |
|
||||
| [RubyGems]({{< relref "doc/packages/rubygems.en-us.md" >}}) | Ruby | `gem`, `Bundler` |
|
||||
|
||||
|
|
|
@ -0,0 +1,83 @@
|
|||
---
|
||||
date: "2022-07-31T00:00:00+00:00"
|
||||
title: "Pub Packages Repository"
|
||||
slug: "packages/pub"
|
||||
draft: false
|
||||
toc: false
|
||||
menu:
|
||||
sidebar:
|
||||
parent: "packages"
|
||||
name: "Pub"
|
||||
weight: 90
|
||||
identifier: "pub"
|
||||
---
|
||||
|
||||
# Pub Packages Repository
|
||||
|
||||
Publish [Pub](https://dart.dev/guides/packages) packages for your user or organization.
|
||||
|
||||
**Table of Contents**
|
||||
|
||||
{{< toc >}}
|
||||
|
||||
## Requirements
|
||||
|
||||
To work with the Pub package registry, you need to use the tools [dart](https://dart.dev/tools/dart-tool) and/or [flutter](https://docs.flutter.dev/reference/flutter-cli).
|
||||
|
||||
The following examples use dart.
|
||||
|
||||
## Configuring the package registry
|
||||
|
||||
To register the package registry and provide credentials, execute:
|
||||
|
||||
```shell
|
||||
dart pub token add https://gitea.example.com/api/packages/{owner}/pub
|
||||
```
|
||||
|
||||
| Placeholder | Description |
|
||||
| ------------ | ----------- |
|
||||
| `owner` | The owner of the package. |
|
||||
|
||||
You need to provide your [personal access token]({{< relref "doc/developers/api-usage.en-us.md#authentication" >}}).
|
||||
|
||||
## Publish a package
|
||||
|
||||
To publish a package, edit the `pubspec.yaml` and add the following line:
|
||||
|
||||
```yaml
|
||||
publish_to: https://gitea.example.com/api/packages/{owner}/pub
|
||||
```
|
||||
|
||||
| Placeholder | Description |
|
||||
| ------------ | ----------- |
|
||||
| `owner` | The owner of the package. |
|
||||
|
||||
Now you can publish the package by running the following command:
|
||||
|
||||
```shell
|
||||
dart pub publish
|
||||
```
|
||||
|
||||
You cannot publish a package if a package of the same name and version already exists. You must delete the existing package first.
|
||||
|
||||
## Install a package
|
||||
|
||||
To install a Pub package from the package registry, execute the following command:
|
||||
|
||||
```shell
|
||||
dart pub add {package_name} --hosted-url=https://gitea.example.com/api/packages/{owner}/pub/
|
||||
```
|
||||
|
||||
| Parameter | Description |
|
||||
| ----------------- | ----------- |
|
||||
| `owner` | The owner of the package. |
|
||||
| `package_name` | The package name. |
|
||||
|
||||
For example:
|
||||
|
||||
```shell
|
||||
# use latest version
|
||||
dart pub add mypackage --hosted-url=https://gitea.example.com/api/packages/testuser/pub/
|
||||
# specify version
|
||||
dart pub add mypackage:1.0.8 --hosted-url=https://gitea.example.com/api/packages/testuser/pub/
|
||||
```
|
|
@ -8,7 +8,7 @@ menu:
|
|||
sidebar:
|
||||
parent: "packages"
|
||||
name: "PyPI"
|
||||
weight: 90
|
||||
weight: 100
|
||||
identifier: "pypi"
|
||||
---
|
||||
|
||||
|
|
|
@ -8,7 +8,7 @@ menu:
|
|||
sidebar:
|
||||
parent: "packages"
|
||||
name: "RubyGems"
|
||||
weight: 100
|
||||
weight: 110
|
||||
identifier: "rubygems"
|
||||
---
|
||||
|
||||
|
|
|
@ -23,6 +23,12 @@ To update Gitea, download a newer version, stop the old one, perform a backup, a
|
|||
Every time a Gitea instance starts up, it checks whether a database migration should be run.
|
||||
If a database migration is required, Gitea will take some time to complete the upgrade and then serve.
|
||||
|
||||
## Check the Changelog for breaking changes
|
||||
|
||||
To make Gitea better, some breaking changes are unavoidable, especially for big milestone releases.
|
||||
Before upgrade, please read the [Changelog on Gitea blog](https://blog.gitea.io/)
|
||||
and check whether the breaking changes affect your Gitea instance.
|
||||
|
||||
## Backup for downgrade
|
||||
|
||||
Gitea keeps compatibility for patch versions whose first two fields are the same (`a.b.x` -> `a.b.y`),
|
||||
|
|
|
@ -11,12 +11,6 @@
|
|||
<div class=" content">
|
||||
<section class="resume-section p-3 p-lg-5 d-flex flex-column">
|
||||
<div class="my-auto" >
|
||||
<form action="{{ "search" | absLangURL }}">
|
||||
<label>Search:
|
||||
<input id="search-query" name="s"/>
|
||||
</label>
|
||||
</form>
|
||||
<br/>
|
||||
<div id="search-results"></div>
|
||||
</div>
|
||||
</section>
|
||||
|
|
1
go.mod
|
@ -5,6 +5,7 @@ go 1.18
|
|||
require (
|
||||
code.gitea.io/gitea-vet v0.2.2-0.20220122151748-48ebc902541b
|
||||
code.gitea.io/sdk/gitea v0.15.1
|
||||
codeberg.org/gusted/mcaptcha v0.0.0-20220722211632-55c1ffff1222
|
||||
gitea.com/go-chi/binding v0.0.0-20220309004920-114340dabecb
|
||||
gitea.com/go-chi/cache v0.2.0
|
||||
gitea.com/go-chi/captcha v0.0.0-20211013065431-70641c1a35d5
|
||||
|
|
2
go.sum
|
@ -62,6 +62,8 @@ code.gitea.io/gitea-vet v0.2.2-0.20220122151748-48ebc902541b/go.mod h1:zcNbT/aJE
|
|||
code.gitea.io/sdk/gitea v0.11.3/go.mod h1:z3uwDV/b9Ls47NGukYM9XhnHtqPh/J+t40lsUrR6JDY=
|
||||
code.gitea.io/sdk/gitea v0.15.1 h1:WJreC7YYuxbn0UDaPuWIe/mtiNKTvLN8MLkaw71yx/M=
|
||||
code.gitea.io/sdk/gitea v0.15.1/go.mod h1:klY2LVI3s3NChzIk/MzMn7G1FHrfU7qd63iSMVoHRBA=
|
||||
codeberg.org/gusted/mcaptcha v0.0.0-20220722211632-55c1ffff1222 h1:PCW4i+gnQ9XxF8V+nBch3KWdGe4MiP3xXUCA/z0jhHk=
|
||||
codeberg.org/gusted/mcaptcha v0.0.0-20220722211632-55c1ffff1222/go.mod h1:IIAjsijsd8q1isWX8MACefDEgTQslQ4stk2AeeTt3kM=
|
||||
contrib.go.opencensus.io/exporter/aws v0.0.0-20181029163544-2befc13012d0/go.mod h1:uu1P0UCM/6RbsMrgPa98ll8ZcHM858i/AD06a9aLRCA=
|
||||
contrib.go.opencensus.io/exporter/ocagent v0.5.0/go.mod h1:ImxhfLRpxoYiSq891pBrLVhN+qmP8BTVvdH2YLs7Gl0=
|
||||
contrib.go.opencensus.io/exporter/stackdriver v0.12.1/go.mod h1:iwB6wGarfphGGe/e5CWqyUk/cLzKnWsOKPVW3no6OTw=
|
||||
|
|
|
@ -16,6 +16,7 @@ import (
|
|||
repo_model "code.gitea.io/gitea/models/repo"
|
||||
"code.gitea.io/gitea/models/unittest"
|
||||
user_model "code.gitea.io/gitea/models/user"
|
||||
"code.gitea.io/gitea/modules/setting"
|
||||
api "code.gitea.io/gitea/modules/structs"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
@ -171,19 +172,21 @@ func TestAPISearchIssues(t *testing.T) {
|
|||
|
||||
token := getUserToken(t, "user2")
|
||||
|
||||
link, _ := url.Parse("/api/v1/repos/issues/search")
|
||||
req := NewRequest(t, "GET", link.String()+"?token="+token)
|
||||
resp := MakeRequest(t, req, http.StatusOK)
|
||||
var apiIssues []*api.Issue
|
||||
DecodeJSON(t, resp, &apiIssues)
|
||||
assert.Len(t, apiIssues, 10)
|
||||
// as this API was used in the frontend, it uses UI page size
|
||||
expectedIssueCount := 15 // from the fixtures
|
||||
if expectedIssueCount > setting.UI.IssuePagingNum {
|
||||
expectedIssueCount = setting.UI.IssuePagingNum
|
||||
}
|
||||
|
||||
link, _ := url.Parse("/api/v1/repos/issues/search")
|
||||
query := url.Values{"token": {getUserToken(t, "user1")}}
|
||||
var apiIssues []*api.Issue
|
||||
|
||||
query := url.Values{"token": {token}}
|
||||
link.RawQuery = query.Encode()
|
||||
req = NewRequest(t, "GET", link.String())
|
||||
resp = MakeRequest(t, req, http.StatusOK)
|
||||
req := NewRequest(t, "GET", link.String())
|
||||
resp := MakeRequest(t, req, http.StatusOK)
|
||||
DecodeJSON(t, resp, &apiIssues)
|
||||
assert.Len(t, apiIssues, 10)
|
||||
assert.Len(t, apiIssues, expectedIssueCount)
|
||||
|
||||
since := "2000-01-01T00%3A50%3A01%2B00%3A00" // 946687801
|
||||
before := time.Unix(999307200, 0).Format(time.RFC3339)
|
||||
|
@ -211,14 +214,15 @@ func TestAPISearchIssues(t *testing.T) {
|
|||
resp = MakeRequest(t, req, http.StatusOK)
|
||||
DecodeJSON(t, resp, &apiIssues)
|
||||
assert.EqualValues(t, "17", resp.Header().Get("X-Total-Count"))
|
||||
assert.Len(t, apiIssues, 10) // there are more but 10 is page item limit
|
||||
assert.Len(t, apiIssues, 17)
|
||||
|
||||
query.Add("limit", "20")
|
||||
query.Add("limit", "10")
|
||||
link.RawQuery = query.Encode()
|
||||
req = NewRequest(t, "GET", link.String())
|
||||
resp = MakeRequest(t, req, http.StatusOK)
|
||||
DecodeJSON(t, resp, &apiIssues)
|
||||
assert.Len(t, apiIssues, 17)
|
||||
assert.EqualValues(t, "17", resp.Header().Get("X-Total-Count"))
|
||||
assert.Len(t, apiIssues, 10)
|
||||
|
||||
query = url.Values{"assigned": {"true"}, "state": {"all"}, "token": {token}}
|
||||
link.RawQuery = query.Encode()
|
||||
|
@ -266,23 +270,21 @@ func TestAPISearchIssues(t *testing.T) {
|
|||
func TestAPISearchIssuesWithLabels(t *testing.T) {
|
||||
defer prepareTestEnv(t)()
|
||||
|
||||
token := getUserToken(t, "user1")
|
||||
// as this API was used in the frontend, it uses UI page size
|
||||
expectedIssueCount := 15 // from the fixtures
|
||||
if expectedIssueCount > setting.UI.IssuePagingNum {
|
||||
expectedIssueCount = setting.UI.IssuePagingNum
|
||||
}
|
||||
|
||||
link, _ := url.Parse("/api/v1/repos/issues/search")
|
||||
req := NewRequest(t, "GET", link.String()+"?token="+token)
|
||||
resp := MakeRequest(t, req, http.StatusOK)
|
||||
query := url.Values{"token": {getUserToken(t, "user1")}}
|
||||
var apiIssues []*api.Issue
|
||||
DecodeJSON(t, resp, &apiIssues)
|
||||
|
||||
assert.Len(t, apiIssues, 10)
|
||||
|
||||
query := url.Values{}
|
||||
query.Add("token", token)
|
||||
link.RawQuery = query.Encode()
|
||||
req = NewRequest(t, "GET", link.String())
|
||||
resp = MakeRequest(t, req, http.StatusOK)
|
||||
req := NewRequest(t, "GET", link.String())
|
||||
resp := MakeRequest(t, req, http.StatusOK)
|
||||
DecodeJSON(t, resp, &apiIssues)
|
||||
assert.Len(t, apiIssues, 10)
|
||||
assert.Len(t, apiIssues, expectedIssueCount)
|
||||
|
||||
query.Add("labels", "label1")
|
||||
link.RawQuery = query.Encode()
|
||||
|
|
|
@ -276,11 +276,23 @@ func TestPackageContainer(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
// Overwrite existing tag
|
||||
req = NewRequest(t, "GET", fmt.Sprintf("%s/manifests/%s", url, tag))
|
||||
addTokenAuthHeader(req, userToken)
|
||||
MakeRequest(t, req, http.StatusOK)
|
||||
|
||||
pv, err = packages_model.GetVersionByNameAndVersion(db.DefaultContext, user.ID, packages_model.TypeContainer, image, tag)
|
||||
assert.NoError(t, err)
|
||||
assert.EqualValues(t, 1, pv.DownloadCount)
|
||||
|
||||
// Overwrite existing tag should keep the download count
|
||||
req = NewRequestWithBody(t, "PUT", fmt.Sprintf("%s/manifests/%s", url, tag), strings.NewReader(manifestContent))
|
||||
addTokenAuthHeader(req, userToken)
|
||||
req.Header.Set("Content-Type", oci.MediaTypeDockerManifest)
|
||||
MakeRequest(t, req, http.StatusCreated)
|
||||
|
||||
pv, err = packages_model.GetVersionByNameAndVersion(db.DefaultContext, user.ID, packages_model.TypeContainer, image, tag)
|
||||
assert.NoError(t, err)
|
||||
assert.EqualValues(t, 1, pv.DownloadCount)
|
||||
})
|
||||
|
||||
t.Run("HeadManifest", func(t *testing.T) {
|
||||
|
|
|
@ -23,16 +23,16 @@ func TestPackageGeneric(t *testing.T) {
|
|||
user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User)
|
||||
|
||||
packageName := "te-st_pac.kage"
|
||||
packageVersion := "1.0.3"
|
||||
packageVersion := "1.0.3-te st"
|
||||
filename := "fi-le_na.me"
|
||||
content := []byte{1, 2, 3}
|
||||
|
||||
url := fmt.Sprintf("/api/packages/%s/generic/%s/%s/%s", user.Name, packageName, packageVersion, filename)
|
||||
url := fmt.Sprintf("/api/packages/%s/generic/%s/%s", user.Name, packageName, packageVersion)
|
||||
|
||||
t.Run("Upload", func(t *testing.T) {
|
||||
defer PrintCurrentTest(t)()
|
||||
|
||||
req := NewRequestWithBody(t, "PUT", url, bytes.NewReader(content))
|
||||
req := NewRequestWithBody(t, "PUT", url+"/"+filename, bytes.NewReader(content))
|
||||
AddBasicAuthHeader(req, user.Name)
|
||||
MakeRequest(t, req, http.StatusCreated)
|
||||
|
||||
|
@ -55,54 +55,139 @@ func TestPackageGeneric(t *testing.T) {
|
|||
pb, err := packages.GetBlobByID(db.DefaultContext, pfs[0].BlobID)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, int64(len(content)), pb.Size)
|
||||
})
|
||||
|
||||
t.Run("UploadExists", func(t *testing.T) {
|
||||
t.Run("Exists", func(t *testing.T) {
|
||||
defer PrintCurrentTest(t)()
|
||||
|
||||
req := NewRequestWithBody(t, "PUT", url, bytes.NewReader(content))
|
||||
req := NewRequestWithBody(t, "PUT", url+"/"+filename, bytes.NewReader(content))
|
||||
AddBasicAuthHeader(req, user.Name)
|
||||
MakeRequest(t, req, http.StatusConflict)
|
||||
})
|
||||
|
||||
t.Run("Additional", func(t *testing.T) {
|
||||
defer PrintCurrentTest(t)()
|
||||
|
||||
req := NewRequestWithBody(t, "PUT", url+"/dummy.bin", bytes.NewReader(content))
|
||||
AddBasicAuthHeader(req, user.Name)
|
||||
MakeRequest(t, req, http.StatusCreated)
|
||||
|
||||
// Check deduplication
|
||||
pfs, err := packages.GetFilesByVersionID(db.DefaultContext, pvs[0].ID)
|
||||
assert.NoError(t, err)
|
||||
assert.Len(t, pfs, 2)
|
||||
assert.Equal(t, pfs[0].BlobID, pfs[1].BlobID)
|
||||
})
|
||||
|
||||
t.Run("InvalidParameter", func(t *testing.T) {
|
||||
defer PrintCurrentTest(t)()
|
||||
|
||||
req := NewRequestWithBody(t, "PUT", fmt.Sprintf("/api/packages/%s/generic/%s/%s/%s", user.Name, "invalid+package name", packageVersion, filename), bytes.NewReader(content))
|
||||
AddBasicAuthHeader(req, user.Name)
|
||||
MakeRequest(t, req, http.StatusBadRequest)
|
||||
|
||||
req = NewRequestWithBody(t, "PUT", fmt.Sprintf("/api/packages/%s/generic/%s/%s/%s", user.Name, packageName, "%20test ", filename), bytes.NewReader(content))
|
||||
AddBasicAuthHeader(req, user.Name)
|
||||
MakeRequest(t, req, http.StatusBadRequest)
|
||||
|
||||
req = NewRequestWithBody(t, "PUT", fmt.Sprintf("/api/packages/%s/generic/%s/%s/%s", user.Name, packageName, packageVersion, "inval+id.na me"), bytes.NewReader(content))
|
||||
AddBasicAuthHeader(req, user.Name)
|
||||
MakeRequest(t, req, http.StatusBadRequest)
|
||||
})
|
||||
})
|
||||
|
||||
t.Run("Download", func(t *testing.T) {
|
||||
defer PrintCurrentTest(t)()
|
||||
|
||||
req := NewRequest(t, "GET", url)
|
||||
checkDownloadCount := func(count int64) {
|
||||
pvs, err := packages.GetVersionsByPackageType(db.DefaultContext, user.ID, packages.TypeGeneric)
|
||||
assert.NoError(t, err)
|
||||
assert.Len(t, pvs, 1)
|
||||
assert.Equal(t, count, pvs[0].DownloadCount)
|
||||
}
|
||||
|
||||
checkDownloadCount(0)
|
||||
|
||||
req := NewRequest(t, "GET", url+"/"+filename)
|
||||
resp := MakeRequest(t, req, http.StatusOK)
|
||||
|
||||
assert.Equal(t, content, resp.Body.Bytes())
|
||||
|
||||
pvs, err := packages.GetVersionsByPackageType(db.DefaultContext, user.ID, packages.TypeGeneric)
|
||||
assert.NoError(t, err)
|
||||
assert.Len(t, pvs, 1)
|
||||
assert.Equal(t, int64(1), pvs[0].DownloadCount)
|
||||
checkDownloadCount(1)
|
||||
|
||||
req = NewRequest(t, "GET", url+"/dummy.bin")
|
||||
MakeRequest(t, req, http.StatusOK)
|
||||
|
||||
checkDownloadCount(2)
|
||||
|
||||
t.Run("NotExists", func(t *testing.T) {
|
||||
defer PrintCurrentTest(t)()
|
||||
|
||||
req := NewRequest(t, "GET", url+"/not.found")
|
||||
MakeRequest(t, req, http.StatusNotFound)
|
||||
})
|
||||
})
|
||||
|
||||
t.Run("Delete", func(t *testing.T) {
|
||||
defer PrintCurrentTest(t)()
|
||||
|
||||
req := NewRequest(t, "DELETE", url)
|
||||
t.Run("File", func(t *testing.T) {
|
||||
defer PrintCurrentTest(t)()
|
||||
|
||||
req := NewRequest(t, "DELETE", url+"/"+filename)
|
||||
MakeRequest(t, req, http.StatusUnauthorized)
|
||||
|
||||
req = NewRequest(t, "DELETE", url+"/"+filename)
|
||||
AddBasicAuthHeader(req, user.Name)
|
||||
MakeRequest(t, req, http.StatusOK)
|
||||
MakeRequest(t, req, http.StatusNoContent)
|
||||
|
||||
req = NewRequest(t, "GET", url+"/"+filename)
|
||||
MakeRequest(t, req, http.StatusNotFound)
|
||||
|
||||
req = NewRequest(t, "DELETE", url+"/"+filename)
|
||||
AddBasicAuthHeader(req, user.Name)
|
||||
MakeRequest(t, req, http.StatusNotFound)
|
||||
|
||||
pvs, err := packages.GetVersionsByPackageType(db.DefaultContext, user.ID, packages.TypeGeneric)
|
||||
assert.NoError(t, err)
|
||||
assert.Len(t, pvs, 1)
|
||||
|
||||
t.Run("RemovesVersion", func(t *testing.T) {
|
||||
defer PrintCurrentTest(t)()
|
||||
|
||||
req = NewRequest(t, "DELETE", url+"/dummy.bin")
|
||||
AddBasicAuthHeader(req, user.Name)
|
||||
MakeRequest(t, req, http.StatusNoContent)
|
||||
|
||||
pvs, err := packages.GetVersionsByPackageType(db.DefaultContext, user.ID, packages.TypeGeneric)
|
||||
assert.NoError(t, err)
|
||||
assert.Empty(t, pvs)
|
||||
})
|
||||
|
||||
t.Run("DownloadNotExists", func(t *testing.T) {
|
||||
defer PrintCurrentTest(t)()
|
||||
|
||||
req := NewRequest(t, "GET", url)
|
||||
MakeRequest(t, req, http.StatusNotFound)
|
||||
})
|
||||
|
||||
t.Run("DeleteNotExists", func(t *testing.T) {
|
||||
t.Run("Version", func(t *testing.T) {
|
||||
defer PrintCurrentTest(t)()
|
||||
|
||||
req := NewRequest(t, "DELETE", url)
|
||||
req := NewRequestWithBody(t, "PUT", url+"/"+filename, bytes.NewReader(content))
|
||||
AddBasicAuthHeader(req, user.Name)
|
||||
MakeRequest(t, req, http.StatusCreated)
|
||||
|
||||
req = NewRequest(t, "DELETE", url)
|
||||
MakeRequest(t, req, http.StatusUnauthorized)
|
||||
|
||||
req = NewRequest(t, "DELETE", url)
|
||||
AddBasicAuthHeader(req, user.Name)
|
||||
MakeRequest(t, req, http.StatusNoContent)
|
||||
|
||||
pvs, err := packages.GetVersionsByPackageType(db.DefaultContext, user.ID, packages.TypeGeneric)
|
||||
assert.NoError(t, err)
|
||||
assert.Empty(t, pvs)
|
||||
|
||||
req = NewRequest(t, "GET", url+"/"+filename)
|
||||
MakeRequest(t, req, http.StatusNotFound)
|
||||
|
||||
req = NewRequest(t, "DELETE", url)
|
||||
AddBasicAuthHeader(req, user.Name)
|
||||
MakeRequest(t, req, http.StatusNotFound)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
|
|
@ -42,6 +42,7 @@ func TestPackageMaven(t *testing.T) {
|
|||
defer PrintCurrentTest(t)()
|
||||
|
||||
putFile(t, fmt.Sprintf("/%s/%s", packageVersion, filename), "test", http.StatusCreated)
|
||||
putFile(t, fmt.Sprintf("/%s/%s", packageVersion, filename), "test", http.StatusBadRequest)
|
||||
putFile(t, "/maven-metadata.xml", "test", http.StatusOK)
|
||||
|
||||
pvs, err := packages.GetVersionsByPackageType(db.DefaultContext, user.ID, packages.TypeMaven)
|
||||
|
@ -135,12 +136,14 @@ func TestPackageMaven(t *testing.T) {
|
|||
pfs, err := packages.GetFilesByVersionID(db.DefaultContext, pvs[0].ID)
|
||||
assert.NoError(t, err)
|
||||
assert.Len(t, pfs, 2)
|
||||
i := 0
|
||||
if strings.HasSuffix(pfs[1].Name, ".pom") {
|
||||
i = 1
|
||||
for _, pf := range pfs {
|
||||
if strings.HasSuffix(pf.Name, ".pom") {
|
||||
assert.Equal(t, filename+".pom", pf.Name)
|
||||
assert.True(t, pf.IsLead)
|
||||
} else {
|
||||
assert.False(t, pf.IsLead)
|
||||
}
|
||||
}
|
||||
assert.Equal(t, filename+".pom", pfs[i].Name)
|
||||
assert.True(t, pfs[i].IsLead)
|
||||
})
|
||||
|
||||
t.Run("DownloadPOM", func(t *testing.T) {
|
||||
|
@ -202,4 +205,13 @@ func TestPackageMaven(t *testing.T) {
|
|||
assert.Equal(t, checksum, resp.Body.String())
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("UploadSnapshot", func(t *testing.T) {
|
||||
snapshotVersion := packageVersion + "-SNAPSHOT"
|
||||
|
||||
putFile(t, fmt.Sprintf("/%s/%s", snapshotVersion, filename), "test", http.StatusCreated)
|
||||
putFile(t, "/maven-metadata.xml", "test", http.StatusOK)
|
||||
putFile(t, fmt.Sprintf("/%s/maven-metadata.xml", snapshotVersion), "test", http.StatusCreated)
|
||||
putFile(t, fmt.Sprintf("/%s/maven-metadata.xml", snapshotVersion), "test-overwrite", http.StatusCreated)
|
||||
})
|
||||
}
|
||||
|
|
|
@ -36,17 +36,19 @@ func TestPackageNpm(t *testing.T) {
|
|||
packageDescription := "Test Description"
|
||||
|
||||
data := "H4sIAAAAAAAA/ytITM5OTE/VL4DQelnF+XkMVAYGBgZmJiYK2MRBwNDcSIHB2NTMwNDQzMwAqA7IMDUxA9LUdgg2UFpcklgEdAql5kD8ogCnhwio5lJQUMpLzE1VslJQcihOzi9I1S9JLS7RhSYIJR2QgrLUouLM/DyQGkM9Az1D3YIiqExKanFyUWZBCVQ2BKhVwQVJDKwosbQkI78IJO/tZ+LsbRykxFXLNdA+HwWjYBSMgpENACgAbtAACAAA"
|
||||
upload := `{
|
||||
|
||||
buildUpload := func(version string) string {
|
||||
return `{
|
||||
"_id": "` + packageName + `",
|
||||
"name": "` + packageName + `",
|
||||
"description": "` + packageDescription + `",
|
||||
"dist-tags": {
|
||||
"` + packageTag + `": "` + packageVersion + `"
|
||||
"` + packageTag + `": "` + version + `"
|
||||
},
|
||||
"versions": {
|
||||
"` + packageVersion + `": {
|
||||
"` + version + `": {
|
||||
"name": "` + packageName + `",
|
||||
"version": "` + packageVersion + `",
|
||||
"version": "` + version + `",
|
||||
"description": "` + packageDescription + `",
|
||||
"author": {
|
||||
"name": "` + packageAuthor + `"
|
||||
|
@ -58,11 +60,12 @@ func TestPackageNpm(t *testing.T) {
|
|||
}
|
||||
},
|
||||
"_attachments": {
|
||||
"` + packageName + `-` + packageVersion + `.tgz": {
|
||||
"` + packageName + `-` + version + `.tgz": {
|
||||
"data": "` + data + `"
|
||||
}
|
||||
}
|
||||
}`
|
||||
}
|
||||
|
||||
root := fmt.Sprintf("/api/packages/%s/npm/%s", user.Name, url.QueryEscape(packageName))
|
||||
tagsRoot := fmt.Sprintf("/api/packages/%s/npm/-/package/%s/dist-tags", user.Name, url.QueryEscape(packageName))
|
||||
|
@ -71,7 +74,7 @@ func TestPackageNpm(t *testing.T) {
|
|||
t.Run("Upload", func(t *testing.T) {
|
||||
defer PrintCurrentTest(t)()
|
||||
|
||||
req := NewRequestWithBody(t, "PUT", root, strings.NewReader(upload))
|
||||
req := NewRequestWithBody(t, "PUT", root, strings.NewReader(buildUpload(packageVersion)))
|
||||
req = addTokenAuthHeader(req, token)
|
||||
MakeRequest(t, req, http.StatusCreated)
|
||||
|
||||
|
@ -103,7 +106,7 @@ func TestPackageNpm(t *testing.T) {
|
|||
t.Run("UploadExists", func(t *testing.T) {
|
||||
defer PrintCurrentTest(t)()
|
||||
|
||||
req := NewRequestWithBody(t, "PUT", root, strings.NewReader(upload))
|
||||
req := NewRequestWithBody(t, "PUT", root, strings.NewReader(buildUpload(packageVersion)))
|
||||
req = addTokenAuthHeader(req, token)
|
||||
MakeRequest(t, req, http.StatusBadRequest)
|
||||
})
|
||||
|
@ -219,4 +222,57 @@ func TestPackageNpm(t *testing.T) {
|
|||
test(t, http.StatusOK, "dummy")
|
||||
test(t, http.StatusOK, packageTag2)
|
||||
})
|
||||
|
||||
t.Run("Delete", func(t *testing.T) {
|
||||
defer PrintCurrentTest(t)()
|
||||
|
||||
req := NewRequestWithBody(t, "PUT", root, strings.NewReader(buildUpload(packageVersion+"-dummy")))
|
||||
req = addTokenAuthHeader(req, token)
|
||||
MakeRequest(t, req, http.StatusCreated)
|
||||
|
||||
req = NewRequest(t, "PUT", root+"/-rev/dummy")
|
||||
MakeRequest(t, req, http.StatusUnauthorized)
|
||||
|
||||
req = NewRequest(t, "PUT", root+"/-rev/dummy")
|
||||
req = addTokenAuthHeader(req, token)
|
||||
MakeRequest(t, req, http.StatusOK)
|
||||
|
||||
t.Run("Version", func(t *testing.T) {
|
||||
defer PrintCurrentTest(t)()
|
||||
|
||||
pvs, err := packages.GetVersionsByPackageType(db.DefaultContext, user.ID, packages.TypeNpm)
|
||||
assert.NoError(t, err)
|
||||
assert.Len(t, pvs, 2)
|
||||
|
||||
req := NewRequest(t, "DELETE", fmt.Sprintf("%s/-/%s/%s/-rev/dummy", root, packageVersion, filename))
|
||||
MakeRequest(t, req, http.StatusUnauthorized)
|
||||
|
||||
req = NewRequest(t, "DELETE", fmt.Sprintf("%s/-/%s/%s/-rev/dummy", root, packageVersion, filename))
|
||||
req = addTokenAuthHeader(req, token)
|
||||
MakeRequest(t, req, http.StatusOK)
|
||||
|
||||
pvs, err = packages.GetVersionsByPackageType(db.DefaultContext, user.ID, packages.TypeNpm)
|
||||
assert.NoError(t, err)
|
||||
assert.Len(t, pvs, 1)
|
||||
})
|
||||
|
||||
t.Run("Full", func(t *testing.T) {
|
||||
defer PrintCurrentTest(t)()
|
||||
|
||||
pvs, err := packages.GetVersionsByPackageType(db.DefaultContext, user.ID, packages.TypeNpm)
|
||||
assert.NoError(t, err)
|
||||
assert.Len(t, pvs, 1)
|
||||
|
||||
req := NewRequest(t, "DELETE", root+"/-rev/dummy")
|
||||
MakeRequest(t, req, http.StatusUnauthorized)
|
||||
|
||||
req = NewRequest(t, "DELETE", root+"/-rev/dummy")
|
||||
req = addTokenAuthHeader(req, token)
|
||||
MakeRequest(t, req, http.StatusOK)
|
||||
|
||||
pvs, err = packages.GetVersionsByPackageType(db.DefaultContext, user.ID, packages.TypeNpm)
|
||||
assert.NoError(t, err)
|
||||
assert.Len(t, pvs, 0)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
|
|
@ -24,9 +24,16 @@ import (
|
|||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func addNuGetAPIKeyHeader(request *http.Request, token string) *http.Request {
|
||||
request.Header.Set("X-NuGet-ApiKey", token)
|
||||
return request
|
||||
}
|
||||
|
||||
func TestPackageNuGet(t *testing.T) {
|
||||
defer prepareTestEnv(t)()
|
||||
|
||||
user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User)
|
||||
token := getUserToken(t, user.Name)
|
||||
|
||||
packageName := "test.package"
|
||||
packageVersion := "1.0.3"
|
||||
|
@ -60,6 +67,10 @@ func TestPackageNuGet(t *testing.T) {
|
|||
|
||||
req := NewRequest(t, "GET", fmt.Sprintf("%s/index.json", url))
|
||||
req = AddBasicAuthHeader(req, user.Name)
|
||||
MakeRequest(t, req, http.StatusOK)
|
||||
|
||||
req = NewRequest(t, "GET", fmt.Sprintf("%s/index.json", url))
|
||||
req = addNuGetAPIKeyHeader(req, token)
|
||||
resp := MakeRequest(t, req, http.StatusOK)
|
||||
|
||||
var result nuget.ServiceIndexResponse
|
||||
|
|
|
@ -0,0 +1,179 @@
|
|||
// Copyright 2022 The Gitea Authors. All rights reserved.
|
||||
// Use of this source code is governed by a MIT-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package integrations
|
||||
|
||||
import (
|
||||
"archive/tar"
|
||||
"bytes"
|
||||
"compress/gzip"
|
||||
"fmt"
|
||||
"io"
|
||||
"mime/multipart"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"code.gitea.io/gitea/models/db"
|
||||
"code.gitea.io/gitea/models/packages"
|
||||
"code.gitea.io/gitea/models/unittest"
|
||||
user_model "code.gitea.io/gitea/models/user"
|
||||
pub_module "code.gitea.io/gitea/modules/packages/pub"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestPackagePub(t *testing.T) {
|
||||
defer prepareTestEnv(t)()
|
||||
user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User)
|
||||
|
||||
token := "Bearer " + getUserToken(t, user.Name)
|
||||
|
||||
packageName := "test_package"
|
||||
packageVersion := "1.0.1"
|
||||
packageDescription := "Test Description"
|
||||
|
||||
filename := fmt.Sprintf("%s.tar.gz", packageVersion)
|
||||
|
||||
pubspecContent := `name: ` + packageName + `
|
||||
version: ` + packageVersion + `
|
||||
description: ` + packageDescription
|
||||
|
||||
var buf bytes.Buffer
|
||||
zw := gzip.NewWriter(&buf)
|
||||
archive := tar.NewWriter(zw)
|
||||
archive.WriteHeader(&tar.Header{
|
||||
Name: "pubspec.yaml",
|
||||
Mode: 0o600,
|
||||
Size: int64(len(pubspecContent)),
|
||||
})
|
||||
archive.Write([]byte(pubspecContent))
|
||||
archive.Close()
|
||||
zw.Close()
|
||||
content := buf.Bytes()
|
||||
|
||||
root := fmt.Sprintf("/api/packages/%s/pub", user.Name)
|
||||
|
||||
t.Run("Upload", func(t *testing.T) {
|
||||
defer PrintCurrentTest(t)()
|
||||
|
||||
uploadURL := root + "/api/packages/versions/new"
|
||||
|
||||
req := NewRequest(t, "GET", uploadURL)
|
||||
MakeRequest(t, req, http.StatusUnauthorized)
|
||||
|
||||
req = NewRequest(t, "GET", uploadURL)
|
||||
addTokenAuthHeader(req, token)
|
||||
resp := MakeRequest(t, req, http.StatusOK)
|
||||
|
||||
type UploadRequest struct {
|
||||
URL string `json:"url"`
|
||||
Fields map[string]string `json:"fields"`
|
||||
}
|
||||
|
||||
var result UploadRequest
|
||||
DecodeJSON(t, resp, &result)
|
||||
|
||||
assert.Empty(t, result.Fields)
|
||||
|
||||
uploadFile := func(t *testing.T, url string, content []byte, expectedStatus int) *httptest.ResponseRecorder {
|
||||
body := &bytes.Buffer{}
|
||||
writer := multipart.NewWriter(body)
|
||||
part, _ := writer.CreateFormFile("file", "dummy.tar.gz")
|
||||
_, _ = io.Copy(part, bytes.NewReader(content))
|
||||
|
||||
_ = writer.Close()
|
||||
|
||||
req := NewRequestWithBody(t, "POST", url, body)
|
||||
req.Header.Add("Content-Type", writer.FormDataContentType())
|
||||
addTokenAuthHeader(req, token)
|
||||
return MakeRequest(t, req, expectedStatus)
|
||||
}
|
||||
|
||||
resp = uploadFile(t, result.URL, content, http.StatusNoContent)
|
||||
|
||||
req = NewRequest(t, "GET", resp.Header().Get("Location"))
|
||||
addTokenAuthHeader(req, token)
|
||||
MakeRequest(t, req, http.StatusOK)
|
||||
|
||||
pvs, err := packages.GetVersionsByPackageType(db.DefaultContext, user.ID, packages.TypePub)
|
||||
assert.NoError(t, err)
|
||||
assert.Len(t, pvs, 1)
|
||||
|
||||
pd, err := packages.GetPackageDescriptor(db.DefaultContext, pvs[0])
|
||||
assert.NoError(t, err)
|
||||
assert.NotNil(t, pd.SemVer)
|
||||
assert.IsType(t, &pub_module.Metadata{}, pd.Metadata)
|
||||
assert.Equal(t, packageName, pd.Package.Name)
|
||||
assert.Equal(t, packageVersion, pd.Version.Version)
|
||||
|
||||
pfs, err := packages.GetFilesByVersionID(db.DefaultContext, pvs[0].ID)
|
||||
assert.NoError(t, err)
|
||||
assert.Len(t, pfs, 1)
|
||||
assert.Equal(t, filename, pfs[0].Name)
|
||||
assert.True(t, pfs[0].IsLead)
|
||||
|
||||
pb, err := packages.GetBlobByID(db.DefaultContext, pfs[0].BlobID)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, int64(len(content)), pb.Size)
|
||||
|
||||
resp = uploadFile(t, result.URL, content, http.StatusBadRequest)
|
||||
})
|
||||
|
||||
t.Run("Download", func(t *testing.T) {
|
||||
defer PrintCurrentTest(t)()
|
||||
|
||||
req := NewRequest(t, "GET", fmt.Sprintf("%s/api/packages/%s/%s", root, packageName, packageVersion))
|
||||
resp := MakeRequest(t, req, http.StatusOK)
|
||||
|
||||
type VersionMetadata struct {
|
||||
Version string `json:"version"`
|
||||
ArchiveURL string `json:"archive_url"`
|
||||
Published time.Time `json:"published"`
|
||||
Pubspec interface{} `json:"pubspec,omitempty"`
|
||||
}
|
||||
|
||||
var result VersionMetadata
|
||||
DecodeJSON(t, resp, &result)
|
||||
|
||||
assert.Equal(t, packageVersion, result.Version)
|
||||
assert.NotNil(t, result.Pubspec)
|
||||
|
||||
req = NewRequest(t, "GET", result.ArchiveURL)
|
||||
resp = MakeRequest(t, req, http.StatusOK)
|
||||
|
||||
assert.Equal(t, content, resp.Body.Bytes())
|
||||
})
|
||||
|
||||
t.Run("EnumeratePackageVersions", func(t *testing.T) {
|
||||
defer PrintCurrentTest(t)()
|
||||
|
||||
req := NewRequest(t, "GET", fmt.Sprintf("%s/api/packages/%s", root, packageName))
|
||||
resp := MakeRequest(t, req, http.StatusOK)
|
||||
|
||||
type VersionMetadata struct {
|
||||
Version string `json:"version"`
|
||||
ArchiveURL string `json:"archive_url"`
|
||||
Published time.Time `json:"published"`
|
||||
Pubspec interface{} `json:"pubspec,omitempty"`
|
||||
}
|
||||
|
||||
type PackageVersions struct {
|
||||
Name string `json:"name"`
|
||||
Latest *VersionMetadata `json:"latest"`
|
||||
Versions []*VersionMetadata `json:"versions"`
|
||||
}
|
||||
|
||||
var result PackageVersions
|
||||
DecodeJSON(t, resp, &result)
|
||||
|
||||
assert.Equal(t, packageName, result.Name)
|
||||
assert.NotNil(t, result.Latest)
|
||||
assert.Len(t, result.Versions, 1)
|
||||
assert.Equal(t, result.Latest.Version, result.Versions[0].Version)
|
||||
assert.Equal(t, packageVersion, result.Latest.Version)
|
||||
assert.NotNil(t, result.Latest.Pubspec)
|
||||
})
|
||||
}
|
|
@ -156,11 +156,6 @@ func standardCommitAndPushTest(t *testing.T, dstPath string) (little, big string
|
|||
func lfsCommitAndPushTest(t *testing.T, dstPath string) (littleLFS, bigLFS string) {
|
||||
t.Run("LFS", func(t *testing.T) {
|
||||
defer PrintCurrentTest(t)()
|
||||
git.CheckLFSVersion()
|
||||
if !setting.LFS.StartServer {
|
||||
t.Skip()
|
||||
return
|
||||
}
|
||||
prefix := "lfs-data-file-"
|
||||
err := git.NewCommand(git.DefaultContext, "lfs").AddArguments("install").Run(&git.RunOpts{Dir: dstPath})
|
||||
assert.NoError(t, err)
|
||||
|
@ -226,7 +221,6 @@ func rawTest(t *testing.T, ctx *APITestContext, little, big, littleLFS, bigLFS s
|
|||
resp := session.MakeRequestNilResponseRecorder(t, req, http.StatusOK)
|
||||
assert.Equal(t, littleSize, resp.Length)
|
||||
|
||||
git.CheckLFSVersion()
|
||||
if setting.LFS.StartServer {
|
||||
req = NewRequest(t, "GET", path.Join("/", username, reponame, "/raw/branch/master/", littleLFS))
|
||||
resp := session.MakeRequest(t, req, http.StatusOK)
|
||||
|
@ -268,12 +262,9 @@ func mediaTest(t *testing.T, ctx *APITestContext, little, big, littleLFS, bigLFS
|
|||
resp := session.MakeRequestNilResponseRecorder(t, req, http.StatusOK)
|
||||
assert.Equal(t, littleSize, resp.Length)
|
||||
|
||||
git.CheckLFSVersion()
|
||||
if setting.LFS.StartServer {
|
||||
req = NewRequest(t, "GET", path.Join("/", username, reponame, "/media/branch/master/", littleLFS))
|
||||
resp = session.MakeRequestNilResponseRecorder(t, req, http.StatusOK)
|
||||
assert.Equal(t, littleSize, resp.Length)
|
||||
}
|
||||
|
||||
if !testing.Short() {
|
||||
req = NewRequest(t, "GET", path.Join("/", username, reponame, "/media/branch/master/", big))
|
||||
|
|
|
@ -175,10 +175,9 @@ func initIntegrationTest() {
|
|||
setting.Repository.DefaultBranch = "master" // many test code still assume that default branch is called "master"
|
||||
_ = util.RemoveAll(repo_module.LocalCopyPath())
|
||||
|
||||
if err := git.InitOnceWithSync(context.Background()); err != nil {
|
||||
if err := git.InitFull(context.Background()); err != nil {
|
||||
log.Fatal("git.InitOnceWithSync: %v", err)
|
||||
}
|
||||
git.CheckLFSVersion()
|
||||
|
||||
setting.InitDBConfig()
|
||||
if err := storage.Init(); err != nil {
|
||||
|
@ -285,7 +284,6 @@ func prepareTestEnv(t testing.TB, skip ...int) func() {
|
|||
assert.NoError(t, unittest.LoadFixtures())
|
||||
assert.NoError(t, util.RemoveAll(setting.RepoRootPath))
|
||||
assert.NoError(t, unittest.CopyDir(path.Join(filepath.Dir(setting.AppPath), "integrations/gitea-repositories-meta"), setting.RepoRootPath))
|
||||
assert.NoError(t, git.InitOnceWithSync(context.Background())) // the gitconfig has been removed above, so sync the gitconfig again
|
||||
ownerDirs, err := os.ReadDir(setting.RepoRootPath)
|
||||
if err != nil {
|
||||
assert.NoError(t, err, "unable to read the new repo root: %v\n", err)
|
||||
|
@ -586,7 +584,6 @@ func resetFixtures(t *testing.T) {
|
|||
assert.NoError(t, unittest.LoadFixtures())
|
||||
assert.NoError(t, util.RemoveAll(setting.RepoRootPath))
|
||||
assert.NoError(t, unittest.CopyDir(path.Join(filepath.Dir(setting.AppPath), "integrations/gitea-repositories-meta"), setting.RepoRootPath))
|
||||
assert.NoError(t, git.InitOnceWithSync(context.Background())) // the gitconfig has been removed above, so sync the gitconfig again
|
||||
ownerDirs, err := os.ReadDir(setting.RepoRootPath)
|
||||
if err != nil {
|
||||
assert.NoError(t, err, "unable to read the new repo root: %v\n", err)
|
||||
|
|
|
@ -356,17 +356,17 @@ func TestSearchIssues(t *testing.T) {
|
|||
|
||||
session := loginUser(t, "user2")
|
||||
|
||||
expectedIssueCount := 15 // from the fixtures
|
||||
if expectedIssueCount > setting.UI.IssuePagingNum {
|
||||
expectedIssueCount = setting.UI.IssuePagingNum
|
||||
}
|
||||
|
||||
link, _ := url.Parse("/issues/search")
|
||||
req := NewRequest(t, "GET", link.String())
|
||||
resp := session.MakeRequest(t, req, http.StatusOK)
|
||||
var apiIssues []*api.Issue
|
||||
DecodeJSON(t, resp, &apiIssues)
|
||||
assert.Len(t, apiIssues, 10)
|
||||
|
||||
req = NewRequest(t, "GET", link.String())
|
||||
resp = session.MakeRequest(t, req, http.StatusOK)
|
||||
DecodeJSON(t, resp, &apiIssues)
|
||||
assert.Len(t, apiIssues, 10)
|
||||
assert.Len(t, apiIssues, expectedIssueCount)
|
||||
|
||||
since := "2000-01-01T00%3A50%3A01%2B00%3A00" // 946687801
|
||||
before := time.Unix(999307200, 0).Format(time.RFC3339)
|
||||
|
@ -394,14 +394,15 @@ func TestSearchIssues(t *testing.T) {
|
|||
resp = session.MakeRequest(t, req, http.StatusOK)
|
||||
DecodeJSON(t, resp, &apiIssues)
|
||||
assert.EqualValues(t, "17", resp.Header().Get("X-Total-Count"))
|
||||
assert.Len(t, apiIssues, 10) // there are more but 10 is page item limit
|
||||
assert.Len(t, apiIssues, 17)
|
||||
|
||||
query.Add("limit", "20")
|
||||
query.Add("limit", "5")
|
||||
link.RawQuery = query.Encode()
|
||||
req = NewRequest(t, "GET", link.String())
|
||||
resp = session.MakeRequest(t, req, http.StatusOK)
|
||||
DecodeJSON(t, resp, &apiIssues)
|
||||
assert.Len(t, apiIssues, 17)
|
||||
assert.EqualValues(t, "17", resp.Header().Get("X-Total-Count"))
|
||||
assert.Len(t, apiIssues, 5)
|
||||
|
||||
query = url.Values{"assigned": {"true"}, "state": {"all"}}
|
||||
link.RawQuery = query.Encode()
|
||||
|
@ -449,29 +450,26 @@ func TestSearchIssues(t *testing.T) {
|
|||
func TestSearchIssuesWithLabels(t *testing.T) {
|
||||
defer prepareTestEnv(t)()
|
||||
|
||||
token := getUserToken(t, "user1")
|
||||
|
||||
link, _ := url.Parse("/api/v1/repos/issues/search?token=" + token)
|
||||
req := NewRequest(t, "GET", link.String())
|
||||
resp := MakeRequest(t, req, http.StatusOK)
|
||||
var apiIssues []*api.Issue
|
||||
DecodeJSON(t, resp, &apiIssues)
|
||||
|
||||
assert.Len(t, apiIssues, 10)
|
||||
|
||||
query := url.Values{
|
||||
"token": []string{token},
|
||||
expectedIssueCount := 15 // from the fixtures
|
||||
if expectedIssueCount > setting.UI.IssuePagingNum {
|
||||
expectedIssueCount = setting.UI.IssuePagingNum
|
||||
}
|
||||
|
||||
session := loginUser(t, "user1")
|
||||
link, _ := url.Parse("/issues/search")
|
||||
query := url.Values{}
|
||||
var apiIssues []*api.Issue
|
||||
|
||||
link.RawQuery = query.Encode()
|
||||
req = NewRequest(t, "GET", link.String())
|
||||
resp = MakeRequest(t, req, http.StatusOK)
|
||||
req := NewRequest(t, "GET", link.String())
|
||||
resp := session.MakeRequest(t, req, http.StatusOK)
|
||||
DecodeJSON(t, resp, &apiIssues)
|
||||
assert.Len(t, apiIssues, 10)
|
||||
assert.Len(t, apiIssues, expectedIssueCount)
|
||||
|
||||
query.Add("labels", "label1")
|
||||
link.RawQuery = query.Encode()
|
||||
req = NewRequest(t, "GET", link.String())
|
||||
resp = MakeRequest(t, req, http.StatusOK)
|
||||
resp = session.MakeRequest(t, req, http.StatusOK)
|
||||
DecodeJSON(t, resp, &apiIssues)
|
||||
assert.Len(t, apiIssues, 2)
|
||||
|
||||
|
@ -479,7 +477,7 @@ func TestSearchIssuesWithLabels(t *testing.T) {
|
|||
query.Set("labels", "label1,label2")
|
||||
link.RawQuery = query.Encode()
|
||||
req = NewRequest(t, "GET", link.String())
|
||||
resp = MakeRequest(t, req, http.StatusOK)
|
||||
resp = session.MakeRequest(t, req, http.StatusOK)
|
||||
DecodeJSON(t, resp, &apiIssues)
|
||||
assert.Len(t, apiIssues, 2)
|
||||
|
||||
|
@ -487,7 +485,7 @@ func TestSearchIssuesWithLabels(t *testing.T) {
|
|||
query.Set("labels", "orglabel4")
|
||||
link.RawQuery = query.Encode()
|
||||
req = NewRequest(t, "GET", link.String())
|
||||
resp = MakeRequest(t, req, http.StatusOK)
|
||||
resp = session.MakeRequest(t, req, http.StatusOK)
|
||||
DecodeJSON(t, resp, &apiIssues)
|
||||
assert.Len(t, apiIssues, 1)
|
||||
|
||||
|
@ -496,7 +494,7 @@ func TestSearchIssuesWithLabels(t *testing.T) {
|
|||
query.Add("state", "all")
|
||||
link.RawQuery = query.Encode()
|
||||
req = NewRequest(t, "GET", link.String())
|
||||
resp = MakeRequest(t, req, http.StatusOK)
|
||||
resp = session.MakeRequest(t, req, http.StatusOK)
|
||||
DecodeJSON(t, resp, &apiIssues)
|
||||
assert.Len(t, apiIssues, 2)
|
||||
|
||||
|
@ -504,7 +502,7 @@ func TestSearchIssuesWithLabels(t *testing.T) {
|
|||
query.Set("labels", "label1,orglabel4")
|
||||
link.RawQuery = query.Encode()
|
||||
req = NewRequest(t, "GET", link.String())
|
||||
resp = MakeRequest(t, req, http.StatusOK)
|
||||
resp = session.MakeRequest(t, req, http.StatusOK)
|
||||
DecodeJSON(t, resp, &apiIssues)
|
||||
assert.Len(t, apiIssues, 2)
|
||||
}
|
||||
|
|
|
@ -14,7 +14,6 @@ import (
|
|||
|
||||
git_model "code.gitea.io/gitea/models/git"
|
||||
repo_model "code.gitea.io/gitea/models/repo"
|
||||
"code.gitea.io/gitea/modules/git"
|
||||
"code.gitea.io/gitea/modules/json"
|
||||
"code.gitea.io/gitea/modules/lfs"
|
||||
"code.gitea.io/gitea/modules/setting"
|
||||
|
@ -83,11 +82,6 @@ func checkResponseTestContentEncoding(t *testing.T, content *[]byte, resp *httpt
|
|||
|
||||
func TestGetLFSSmall(t *testing.T) {
|
||||
defer prepareTestEnv(t)()
|
||||
git.CheckLFSVersion()
|
||||
if !setting.LFS.StartServer {
|
||||
t.Skip()
|
||||
return
|
||||
}
|
||||
content := []byte("A very small file\n")
|
||||
|
||||
resp := storeAndGetLfs(t, &content, nil, http.StatusOK)
|
||||
|
@ -96,11 +90,6 @@ func TestGetLFSSmall(t *testing.T) {
|
|||
|
||||
func TestGetLFSLarge(t *testing.T) {
|
||||
defer prepareTestEnv(t)()
|
||||
git.CheckLFSVersion()
|
||||
if !setting.LFS.StartServer {
|
||||
t.Skip()
|
||||
return
|
||||
}
|
||||
content := make([]byte, web.GzipMinSize*10)
|
||||
for i := range content {
|
||||
content[i] = byte(i % 256)
|
||||
|
@ -112,11 +101,6 @@ func TestGetLFSLarge(t *testing.T) {
|
|||
|
||||
func TestGetLFSGzip(t *testing.T) {
|
||||
defer prepareTestEnv(t)()
|
||||
git.CheckLFSVersion()
|
||||
if !setting.LFS.StartServer {
|
||||
t.Skip()
|
||||
return
|
||||
}
|
||||
b := make([]byte, web.GzipMinSize*10)
|
||||
for i := range b {
|
||||
b[i] = byte(i % 256)
|
||||
|
@ -133,11 +117,6 @@ func TestGetLFSGzip(t *testing.T) {
|
|||
|
||||
func TestGetLFSZip(t *testing.T) {
|
||||
defer prepareTestEnv(t)()
|
||||
git.CheckLFSVersion()
|
||||
if !setting.LFS.StartServer {
|
||||
t.Skip()
|
||||
return
|
||||
}
|
||||
b := make([]byte, web.GzipMinSize*10)
|
||||
for i := range b {
|
||||
b[i] = byte(i % 256)
|
||||
|
@ -156,11 +135,6 @@ func TestGetLFSZip(t *testing.T) {
|
|||
|
||||
func TestGetLFSRangeNo(t *testing.T) {
|
||||
defer prepareTestEnv(t)()
|
||||
git.CheckLFSVersion()
|
||||
if !setting.LFS.StartServer {
|
||||
t.Skip()
|
||||
return
|
||||
}
|
||||
content := []byte("123456789\n")
|
||||
|
||||
resp := storeAndGetLfs(t, &content, nil, http.StatusOK)
|
||||
|
@ -169,11 +143,6 @@ func TestGetLFSRangeNo(t *testing.T) {
|
|||
|
||||
func TestGetLFSRange(t *testing.T) {
|
||||
defer prepareTestEnv(t)()
|
||||
git.CheckLFSVersion()
|
||||
if !setting.LFS.StartServer {
|
||||
t.Skip()
|
||||
return
|
||||
}
|
||||
content := []byte("123456789\n")
|
||||
|
||||
tests := []struct {
|
||||
|
|
|
@ -82,8 +82,7 @@ func initMigrationTest(t *testing.T) func() {
|
|||
}
|
||||
}
|
||||
|
||||
assert.NoError(t, git.InitOnceWithSync(context.Background()))
|
||||
git.CheckLFSVersion()
|
||||
assert.NoError(t, git.InitFull(context.Background()))
|
||||
setting.InitDBConfig()
|
||||
setting.NewLogServices(true)
|
||||
return deferFn
|
||||
|
|
|
@ -56,11 +56,11 @@ func TestPullCreate_CommitStatus(t *testing.T) {
|
|||
}
|
||||
|
||||
statesIcons := map[api.CommitStatusState]string{
|
||||
api.CommitStatusPending: "circle icon yellow",
|
||||
api.CommitStatusSuccess: "check icon green",
|
||||
api.CommitStatusError: "warning icon red",
|
||||
api.CommitStatusFailure: "remove icon red",
|
||||
api.CommitStatusWarning: "warning sign icon yellow",
|
||||
api.CommitStatusPending: "octicon-dot-fill",
|
||||
api.CommitStatusSuccess: "octicon-check",
|
||||
api.CommitStatusError: "gitea-exclamation",
|
||||
api.CommitStatusFailure: "octicon-x",
|
||||
api.CommitStatusWarning: "gitea-exclamation",
|
||||
}
|
||||
|
||||
testCtx := NewAPITestContext(t, "user1", "repo1")
|
||||
|
@ -80,9 +80,9 @@ func TestPullCreate_CommitStatus(t *testing.T) {
|
|||
assert.NotEmpty(t, commitURL)
|
||||
assert.EqualValues(t, commitID, path.Base(commitURL))
|
||||
|
||||
cls, ok := doc.doc.Find("#commits-table tbody tr td.message i.commit-status").Last().Attr("class")
|
||||
cls, ok := doc.doc.Find("#commits-table tbody tr td.message .commit-status").Last().Attr("class")
|
||||
assert.True(t, ok)
|
||||
assert.EqualValues(t, "commit-status "+statesIcons[status], cls)
|
||||
assert.Contains(t, cls, statesIcons[status])
|
||||
}
|
||||
})
|
||||
}
|
||||
|
|
|
@ -55,7 +55,7 @@ func doTestRepoCommitWithStatus(t *testing.T, state string, classes ...string) {
|
|||
|
||||
doc = NewHTMLParser(t, resp.Body)
|
||||
// Check if commit status is displayed in message column
|
||||
sel := doc.doc.Find("#commits-table tbody tr td.message a.commit-statuses-trigger i.commit-status")
|
||||
sel := doc.doc.Find("#commits-table tbody tr td.message a.commit-statuses-trigger .commit-status")
|
||||
assert.Equal(t, 1, sel.Length())
|
||||
for _, class := range classes {
|
||||
assert.True(t, sel.HasClass(class))
|
||||
|
@ -96,21 +96,21 @@ func testRepoCommitsWithStatus(t *testing.T, resp, respOne *httptest.ResponseRec
|
|||
}
|
||||
|
||||
func TestRepoCommitsWithStatusPending(t *testing.T) {
|
||||
doTestRepoCommitWithStatus(t, "pending", "circle", "yellow")
|
||||
doTestRepoCommitWithStatus(t, "pending", "octicon-dot-fill", "yellow")
|
||||
}
|
||||
|
||||
func TestRepoCommitsWithStatusSuccess(t *testing.T) {
|
||||
doTestRepoCommitWithStatus(t, "success", "check", "green")
|
||||
doTestRepoCommitWithStatus(t, "success", "octicon-check", "green")
|
||||
}
|
||||
|
||||
func TestRepoCommitsWithStatusError(t *testing.T) {
|
||||
doTestRepoCommitWithStatus(t, "error", "warning", "red")
|
||||
doTestRepoCommitWithStatus(t, "error", "gitea-exclamation", "red")
|
||||
}
|
||||
|
||||
func TestRepoCommitsWithStatusFailure(t *testing.T) {
|
||||
doTestRepoCommitWithStatus(t, "failure", "remove", "red")
|
||||
doTestRepoCommitWithStatus(t, "failure", "octicon-x", "red")
|
||||
}
|
||||
|
||||
func TestRepoCommitsWithStatusWarning(t *testing.T) {
|
||||
doTestRepoCommitWithStatus(t, "warning", "warning", "sign", "yellow")
|
||||
doTestRepoCommitWithStatus(t, "warning", "gitea-exclamation", "yellow")
|
||||
}
|
||||
|
|
6
main.go
|
@ -171,9 +171,9 @@ func setAppHelpTemplates() {
|
|||
}
|
||||
|
||||
func adjustHelpTemplate(originalTemplate string) string {
|
||||
overrided := ""
|
||||
overridden := ""
|
||||
if _, ok := os.LookupEnv("GITEA_CUSTOM"); ok {
|
||||
overrided = "(GITEA_CUSTOM)"
|
||||
overridden = "(GITEA_CUSTOM)"
|
||||
}
|
||||
|
||||
return fmt.Sprintf(`%s
|
||||
|
@ -183,7 +183,7 @@ DEFAULT CONFIGURATION:
|
|||
AppPath: %s
|
||||
AppWorkPath: %s
|
||||
|
||||
`, originalTemplate, setting.CustomPath, overrided, setting.CustomConf, setting.AppPath, setting.AppWorkPath)
|
||||
`, originalTemplate, setting.CustomPath, overridden, setting.CustomConf, setting.AppPath, setting.AppWorkPath)
|
||||
}
|
||||
|
||||
func formatBuiltWith() string {
|
||||
|
|
|
@ -66,11 +66,10 @@ func TestMain(m *testing.M) {
|
|||
|
||||
setting.SetCustomPathAndConf("", "", "")
|
||||
setting.LoadForTest()
|
||||
if err = git.InitOnceWithSync(context.Background()); err != nil {
|
||||
fmt.Printf("Unable to InitOnceWithSync: %v\n", err)
|
||||
if err = git.InitFull(context.Background()); err != nil {
|
||||
fmt.Printf("Unable to InitFull: %v\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
git.CheckLFSVersion()
|
||||
setting.InitDBConfig()
|
||||
setting.NewLogServices(true)
|
||||
|
||||
|
@ -207,7 +206,6 @@ func prepareTestEnv(t *testing.T, skip int, syncModels ...interface{}) (*xorm.En
|
|||
deferFn := PrintCurrentTest(t, ourSkip)
|
||||
assert.NoError(t, os.RemoveAll(setting.RepoRootPath))
|
||||
assert.NoError(t, unittest.CopyDir(path.Join(filepath.Dir(setting.AppPath), "integrations/gitea-repositories-meta"), setting.RepoRootPath))
|
||||
assert.NoError(t, git.InitOnceWithSync(context.Background())) // the gitconfig has been removed above, so sync the gitconfig again
|
||||
ownerDirs, err := os.ReadDir(setting.RepoRootPath)
|
||||
if err != nil {
|
||||
assert.NoError(t, err, "unable to read the new repo root: %v\n", err)
|
||||
|
|
|
@ -12,18 +12,17 @@ import (
|
|||
"xorm.io/xorm/schemas"
|
||||
)
|
||||
|
||||
func addContainerRepositoryProperty(x *xorm.Engine) error {
|
||||
func addContainerRepositoryProperty(x *xorm.Engine) (err error) {
|
||||
switch x.Dialect().URI().DBType {
|
||||
case schemas.SQLITE:
|
||||
_, err := x.Exec("INSERT INTO package_property (ref_type, ref_id, name, value) SELECT ?, p.id, ?, u.lower_name || '/' || p.lower_name FROM package p JOIN `user` u ON p.owner_id = u.id WHERE p.type = ?", packages_model.PropertyTypePackage, container_module.PropertyRepository, packages_model.TypeContainer)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, err = x.Exec("INSERT INTO package_property (ref_type, ref_id, name, value) SELECT ?, p.id, ?, u.lower_name || '/' || p.lower_name FROM package p JOIN `user` u ON p.owner_id = u.id WHERE p.type = ?",
|
||||
packages_model.PropertyTypePackage, container_module.PropertyRepository, packages_model.TypeContainer)
|
||||
case schemas.MSSQL:
|
||||
_, err = x.Exec("INSERT INTO package_property (ref_type, ref_id, name, value) SELECT ?, p.id, ?, u.lower_name + '/' + p.lower_name FROM package p JOIN `user` u ON p.owner_id = u.id WHERE p.type = ?",
|
||||
packages_model.PropertyTypePackage, container_module.PropertyRepository, packages_model.TypeContainer)
|
||||
default:
|
||||
_, err := x.Exec("INSERT INTO package_property (ref_type, ref_id, name, value) SELECT ?, p.id, ?, CONCAT(u.lower_name, '/', p.lower_name) FROM package p JOIN `user` u ON p.owner_id = u.id WHERE p.type = ?", packages_model.PropertyTypePackage, container_module.PropertyRepository, packages_model.TypeContainer)
|
||||
if err != nil {
|
||||
_, err = x.Exec("INSERT INTO package_property (ref_type, ref_id, name, value) SELECT ?, p.id, ?, CONCAT(u.lower_name, '/', p.lower_name) FROM package p JOIN `user` u ON p.owner_id = u.id WHERE p.type = ?",
|
||||
packages_model.PropertyTypePackage, container_module.PropertyRepository, packages_model.TypeContainer)
|
||||
}
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -19,6 +19,7 @@ import (
|
|||
"code.gitea.io/gitea/modules/packages/maven"
|
||||
"code.gitea.io/gitea/modules/packages/npm"
|
||||
"code.gitea.io/gitea/modules/packages/nuget"
|
||||
"code.gitea.io/gitea/modules/packages/pub"
|
||||
"code.gitea.io/gitea/modules/packages/pypi"
|
||||
"code.gitea.io/gitea/modules/packages/rubygems"
|
||||
|
||||
|
@ -143,6 +144,8 @@ func GetPackageDescriptor(ctx context.Context, pv *PackageVersion) (*PackageDesc
|
|||
metadata = &npm.Metadata{}
|
||||
case TypeMaven:
|
||||
metadata = &maven.Metadata{}
|
||||
case TypePub:
|
||||
metadata = &pub.Metadata{}
|
||||
case TypePyPI:
|
||||
metadata = &pypi.Metadata{}
|
||||
case TypeRubyGems:
|
||||
|
|
|
@ -39,6 +39,7 @@ const (
|
|||
TypeMaven Type = "maven"
|
||||
TypeNpm Type = "npm"
|
||||
TypeNuGet Type = "nuget"
|
||||
TypePub Type = "pub"
|
||||
TypePyPI Type = "pypi"
|
||||
TypeRubyGems Type = "rubygems"
|
||||
)
|
||||
|
@ -62,6 +63,8 @@ func (pt Type) Name() string {
|
|||
return "npm"
|
||||
case TypeNuGet:
|
||||
return "NuGet"
|
||||
case TypePub:
|
||||
return "Pub"
|
||||
case TypePyPI:
|
||||
return "PyPI"
|
||||
case TypeRubyGems:
|
||||
|
@ -89,6 +92,8 @@ func (pt Type) SVGName() string {
|
|||
return "gitea-npm"
|
||||
case TypeNuGet:
|
||||
return "gitea-nuget"
|
||||
case TypePub:
|
||||
return "gitea-pub"
|
||||
case TypePyPI:
|
||||
return "gitea-python"
|
||||
case TypeRubyGems:
|
||||
|
|
|
@ -170,3 +170,15 @@ func GetReviewers(ctx context.Context, repo *Repository, doerID, posterID int64)
|
|||
users := make([]*user_model.User, 0, 8)
|
||||
return users, db.GetEngine(ctx).Where(cond).OrderBy(user_model.GetOrderByName()).Find(&users)
|
||||
}
|
||||
|
||||
// GetIssuePosters returns all users that have authored an issue/pull request for the given repository
|
||||
func GetIssuePosters(ctx context.Context, repo *Repository, isPull bool) ([]*user_model.User, error) {
|
||||
users := make([]*user_model.User, 0, 8)
|
||||
cond := builder.In("`user`.id",
|
||||
builder.Select("poster_id").From("issue").Where(
|
||||
builder.Eq{"repo_id": repo.ID}.
|
||||
And(builder.Eq{"is_pull": isPull}),
|
||||
).GroupBy("poster_id"),
|
||||
)
|
||||
return users, db.GetEngine(ctx).Where(cond).OrderBy(user_model.GetOrderByName()).Find(&users)
|
||||
}
|
||||
|
|
|
@ -120,11 +120,9 @@ func MainTest(m *testing.M, testOpts *TestOptions) {
|
|||
fatalTestError("util.CopyDir: %v\n", err)
|
||||
}
|
||||
|
||||
if err = git.InitOnceWithSync(context.Background()); err != nil {
|
||||
if err = git.InitFull(context.Background()); err != nil {
|
||||
fatalTestError("git.Init: %v\n", err)
|
||||
}
|
||||
git.CheckLFSVersion()
|
||||
|
||||
ownerDirs, err := os.ReadDir(setting.RepoRootPath)
|
||||
if err != nil {
|
||||
fatalTestError("unable to read the new repo root: %v\n", err)
|
||||
|
@ -206,8 +204,6 @@ func PrepareTestEnv(t testing.TB) {
|
|||
assert.NoError(t, util.RemoveAll(setting.RepoRootPath))
|
||||
metaPath := filepath.Join(giteaRoot, "integrations", "gitea-repositories-meta")
|
||||
assert.NoError(t, CopyDir(metaPath, setting.RepoRootPath))
|
||||
assert.NoError(t, git.InitOnceWithSync(context.Background())) // the gitconfig has been removed above, so sync the gitconfig again
|
||||
|
||||
ownerDirs, err := os.ReadDir(setting.RepoRootPath)
|
||||
assert.NoError(t, err)
|
||||
for _, ownerDir := range ownerDirs {
|
||||
|
|
|
@ -399,6 +399,10 @@ func CreateWebhook(ctx context.Context, w *Webhook) error {
|
|||
|
||||
// CreateWebhooks creates multiple web hooks
|
||||
func CreateWebhooks(ctx context.Context, ws []*Webhook) error {
|
||||
// xorm returns err "no element on slice when insert" for empty slices.
|
||||
if len(ws) == 0 {
|
||||
return nil
|
||||
}
|
||||
for i := 0; i < len(ws); i++ {
|
||||
ws[i].Type = strings.TrimSpace(ws[i].Type)
|
||||
}
|
||||
|
|
|
@ -224,7 +224,7 @@ func (ctx *Context) HTML(status int, name base.TplName) {
|
|||
ctx.Data["TemplateLoadTimes"] = func() string {
|
||||
return strconv.FormatInt(time.Since(tmplStartTime).Nanoseconds()/1e6, 10) + "ms"
|
||||
}
|
||||
if err := ctx.Render.HTML(ctx.Resp, status, string(name), ctx.Data); err != nil {
|
||||
if err := ctx.Render.HTML(ctx.Resp, status, string(name), templates.BaseVars().Merge(ctx.Data)); err != nil {
|
||||
if status == http.StatusInternalServerError && name == base.TplName("status/500") {
|
||||
ctx.PlainText(http.StatusInternalServerError, "Unable to find status/500 template")
|
||||
return
|
||||
|
|
|
@ -30,9 +30,6 @@ func iteratePRs(ctx context.Context, repo *repo_model.Repository, each func(*rep
|
|||
}
|
||||
|
||||
func checkPRMergeBase(ctx context.Context, logger log.Logger, autofix bool) error {
|
||||
if err := git.InitOnceWithSync(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
numRepos := 0
|
||||
numPRs := 0
|
||||
numPRsUpdated := 0
|
||||
|
|
|
@ -190,10 +190,6 @@ func checkDaemonExport(ctx context.Context, logger log.Logger, autofix bool) err
|
|||
}
|
||||
|
||||
func checkCommitGraph(ctx context.Context, logger log.Logger, autofix bool) error {
|
||||
if err := git.InitOnceWithSync(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
numRepos := 0
|
||||
numNeedUpdate := 0
|
||||
numWritten := 0
|
||||
|
|
|
@ -95,10 +95,11 @@ func (c *Command) AddArguments(args ...string) *Command {
|
|||
return c
|
||||
}
|
||||
|
||||
// RunOpts represents parameters to run the command
|
||||
// RunOpts represents parameters to run the command. If UseContextTimeout is specified, then Timeout is ignored.
|
||||
type RunOpts struct {
|
||||
Env []string
|
||||
Timeout time.Duration
|
||||
UseContextTimeout bool
|
||||
Dir string
|
||||
Stdout, Stderr io.Writer
|
||||
Stdin io.Reader
|
||||
|
@ -171,7 +172,15 @@ func (c *Command) Run(opts *RunOpts) error {
|
|||
desc = fmt.Sprintf("%s %s [repo_path: %s]", c.name, strings.Join(args, " "), opts.Dir)
|
||||
}
|
||||
|
||||
ctx, cancel, finished := process.GetManager().AddContextTimeout(c.parentContext, opts.Timeout, desc)
|
||||
var ctx context.Context
|
||||
var cancel context.CancelFunc
|
||||
var finished context.CancelFunc
|
||||
|
||||
if opts.UseContextTimeout {
|
||||
ctx, cancel, finished = process.GetManager().AddContext(c.parentContext, desc)
|
||||
} else {
|
||||
ctx, cancel, finished = process.GetManager().AddContextTimeout(c.parentContext, opts.Timeout, desc)
|
||||
}
|
||||
defer finished()
|
||||
|
||||
cmd := exec.CommandContext(ctx, c.name, c.args...)
|
||||
|
|
|
@ -15,7 +15,6 @@ import (
|
|||
"regexp"
|
||||
"runtime"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"code.gitea.io/gitea/modules/log"
|
||||
|
@ -24,8 +23,8 @@ import (
|
|||
"github.com/hashicorp/go-version"
|
||||
)
|
||||
|
||||
// GitVersionRequired is the minimum Git version required
|
||||
const GitVersionRequired = "2.0.0"
|
||||
// RequiredVersion is the minimum Git version required
|
||||
const RequiredVersion = "2.0.0"
|
||||
|
||||
var (
|
||||
// GitExecutable is the command name of git
|
||||
|
@ -43,7 +42,7 @@ var (
|
|||
|
||||
// loadGitVersion returns current Git version from shell. Internal usage only.
|
||||
func loadGitVersion() (*version.Version, error) {
|
||||
// doesn't need RWMutex because its exec by Init()
|
||||
// doesn't need RWMutex because it's executed by Init()
|
||||
if gitVersion != nil {
|
||||
return gitVersion, nil
|
||||
}
|
||||
|
@ -90,7 +89,7 @@ func SetExecutablePath(path string) error {
|
|||
return fmt.Errorf("unable to load git version: %w", err)
|
||||
}
|
||||
|
||||
versionRequired, err := version.NewVersion(GitVersionRequired)
|
||||
versionRequired, err := version.NewVersion(RequiredVersion)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -104,7 +103,7 @@ func SetExecutablePath(path string) error {
|
|||
moreHint = "get git: https://git-scm.com/download/linux and https://ius.io"
|
||||
}
|
||||
}
|
||||
return fmt.Errorf("installed git version %q is not supported, Gitea requires git version >= %q, %s", gitVersion.Original(), GitVersionRequired, moreHint)
|
||||
return fmt.Errorf("installed git version %q is not supported, Gitea requires git version >= %q, %s", gitVersion.Original(), RequiredVersion, moreHint)
|
||||
}
|
||||
|
||||
return nil
|
||||
|
@ -131,7 +130,7 @@ func checkInit() error {
|
|||
return errors.New("unable to init Git's HomeDir, incorrect initialization of the setting and git modules")
|
||||
}
|
||||
if DefaultContext != nil {
|
||||
log.Warn("git module has been initialized already, duplicate init should be fixed")
|
||||
log.Warn("git module has been initialized already, duplicate init may work but it's better to fix it")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
@ -140,7 +139,7 @@ func checkInit() error {
|
|||
func HomeDir() string {
|
||||
if setting.Git.HomePath == "" {
|
||||
// strict check, make sure the git module is initialized correctly.
|
||||
// attention: when the git module is called in gitea sub-command (serv/hook), the log module is not able to show messages to users.
|
||||
// attention: when the git module is called in gitea sub-command (serv/hook), the log module might not obviously show messages to users/developers.
|
||||
// for example: if there is gitea git hook code calling git.NewCommand before git.InitXxx, the integration test won't show the real failure reasons.
|
||||
log.Fatal("Unable to init Git's HomeDir, incorrect initialization of the setting and git modules")
|
||||
return ""
|
||||
|
@ -149,14 +148,14 @@ func HomeDir() string {
|
|||
}
|
||||
|
||||
// InitSimple initializes git module with a very simple step, no config changes, no global command arguments.
|
||||
// This method doesn't change anything to filesystem. At the moment, it is only used by "git serv" sub-command, no data-race
|
||||
// However, in integration test, the sub-command function may be called in the current process, so the InitSimple would be called multiple times, too
|
||||
// This method doesn't change anything to filesystem. At the moment, it is only used by some Gitea sub-commands.
|
||||
func InitSimple(ctx context.Context) error {
|
||||
if err := checkInit(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
DefaultContext = ctx
|
||||
globalCommandArgs = nil
|
||||
|
||||
if setting.Git.Timeout.Default > 0 {
|
||||
defaultCommandExecutionTimeout = time.Duration(setting.Git.Timeout.Default) * time.Second
|
||||
|
@ -165,17 +164,13 @@ func InitSimple(ctx context.Context) error {
|
|||
return SetExecutablePath(setting.Git.Path)
|
||||
}
|
||||
|
||||
var initOnce sync.Once
|
||||
|
||||
// InitOnceWithSync initializes git module with version check and change global variables, sync gitconfig.
|
||||
// This method will update the global variables ONLY ONCE (just like git.CheckLFSVersion -- which is not ideal too),
|
||||
// otherwise there will be data-race problem at the moment.
|
||||
func InitOnceWithSync(ctx context.Context) (err error) {
|
||||
// InitFull initializes git module with version check and change global variables, sync gitconfig.
|
||||
// It should only be called once at the beginning of the program initialization (TestMain/GlobalInitInstalled) as this code makes unsynchronized changes to variables.
|
||||
func InitFull(ctx context.Context) (err error) {
|
||||
if err = checkInit(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
initOnce.Do(func() {
|
||||
if err = InitSimple(ctx); err != nil {
|
||||
return
|
||||
}
|
||||
|
@ -201,10 +196,14 @@ func InitOnceWithSync(ctx context.Context) (err error) {
|
|||
}
|
||||
|
||||
SupportProcReceive = CheckGitVersionAtLeast("2.29") == nil
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
|
||||
if setting.LFS.StartServer {
|
||||
if CheckGitVersionAtLeast("2.1.2") != nil {
|
||||
return errors.New("LFS server support requires Git >= 2.1.2")
|
||||
}
|
||||
globalCommandArgs = append(globalCommandArgs, "-c", "filter.lfs.required=", "-c", "filter.lfs.smudge=", "-c", "filter.lfs.clean=")
|
||||
}
|
||||
|
||||
return syncGitConfig()
|
||||
}
|
||||
|
||||
|
|
|
@ -28,7 +28,7 @@ func testRun(m *testing.M) error {
|
|||
defer util.RemoveAll(gitHomePath)
|
||||
setting.Git.HomePath = gitHomePath
|
||||
|
||||
if err = InitOnceWithSync(context.Background()); err != nil {
|
||||
if err = InitFull(context.Background()); err != nil {
|
||||
return fmt.Errorf("failed to call Init: %w", err)
|
||||
}
|
||||
|
||||
|
|
|
@ -1,31 +0,0 @@
|
|||
// Copyright 2021 The Gitea Authors. All rights reserved.
|
||||
// Use of this source code is governed by a MIT-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package git
|
||||
|
||||
import (
|
||||
"sync"
|
||||
|
||||
logger "code.gitea.io/gitea/modules/log"
|
||||
"code.gitea.io/gitea/modules/setting"
|
||||
)
|
||||
|
||||
var once sync.Once
|
||||
|
||||
// CheckLFSVersion will check lfs version, if not satisfied, then disable it.
|
||||
func CheckLFSVersion() {
|
||||
if setting.LFS.StartServer {
|
||||
// Disable LFS client hooks if installed for the current OS user
|
||||
// Needs at least git v2.1.2
|
||||
if CheckGitVersionAtLeast("2.1.2") != nil {
|
||||
setting.LFS.StartServer = false
|
||||
logger.Error("LFS server support needs at least Git v2.1.2")
|
||||
} else {
|
||||
once.Do(func() {
|
||||
globalCommandArgs = append(globalCommandArgs, "-c", "filter.lfs.required=",
|
||||
"-c", "filter.lfs.smudge=", "-c", "filter.lfs.clean=")
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
// Copyright 2022 The Gitea Authors. All rights reserved.
|
||||
// Use of this source code is governed by a MIT-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package mcaptcha
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"code.gitea.io/gitea/modules/setting"
|
||||
|
||||
"codeberg.org/gusted/mcaptcha"
|
||||
)
|
||||
|
||||
func Verify(ctx context.Context, token string) (bool, error) {
|
||||
valid, err := mcaptcha.Verify(ctx, &mcaptcha.VerifyOpts{
|
||||
InstanceURL: setting.Service.McaptchaURL,
|
||||
Sitekey: setting.Service.McaptchaSitekey,
|
||||
Secret: setting.Service.McaptchaSecret,
|
||||
Token: token,
|
||||
})
|
||||
if err != nil {
|
||||
return false, fmt.Errorf("wasn't able to verify mCaptcha: %v", err)
|
||||
}
|
||||
return valid, nil
|
||||
}
|
|
@ -0,0 +1,154 @@
|
|||
// Copyright 2022 The Gitea Authors. All rights reserved.
|
||||
// Use of this source code is governed by a MIT-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package pub
|
||||
|
||||
import (
|
||||
"archive/tar"
|
||||
"compress/gzip"
|
||||
"errors"
|
||||
"io"
|
||||
"regexp"
|
||||
"strings"
|
||||
|
||||
"code.gitea.io/gitea/modules/validation"
|
||||
|
||||
"github.com/hashicorp/go-version"
|
||||
"gopkg.in/yaml.v2"
|
||||
)
|
||||
|
||||
var (
|
||||
ErrMissingPubspecFile = errors.New("Pubspec file is missing")
|
||||
ErrPubspecFileTooLarge = errors.New("Pubspec file is too large")
|
||||
ErrInvalidName = errors.New("Package name is invalid")
|
||||
ErrInvalidVersion = errors.New("Package version is invalid")
|
||||
)
|
||||
|
||||
var namePattern = regexp.MustCompile(`\A[a-zA-Z_][a-zA-Z0-9_]*\z`)
|
||||
|
||||
// https://github.com/dart-lang/pub-dev/blob/4d582302a8d10152a5cd6129f65bf4f4dbca239d/pkg/pub_package_reader/lib/pub_package_reader.dart#L143
|
||||
const maxPubspecFileSize = 128 * 1024
|
||||
|
||||
// Package represents a Pub package
|
||||
type Package struct {
|
||||
Name string
|
||||
Version string
|
||||
Metadata *Metadata
|
||||
}
|
||||
|
||||
// Metadata represents the metadata of a Pub package
|
||||
type Metadata struct {
|
||||
Description string `json:"description,omitempty"`
|
||||
ProjectURL string `json:"project_url,omitempty"`
|
||||
RepositoryURL string `json:"repository_url,omitempty"`
|
||||
DocumentationURL string `json:"documentation_url,omitempty"`
|
||||
Readme string `json:"readme,omitempty"`
|
||||
Pubspec interface{} `json:"pubspec"`
|
||||
}
|
||||
|
||||
type pubspecPackage struct {
|
||||
Name string `yaml:"name"`
|
||||
Version string `yaml:"version"`
|
||||
Description string `yaml:"description"`
|
||||
Homepage string `yaml:"homepage"`
|
||||
Repository string `yaml:"repository"`
|
||||
Documentation string `yaml:"documentation"`
|
||||
}
|
||||
|
||||
// ParsePackage parses the Pub package file
|
||||
func ParsePackage(r io.Reader) (*Package, error) {
|
||||
gzr, err := gzip.NewReader(r)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer gzr.Close()
|
||||
|
||||
var p *Package
|
||||
var readme string
|
||||
|
||||
tr := tar.NewReader(gzr)
|
||||
for {
|
||||
hd, err := tr.Next()
|
||||
if err == io.EOF {
|
||||
break
|
||||
}
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if hd.Typeflag != tar.TypeReg {
|
||||
continue
|
||||
}
|
||||
|
||||
if hd.Name == "pubspec.yaml" {
|
||||
if hd.Size > maxPubspecFileSize {
|
||||
return nil, ErrPubspecFileTooLarge
|
||||
}
|
||||
p, err = ParsePubspecMetadata(tr)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
} else if strings.ToLower(hd.Name) == "readme.md" {
|
||||
data, err := io.ReadAll(tr)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
readme = string(data)
|
||||
}
|
||||
}
|
||||
|
||||
if p == nil {
|
||||
return nil, ErrMissingPubspecFile
|
||||
}
|
||||
|
||||
p.Metadata.Readme = readme
|
||||
|
||||
return p, nil
|
||||
}
|
||||
|
||||
// ParsePubspecMetadata parses a Pubspec file to retrieve the metadata of a Pub package
|
||||
func ParsePubspecMetadata(r io.Reader) (*Package, error) {
|
||||
buf, err := io.ReadAll(io.LimitReader(r, maxPubspecFileSize))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var p pubspecPackage
|
||||
if err := yaml.Unmarshal(buf, &p); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if !namePattern.MatchString(p.Name) {
|
||||
return nil, ErrInvalidName
|
||||
}
|
||||
|
||||
v, err := version.NewSemver(p.Version)
|
||||
if err != nil {
|
||||
return nil, ErrInvalidVersion
|
||||
}
|
||||
|
||||
if !validation.IsValidURL(p.Homepage) {
|
||||
p.Homepage = ""
|
||||
}
|
||||
if !validation.IsValidURL(p.Repository) {
|
||||
p.Repository = ""
|
||||
}
|
||||
|
||||
var pubspec interface{}
|
||||
if err := yaml.Unmarshal(buf, &pubspec); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &Package{
|
||||
Name: p.Name,
|
||||
Version: v.String(),
|
||||
Metadata: &Metadata{
|
||||
Description: p.Description,
|
||||
ProjectURL: p.Homepage,
|
||||
RepositoryURL: p.Repository,
|
||||
DocumentationURL: p.Documentation,
|
||||
Pubspec: pubspec,
|
||||
},
|
||||
}, nil
|
||||
}
|
|
@ -0,0 +1,136 @@
|
|||
// Copyright 2022 The Gitea Authors. All rights reserved.
|
||||
// Use of this source code is governed by a MIT-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package pub
|
||||
|
||||
import (
|
||||
"archive/tar"
|
||||
"bytes"
|
||||
"compress/gzip"
|
||||
"io"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
const (
|
||||
packageName = "gitea"
|
||||
packageVersion = "1.0.1"
|
||||
description = "Package Description"
|
||||
projectURL = "https://gitea.io"
|
||||
repositoryURL = "https://gitea.io/gitea/gitea"
|
||||
documentationURL = "https://docs.gitea.io"
|
||||
)
|
||||
|
||||
const pubspecContent = `name: ` + packageName + `
|
||||
version: ` + packageVersion + `
|
||||
description: ` + description + `
|
||||
homepage: ` + projectURL + `
|
||||
repository: ` + repositoryURL + `
|
||||
documentation: ` + documentationURL + `
|
||||
|
||||
environment:
|
||||
sdk: '>=2.16.0 <3.0.0'
|
||||
|
||||
dependencies:
|
||||
flutter:
|
||||
sdk: flutter
|
||||
path: '>=1.8.0 <3.0.0'
|
||||
|
||||
dev_dependencies:
|
||||
http: '>=0.13.0'`
|
||||
|
||||
func TestParsePackage(t *testing.T) {
|
||||
createArchive := func(files map[string][]byte) io.Reader {
|
||||
var buf bytes.Buffer
|
||||
zw := gzip.NewWriter(&buf)
|
||||
tw := tar.NewWriter(zw)
|
||||
for filename, content := range files {
|
||||
hdr := &tar.Header{
|
||||
Name: filename,
|
||||
Mode: 0o600,
|
||||
Size: int64(len(content)),
|
||||
}
|
||||
tw.WriteHeader(hdr)
|
||||
tw.Write(content)
|
||||
}
|
||||
tw.Close()
|
||||
zw.Close()
|
||||
return &buf
|
||||
}
|
||||
|
||||
t.Run("MissingPubspecFile", func(t *testing.T) {
|
||||
data := createArchive(map[string][]byte{"dummy.txt": {}})
|
||||
|
||||
pp, err := ParsePackage(data)
|
||||
assert.Nil(t, pp)
|
||||
assert.ErrorIs(t, err, ErrMissingPubspecFile)
|
||||
})
|
||||
|
||||
t.Run("PubspecFileTooLarge", func(t *testing.T) {
|
||||
data := createArchive(map[string][]byte{"pubspec.yaml": make([]byte, 200*1024)})
|
||||
|
||||
pp, err := ParsePackage(data)
|
||||
assert.Nil(t, pp)
|
||||
assert.ErrorIs(t, err, ErrPubspecFileTooLarge)
|
||||
})
|
||||
|
||||
t.Run("InvalidPubspecFile", func(t *testing.T) {
|
||||
data := createArchive(map[string][]byte{"pubspec.yaml": {}})
|
||||
|
||||
pp, err := ParsePackage(data)
|
||||
assert.Nil(t, pp)
|
||||
assert.Error(t, err)
|
||||
})
|
||||
|
||||
t.Run("Valid", func(t *testing.T) {
|
||||
data := createArchive(map[string][]byte{"pubspec.yaml": []byte(pubspecContent)})
|
||||
|
||||
pp, err := ParsePackage(data)
|
||||
assert.NoError(t, err)
|
||||
assert.NotNil(t, pp)
|
||||
assert.Empty(t, pp.Metadata.Readme)
|
||||
})
|
||||
|
||||
t.Run("ValidWithReadme", func(t *testing.T) {
|
||||
data := createArchive(map[string][]byte{"pubspec.yaml": []byte(pubspecContent), "README.md": []byte("readme")})
|
||||
|
||||
pp, err := ParsePackage(data)
|
||||
assert.NoError(t, err)
|
||||
assert.NotNil(t, pp)
|
||||
assert.Equal(t, "readme", pp.Metadata.Readme)
|
||||
})
|
||||
}
|
||||
|
||||
func TestParsePubspecMetadata(t *testing.T) {
|
||||
t.Run("InvalidName", func(t *testing.T) {
|
||||
for _, name := range []string{"123abc", "ab-cd"} {
|
||||
pp, err := ParsePubspecMetadata(strings.NewReader(`name: ` + name))
|
||||
assert.Nil(t, pp)
|
||||
assert.ErrorIs(t, err, ErrInvalidName)
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("InvalidVersion", func(t *testing.T) {
|
||||
pp, err := ParsePubspecMetadata(strings.NewReader(`name: dummy
|
||||
version: invalid`))
|
||||
assert.Nil(t, pp)
|
||||
assert.ErrorIs(t, err, ErrInvalidVersion)
|
||||
})
|
||||
|
||||
t.Run("Valid", func(t *testing.T) {
|
||||
pp, err := ParsePubspecMetadata(strings.NewReader(pubspecContent))
|
||||
assert.NoError(t, err)
|
||||
assert.NotNil(t, pp)
|
||||
|
||||
assert.Equal(t, packageName, pp.Name)
|
||||
assert.Equal(t, packageVersion, pp.Version)
|
||||
assert.Equal(t, description, pp.Metadata.Description)
|
||||
assert.Equal(t, projectURL, pp.Metadata.ProjectURL)
|
||||
assert.Equal(t, repositoryURL, pp.Metadata.RepositoryURL)
|
||||
assert.Equal(t, documentationURL, pp.Metadata.DocumentationURL)
|
||||
assert.NotNil(t, pp.Metadata.Pubspec)
|
||||
})
|
||||
}
|
|
@ -8,6 +8,7 @@ import (
|
|||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
|
||||
"code.gitea.io/gitea/modules/git"
|
||||
"code.gitea.io/gitea/modules/setting"
|
||||
|
@ -153,6 +154,10 @@ func createDelegateHooks(repoPath string) (err error) {
|
|||
}
|
||||
|
||||
func checkExecutable(filename string) bool {
|
||||
// windows has no concept of a executable bit
|
||||
if runtime.GOOS == "windows" {
|
||||
return true
|
||||
}
|
||||
fileInfo, err := os.Stat(filename)
|
||||
if err != nil {
|
||||
return false
|
||||
|
|
|
@ -47,6 +47,9 @@ var Service = struct {
|
|||
RecaptchaURL string
|
||||
HcaptchaSecret string
|
||||
HcaptchaSitekey string
|
||||
McaptchaSecret string
|
||||
McaptchaSitekey string
|
||||
McaptchaURL string
|
||||
DefaultKeepEmailPrivate bool
|
||||
DefaultAllowCreateOrganization bool
|
||||
DefaultUserIsRestricted bool
|
||||
|
@ -133,6 +136,9 @@ func newService() {
|
|||
Service.RecaptchaURL = sec.Key("RECAPTCHA_URL").MustString("https://www.google.com/recaptcha/")
|
||||
Service.HcaptchaSecret = sec.Key("HCAPTCHA_SECRET").MustString("")
|
||||
Service.HcaptchaSitekey = sec.Key("HCAPTCHA_SITEKEY").MustString("")
|
||||
Service.McaptchaURL = sec.Key("MCAPTCHA_URL").MustString("https://demo.mcaptcha.org/")
|
||||
Service.McaptchaSecret = sec.Key("MCAPTCHA_SECRET").MustString("")
|
||||
Service.McaptchaSitekey = sec.Key("MCAPTCHA_SITEKEY").MustString("")
|
||||
Service.DefaultKeepEmailPrivate = sec.Key("DEFAULT_KEEP_EMAIL_PRIVATE").MustBool()
|
||||
Service.DefaultAllowCreateOrganization = sec.Key("DEFAULT_ALLOW_CREATE_ORGANIZATION").MustBool(true)
|
||||
Service.DefaultUserIsRestricted = sec.Key("DEFAULT_USER_IS_RESTRICTED").MustBool(false)
|
||||
|
|
|
@ -59,6 +59,7 @@ const (
|
|||
ImageCaptcha = "image"
|
||||
ReCaptcha = "recaptcha"
|
||||
HCaptcha = "hcaptcha"
|
||||
MCaptcha = "mcaptcha"
|
||||
)
|
||||
|
||||
// settings
|
||||
|
@ -262,8 +263,8 @@ var (
|
|||
}{
|
||||
ExplorePagingNum: 20,
|
||||
SitemapPagingNum: 20,
|
||||
IssuePagingNum: 10,
|
||||
RepoSearchPagingNum: 10,
|
||||
IssuePagingNum: 20,
|
||||
RepoSearchPagingNum: 20,
|
||||
MembersPagingNum: 20,
|
||||
FeedMaxCommitNum: 5,
|
||||
FeedPagingNum: 20,
|
||||
|
|
|
@ -18,10 +18,22 @@ import (
|
|||
// 45677465s -> 1 year 6 months
|
||||
func SecToTime(duration int64) string {
|
||||
formattedTime := ""
|
||||
years := duration / (3600 * 24 * 7 * 4 * 12)
|
||||
months := (duration / (3600 * 24 * 30)) % 12
|
||||
weeks := (duration / (3600 * 24 * 7)) % 4
|
||||
days := (duration / (3600 * 24)) % 7
|
||||
|
||||
// The following four variables are calculated by taking
|
||||
// into account the previously calculated variables, this avoids
|
||||
// pitfalls when using remainders. As that could lead to incorrect
|
||||
// results when the calculated number equals the quotient number.
|
||||
remainingDays := duration / (60 * 60 * 24)
|
||||
years := remainingDays / 365
|
||||
remainingDays -= years * 365
|
||||
months := remainingDays * 12 / 365
|
||||
remainingDays -= months * 365 / 12
|
||||
weeks := remainingDays / 7
|
||||
remainingDays -= weeks * 7
|
||||
days := remainingDays
|
||||
|
||||
// The following three variables are calculated without depending
|
||||
// on the previous calculated variables.
|
||||
hours := (duration / 3600) % 24
|
||||
minutes := (duration / 60) % 60
|
||||
seconds := duration % 60
|
||||
|
|
|
@ -11,10 +11,21 @@ import (
|
|||
)
|
||||
|
||||
func TestSecToTime(t *testing.T) {
|
||||
assert.Equal(t, SecToTime(66), "1 minute 6 seconds")
|
||||
assert.Equal(t, SecToTime(52410), "14 hours 33 minutes")
|
||||
assert.Equal(t, SecToTime(563418), "6 days 12 hours")
|
||||
assert.Equal(t, SecToTime(1563418), "2 weeks 4 days")
|
||||
assert.Equal(t, SecToTime(3937125), "1 month 2 weeks")
|
||||
assert.Equal(t, SecToTime(45677465), "1 year 5 months")
|
||||
second := int64(1)
|
||||
minute := 60 * second
|
||||
hour := 60 * minute
|
||||
day := 24 * hour
|
||||
year := 365 * day
|
||||
|
||||
assert.Equal(t, "1 minute 6 seconds", SecToTime(minute+6*second))
|
||||
assert.Equal(t, "1 hour", SecToTime(hour))
|
||||
assert.Equal(t, "1 hour", SecToTime(hour+second))
|
||||
assert.Equal(t, "14 hours 33 minutes", SecToTime(14*hour+33*minute+30*second))
|
||||
assert.Equal(t, "6 days 12 hours", SecToTime(6*day+12*hour+30*minute+18*second))
|
||||
assert.Equal(t, "2 weeks 4 days", SecToTime((2*7+4)*day+2*hour+16*minute+58*second))
|
||||
assert.Equal(t, "4 weeks", SecToTime(4*7*day))
|
||||
assert.Equal(t, "4 weeks 1 day", SecToTime((4*7+1)*day))
|
||||
assert.Equal(t, "1 month 2 weeks", SecToTime((6*7+3)*day+13*hour+38*minute+45*second))
|
||||
assert.Equal(t, "11 months", SecToTime(year-25*day))
|
||||
assert.Equal(t, "1 year 5 months", SecToTime(year+163*day+10*hour+11*minute+5*second))
|
||||
}
|
||||
|
|
|
@ -0,0 +1,101 @@
|
|||
Creative Commons Attribution 3.0 IGO
|
||||
|
||||
CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE LEGAL SERVICES. DISTRIBUTION OF THIS LICENSE DOES NOT CREATE AN ATTORNEY-CLIENT RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS INFORMATION ON AN "AS-IS" BASIS. CREATIVE COMMONS MAKES NO WARRANTIES REGARDING THE INFORMATION PROVIDED, AND DISCLAIMS LIABILITY FOR DAMAGES RESULTING FROM ITS USE. THE LICENSOR IS NOT NECESSARILY AN INTERGOVERNMENTAL ORGANIZATION (IGO), AS DEFINED IN THE LICENSE BELOW.
|
||||
|
||||
License
|
||||
|
||||
THE WORK (AS DEFINED BELOW) IS PROVIDED UNDER THE TERMS OF THIS CREATIVE COMMONS PUBLIC LICENSE ("LICENSE"). THE LICENSOR (DEFINED BELOW) HOLDS COPYRIGHT AND OTHER RIGHTS IN THE WORK. ANY USE OF THE WORK OTHER THAN AS AUTHORIZED UNDER THIS LICENSE IS PROHIBITED.
|
||||
|
||||
BY EXERCISING ANY RIGHTS TO THE WORK PROVIDED HERE, YOU ACCEPT AND AGREE TO BE BOUND BY THE TERMS OF THIS LICENSE. THE LICENSOR GRANTS YOU THE RIGHTS CONTAINED HERE IN CONSIDERATION FOR YOUR ACCEPTANCE AND AGREEMENT TO THE TERMS OF THE LICENSE.
|
||||
|
||||
1. Definitions
|
||||
|
||||
a. "IGO" means, solely and exclusively for purposes of this License, an organization established by a treaty or other instrument governed by international law and possessing its own international legal personality. Other organizations established to carry out activities across national borders and that accordingly enjoy immunity from legal process are also IGOs for the sole and exclusive purposes of this License. IGOs may include as members, in addition to states, other entities.
|
||||
|
||||
b. "Work" means the literary and/or artistic work eligible for copyright protection, whatever may be the mode or form of its expression including digital form, and offered under the terms of this License. It is understood that a database, which by reason of the selection and arrangement of its contents constitutes an intellectual creation, is considered a Work.
|
||||
|
||||
c. "Licensor" means the individual, individuals, entity or entities that offer(s) the Work under the terms of this License and may be, but is not necessarily, an IGO.
|
||||
|
||||
d. "You" means an individual or entity exercising rights under this License.
|
||||
|
||||
e. "Reproduce" means to make a copy of the Work in any manner or form, and by any means.
|
||||
|
||||
f. "Distribute" means the activity of making publicly available the Work or Adaptation (or copies of the Work or Adaptation), as applicable, by sale, rental, public lending or any other known form of transfer of ownership or possession of the Work or copy of the Work.
|
||||
|
||||
g. "Publicly Perform" means to perform public recitations of the Work and to communicate to the public those public recitations, by any means or process, including by wire or wireless means or public digital performances; to make available to the public Works in such a way that members of the public may access these Works from a place and at a place individually chosen by them; to perform the Work to the public by any means or process and the communication to the public of the performances of the Work, including by public digital performance; to broadcast and rebroadcast the Work by any means including signs, sounds or images.
|
||||
|
||||
h. "Adaptation" means a work derived from or based upon the Work, or upon the Work and other pre-existing works. Adaptations may include works such as translations, derivative works, or any alterations and arrangements of any kind involving the Work. For purposes of this License, where the Work is a musical work, performance, or phonogram, the synchronization of the Work in timed-relation with a moving image is an Adaptation. For the avoidance of doubt, including the Work in a Collection is not an Adaptation.
|
||||
|
||||
i. "Collection" means a collection of literary or artistic works or other works or subject matter other than works listed in Section 1(b) which by reason of the selection and arrangement of their contents, constitute intellectual creations, in which the Work is included in its entirety in unmodified form along with one or more other contributions, each constituting separate and independent works in themselves, which together are assembled into a collective whole. For the avoidance of doubt, a Collection will not be considered as an Adaptation.
|
||||
|
||||
2. Scope of this License. Nothing in this License is intended to reduce, limit, or restrict any uses free from copyright protection.
|
||||
|
||||
3. License Grant. Subject to the terms and conditions of this License, the Licensor hereby grants You a worldwide, royalty-free, non-exclusive license to exercise the rights in the Work as follows:
|
||||
|
||||
a. to Reproduce, Distribute and Publicly Perform the Work, to incorporate the Work into one or more Collections, and to Reproduce, Distribute and Publicly Perform the Work as incorporated in the Collections; and,
|
||||
|
||||
b. to create, Reproduce, Distribute and Publicly Perform Adaptations, provided that You clearly label, demarcate or otherwise identify that changes were made to the original Work.
|
||||
|
||||
c. For the avoidance of doubt:
|
||||
|
||||
i. Non-waivable Compulsory License Schemes. In those jurisdictions in which the right to collect royalties through any statutory or compulsory licensing scheme cannot be waived, the Licensor reserves the exclusive right to collect such royalties for any exercise by You of the rights granted under this License;
|
||||
|
||||
ii. Waivable Compulsory License Schemes. In those jurisdictions in which the right to collect royalties through any statutory or compulsory licensing scheme can be waived, the Licensor waives the exclusive right to collect such royalties for any exercise by You of the rights granted under this License; and,
|
||||
|
||||
iii. Voluntary License Schemes. To the extent possible, the Licensor waives the right to collect royalties from You for the exercise of the Licensed Rights, whether directly or through a collecting society under any voluntary licensing scheme.
|
||||
|
||||
This License lasts for the duration of the term of the copyright in the Work licensed by the Licensor. The above rights may be exercised in all media and formats whether now known or hereafter devised. The above rights include the right to make such modifications as are technically necessary to exercise the rights in other media and formats. All rights not expressly granted by the Licensor are hereby reserved.
|
||||
|
||||
4. Restrictions. The license granted in Section 3 above is expressly made subject to and limited by the following restrictions:
|
||||
|
||||
a. You may Distribute or Publicly Perform the Work only under the terms of this License. You must include a copy of, or the Uniform Resource Identifier (URI) for, this License with every copy of the Work You Distribute or Publicly Perform. You may not offer or impose any terms on the Work that restrict the terms of this License or the ability of the recipient of the Work to exercise the rights granted to that recipient under the terms of the License. You may not sublicense the Work (see section 8(a)). You must keep intact all notices that refer to this License and to the disclaimer of warranties with every copy of the Work You Distribute or Publicly Perform. When You Distribute or Publicly Perform the Work, You may not impose any effective technological measures on the Work that restrict the ability of a recipient of the Work from You to exercise the rights granted to that recipient under the terms of the License. This Section 4(a) applies to the Work as incorporated in a Collection, but this does not require the Collection apart from the Work itself to be made subject to the terms of this License. If You create a Collection, upon notice from a Licensor You must, to the extent practicable, remove from the Collection any credit (inclusive of any logo, trademark, official mark or official emblem) as required by Section 4(b), as requested. If You create an Adaptation, upon notice from a Licensor You must, to the extent practicable, remove from the Adaptation any credit (inclusive of any logo, trademark, official mark or official emblem) as required by Section 4(b), as requested.
|
||||
|
||||
b. If You Distribute, or Publicly Perform the Work or any Adaptations or Collections, You must, unless a request has been made pursuant to Section 4(a), keep intact all copyright notices for the Work and provide, reasonable to the medium or means You are utilizing: (i) any attributions that the Licensor indicates be associated with the Work as indicated in a copyright notice, (ii) the title of the Work if supplied; (iii) to the extent reasonably practicable, the URI, if any, that the Licensor specifies to be associated with the Work, unless such URI does not refer to the copyright notice or licensing information for the Work; and, (iv) consistent with Section 3(b), in the case of an Adaptation, a credit identifying the use of the Work in the Adaptation. The credit required by this Section 4(b) may be implemented in any reasonable manner; provided, however, that in the case of an Adaptation or Collection, at a minimum such credit will appear, if a credit for all contributors to the Adaptation or Collection appears, then as part of these credits and in a manner at least as prominent as the credits for the other contributors. For the avoidance of doubt, You may only use the credit required by this Section for the purpose of attribution in the manner set out above and, by exercising Your rights under this License, You may not implicitly or explicitly assert or imply any connection with, sponsorship or endorsement by the Licensor or others designated for attribution, of You or Your use of the Work, without the separate, express prior written permission of the Licensor or such others.
|
||||
|
||||
c. Except as otherwise agreed in writing by the Licensor, if You Reproduce, Distribute or Publicly Perform the Work either by itself or as part of any Adaptations or Collections, You must not distort, mutilate, modify or take other derogatory action in relation to the Work which would be prejudicial to the honor or reputation of the Licensor where moral rights apply.
|
||||
|
||||
5. Representations, Warranties and Disclaimer
|
||||
|
||||
THE LICENSOR OFFERS THE WORK AS-IS AND MAKES NO REPRESENTATIONS OR WARRANTIES OF ANY KIND CONCERNING THE WORK, EXPRESS, IMPLIED, STATUTORY OR OTHERWISE, INCLUDING, WITHOUT LIMITATION, WARRANTIES OF TITLE, MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NONINFRINGEMENT, OR THE ABSENCE OF LATENT OR OTHER DEFECTS, ACCURACY, OR THE PRESENCE OF ERRORS, WHETHER OR NOT DISCOVERABLE.
|
||||
|
||||
6. Limitation on Liability
|
||||
|
||||
IN NO EVENT WILL THE LICENSOR BE LIABLE TO YOU ON ANY LEGAL THEORY FOR ANY SPECIAL, INCIDENTAL, CONSEQUENTIAL, PUNITIVE OR EXEMPLARY DAMAGES ARISING OUT OF THIS LICENSE OR THE USE OF THE WORK, EVEN IF THE LICENSOR HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
|
||||
|
||||
7. Termination
|
||||
|
||||
a. Subject to the terms and conditions set forth in this License, the license granted here lasts for the duration of the term of the copyright in the Work licensed by the Licensor as stated in Section 3. Notwithstanding the above, the Licensor reserves the right to release the Work under different license terms or to stop distributing the Work at any time; provided, however that any such election will not serve to withdraw this License (or any other license that has been, or is required to be, granted under the terms of this License), and this License will continue in full force and effect unless terminated as stated below.
|
||||
|
||||
b. If You fail to comply with this License, then this License and the rights granted hereunder will terminate automatically upon any breach by You of the terms of this License. Individuals or entities who have received Adaptations or Collections from You under this License, however, will not have their licenses terminated provided such individuals or entities remain in full compliance with those licenses. Sections 1, 2, 5, 6, 7, and 8 will survive any termination of this License. Notwithstanding the foregoing, this License reinstates automatically as of the date the violation is cured, provided it is cured within 30 days of You discovering the violation, or upon express reinstatement by the Licensor. For the avoidance of doubt, this Section 7(b) does not affect any rights the Licensor may have to seek remedies for violations of this License by You.
|
||||
|
||||
8. Miscellaneous
|
||||
|
||||
a. Each time You Distribute or Publicly Perform the Work or a Collection, the Licensor offers to the recipient a license to the Work on the same terms and conditions as the license granted to You under this License.
|
||||
|
||||
b. Each time You Distribute or Publicly Perform an Adaptation, the Licensor offers to the recipient a license to the original Work on the same terms and conditions as the license granted to You under this License.
|
||||
|
||||
c. If any provision of this License is invalid or unenforceable, it shall not affect the validity or enforceability of the remainder of the terms of this License, and without further action, such provision shall be reformed to the minimum extent necessary to make such provision valid and enforceable.
|
||||
|
||||
d. No term or provision of this License shall be deemed waived and no breach consented to unless such waiver or consent shall be in writing and signed by the Licensor.
|
||||
|
||||
e. This License constitutes the entire agreement between You and the Licensor with respect to the Work licensed here. There are no understandings, agreements or representations with respect to the Work not specified here. The Licensor shall not be bound by any additional provisions that may appear in any communication from You. This License may not be modified without the mutual written agreement of the Licensor and You.
|
||||
|
||||
f. The rights granted under, and the subject matter referenced, in this License were drafted utilizing the terminology of the Berne Convention for the Protection of Literary and Artistic Works (as amended on September 28, 1979), the Rome Convention of 1961, the WIPO Copyright Treaty of 1996, the WIPO Performances and Phonograms Treaty of 1996 and the Universal Copyright Convention (as revised on July 24, 1971). Interpretation of the scope of the rights granted by the Licensor and the conditions imposed on You under this License, this License, and the rights and conditions set forth herein shall be made with reference to copyright as determined in accordance with general principles of international law, including the above mentioned conventions.
|
||||
|
||||
g. Nothing in this License constitutes or may be interpreted as a limitation upon or waiver of any privileges and immunities that may apply to the Licensor or You, including immunity from the legal processes of any jurisdiction, national court or other authority.
|
||||
|
||||
h. Where the Licensor is an IGO, any and all disputes arising under this License that cannot be settled amicably shall be resolved in accordance with the following procedure:
|
||||
|
||||
i. Pursuant to a notice of mediation communicated by reasonable means by either You or the Licensor to the other, the dispute shall be submitted to non-binding mediation conducted in accordance with rules designated by the Licensor in the copyright notice published with the Work, or if none then in accordance with those communicated in the notice of mediation. The language used in the mediation proceedings shall be English unless otherwise agreed.
|
||||
|
||||
ii. If any such dispute has not been settled within 45 days following the date on which the notice of mediation is provided, either You or the Licensor may, pursuant to a notice of arbitration communicated by reasonable means to the other, elect to have the dispute referred to and finally determined by arbitration. The arbitration shall be conducted in accordance with the rules designated by the Licensor in the copyright notice published with the Work, or if none then in accordance with the UNCITRAL Arbitration Rules as then in force. The arbitral tribunal shall consist of a sole arbitrator and the language of the proceedings shall be English unless otherwise agreed. The place of arbitration shall be where the Licensor has its headquarters. The arbitral proceedings shall be conducted remotely (e.g., via telephone conference or written submissions) whenever practicable.
|
||||
|
||||
iii. Interpretation of this License in any dispute submitted to mediation or arbitration shall be as set forth in Section 8(f), above.
|
||||
|
||||
Creative Commons Notice
|
||||
|
||||
Creative Commons is not a party to this License, and makes no warranty whatsoever in connection with the Work. Creative Commons will not be liable to You or any party on any legal theory for any damages whatsoever, including without limitation any general, special, incidental or consequential damages arising in connection to this license. Notwithstanding the foregoing two (2) sentences, if Creative Commons has expressly identified itself as the Licensor hereunder, it shall have all rights and obligations of the Licensor.
|
||||
|
||||
Except for the limited purpose of indicating to the public that the Work is licensed under the CCPL, Creative Commons does not authorize the use by either party of the trademark "Creative Commons" or any related trademark or logo of Creative Commons without the prior written consent of Creative Commons. Any permitted use will be in compliance with Creative Commons' then-current trademark usage guidelines, as may be published on its website or otherwise made available upon request from time to time. For the avoidance of doubt, this trademark restriction does not form part of this License.
|
||||
|
||||
Creative Commons may be contacted at https://creativecommons.org/.
|
|
@ -0,0 +1,8 @@
|
|||
LICENSE
|
||||
-------
|
||||
|
||||
LZMA SDK is written and placed in the public domain by Igor Pavlov.
|
||||
|
||||
Some code in LZMA is based on public domain code from another developers:
|
||||
1) PPMd var.H (2001): Dmitry Shkarin
|
||||
2) SHA-256: Wei Dai (Crypto++ library)
|
|
@ -0,0 +1,15 @@
|
|||
LICENSE
|
||||
-------
|
||||
|
||||
LZMA SDK is written and placed in the public domain by Igor Pavlov.
|
||||
|
||||
Some code in LZMA SDK is based on public domain code from another developers:
|
||||
1) PPMd var.H (2001): Dmitry Shkarin
|
||||
2) SHA-256: Wei Dai (Crypto++ library)
|
||||
|
||||
Anyone is free to copy, modify, publish, use, compile, sell, or distribute the
|
||||
original LZMA SDK code, either in source code form or as a compiled binary, for
|
||||
any purpose, commercial or non-commercial, and by any means.
|
||||
|
||||
LZMA SDK code is compatible with open source licenses, for example, you can
|
||||
include it to GNU GPL or GNU LGPL code.
|
|
@ -0,0 +1,61 @@
|
|||
NICTA Public Software Licence
|
||||
Version 1.0
|
||||
|
||||
Copyright © 2004 National ICT Australia Ltd
|
||||
|
||||
All rights reserved.
|
||||
|
||||
By this licence, National ICT Australia Ltd (NICTA) grants permission,
|
||||
free of charge, to any person who obtains a copy of this software
|
||||
and any associated documentation files ("the Software") to use and
|
||||
deal with the Software in source code and binary forms without
|
||||
restriction, with or without modification, and to permit persons
|
||||
to whom the Software is furnished to do so, provided that the
|
||||
following conditions are met:
|
||||
|
||||
- Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimers.
|
||||
- Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimers in
|
||||
the documentation and/or other materials provided with the
|
||||
distribution.
|
||||
- The name of NICTA may not be used to endorse or promote products
|
||||
derived from this Software without specific prior written permission.
|
||||
|
||||
EXCEPT AS EXPRESSLY STATED IN THIS LICENCE AND TO THE FULL EXTENT
|
||||
PERMITTED BY APPLICABLE LAW, THE SOFTWARE IS PROVIDED "AS-IS" AND
|
||||
NICTA MAKES NO REPRESENTATIONS, WARRANTIES OR CONDITIONS OF ANY
|
||||
KIND, EXPRESS OR IMPLIED, INCLUDING, WITHOUT LIMITATION, ANY
|
||||
REPRESENTATIONS, WARRANTIES OR CONDITIONS REGARDING THE CONTENTS
|
||||
OR ACCURACY OF THE SOFTWARE, OR OF TITLE, MERCHANTABILITY, FITNESS
|
||||
FOR A PARTICULAR PURPOSE, NONINFRINGEMENT, THE ABSENCE OF LATENT
|
||||
OR OTHER DEFECTS, OR THE PRESENCE OR ABSENCE OF ERRORS, WHETHER OR
|
||||
NOT DISCOVERABLE.
|
||||
|
||||
TO THE FULL EXTENT PERMITTED BY APPLICABLE LAW, IN NO EVENT WILL
|
||||
NICTA BE LIABLE ON ANY LEGAL THEORY (INCLUDING, WITHOUT LIMITATION,
|
||||
NEGLIGENCE) FOR ANY LOSS OR DAMAGE WHATSOEVER, INCLUDING (WITHOUT
|
||||
LIMITATION) LOSS OF PRODUCTION OR OPERATION TIME, LOSS, DAMAGE OR
|
||||
CORRUPTION OF DATA OR RECORDS; OR LOSS OF ANTICIPATED SAVINGS,
|
||||
OPPORTUNITY, REVENUE, PROFIT OR GOODWILL, OR OTHER ECONOMIC LOSS;
|
||||
OR ANY SPECIAL, INCIDENTAL, INDIRECT, CONSEQUENTIAL, PUNITIVE OR
|
||||
EXEMPLARY DAMAGES ARISING OUT OF OR IN CONNECTION WITH THIS LICENCE,
|
||||
THE SOFTWARE OR THE USE OF THE SOFTWARE, EVEN IF NICTA HAS BEEN
|
||||
ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
|
||||
|
||||
If applicable legislation implies warranties or conditions, or
|
||||
imposes obligations or liability on NICTA in respect of the Software
|
||||
that cannot be wholly or partly excluded, restricted or modified,
|
||||
NICTA's liability is limited, to the full extent permitted by the
|
||||
applicable legislation, at its option, to:
|
||||
|
||||
a. in the case of goods, any one or more of the following:
|
||||
i. the replacement of the goods or the supply of equivalent goods;
|
||||
ii. the repair of the goods;
|
||||
iii. the payment of the cost of replacing the goods or of acquiring
|
||||
equivalent goods;
|
||||
iv. the payment of the cost of having the goods repaired; or
|
||||
b. in the case of services:
|
||||
i. the supplying of the services again; or
|
||||
ii. the payment of the cost of having the services supplied
|
||||
again.
|
|
@ -1063,6 +1063,7 @@ normal_view = Normal View
|
|||
line = line
|
||||
lines = lines
|
||||
|
||||
editor.add_file = Add File
|
||||
editor.new_file = New File
|
||||
editor.upload_file = Upload File
|
||||
editor.edit_file = Edit File
|
||||
|
@ -1268,6 +1269,8 @@ issues.filter_milestone = Milestone
|
|||
issues.filter_milestone_no_select = All milestones
|
||||
issues.filter_assignee = Assignee
|
||||
issues.filter_assginee_no_select = All assignees
|
||||
issues.filter_poster = Author
|
||||
issues.filter_poster_no_select = All authors
|
||||
issues.filter_type = Type
|
||||
issues.filter_type.all_issues = All issues
|
||||
issues.filter_type.assigned_to_you = Assigned to you
|
||||
|
@ -3111,6 +3114,10 @@ npm.dependencies.development = Development Dependencies
|
|||
npm.dependencies.peer = Peer Dependencies
|
||||
npm.dependencies.optional = Optional Dependencies
|
||||
npm.details.tag = Tag
|
||||
pub.install = To install the package using Dart, run the following command:
|
||||
pub.documentation = For more information on the Pub registry, see <a target="_blank" rel="noopener noreferrer" href="https://docs.gitea.io/en-us/packages/pub/">the documentation</a>.
|
||||
pub.details.repository_site = Repository Site
|
||||
pub.details.documentation_site = Documentation Site
|
||||
pypi.requires = Requires Python
|
||||
pypi.install = To install the package using pip, run the following command:
|
||||
pypi.documentation = For more information on the PyPI registry, see <a target="_blank" rel="noopener noreferrer" href="https://docs.gitea.io/en-us/packages/pypi/">the documentation</a>.
|
||||
|
|
|
@ -179,6 +179,8 @@ log_root_path_helper=Archivos de registro se escribirán en este directorio.
|
|||
|
||||
optional_title=Configuración opcional
|
||||
email_title=Configuración de Correo
|
||||
smtp_addr=Servidor SMTP
|
||||
smtp_port=Puerto SMTP
|
||||
smtp_from=Enviar correos electrónicos como
|
||||
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>.
|
||||
mailer_user=Nombre de usuario SMTP
|
||||
|
@ -1061,6 +1063,7 @@ normal_view=Vista normal
|
|||
line=línea
|
||||
lines=líneas
|
||||
|
||||
editor.add_file=Añadir archivo
|
||||
editor.new_file=Nuevo Archivo
|
||||
editor.upload_file=Subir archivo
|
||||
editor.edit_file=Editar Archivo
|
||||
|
@ -2794,13 +2797,19 @@ config.queue_length=Tamaño de Cola de Envío
|
|||
config.deliver_timeout=Timeout de Entrega
|
||||
config.skip_tls_verify=Saltar verificación TLS
|
||||
|
||||
config.mailer_config=Configuración del servidor de correo
|
||||
config.mailer_enabled=Activado
|
||||
config.mailer_enable_helo=Habilitar HELO
|
||||
config.mailer_name=Nombre
|
||||
config.mailer_protocol=Protocolo
|
||||
config.mailer_smtp_addr=Dirección SMTP
|
||||
config.mailer_smtp_port=Puerto SMTP
|
||||
config.mailer_user=Usuario
|
||||
config.mailer_use_sendmail=Usar Sendmail
|
||||
config.mailer_sendmail_path=Ruta de Sendmail
|
||||
config.mailer_sendmail_args=Argumentos adicionales por Sendmail
|
||||
config.mailer_sendmail_timeout=Tiempo de espera de Sendmail
|
||||
config.mailer_use_dummy=Dummy
|
||||
config.test_email_placeholder=Correo electrónico (ej. test@ejemplo.com)
|
||||
config.send_test_mail=Enviar prueba de correo
|
||||
config.test_mail_failed=Fallo al enviar correo electrónico de prueba a '%s': %v
|
||||
|
@ -3103,6 +3112,10 @@ npm.dependencies.development=Dependencias de desarrollo
|
|||
npm.dependencies.peer=Dependencias de pares
|
||||
npm.dependencies.optional=Dependencias opcionales
|
||||
npm.details.tag=Etiqueta
|
||||
pub.install=Para instalar el paquete usando Dart, ejecute el siguiente comando:
|
||||
pub.documentation=Para obtener más información sobre el registro de Pub, consulte <a target="_blank" rel="noopener noreferrer" href="https://docs.gitea.io/en-us/packages/pub/">la documentación</a>.
|
||||
pub.details.repository_site=Sitio del repositorio
|
||||
pub.details.documentation_site=Sitio de documentación
|
||||
pypi.requires=Requiere Python
|
||||
pypi.install=Para instalar el paquete usando pip, ejecute el siguiente comando:
|
||||
pypi.documentation=Para obtener más información sobre el registro PyPI, consulte <a target="_blank" rel="noopener noreferrer" href="https://docs.gitea.io/en-us/packages/pypi/">la documentación</a>.
|
||||
|
|
|
@ -2,6 +2,7 @@ home=Etusivu
|
|||
dashboard=Kojelauta
|
||||
explore=Tutki
|
||||
help=Apua
|
||||
logo=Logo
|
||||
sign_in=Kirjaudu sisään
|
||||
sign_in_with=Kirjaudu sisään tunnuksilla
|
||||
sign_out=Kirjaudu ulos
|
||||
|
@ -21,16 +22,28 @@ signed_in_as=Kirjautuneena käyttäjänä
|
|||
enable_javascript=Tämä sivusto toimii paremmin JavaScriptillä.
|
||||
toc=Sisällysluettelo
|
||||
licenses=Lisenssit
|
||||
return_to_gitea=Palaa Giteaan
|
||||
|
||||
username=Käyttäjätunnus
|
||||
email=Sähköpostiosoite
|
||||
password=Salasana
|
||||
access_token=Pääsymerkki
|
||||
re_type=Kirjoita salasana uudelleen
|
||||
captcha=CAPTCHA
|
||||
twofa=Kaksivaiheinen todennus
|
||||
twofa_scratch=Kaksivaiheinen kertakäyttöinen koodi
|
||||
passcode=Tunnuskoodi
|
||||
|
||||
webauthn_insert_key=Aseta turva-avaimesi
|
||||
webauthn_press_button=Paina turva-avaimesi painiketta…
|
||||
webauthn_error=Turva-avainta ei voitu lukea.
|
||||
webauthn_unsupported_browser=Selaimesi ei tällä hetkellä tue WebAuthnia.
|
||||
webauthn_error_insecure=WebAuthn tukee vain suojattuja yhteyksiä. Testaukseen HTTP:n yli, voit käyttää osoitetta "localhost" tai "127.0.0.1"
|
||||
webauthn_error_unable_to_process=Palvelin ei pystynyt toteuttamaan kutsua.
|
||||
webauthn_error_duplicated=Turva-avainta ei ole sallittu tässä pyynnössä. Varmista, ettei avainta ole jo rekisteröity.
|
||||
webauthn_error_empty=Sinun täytyy asettaa nimi tälle avaimelle.
|
||||
webauthn_error_timeout=Aikakatkaisu saavutettu ennenkuin avaintasi on voitu lukea. Lataa tämä sivu uudelleen ja yritä uudelleen.
|
||||
webauthn_reload=Päivitä
|
||||
|
||||
repository=Repo
|
||||
organization=Organisaatio
|
||||
|
@ -40,6 +53,7 @@ new_migrate=Uusi migraatio
|
|||
new_mirror=Uusi peilaus
|
||||
new_fork=Uusi repositorio
|
||||
new_org=Uusi organisaatio
|
||||
new_project=Uusi projekti
|
||||
manage_org=Ylläpidä organisaatioita
|
||||
admin_panel=Sivuston ylläpito
|
||||
account_settings=Tilin asetukset
|
||||
|
@ -59,28 +73,47 @@ pull_requests=Pull requestit
|
|||
issues=Ongelmat
|
||||
milestones=Merkkipaalut
|
||||
|
||||
ok=OK
|
||||
cancel=Peruuta
|
||||
save=Tallenna
|
||||
add=Lisää
|
||||
add_all=Lisää kaikki
|
||||
remove=Poista
|
||||
remove_all=Poista kaikki
|
||||
edit=Muokkaa
|
||||
|
||||
copy=Kopioi
|
||||
copy_url=Kopioi osoite
|
||||
copy_branch=Kopioi haaran nimi
|
||||
copy_success=Kopioitu!
|
||||
copy_error=Kopiointi epäonnistui
|
||||
|
||||
write=Kirjoita
|
||||
preview=Esikatselu
|
||||
loading=Ladataan…
|
||||
|
||||
step1=Vaihe 1:
|
||||
step2=Vaihe 2:
|
||||
|
||||
error=Virhe
|
||||
error404=Sivu, jota yrität nähdä, joko <strong>ei löydy</strong> tai <strong>et ole oikeutettu</strong> katsomaan sitä.
|
||||
|
||||
never=Ei koskaan
|
||||
|
||||
rss_feed=RSS-syöte
|
||||
|
||||
[error]
|
||||
occurred=Virhe tapahtui
|
||||
report_message=Jos olet varma, että tämä on ongelma Giteassa, etsi ongelmaa <a href="https://github.com/go-gitea/gitea/issues" target="_blank">GitHubista</a> tai avaa uusi ongelma tarvittaessa.
|
||||
missing_csrf=Virheellinen pyyntö: CSRF-tunnusta ei ole olemassa
|
||||
invalid_csrf=Virheellinen pyyntö: Virheellinen CSRF-tunniste
|
||||
not_found=Kohdetta ei löytynyt.
|
||||
network_error=Verkkovirhe
|
||||
|
||||
[startpage]
|
||||
app_desc=Kivuton, itsehostattu Git-palvelu
|
||||
install=Helppo asentaa
|
||||
install_desc=Yksinkertaisesti <a target="_blank" rel="noopener noreferrer" href="https://docs.gitea.io/en-us/install-from-binary/">aja binääri</a> alustallasi, toimita se <a target="_blank" rel="noopener noreferrer" href="https://github.com/go-gitea/gitea/tree/master/docker">Dockerilla</a>, tai saa se <a target="_blank" rel="noopener noreferrer" href="https://docs.gitea.io/en-us/install-from-package/">pakettina</a>.
|
||||
platform=Alustariippumaton
|
||||
platform_desc=Gitea käy missä tahansa alustassa, johon <a target="_blank" rel="noopener noreferrer" href="http://golang.org/">Go</a> kykenee kääntämään. Windows, macOS, Linux, ARM, jne. Valitse omasi!
|
||||
lightweight=Kevyt
|
||||
|
@ -92,6 +125,7 @@ license_desc=Mene osoitteeseen <a target="_blank" rel="noopener noreferrer" href
|
|||
install=Asennus
|
||||
title=Alkuperäiset asetukset
|
||||
docker_helper=Jos ajat Giteaa Dockerin sisällä, lue <a target="_blank" rel="noopener noreferrer" href="%s">ohjeet</a> ennen minkään asetuksen muuttamista.
|
||||
require_db_desc=Gitea tarvitsee toimiakseen MySQL, PostgreSQL, MSSQL, SQLite3 tai TiDB (MySQL protokolla) tietokannan.
|
||||
db_title=Tietokanta asetukset
|
||||
db_type=Tietokanta tyyppi
|
||||
host=Isäntä
|
||||
|
@ -99,10 +133,16 @@ user=Käyttäjätunnus
|
|||
password=Salasana
|
||||
db_name=Tietokannan nimi
|
||||
db_helper=Huomautus MySQL-käyttäjille: käytä InnoDB-tallennusmoottoria, ja jos käytät "utf8mb4" merkistöä, InnoDB-version on oltava yli 5.6.
|
||||
db_schema=Skeema
|
||||
ssl_mode=SSL
|
||||
charset=Merkistö
|
||||
path=Polku
|
||||
sqlite_helper=SQLite3-tietokannan tiedostopolku.<br>Syötä absoluuttinen polku, jos ajat Giteaa palveluna.
|
||||
reinstall_error=Yrität asentaa olemassa olevaan Gitea tietokantaan
|
||||
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:
|
||||
reinstall_confirm_check_1=Tiedot, jotka on salattu SECRET_KEY:llä app.ini:ssä saatetaan menettää: käyttäjät eivät ehkä voi kirjautua sisään 2FA/OTP:lla ja peilit eivät välttämättä toimi oikein. Ruksaamalla tämän vahvistat, että nykyinen app.ini -tiedosto sisältää oikean SECRET_KEY:n.
|
||||
reinstall_confirm_check_2=Repot ja asetukset saattaa olla tarpeen uudelleensynkronoida. Valitsemalla tämän vahvistat, että uudelleensynkronoit repojen koukut ja authorized_keys -tiedoston manuaalisesti. Varmistat, että repon ja peilin asetukset ovat oikeat.
|
||||
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.
|
||||
err_empty_db_path=SQLite3-tietokannan polku ei voi olla tyhjä.
|
||||
no_admin_and_disable_registration=Et voi kytkeä rekisteröintiä pois luomatta sitä ennen ylläpitotiliä.
|
||||
err_empty_admin_password=Ylläpitäjän salasana ei voi olla tyhjä.
|
||||
|
@ -119,6 +159,7 @@ lfs_path=Git LFS -juuripolku
|
|||
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.
|
||||
run_user=Aja käyttäjänä
|
||||
run_user_helper=Anna käyttäjätunnus, jona Giteaa ajetaan. Käyttäjällä on oltava oikeudet repositorioiden juuripolkuun.
|
||||
domain=Palvelimen verkkotunnus
|
||||
ssh_port=SSH-palvelimen portti
|
||||
ssh_port_helper=Porttinumero, jossa SSH-palvelimesi kuuntelee. Jätä tyhjäksi kytkeäksesi pois.
|
||||
http_port=Gitean HTTP-kuunteluportti
|
||||
|
@ -150,6 +191,7 @@ openid_signin=Ota OpenID kirjautuminen käyttöön
|
|||
openid_signin_popup=Ota käyttöön kirjautuminen OpenID:n kautta.
|
||||
openid_signup=Ota käyttöön OpenID itse-rekisteröinti
|
||||
openid_signup_popup=Ota käyttöön OpenID-pohjainen käyttäjän itse-rekisteröinti.
|
||||
enable_captcha=Ota käyttöön CAPTCHA rekisteröityessä
|
||||
enable_captcha_popup=Pakollinen captcha käyttäjän itse rekisteröityessä.
|
||||
require_sign_in_view=Vaadi sisäänkirjautuminen sivujen näkemiseksi
|
||||
require_sign_in_view_popup=Rajoita pääsy vain kirjautuneille käyttäjille. Vierailijat näkevät vain 'kirjaudu sisään' ja rekisteröidy -sivut.
|
||||
|
@ -164,22 +206,41 @@ test_git_failed=Epäonnistui testata 'git' komentoa: %v
|
|||
sqlite3_not_available=Tämä Gitea versio ei tue SQLite3. Lataa virallinen binääriversio kohteesta %s (ei 'gobuild' versio).
|
||||
invalid_db_setting=Tietokanta-asetukset ovat väärin: %v
|
||||
invalid_repo_path=Repojen juuri polku on virheellinen: %v
|
||||
invalid_app_data_path=Sovelluksen datapolku on virheellinen: %v
|
||||
internal_token_failed=Sisäisen pääsymerkin luonti epäonnistui: %v
|
||||
save_config_failed=Asetusten tallentaminen epäonnistui: %v
|
||||
install_success=Tervetuloa! Kiitos kun valitsit Gitean. Pidä hauskaa!
|
||||
default_keep_email_private=Piilota sähköpostiosoitteet oletuksena
|
||||
default_enable_timetracking=Ota ajan seuranta oletusarvoisesti käyttöön
|
||||
default_enable_timetracking_popup=Ota käyttöön uusien repojen aikaseuranta oletusarvoisesti.
|
||||
no_reply_address=Piilotettu sähköpostin verkkotunnus
|
||||
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'.
|
||||
password_algorithm=Salasanan hajautusalgoritmi
|
||||
password_algorithm_helper=Aseta salasanan hajautusalgoritmi. Algoritmeillä on eri vaatimukset ja vahvuudet. `argon2`, vaikka sillä on hyvät ominaisuudet, käyttää paljon muistia ja voi olla sopimaton pienille järjestelmille.
|
||||
|
||||
[home]
|
||||
uname_holder=Käyttäjätunnus tai sähköpostiosoite
|
||||
password_holder=Salasana
|
||||
switch_dashboard_context=Vaihda kojelaudan kontekstia
|
||||
my_repos=Repot
|
||||
show_more_repos=Näytä lisää repoja…
|
||||
collaborative_repos=Yhteistyö repot
|
||||
my_orgs=Organisaationi
|
||||
my_mirrors=Peilini
|
||||
view_home=Näytä %s
|
||||
search_repos=Etsi repo…
|
||||
filter=Muut suodattimet
|
||||
filter_by_team_repositories=Suodata tiimin repojen mukaan
|
||||
feed_of=Syöte "%s"
|
||||
|
||||
show_archived=Arkistoidut
|
||||
show_both_archived_unarchived=Näytetään arkistoidut ja arkistoimattomat
|
||||
show_only_archived=Näytetään vain arkistoidut
|
||||
show_only_unarchived=Näytetään vain arkistoimattomat
|
||||
|
||||
show_private=Yksityinen
|
||||
show_only_private=Näytetään vain yksityiset
|
||||
show_only_public=Näytetään vain julkiset
|
||||
|
||||
issues.in_your_repos=Repoissasi
|
||||
|
||||
|
@ -189,6 +250,7 @@ users=Käyttäjät
|
|||
organizations=Organisaatiot
|
||||
search=Hae
|
||||
code=Koodi
|
||||
search.match=Osuma
|
||||
repo_no_results=Vastaavia repoja ei löydy.
|
||||
user_no_results=Vastaavia käyttäjiä ei löytynyt.
|
||||
org_no_results=Ei löytynyt vastaavia organisaatioita.
|
||||
|
@ -202,6 +264,7 @@ register_helper_msg=On jo tili? Kirjaudu sisään nyt!
|
|||
social_register_helper_msg=Onko sinulla jo tili? Linkitä se nyt!
|
||||
disable_register_prompt=Rekisteröinti on estetty. Ota yhteys ylläpitäjääsi.
|
||||
disable_register_mail=Sähköpostivahvistus rekisteröinnille on estetty.
|
||||
remember_me=Muista tämä laite
|
||||
forgot_password_title=Unohtuiko salasana
|
||||
forgot_password=Unohtuiko salasana?
|
||||
sign_up_now=Tarvitsetko tilin? Rekisteröidy nyt.
|
||||
|
@ -209,6 +272,7 @@ sign_up_successful=Tilin luonti onnistui.
|
|||
confirmation_mail_sent_prompt=Uusi varmistussähköposti on lähetetty osoitteeseen <b>%s</b>, ole hyvä ja tarkista saapuneet seuraavan %s tunnin sisällä saadaksesi rekisteröintiprosessin valmiiksi.
|
||||
must_change_password=Vaihda salasanasi
|
||||
allow_password_change=Vaadi käyttäjää vaihtamaan salasanansa (suositeltava)
|
||||
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.
|
||||
active_your_account=Aktivoi tilisi
|
||||
account_activated=Tili on aktivoitu
|
||||
prohibit_login=Kirjautuminen estetty
|
||||
|
@ -217,9 +281,11 @@ resent_limit_prompt=Olet jo tilannut aktivointisähköpostin hetki sitten. Ole h
|
|||
has_unconfirmed_mail=Hei %s, sinulla on varmistamaton sähköposti osoite (<b>%s</b>). Jos et ole saanut varmistus sähköpostia tai tarvitset uudelleenlähetyksen, ole hyvä ja klikkaa allaolevaa painiketta.
|
||||
resend_mail=Klikkaa tästä uudelleenlähettääksesi aktivointi sähköpostisi
|
||||
email_not_associate=Tätä sähköpostiosoitetta ei ole liitetty mihinkään tiliin.
|
||||
send_reset_mail=Lähetä tilin palautussähköposti
|
||||
reset_password=Tilin palautus
|
||||
invalid_code=Vahvistusavain on virheellinen tai vanhentunut.
|
||||
reset_password_helper=Palauta käyttäjätili
|
||||
reset_password_wrong_user=Olet kirjautunut sisään nimellä %s, mutta tilin palautuslinkki on tarkoitettu kohteelle %s
|
||||
password_too_short=Salasanan pituus ei voi olla vähemmän kuin %d merkkiä.
|
||||
non_local_account=Ei-lokaalit käyttäjät eivät voi päivittää salasanojaan Gitean web-käyttöliittymän kautta.
|
||||
verify=Vahvista
|
||||
|
@ -231,10 +297,12 @@ twofa_scratch_token_incorrect=Kertakäyttökoodisi on virheellinen.
|
|||
login_userpass=Kirjaudu sisään
|
||||
login_openid=OpenID
|
||||
oauth_signup_tab=Rekisteröi uusi tili
|
||||
oauth_signup_title=Viimeistele tili
|
||||
oauth_signup_submit=Viimeistele tili
|
||||
oauth_signin_tab=Linkitä olemassa olevaan tiliin
|
||||
oauth_signin_title=Kirjaudu sisään valtuuttaaksesi linkitetyn tilin
|
||||
oauth_signin_submit=Yhdistä tiliin
|
||||
oauth.signin.error.access_denied=Valtuutuspyyntö on evätty.
|
||||
openid_connect_submit=Connect
|
||||
openid_connect_title=Yhdistä olemassaolevaan tiliin
|
||||
openid_connect_desc=Valittu OpenID-osoite on tuntematon. Liitä se uuteen tiliin täällä.
|
||||
|
@ -250,22 +318,38 @@ authorize_title=Valtuutatko "%s" pääsemään tilillesi?
|
|||
authorization_failed=Käyttöoikeuden varmistus epäonnistui
|
||||
authorization_failed_desc=Käyttöoikeuden varmistus epäonnistui virheellisen pyynnön takia. Ota yhteyttä sovelluksen ylläpitäjään, jonka olet yrittänyt valtuuttaa.
|
||||
sspi_auth_failed=SSPI todennus epäonnistui
|
||||
password_pwned=Valitsemasi salasana on <a target="_blank" rel="noopener noreferrer" href="https://haveibeenpwned.com/Passwords">varastettujen salasanojen luettelossa</a>, joka on aiemmin paljastunut julkisissa tietorikkomuksissa. Yritä uudelleen toisella salasanalla.
|
||||
|
||||
[mail]
|
||||
view_it_on=Näytä %s
|
||||
link_not_working_do_paste=Eikö toimi? Yritä kopioida ja liittää se selaimeesi.
|
||||
hi_user_x=Hei <b>%s</b>,
|
||||
|
||||
activate_account=Ole hyvä ja aktivoi tilisi
|
||||
|
||||
activate_email=Vahvista sähköpostiosoitteesi
|
||||
activate_email.title=%s, vahvista sähköpostiosoitteesi
|
||||
|
||||
register_notify=Tervetuloa Giteaan
|
||||
register_notify.text_2=Voit nyt kirjautua käyttäjätunnuksella: %s.
|
||||
|
||||
reset_password=Palauta käyttäjätili
|
||||
reset_password.title=%s, olet pyytänyt tilisi palauttamista
|
||||
|
||||
register_success=Rekisteröinti onnistui
|
||||
|
||||
|
||||
issue.x_mentioned_you=<b>@%s</b> mainitsi sinut:
|
||||
issue.action.push_1=<b>@%[1]s</b> työnsi %[3]d commitin kohteeseen %[2]s
|
||||
issue.action.push_n=<b>@%[1]s</b> työnsi %[3]d committia kohteeseen %[2]s
|
||||
|
||||
release.title=Otsikko: %s
|
||||
release.note=Huomautus:
|
||||
release.downloads=Lataukset:
|
||||
release.download.zip=Lähdekoodi (ZIP)
|
||||
release.download.targz=Lähdekoodi (TAR.GZ)
|
||||
|
||||
repo.transfer.to_you=sinä
|
||||
|
||||
|
||||
[modal]
|
||||
|
@ -286,6 +370,7 @@ AuthName=Luvan nimi
|
|||
AdminEmail=Ylläpito sähköposti
|
||||
|
||||
NewBranchName=Uuden haaran nimi
|
||||
CommitSummary=Commitin yhteenveto
|
||||
CommitMessage=Commitin viesti
|
||||
CommitChoice=Commitin valinta
|
||||
TreeName=Tiedostopolku
|
||||
|
@ -301,17 +386,24 @@ max_size_error=` täytyy sisältää enintään %s merkkiä.`
|
|||
email_error=` ei ole kelvollinen sähköpostiosoite.`
|
||||
include_error=` täytyy sisältää tekstiosa '%s'.`
|
||||
unknown_error=Tuntematon virhe:
|
||||
captcha_incorrect=CAPTCHA koodi on virheellinen.
|
||||
password_not_match=Salasanat eivät täsmää.
|
||||
lang_select_error=Valitse kieli listalta.
|
||||
|
||||
username_been_taken=Käyttäjätunnus on jo varattu.
|
||||
repo_name_been_taken=Repon nimi on jo käytössä.
|
||||
repository_force_private=Pakotettu yksityisyys käytössä: yksityisiä repoja ei voida muuttaa julkisiksi.
|
||||
org_name_been_taken=Organisaation nimi on jo käytössä.
|
||||
team_name_been_taken=Tiimin nimi on jo varattu.
|
||||
email_been_used=Sähköpostiosoite on jo käytössä.
|
||||
email_invalid=Sähköpostiosoite on virheellinen.
|
||||
openid_been_used=OpenID-osoite '%s' on jo käytössä.
|
||||
username_password_incorrect=Käyttäjätunnus tai salasana on virheellinen.
|
||||
password_lowercase_one=Ainakin yksi pieni kirjan
|
||||
password_uppercase_one=Ainakin yksi iso kirjain
|
||||
password_digit_one=Ainakin yksi numero
|
||||
password_special_one=Ainakin yksi erikoismerkki (välimerkki, sulut, lainausmerkit, jne.)
|
||||
enterred_invalid_org_name=Antamasi organisaation nimi on virheellinen.
|
||||
enterred_invalid_password=Syöttämäsi salasana oli väärä.
|
||||
user_not_exist=Käyttäjää ei ole olemassa.
|
||||
team_not_exist=Tiimiä ei ole olemassa.
|
||||
|
@ -332,16 +424,20 @@ repositories=Repot
|
|||
activity=Julkinen toiminta
|
||||
followers=Seuraajat
|
||||
starred=Tähdelliset repot
|
||||
projects=Projektit
|
||||
following=Seurataan
|
||||
follow=Seuraa
|
||||
unfollow=Lopeta seuraaminen
|
||||
heatmap.loading=Ladataan lämpökarttaa…
|
||||
user_bio=Elämäkerta
|
||||
|
||||
form.name_reserved=Käyttäjätunnus '%s' on varattu.
|
||||
form.name_chars_not_allowed=Käyttäjänimi '%s' sisältää virheellisiä merkkejä.
|
||||
|
||||
[settings]
|
||||
profile=Profiili
|
||||
account=Tili
|
||||
appearance=Ulkoasu
|
||||
password=Salasana
|
||||
security=Turvallisuus
|
||||
avatar=Profiilikuva
|
||||
|
@ -355,8 +451,10 @@ twofa=Kaksivaiheinen todennus
|
|||
account_link=Linkitetyt tilit
|
||||
organization=Organisaatiot
|
||||
uid=Käyttäjä ID
|
||||
webauthn=Turva-avaimet
|
||||
|
||||
public_profile=Julkinen profiili
|
||||
biography_placeholder=Kerro itsestäsi
|
||||
profile_desc=Sähköpostiosoitettasi käytetään ilmoituksiin ja muihin toimintoihin.
|
||||
password_username_disabled=Ei-paikalliset käyttäjät eivät voi muuttaa käyttäjätunnustaan. Ole hyvä ja ota yhteyttä sivuston ylläpitäjään saadaksesi lisätietoa.
|
||||
full_name=Kokonimi
|
||||
|
@ -364,6 +462,9 @@ website=Nettisivut
|
|||
location=Sijainti
|
||||
update_theme=Päivitä teema
|
||||
update_profile=Päivitä profiili
|
||||
update_language=Päivitä kieli
|
||||
update_language_not_found=Kieli '%s' ei ole käytettävissä.
|
||||
update_language_success=Kieli on päivitetty.
|
||||
update_profile_success=Profiilisi on päivitetty.
|
||||
change_username=Käyttäjätunnuksesi on muutettu.
|
||||
change_username_prompt=Huomio: käyttäjätunnuksen muutos muuttaa myös tilisi URL:n.
|
||||
|
@ -371,6 +472,23 @@ continue=Jatka
|
|||
cancel=Peruuta
|
||||
language=Kieli
|
||||
ui=Teema
|
||||
hidden_comment_types=Piilotetut kommenttityypit
|
||||
comment_type_group_reference=Viittaus
|
||||
comment_type_group_label=Tunniste
|
||||
comment_type_group_milestone=Merkkipaalu
|
||||
comment_type_group_assignee=Osoitettu henkilölle
|
||||
comment_type_group_title=Otsikko
|
||||
comment_type_group_branch=Haara
|
||||
comment_type_group_time_tracking=Ajan seuranta
|
||||
comment_type_group_deadline=Määräaika
|
||||
comment_type_group_dependency=Riippuvuus
|
||||
comment_type_group_lock=Lukituksen tila
|
||||
comment_type_group_review_request=Arviointipyyntö
|
||||
comment_type_group_pull_request_push=Lisätyt commitit
|
||||
comment_type_group_project=Projekti
|
||||
saved_successfully=Asetuksesi tallennettiin onnistuneesti.
|
||||
privacy=Yksityisyys
|
||||
keep_activity_private=Piilota toiminta profiilisivulta
|
||||
|
||||
lookup_avatar_by_mail=Hae profiilikuva sähköpostin perusteella
|
||||
federated_avatar_lookup=Ulkopuolinen profiilikuvan haku
|
||||
|
@ -397,17 +515,23 @@ primary=Ensisijainen
|
|||
activated=Aktivoitu
|
||||
requires_activation=Vaatii aktivoinnin
|
||||
primary_email=Tee ensisijainen
|
||||
activate_email=Lähetä aktivointi
|
||||
activations_pending=Odottaa aktivointia
|
||||
delete_email=Poista
|
||||
email_deletion=Poista sähköpostiosoite
|
||||
email_deletion_desc=Sähköpostiosoite ja siihen liittyvät tiedot poistetaan tililtäsi. Kyseisen sähköpostiosoitteen sisältävät commitit pysyvät muuttumattomia. Jatketaanko?
|
||||
email_deletion_success=Sähköpostiosoite on poistettu.
|
||||
theme_update_success=Teemasi on päivitetty.
|
||||
theme_update_error=Valittua teemaa ei löydy.
|
||||
openid_deletion=Poista OpenID-osoite
|
||||
openid_deletion_success=OpenID-osoite on poistettu.
|
||||
add_new_email=Lisää uusi sähköpostiosoite
|
||||
add_new_openid=Lisää uusi OpenID URI
|
||||
add_email=Lisää sähköpostiosoite
|
||||
add_openid=Lisää OpenID URI
|
||||
add_email_success=Uusi sähköpostiosoite on lisätty.
|
||||
email_preference_set_success=Sähköpostin asetukset on asetettu onnistuneesti.
|
||||
add_openid_success=Uusi OpenID-osoite on lisätty.
|
||||
keep_email_private=Piilota sähköpostiosoite
|
||||
keep_email_private_popup=Sähköpostiosoitteesi on piilotettu muilta käyttäjiltä.
|
||||
openid_desc=OpenID mahdollistaa todentamisen delegoinnin ulkopuoliselle palvelun tarjoajalle.
|
||||
|
@ -421,10 +545,35 @@ ssh_helper=<strong>Tarvitsetko apua?</strong> Tutustu GitHubin oppaaseen <a href
|
|||
gpg_helper=<strong>Tarvitsetko apua?</strong> Katso GitHubin opas <a href="%s">GPG</a>:stä.
|
||||
add_new_key=Lisää SSH avain
|
||||
add_new_gpg_key=Lisää GPG-avain
|
||||
key_content_ssh_placeholder=Alkaa sanoilla 'ssh-ed25519', 'ssh-rsa', 'ecdsa-sha2-nistp256', 'ecdsa-sha2-nistp384', 'ecdsa-sha2-nistp521', 'sk-ecdsa-sha2-nistp256@openssh.com', tai 'sk-ssh-ed25519@openssh.com'
|
||||
key_content_gpg_placeholder=Alkaa sanoilla '-----BEGIN PGP PUBLIC KEY BLOCK-----'
|
||||
ssh_key_name_used=Samanniminen SSH avain on jo olemassa tililläsi.
|
||||
gpg_key_id_used=Julkinen GPG-avain samalla tunnuksella on jo olemassa.
|
||||
gpg_no_key_email_found=Tämä GPG-avain ei vastaa mitään tiliisi liitettyä aktivoitua sähköpostiosoitetta. Se voidaan silti lisätä, jos allekirjoitat annetun pääsymerkin.
|
||||
gpg_key_verified=Vahvistettu avain
|
||||
gpg_key_verified_long=Avain on vahvistettu pääsymerkillä ja sitä voidaan käyttää todentamaan commitit, jotka vastaavat tämän käyttäjän aktivoituja sähköpostiosoitteita tämän avaimen kaikkien vastaavien identiteettien lisäksi.
|
||||
gpg_key_verify=Vahvista
|
||||
gpg_token_required=Sinun täytyy antaa allekirjoitus alla olevalle pääsymerkille
|
||||
gpg_token=Pääsymerkki
|
||||
gpg_token_help=Voit luoda allekirjoituksen käyttäen:
|
||||
gpg_token_code=echo "%s" | gpg -a --default-key %s --detach-sig
|
||||
gpg_token_signature=Panssaroitu GPG-allekirjoitus
|
||||
key_signature_gpg_placeholder=Alkaa sanoilla '-----BEGIN PGP SIGNATURE-----'
|
||||
verify_gpg_key_success=GPG-avain '%s' on vahvistettu.
|
||||
ssh_key_verified=Vahvistettu avain
|
||||
ssh_key_verified_long=Avain on vahvistettu pääsymerkillä ja sitä voidaan käyttää todentamaan commitit, jotka vastaavat tämän käyttäjän aktivoituja sähköpostiosoitteita.
|
||||
ssh_key_verify=Vahvista
|
||||
ssh_token_required=Sinun täytyy antaa allekirjoitus alla olevalle pääsymerkille
|
||||
ssh_token=Pääsymerkki
|
||||
ssh_token_help=Voit luoda allekirjoituksen käyttäen:
|
||||
ssh_token_signature=Panssaroitu SSH-allekirjoitus
|
||||
key_signature_ssh_placeholder=Alkaa sanoilla '-----BEGIN SSH SIGNATURE-----'
|
||||
verify_ssh_key_success=SSH avain '%s' on vahvistettu.
|
||||
subkeys=Aliavaimet
|
||||
key_id=Avain ID
|
||||
key_name=Avaimen nimi
|
||||
key_content=Sisältö
|
||||
principal_content=Sisältö
|
||||
add_key_success=SSH-avain '%s' on lisätty.
|
||||
add_gpg_key_success=GPG-avain '%s' lisättiin.
|
||||
delete_key=Poista
|
||||
|
@ -434,13 +583,22 @@ gpg_key_deletion_desc=GPG-avaimen poistaminen peruuttaa sillä allekirjoitettuje
|
|||
gpg_key_deletion_success=GPG-avain on poistettu.
|
||||
add_on=Lisätty
|
||||
valid_until=Vanhenee
|
||||
valid_forever=Voimassa ikuisesti
|
||||
last_used=Käytetty viimeksi
|
||||
no_activity=Ei viimeaikaista toimintaa
|
||||
can_read_info=Luku
|
||||
can_write_info=Kirjoitus
|
||||
show_openid=Näytä profiilissa
|
||||
hide_openid=Piilota profiilista
|
||||
ssh_disabled=SSH pois käytöstä
|
||||
manage_social=Hallitse liitettyjä sosiaalisia tilejä
|
||||
|
||||
manage_access_token=Hallitse pääsymerkkejä
|
||||
generate_new_token=Luo uusi pääsymerkki
|
||||
new_token_desc=Pääsymerkkiä käyttävillä sovelluksilla on täysi pääsy tiliisi.
|
||||
token_name=Pääsymerkin nimi
|
||||
generate_token=Luo pääsymerkki
|
||||
generate_token_success=Uusi pääsymerkkisi on nyt luotu. Kopioi se nyt, koska sitä ei näytetä enää uudelleen.
|
||||
delete_token=Poista
|
||||
access_token_deletion=Poista pääsymerkki
|
||||
|
||||
|
@ -458,8 +616,15 @@ oauth2_application_edit=Muokkaa
|
|||
|
||||
|
||||
twofa_desc=Kaksivaiheinen todennus parantaa tilisi turvallisuutta.
|
||||
twofa_is_enrolled=Tilisi <strong>käyttää</strong> kaksivaiheista vahvistusta.
|
||||
twofa_not_enrolled=Tilisi ei tällä hetkellä käytä kaksivaiheista vahvistusta.
|
||||
twofa_enroll=Ota kaksivaiheinen vahvistus käyttöön
|
||||
twofa_disabled=Kaksivaiheinen todennus on otettu pois käytöstä.
|
||||
scan_this_image=Skannaa tämä kuva tunnistautumissovelluksellasi:
|
||||
or_enter_secret=Tai kirjoita salainen avain: %s
|
||||
twofa_enrolled=Tiliisi on otettu käyttöön kaksivaiheinen vahvistus. Ota palautustunnus (%s) talteen turvalliseen paikkaan, sillä se näytetään vain kerran!
|
||||
|
||||
webauthn_nickname=Nimimerkki
|
||||
|
||||
manage_account_links=Hallitse linkitettyjä tilejä
|
||||
manage_account_links_desc=Nämä ulkoiset tilit on linkitetty Gitea tiliisi.
|
||||
|
@ -475,37 +640,60 @@ delete_prompt=Tämä toiminto poistaa käyttäjätilisi pysyvästi. Toimintoa <s
|
|||
confirm_delete_account=Varmista poisto
|
||||
delete_account_title=Poista käyttäjätili
|
||||
|
||||
email_notifications.enable=Ota käyttöön sähköposti-ilmoitukset
|
||||
|
||||
visibility=Käyttäjän näkyvyys
|
||||
visibility.public=Julkinen
|
||||
visibility.public_tooltip=Näkyvissä kaikille käyttäjille
|
||||
visibility.limited=Rajattu
|
||||
visibility.private=Yksityinen
|
||||
|
||||
[repo]
|
||||
new_repo_helper=Repo sisältää kaikki projektitiedostot, mukaan lukien revisiohistorian. Onko sinulla repo jo muualla? <a href="%s">Voit siirtää repon.</a>
|
||||
owner=Omistaja
|
||||
owner_helper=Jotkin organisaatiot eivät välttämättä näy pudotusvalikossa, koska repojen maksimimäärää on rajoitettu.
|
||||
repo_name=Repon nimi
|
||||
repo_name_helper=Hyvä repon nimi on lyhyt, mieleenpainuva ja yksilöllinen.
|
||||
repo_size=Repon koko
|
||||
template=Malli
|
||||
template_select=Valitse malli.
|
||||
template_helper=Tee reposta mallipohja
|
||||
visibility=Näkyvyys
|
||||
visibility_description=Vain omistaja tai organisaation jäsenet, jos heillä on oikeudet, voivat nähdä sen.
|
||||
visibility_helper=Tee reposta yksityinen
|
||||
fork_repo=Forkkaa repo
|
||||
fork_from=Forkkaa lähteestä
|
||||
fork_visibility_helper=Forkatun repon näkyvyyttä ei voi muuttaa.
|
||||
clone_in_vsc=Kloonaa VS Codessa
|
||||
download_zip=Lataa ZIP
|
||||
download_tar=Lataa TAR.GZ
|
||||
repo_desc=Kuvaus
|
||||
repo_lang=Kieli
|
||||
repo_gitignore_helper=Valitse .gitignore mallit.
|
||||
issue_labels=Ongelmien tunnisteet
|
||||
issue_labels_helper=Valitse pohja ongelmien nimilapuille.
|
||||
license=Lisenssi
|
||||
license_helper=Valitse lisenssitiedosto.
|
||||
readme=README
|
||||
auto_init=Alusta repo (Luo .gitignore, License ja README)
|
||||
create_repo=Luo repo
|
||||
default_branch=Oletus branch
|
||||
mirror_prune=Karsi
|
||||
watchers=Tarkkailijat
|
||||
stargazers=Tähtiharrastajat
|
||||
forks=Haarat
|
||||
pick_reaction=Valitse reaktiosi
|
||||
delete_preexisting_label=Poista
|
||||
|
||||
|
||||
desc.private=Yksityinen
|
||||
desc.public=Julkinen
|
||||
desc.private_template=Yksityinen malli
|
||||
desc.public_template=Malli
|
||||
desc.internal=Sisäinen
|
||||
|
||||
template.git_hooks=Git-koukut
|
||||
template.webhooks=Webkoukut
|
||||
template.topics=Aiheet
|
||||
template.avatar=Profiilikuva
|
||||
template.issue_labels=Ongelmien tunnisteet
|
||||
|
@ -521,15 +709,18 @@ migrate_items_pullrequests=Vetopyynnöt
|
|||
migrate_items_releases=Julkaisut
|
||||
migrate_repo=Siirrä repo
|
||||
migrate.clone_address=Migraation / Kloonaa URL osoitteesta
|
||||
migrate.github_token_desc=Voit laittaa yhden tai useamman pääsymerkin pilkulla erotellen tähän nopeuttaaksesi migraatiota GitHub APIn vauhtirajojen takia. VAROITUS: Tämän ominaisuuden väärinkäyttö voi rikkoa palveluntarjoajan ehtoja ja johtaa tilin estämiseen.
|
||||
migrate.permission_denied=Sinun ei sallita tuovan paikallisia repoja.
|
||||
migrate.failed=Siirto epäonnistui: %v
|
||||
migrate.migrate_items_options=Pääsymerkki vaaditaan lisäkohteiden siirtämiseen
|
||||
migrate.migrating_failed.error=Virhe: %s
|
||||
|
||||
mirror_from=peilaus alkaen
|
||||
forked_from=forkattu lähteestä
|
||||
unwatch=Lopeta tarkkailu
|
||||
watch=Tarkkaile
|
||||
unstar=Peru ääni
|
||||
star=Äänestä
|
||||
unstar=Poista tähti
|
||||
star=Tähti
|
||||
download_archive=Lataa varasto
|
||||
|
||||
no_desc=Ei kuvausta
|
||||
|
@ -549,7 +740,10 @@ labels=Tunnisteet
|
|||
|
||||
milestones=Merkkipaalut
|
||||
commits=Commitit
|
||||
commit=Commit
|
||||
releases=Julkaisut
|
||||
tag=Tagi
|
||||
released_this=julkaisi tämän
|
||||
file_raw=Raaka
|
||||
file_history=Historia
|
||||
file_view_raw=Näytä raaka
|
||||
|
@ -557,6 +751,8 @@ file_permalink=Pysyvä linkki
|
|||
|
||||
video_not_supported_in_browser=Selaimesi ei tue HTML5 video-tagia.
|
||||
audio_not_supported_in_browser=Selaimesi ei tue HTML5 audio-tagia.
|
||||
blame=Selitys
|
||||
download_file=Lataa tiedosto
|
||||
normal_view=Normaali näkymä
|
||||
line=rivi
|
||||
lines=rivejä
|
||||
|
@ -585,6 +781,7 @@ editor.create_new_branch_np=Luo <strong>uusi haara</strong> tälle commitille.
|
|||
editor.cancel=Peruuta
|
||||
editor.filename_cannot_be_empty=Tiedostonimi ei voi olla tyhjä.
|
||||
editor.filename_is_invalid=Tiedostonnimi on epäkelpo: '%s'.
|
||||
editor.branch_already_exists=Haara '%s' on jo olemassa tässä repossa.
|
||||
editor.no_changes_to_show=Ei muutoksia näytettäväksi.
|
||||
editor.add_subdir=Lisää hakemisto…
|
||||
editor.unable_to_upload_files=Tiedostojen lataaminen kohteeseen '%s' epäonnistui virheellä: %v
|
||||
|
@ -600,9 +797,32 @@ commits.date=Päivämäärä
|
|||
commits.older=Vanhemmat
|
||||
commits.newer=Uudemmat
|
||||
commits.signed_by=Allekirjoittanut
|
||||
commits.gpg_key_id=GPG avaimen ID
|
||||
commits.ssh_key_fingerprint=SSH avaimen sormenjälki
|
||||
|
||||
|
||||
|
||||
projects=Projektit
|
||||
projects.description_placeholder=Kuvaus
|
||||
projects.create=Luo projekti
|
||||
projects.title=Otsikko
|
||||
projects.new=Uusi projekti
|
||||
projects.create_success=Projekti '%s' on luotu.
|
||||
projects.deletion=Poista projekti
|
||||
projects.deletion_success=Projekti on poistettu.
|
||||
projects.edit=Muokkaa projektia
|
||||
projects.modify=Päivitä projekti
|
||||
projects.edit_success=Projekti '%s' on päivitetty.
|
||||
projects.type.basic_kanban=Yksinkertainen Kanban
|
||||
projects.type.uncategorized=Luokittelematon
|
||||
projects.board.edit=Muokkaa luetteloa
|
||||
projects.board.new_submit=Lähetä
|
||||
projects.board.new=Uusi taulu
|
||||
projects.board.set_default=Aseta oletukseksi
|
||||
projects.board.delete=Poista taulu
|
||||
projects.board.color=Väri
|
||||
projects.open=Avaa
|
||||
projects.close=Sulje
|
||||
|
||||
issues.desc=Ongelmien, tehtävien ja merkkipaalujen hallinta.
|
||||
issues.filter_milestones=Suodata merkkipaalu
|
||||
|
@ -619,12 +839,14 @@ issues.new.closed_milestone=Suljetut merkkipaalut
|
|||
issues.new.assignees=Käsittelijä
|
||||
issues.new.clear_assignees=Tyhjennä käsittelijä
|
||||
issues.new.no_assignees=Ei käsittelijää
|
||||
issues.choose.blank=Oletus
|
||||
issues.no_ref=Haaraa/tagia ei määritelty
|
||||
issues.create=Ilmoita ongelma
|
||||
issues.new_label=Uusi tunniste
|
||||
issues.new_label_placeholder=Tunnisteen nimi
|
||||
issues.new_label_desc_placeholder=Kuvaus
|
||||
issues.create_label=Luo tunniste
|
||||
issues.label_templates.helper=Valitse tunnistejoukko
|
||||
issues.add_milestone_at=`lisäsi tämän merkkipaaluun <b>%s</b> %s`
|
||||
issues.deleted_milestone=`(poistettu)`
|
||||
issues.self_assign_at=`itse otti tämän käsittelyyn %s`
|
||||
|
@ -640,6 +862,7 @@ issues.filter_type.all_issues=Kaikki ongelmat
|
|||
issues.filter_type.assigned_to_you=Osoitettu sinulle
|
||||
issues.filter_type.created_by_you=Ilmoittamasi
|
||||
issues.filter_type.mentioning_you=Jotka mainitsee sinut
|
||||
issues.filter_type.review_requested=Arvostelua pyydetty
|
||||
issues.filter_sort=Lajittele
|
||||
issues.filter_sort.latest=Uusin
|
||||
issues.filter_sort.oldest=Vanhin
|
||||
|
@ -657,6 +880,7 @@ issues.action_open=Avaa
|
|||
issues.action_close=Sulje
|
||||
issues.action_label=Tunniste
|
||||
issues.action_milestone=Merkkipaalu
|
||||
issues.action_milestone_no_select=Ei merkkipaalua
|
||||
issues.opened_by=%[1]s avasi <a href="%[2]s">%[3]s</a>
|
||||
issues.previous=Edellinen
|
||||
issues.next=Seuraava
|
||||
|
@ -724,9 +948,11 @@ issues.add_time_minutes=Minuuttia
|
|||
issues.add_time_sum_to_small=Aikaa ei syötetty.
|
||||
issues.time_spent_from_all_authors=`Käytetty kokonaisaika: %s`
|
||||
issues.due_date=Määräpäivä
|
||||
issues.due_date_form=vvvv-kk-pp
|
||||
issues.due_date_form_edit=Muokkaa
|
||||
issues.due_date_form_remove=Poista
|
||||
issues.due_date_not_set=Määräpäivää ei asetettu.
|
||||
issues.due_date_overdue=Myöhässä
|
||||
issues.dependency.title=Riippuvuudet
|
||||
issues.dependency.add=Lisää riippuvuus…
|
||||
issues.dependency.cancel=Peru
|
||||
|
@ -734,6 +960,12 @@ issues.dependency.remove=Poista
|
|||
issues.dependency.remove_info=Poistä tämä riippuvuus
|
||||
issues.review.self.approval=Et voi hyväksyä omia vetopyyntöjä.
|
||||
issues.review.approve=hyväksyi nämä muutokset %s
|
||||
issues.review.left_comment=jätti kommentin
|
||||
issues.review.pending=Odottaa
|
||||
issues.reference_issue.body=Kuvaus
|
||||
issues.content_history.deleted=poistettu
|
||||
issues.content_history.edited=muokattu
|
||||
issues.content_history.created=luotu
|
||||
|
||||
|
||||
pulls.new=Uusi pull pyyntö
|
||||
|
@ -775,12 +1007,17 @@ milestones.edit_success=Merkkipaalu '%s' on päivitetty.
|
|||
milestones.filter_sort.most_issues=Eniten ongelmia
|
||||
milestones.filter_sort.least_issues=Vähiten ongelmia
|
||||
|
||||
signing.wont_sign.always=Commitit ovat aina allekirjoitettuja
|
||||
|
||||
|
||||
wiki=Wiki
|
||||
wiki.welcome=Tervetuloa Wikiin.
|
||||
wiki.welcome_desc=Wikissä voit kirjoittaa ja jakaa dokumentaatiota käyttäjien kesken.
|
||||
wiki.create_first_page=Luo ensimmäinen sivu
|
||||
wiki.page=Sivu
|
||||
wiki.filter_page=Suodatin sivu
|
||||
wiki.new_page=Sivu
|
||||
wiki.default_commit_message=Kirjoita muistiinpano tästä päivityksestä (valinnainen).
|
||||
wiki.save_page=Tallenna sivu
|
||||
wiki.last_commit_info=%s muokkasi tätä sivua %s
|
||||
wiki.edit_page_button=Muokkaa
|
||||
|
@ -813,6 +1050,7 @@ activity.new_issues_count_n=Uutta ongelmaa
|
|||
activity.new_issue_label=Avoinna
|
||||
activity.unresolved_conv_label=Auki
|
||||
activity.published_release_label=Julkaistu
|
||||
activity.git_stats_pushed_1=on työntänyt
|
||||
activity.git_stats_file_1=%d tiedosto
|
||||
activity.git_stats_file_n=%d tiedostoa
|
||||
activity.git_stats_addition_1=%d lisäys
|
||||
|
@ -881,15 +1119,27 @@ settings.discord_username=Käyttäjätunnus
|
|||
settings.event_create=Luo
|
||||
settings.event_delete=Poista
|
||||
settings.event_release_desc=Julkaisu julkaistu, päivitetty tai poistettu varastosta.
|
||||
settings.event_push=Työnnä
|
||||
settings.event_repository=Repo
|
||||
settings.event_issue_comment_desc=Ongelman kommentti luotu, muokattu tai poistettu.
|
||||
settings.event_pull_request=Vetopyyntö
|
||||
settings.update_webhook=Päivitä webkoukku
|
||||
settings.delete_webhook=Poista webkoukku
|
||||
settings.recent_deliveries=Viimeisimmät toimitukset
|
||||
settings.hook_type=Koukkutyyppi
|
||||
settings.slack_token=Pääsymerkki
|
||||
settings.slack_domain=Verkkotunnus
|
||||
settings.slack_channel=Kanava
|
||||
settings.web_hook_name_gitea=Gitea
|
||||
settings.web_hook_name_gogs=Gogs
|
||||
settings.web_hook_name_slack=Slack
|
||||
settings.web_hook_name_discord=Discord
|
||||
settings.web_hook_name_dingtalk=DingTalk
|
||||
settings.web_hook_name_telegram=Telegram
|
||||
settings.web_hook_name_matrix=Matrix
|
||||
settings.web_hook_name_feishu=Feishu
|
||||
settings.web_hook_name_larksuite=Lark Suite
|
||||
settings.web_hook_name_packagist=Packagist
|
||||
settings.deploy_keys=Deploy avaimet
|
||||
settings.add_deploy_key=Lisää deploy avain
|
||||
settings.title=Otsikko
|
||||
|
@ -904,12 +1154,20 @@ settings.protect_merge_whitelist_committers_desc=Salli vain listaan merkittyjen
|
|||
settings.protect_merge_whitelist_users=Lista käyttäjistä joilla yhdistämis-oikeus:
|
||||
settings.protect_required_approvals=Vaadittavat hyväksynnät:
|
||||
settings.protect_approvals_whitelist_users=Sallittujen tarkastajien lista:
|
||||
settings.protect_protected_file_patterns_desc=Suojatut tiedostot, joita ei voi muuttaa suoraan, vaikka käyttäjällä olisi oikeudet lisätä, muokata tai poistaa tiedostoja tässä haarassa. Useita malleja voidaan erottaa puolipisteellä ('\;'). Katso <a href="https://pkg.go.dev/github.com/gobwas/glob#Compile">github.com/gobwas/glob</a> dokumentaatio mallisyntaksille. Esimerkkejä: <code>.drone.yml</code>, <code>/docs/**/*.txt</code>.
|
||||
settings.protect_unprotected_file_patterns_desc=Suojaamattomat tiedostot, joita voidaan muuttaa suoraan, jos käyttäjällä on kirjoitusoikeudet, ohittaen push-rajoituksen. Useita kuvioita voidaan erottaa puolipisteellä ('\;'). Katso <a href="https://pkg.go.dev/github.com/gobwas/glob#Compile">github.com/gobwas/glob</a> dokumentaatio kuviosyntaksille. Esimerkkejä: <code>.drone.yml</code>, <code>/docs/**/*.txt</code>.
|
||||
settings.update_protect_branch_success=Haaran '%s' suojaus on päivitetty.
|
||||
settings.remove_protected_branch_success=Haaran '%s' suojaus on poistettu käytöstä.
|
||||
settings.choose_branch=Valitse haara…
|
||||
settings.no_protected_branch=Suojattuja haaroja ei ole.
|
||||
settings.edit_protected_branch=Muokkaa
|
||||
settings.protected_branch_required_approvals_min=Vaadittavat hyväksynnät ei voi olla negatiivinen.
|
||||
settings.tags=Tagit
|
||||
settings.tags.protection.pattern=Tagin kuvio
|
||||
settings.tags.protection.pattern.description=Voit käyttää yhtä nimeä tai glob-kuviota tai säännöllistä lauseketta, joka täsmää useisiin tageihin. Lue lisää <a target="_blank" rel="noopener" href="https://docs.gitea.io/en-us/protected-tags/">suojatut tagit oppaasta</a>.
|
||||
settings.bot_token=Botti pääsymerkki
|
||||
settings.matrix.homeserver_url=Kotipalvelimen URL
|
||||
settings.matrix.access_token=Pääsymerkki
|
||||
settings.archive.button=Arkistoi repo
|
||||
settings.archive.header=Arkistoi tämä repo
|
||||
settings.lfs=LFS
|
||||
|
@ -917,7 +1175,9 @@ settings.lfs_pointers.oid=OID
|
|||
|
||||
diff.browse_source=Selaa lähdekoodia
|
||||
diff.parent=vanhempi
|
||||
diff.commit=commit
|
||||
diff.git-notes=Muistiinpanot
|
||||
diff.options_button=Vertailun asetukset
|
||||
diff.show_split_view=Jaettu näkymä
|
||||
diff.show_unified_view=Yhdistetty näkymä
|
||||
diff.whitespace_button=Tyhjämerkki
|
||||
|
@ -937,6 +1197,7 @@ diff.review.comment=Kommentoi
|
|||
diff.review.approve=Hyväksy
|
||||
|
||||
release.releases=Julkaisut
|
||||
release.tags=Tagit
|
||||
release.new_release=Uusi julkaisu
|
||||
release.draft=Työversio
|
||||
release.prerelease=Esiversio
|
||||
|
@ -963,6 +1224,7 @@ release.downloads=Lataukset
|
|||
branch.name=Haaran nimi
|
||||
branch.delete_head=Poista
|
||||
branch.delete=Poista haara '%s'
|
||||
branch.create_branch=Luo haara <strong>%s</strong>
|
||||
|
||||
|
||||
|
||||
|
@ -1002,7 +1264,9 @@ settings.permission=Käyttöoikeudet
|
|||
settings.visibility=Näkyvyys
|
||||
settings.visibility.public=Julkinen
|
||||
settings.visibility.limited=Rajoitettu (näkyvä vain kirjautuneille käyttäjille)
|
||||
settings.visibility.limited_shortname=Rajattu
|
||||
settings.visibility.private=Yksityinen (näkyvä vain organisaation jäsenille)
|
||||
settings.visibility.private_shortname=Yksityinen
|
||||
|
||||
settings.update_settings=Päivitä asetukset
|
||||
settings.delete=Poista organisaatio
|
||||
|
@ -1053,6 +1317,7 @@ users=Käyttäjätilit
|
|||
organizations=Organisaatiot
|
||||
repositories=Repot
|
||||
authentication=Todennuslähteet
|
||||
emails=Käyttäjien sähköpostit
|
||||
config=Asetukset
|
||||
notices=Järjestelmän ilmoitukset
|
||||
monitor=Valvonta
|
||||
|
@ -1061,10 +1326,13 @@ last_page=Viimeisin
|
|||
total=Yhteensä: %d
|
||||
|
||||
dashboard.statistic=Yhteenveto
|
||||
dashboard.operations=Huoltotoimet
|
||||
dashboard.system_status=Järjestelmän tila
|
||||
dashboard.operation_name=Toiminnon nimi
|
||||
dashboard.operation_switch=Vaihda
|
||||
dashboard.operation_run=Suorita
|
||||
dashboard.delete_inactive_accounts=Poista kaikki aktivoimattomat käyttäjät
|
||||
dashboard.delete_repo_archives=Poista kaikki repojen arkistot (ZIP, TAR.GZ, jne..)
|
||||
dashboard.server_uptime=Palvelimen Uptime
|
||||
dashboard.current_goroutine=Nykyiset Goroutinet
|
||||
dashboard.current_memory_usage=Nykyinen muistinkäyttö
|
||||
|
@ -1099,23 +1367,38 @@ users.name=Käyttäjätunnus
|
|||
users.full_name=Kokonimi
|
||||
users.activated=Aktivoitu
|
||||
users.admin=Ylläpito
|
||||
users.restricted=Rajoitettu
|
||||
users.2fa=2FA
|
||||
users.repos=Repot
|
||||
users.created=Luotu
|
||||
users.last_login=Viimeksi kirjautunut
|
||||
users.never_login=Ei koskaan kirjautunut
|
||||
users.edit=Muokkaa
|
||||
users.auth_source=Todennuslähde
|
||||
users.local=Paikallinen
|
||||
users.password_helper=Jätä salasanakenttä tyhjäksi jos haluat pitää sen muuttamattomana.
|
||||
users.update_profile_success=Käyttäjän tili on päivitetty.
|
||||
users.edit_account=Muokkaa käyttäjän tiliä
|
||||
users.max_repo_creation_desc=(Aseta -1 käyttääksesi globaalia oletusrajaa.)
|
||||
users.is_activated=Käyttäjätili on aktivoitu
|
||||
users.prohibit_login=Ota sisäänkirjautuminen pois käytöstä
|
||||
users.is_admin=Ylläpitäjä
|
||||
users.is_restricted=Rajoitettu tili
|
||||
users.allow_git_hook=Voi luoda Git koukkuja
|
||||
users.allow_create_organization=Voi luoda organisaatioita
|
||||
users.update_profile=Päivitä käyttäjän tili
|
||||
users.delete_account=Poista käyttäjän tili
|
||||
users.list_status_filter.is_restricted=Rajoitettu
|
||||
users.list_status_filter.not_restricted=Ei rajoitettu
|
||||
|
||||
emails.email_manage_panel=Käyttäjien sähköpostien hallinta
|
||||
emails.primary=Ensisijainen
|
||||
emails.activated=Aktivoitu
|
||||
emails.filter_sort.email=Sähköposti
|
||||
emails.filter_sort.email_reverse=Sähköposti (käänteinen)
|
||||
emails.filter_sort.name=Käyttäjänimi
|
||||
emails.filter_sort.name_reverse=Käyttäjänimi (käänteinen)
|
||||
emails.duplicate_active=Tämä sähköpostiosoite on jo käytössä toisella käyttäjällä.
|
||||
|
||||
orgs.org_manage_panel=Organisaatioiden hallinta
|
||||
orgs.name=Nimi
|
||||
|
@ -1128,11 +1411,12 @@ repos.owner=Omistaja
|
|||
repos.name=Nimi
|
||||
repos.private=Yksityinen
|
||||
repos.watches=Tarkkailijat
|
||||
repos.stars=Äänet
|
||||
repos.stars=Tähdet
|
||||
repos.forks=Haarat
|
||||
repos.issues=Ongelmat
|
||||
repos.size=Koko
|
||||
|
||||
packages.owner=Omistaja
|
||||
|
||||
|
||||
|
||||
|
@ -1154,12 +1438,14 @@ auths.user_dn=Käyttäjä DN
|
|||
auths.search_page_size=Sivukoko
|
||||
auths.filter=Käyttäjäsuodatin
|
||||
auths.admin_filter=Ylläpitosuodatin
|
||||
auths.restricted_filter=Rajoitettu suodatin
|
||||
auths.smtp_auth=SMTP todennustyyppi
|
||||
auths.smtphost=SMTP isäntä
|
||||
auths.smtpport=SMTP portti
|
||||
auths.allowed_domains=Sallitut verkkotunnukset
|
||||
auths.skip_tls_verify=Ohita TLS tarkistaminen
|
||||
auths.pam_service_name=PAM palvelun nimi
|
||||
auths.oauth2_tokenURL=Pääsymerkki URL
|
||||
auths.enable_auto_register=Ota käyttöön automaattinen rekisteröinti
|
||||
auths.tips=Vinkit
|
||||
auths.tips.oauth2.general=OAuth2-autentikointi
|
||||
|
@ -1282,6 +1568,8 @@ notices.op=Toiminta
|
|||
create_repo=luotu repo <a href="%s">%s</a>
|
||||
rename_repo=uudelleennimetty repo <code>%[1]s</code> nimelle <a href="%[2]s">%[3]s</a>
|
||||
transfer_repo=siirretty repo <code>%s</code> kohteeseen <a href="%s">%s</a>
|
||||
push_tag=työnsi tagin <a href="%[2]s">%[3]s</a> kohteeseen <a href="%[1]s">%[4]s</a>
|
||||
compare_commits_general=Vertaa committeja
|
||||
|
||||
[tool]
|
||||
ago=%s sitten
|
||||
|
@ -1321,8 +1609,29 @@ mark_as_unread=Merkitse lukemattomaksi
|
|||
mark_all_as_read=Merkitse kaikki luetuiksi
|
||||
|
||||
[gpg]
|
||||
error.no_committer_account=Committaajan sähköpostiosoitteeseen ei ole linkitetty tiliä
|
||||
error.not_signed_commit=Ei allekirjoitettu committi
|
||||
|
||||
[units]
|
||||
|
||||
[packages]
|
||||
title=Paketit
|
||||
desc=Hallitse repon paketteja.
|
||||
empty=Täällä ei vielä ole paketteja.
|
||||
empty.documentation=Lisätietoa pakettirekisteristä löydät <a target="_blank" rel="noopener noreferrer" href="https://docs.gitea.io/en-us/packages/overview">dokumentaatiosta</a>.
|
||||
filter.type=Tyyppi
|
||||
filter.type.all=Kaikki
|
||||
filter.no_result=Suodattimesi ei tuottanut tuloksia.
|
||||
installation=Asennus
|
||||
details.author=Tekijä
|
||||
composer.documentation=Lisätietoa Composer-rekisteristä löydät <a target="_blank" rel="noopener noreferrer" href="https://docs.gitea.io/en-us/packages/composer/">dokumentaatiosta</a>.
|
||||
conan.documentation=Lisätietoa Conan-rekisteristä löydät <a target="_blank" rel="noopener noreferrer" href="https://docs.gitea.io/en-us/packages/conan/">dokumentaatiosta</a>.
|
||||
container.documentation=Lisätietoa Container-rekisteristä löydät<a target="_blank" rel="noopener noreferrer" href="https://docs.gitea.io/en-us/packages/container/">dokumentaatiosta</a>.
|
||||
generic.documentation=Lisätietoa yleisestä pakettirekisteristä löydät <a target="_blank" rel="noopener noreferrer" href="https://docs.gitea.io/en-us/packages/generic">dokumentaatiosta</a>.
|
||||
helm.documentation=Lisätietoa Helm-rekisteristä löydät <a target="_blank" rel="noopener noreferrer" href="https://docs.gitea.io/en-us/packages/helm/">dokumentaatiosta</a>.
|
||||
maven.documentation=Lisätietoa Maven-rekisteristä löydät <a target="_blank" rel="noopener noreferrer" href="https://docs.gitea.io/en-us/packages/maven/">dokumentaatiosta</a>.
|
||||
nuget.documentation=Lisätietoa NuGet-rekisteristä löydät <a target="_blank" rel="noopener noreferrer" href="https://docs.gitea.io/en-us/packages/nuget/">dokumentaatiosta</a>.
|
||||
npm.documentation=Lisätietoa npm-rekisteristä löydät <a target="_blank" rel="noopener noreferrer" href="https://docs.gitea.io/en-us/packages/npm/">dokumentaatiosta</a>.
|
||||
pypi.documentation=Lisätietoa PyPI-rekisteristä löydät <a target="_blank" rel="noopener noreferrer" href="https://docs.gitea.io/en-us/packages/pypi/">dokumentaatiosta</a>.
|
||||
rubygems.documentation=Lisätietoa RubyGems-rekisteristä löydät <a target="_blank" rel="noopener noreferrer" href="https://docs.gitea.io/en-us/packages/rubygems/">dokumentaatiosta</a>.
|
||||
|
||||
|
|
|
@ -1063,6 +1063,7 @@ normal_view=Vista normale
|
|||
line=riga
|
||||
lines=righe
|
||||
|
||||
editor.add_file=Aggiungi file
|
||||
editor.new_file=Nuovo file
|
||||
editor.upload_file=Carica File
|
||||
editor.edit_file=Modifica File
|
||||
|
@ -1268,6 +1269,8 @@ issues.filter_milestone=Traguardo
|
|||
issues.filter_milestone_no_select=Tutte le pietre miliari
|
||||
issues.filter_assignee=Assegnatario
|
||||
issues.filter_assginee_no_select=Tutte le assegnazioni
|
||||
issues.filter_poster=Autore
|
||||
issues.filter_poster_no_select=Tutti gli autori
|
||||
issues.filter_type=Tipo
|
||||
issues.filter_type.all_issues=Tutti i problemi
|
||||
issues.filter_type.assigned_to_you=Assegnati a te
|
||||
|
@ -3111,6 +3114,9 @@ npm.dependencies.development=Dipendenze Di Sviluppo
|
|||
npm.dependencies.peer=Dipendenze Peer
|
||||
npm.dependencies.optional=Dipendenze Opzionali
|
||||
npm.details.tag=Tag
|
||||
pub.install=Per installare il pacchetto utilizzando NuGet, eseguire il seguente comando:
|
||||
pub.documentation=Per ulteriori informazioni sul registro Pub, consultare <a target="_blank" rel="noopener noreferrer" href="https://docs.gitea.io/en-us/packages/pub/">la documentazione</a>.
|
||||
pub.details.repository_site=Sito Repository
|
||||
pypi.requires=Richiede Python
|
||||
pypi.install=Per installare il pacchetto usando pip, eseguire il seguente comando:
|
||||
pypi.documentation=Per ulteriori informazioni sul registro PyPI, consultare <a target="_blank" rel="noopener noreferrer" href="https://docs.gitea.io/en-us/packages/pypi/">la documentazione</a>.
|
||||
|
|
|
@ -2794,13 +2794,19 @@ config.queue_length=キューの長さ
|
|||
config.deliver_timeout=送信タイムアウト
|
||||
config.skip_tls_verify=TLS検証を省略
|
||||
|
||||
config.mailer_config=メーラー設定
|
||||
config.mailer_enabled=有効
|
||||
config.mailer_enable_helo=HELO有効
|
||||
config.mailer_name=名称
|
||||
config.mailer_protocol=プロトコル
|
||||
config.mailer_smtp_addr=SMTPアドレス
|
||||
config.mailer_smtp_port=SMTPポート
|
||||
config.mailer_user=ユーザー
|
||||
config.mailer_use_sendmail=Sendmailを使う
|
||||
config.mailer_sendmail_path=Sendmailのパス
|
||||
config.mailer_sendmail_args=Sendmailの追加引数
|
||||
config.mailer_sendmail_timeout=Sendmail のタイムアウト
|
||||
config.mailer_use_dummy=Dummy
|
||||
config.test_email_placeholder=Email (例 test@example.com)
|
||||
config.send_test_mail=テストメールを送信
|
||||
config.test_mail_failed='%s' へのテストメール送信に失敗しました: %v
|
||||
|
|
|
@ -179,6 +179,8 @@ log_root_path_helper=Žurnalizēšanas faili tiks rakstīti šajā direktorijā.
|
|||
|
||||
optional_title=Neobligātie iestatījumi
|
||||
email_title=E-pastu iestatījumi
|
||||
smtp_addr=SMTP resursdators
|
||||
smtp_port=SMTP ports
|
||||
smtp_from=Nosūtīt e-pastu kā
|
||||
smtp_from_helper=E-pasta adrese, ko Gitea izmantos. Ievadiet tika e-pasta adrese vai izmantojiet "Vārds" <epasts@domens.lv> formātu.
|
||||
mailer_user=SMTP lietotāja vārds
|
||||
|
@ -798,6 +800,7 @@ email_notifications.enable=Iespējot e-pasta paziņojumus
|
|||
email_notifications.onmention=Tikai, ja esmu pieminēts
|
||||
email_notifications.disable=Nesūtīt paziņojumus
|
||||
email_notifications.submit=Saglabāt sūtīšanas iestatījumus
|
||||
email_notifications.andyourown=Iekļaut savus paziņojumus
|
||||
|
||||
visibility=Lietotāja redzamība
|
||||
visibility.public=Publisks
|
||||
|
@ -860,7 +863,9 @@ default_branch=Noklusējuma atzars
|
|||
default_branch_helper=Noklusētais atzars nosaka pamata atzaru uz kuru tiks veidoti izmaiņu pieprasījumi un koda revīziju iesūtīšana.
|
||||
mirror_prune=Izmest
|
||||
mirror_prune_desc=Izdzēst visas ārējās atsauces, kas ārējā repozitorijā vairs neeksistē
|
||||
mirror_interval=Spoguļošanas intervāls (derīgas laika vienības ir 'h', 'm', 's'). Norādiet 0, lai atslēgtu periodisku spoguļošanu. (Minimālais intervāls: %s)
|
||||
mirror_interval_invalid=Nekorekts spoguļošanas intervāls.
|
||||
mirror_sync_on_commit=Sinhronizēt, kad revīzijas tiek iesūtītas
|
||||
mirror_address=Spoguļa adrese
|
||||
mirror_address_desc=Pieslēgšanās rekvizītus norādiet autorizācijas sadaļā.
|
||||
mirror_address_url_invalid=Norādītais URL nav korekts. Norādiet visas URL daļas korekti.
|
||||
|
@ -929,6 +934,7 @@ form.name_pattern_not_allowed=Repozitorija nosaukums '%s' nav atļauts.
|
|||
need_auth=Autorizācija
|
||||
migrate_options=Migrācijas opcijas
|
||||
migrate_service=Migrācijas serviss
|
||||
migrate_options_mirror_helper=Šis repozitorijs būs spogulis
|
||||
migrate_options_lfs=Migrēt LFS failus
|
||||
migrate_options_lfs_endpoint.label=LFS galapunkts
|
||||
migrate_options_lfs_endpoint.description=Migrācija mēģinās izmantot attālināto URL, lai <a target="_blank" rel="noopener noreferrer" href="%s">noteiktu LFS serveri</a>. Var norādīt arī citu galapunktu, ja repozitorija LFS dati ir izvietoti citā vietā.
|
||||
|
@ -1057,6 +1063,7 @@ normal_view=Parastais skats
|
|||
line=rinda
|
||||
lines=rindas
|
||||
|
||||
editor.add_file=Pievienot
|
||||
editor.new_file=Jauna datne
|
||||
editor.upload_file=Augšupielādēt failu
|
||||
editor.edit_file=Labot failu
|
||||
|
@ -1299,6 +1306,7 @@ issues.previous=Iepriekšējā
|
|||
issues.next=Nākamā
|
||||
issues.open_title=Atvērta
|
||||
issues.closed_title=Slēgta
|
||||
issues.draft_title=Melnraksts
|
||||
issues.num_comments=%d komentāri
|
||||
issues.commented_at=` komentēja <a href="#%s">%s</a>`
|
||||
issues.delete_comment_confirm=Vai patiešām vēlaties dzēst šo komentāru?
|
||||
|
@ -1415,6 +1423,7 @@ issues.due_date_form_remove=Noņemt
|
|||
issues.due_date_not_writer=Jums ir nepieciešamas rakstīšanas tiesības uz šo repozitoriju, lai mainītu izpildes termiņu.
|
||||
issues.due_date_not_set=Izpildes termiņš nav uzstādīts.
|
||||
issues.due_date_added=pievienoja izpildes termiņu %s %s
|
||||
issues.due_date_modified=mainīja termiņa datumu no %[2]s uz %[1]s %[3]s
|
||||
issues.due_date_remove=noņēma izpildes termiņu %s %s
|
||||
issues.due_date_overdue=Nokavēts
|
||||
issues.due_date_invalid=Datums līdz nav korekts. Izmantojiet formātu 'gggg-mm-dd'.
|
||||
|
@ -1526,6 +1535,8 @@ pulls.remove_prefix=Noņemt <strong>%s</strong> prefiksu
|
|||
pulls.data_broken=Izmaiņu pieprasījums ir bojāts, jo dzēsta informācija no atdalītā repozitorija.
|
||||
pulls.files_conflicted=Šīs izmaiņu pieprasījuma izmaiņas konfliktē ar mērķa atzaru.
|
||||
pulls.is_checking=Notiek konfliktu pārbaude, mirkli uzgaidiet un atjaunojiet lapu.
|
||||
pulls.is_ancestor=Atzars jau ir pilnībā iekļauts mērķā atzarā. Nav izmaiņu, ko sapludināt.
|
||||
pulls.is_empty=Mērķa atzars jau satur šī atzara izmaiņas. Šī revīzija būs tukša.
|
||||
pulls.required_status_check_failed=Dažas no pārbaudēm nebija veiksmīgas.
|
||||
pulls.required_status_check_missing=Trūkst dažu obligāto pārbaužu.
|
||||
pulls.required_status_check_administrator=Kā administrators Jūs varat sapludināt šo izmaiņu pieprasījumu.
|
||||
|
@ -1604,6 +1615,8 @@ pulls.auto_merge_canceled_schedule=Automātiskā sapludināšana šim izmaiņu p
|
|||
pulls.auto_merge_newly_scheduled_comment=`ieplānoja automātisko sapludināšanu šim izmaiņu pieprasījumam, kad visas pārbaudes būs veiksmīgas %[1]s`
|
||||
pulls.auto_merge_canceled_schedule_comment=`atcēla automātisko sapludināšanu šim izmaiņu pieprasījumam %[1]s`
|
||||
|
||||
pulls.delete.title=Dzēst šo izmaiņu pieprasījumu?
|
||||
pulls.delete.text=Vai patiešām vēlaties dzēst šo izmaiņu pieprasījumu? (Neatgriezeniski tiks izdzēsts viss saturs. Apsveriet iespēju to aizvērt, ja vēlaties informāciju saglabāt vēsturei)
|
||||
|
||||
milestones.new=Jauns atskaites punkts
|
||||
milestones.closed=Aizvērts %s
|
||||
|
@ -2526,6 +2539,8 @@ users.delete_account=Dzēst lietotāja kontu
|
|||
users.cannot_delete_self=Nevar izdzēst sevi
|
||||
users.still_own_repo=Lietotājam pieder repozitoriji, tos sākumā ir nepieciešams izdzēst vai mainīt to īpašnieku.
|
||||
users.still_has_org=Šis lietotājs ir vienas vai vairāku organizāciju biedrs, lietotāju sākumā ir nepieciešams pamest šīs organizācijas vai viņu no tām ir jāizdzēš.
|
||||
users.purge=Attīrīt lietotu
|
||||
users.purge_help=Piespiedu dzēst lietotāju un visus tā repozitorijus, organizācijas un pakotnes. Arī visi lietotāja komentāri tiks dzēsti.
|
||||
users.still_own_packages=Šim lietotājam pieder viena vai vairākas pakotnes. Tās nepieciešams izdzēst.
|
||||
users.deletion_success=Lietotāja konts veiksmīgi izdzēsts.
|
||||
users.reset_2fa=Noņemt 2FA
|
||||
|
@ -2782,13 +2797,19 @@ config.queue_length=Rindas garums
|
|||
config.deliver_timeout=Piegādes noildze
|
||||
config.skip_tls_verify=Izlaist TLS pārbaudi
|
||||
|
||||
config.mailer_config=Pasta sūtītāja konfigurācija
|
||||
config.mailer_enabled=Iespējota
|
||||
config.mailer_enable_helo=Iespējot HELO
|
||||
config.mailer_name=Nosaukums
|
||||
config.mailer_protocol=Protokols
|
||||
config.mailer_smtp_addr=SMTP adrese
|
||||
config.mailer_smtp_port=SMTP ports
|
||||
config.mailer_user=Lietotājs
|
||||
config.mailer_use_sendmail=Izmantot Sendmail
|
||||
config.mailer_sendmail_path=Ceļš līdz sendmail programmai
|
||||
config.mailer_sendmail_args=Papildus Sendmail komandrindas argumenti
|
||||
config.mailer_sendmail_timeout=Sendmail noildze
|
||||
config.mailer_use_dummy=Tukšs
|
||||
config.test_email_placeholder=E-pasts (piemēram, test@example.com)
|
||||
config.send_test_mail=Nosūtīt pārbaudes e-pastu
|
||||
config.test_mail_failed=Neizdevās nosūtīt pārbaudes e-pastu uz '%s': %v
|
||||
|
@ -3025,6 +3046,7 @@ title=Pakotnes
|
|||
desc=Pārvaldīt repozitorija pakotnes.
|
||||
empty=Pašlaik šeit nav nevienas pakotnes.
|
||||
empty.documentation=Papildus informācija par pakotņu reģistru pieejama <a target="_blank" rel="noopener noreferrer" href="https://docs.gitea.io/en-us/packages/overview">dokumentācijā</a>.
|
||||
empty.repo=Neparādās augšupielādēta pakotne? Apmeklējiet <a href="%[1]s">pakotņu iestatījumus</a>, lai sasaistītu ar repozitoriju.
|
||||
filter.type=Veids
|
||||
filter.type.all=Visas
|
||||
filter.no_result=Pēc norādītajiem kritērijiem nekas netika atrasts.
|
||||
|
@ -3090,6 +3112,10 @@ npm.dependencies.development=Izstrādes atkarības
|
|||
npm.dependencies.peer=Netiešās atkarības
|
||||
npm.dependencies.optional=Neobligātās atkarības
|
||||
npm.details.tag=Tags
|
||||
pub.install=Lai instalētu Dart pakotni, izpildiet sekojošu komandu:
|
||||
pub.documentation=Papildus informācija par Pub reģistru pieejama <a target="_blank" rel="noopener noreferrer" href="https://docs.gitea.io/en-us/packages/pub/">dokumentācijā</a>.
|
||||
pub.details.repository_site=Repozitorija izmērs
|
||||
pub.details.documentation_site=Dokumentācijas lapa
|
||||
pypi.requires=Nepieciešams Python
|
||||
pypi.install=Lai instalētu pip pakotni, izpildiet sekojošu komandu:
|
||||
pypi.documentation=Papildus informācija par PyPI reģistru pieejama <a target="_blank" rel="noopener noreferrer" href="https://docs.gitea.io/en-us/packages/pypi/">dokumentācijā</a>.
|
||||
|
|
|
@ -1063,6 +1063,7 @@ normal_view=Normale weergave
|
|||
line=regel
|
||||
lines=regels
|
||||
|
||||
editor.add_file=Bestand toevoegen
|
||||
editor.new_file=Nieuw bestand
|
||||
editor.upload_file=Upload bestand
|
||||
editor.edit_file=Bewerk bestand
|
||||
|
@ -1268,6 +1269,8 @@ issues.filter_milestone=Mijlpaal
|
|||
issues.filter_milestone_no_select=Alle mijlpalen
|
||||
issues.filter_assignee=Aangewezene
|
||||
issues.filter_assginee_no_select=Alle toegewezen personen
|
||||
issues.filter_poster=Auteur
|
||||
issues.filter_poster_no_select=Alle auteurs
|
||||
issues.filter_type=Type
|
||||
issues.filter_type.all_issues=Alle kwesties
|
||||
issues.filter_type.assigned_to_you=Aan jou toegewezen
|
||||
|
@ -1296,6 +1299,11 @@ issues.action_milestone_no_select=Geen mijlpaal
|
|||
issues.action_assignee=Toegewezene
|
||||
issues.action_assignee_no_select=Geen verantwoordelijke
|
||||
issues.opened_by=%[1]s geopend door <a href="%[2]s">%[3]s</a>
|
||||
pulls.merged_by=door <a href="%[2]s">%[3]s</a> was samengevoegd %[1]s
|
||||
pulls.merged_by_fake=bij %[2]s is %[1]s samengevoegd
|
||||
issues.closed_by=door <a href="%[2]s">%[3]s</a> was gesloten %[1]s
|
||||
issues.opened_by_fake=%[1]s geopend door %[2]s
|
||||
issues.closed_by_fake=door %[2]s was gesloten %[1]s
|
||||
issues.previous=Vorige
|
||||
issues.next=Volgende
|
||||
issues.open_title=Open
|
||||
|
@ -1311,6 +1319,8 @@ issues.context.edit=Bewerken
|
|||
issues.context.delete=Verwijder
|
||||
issues.no_content=Er is nog geen inhoud.
|
||||
issues.close_issue=Sluit
|
||||
issues.pull_merged_at=`commit samengevoegd <a class="ui sha" href="%[1]s"><code>%[2]s</code></a> in <b>%[3]s</b> %[4]s`
|
||||
issues.manually_pull_merged_at=`commit <a class="ui sha" href="%[1]s"> handmatig samengevoegd <code>%[2]s</code></a> in <b>%[3]s</b> %[4]s`
|
||||
issues.close_comment_issue=Reageer en sluit
|
||||
issues.reopen_issue=Heropen
|
||||
issues.reopen_comment_issue=Heropen en geef commentaar
|
||||
|
@ -1333,6 +1343,7 @@ issues.is_stale=Er zijn wijzigingen aangebracht in deze PR sinds deze beoordelin
|
|||
issues.remove_request_review=Verwijder beoordelingsverzoek
|
||||
issues.remove_request_review_block=Kan beoordelingsverzoek niet verwijderen
|
||||
issues.dismiss_review=Beoordeling afwijzen
|
||||
issues.dismiss_review_warning=Bent u zeker dat u deze beoordeling wilt afwijzen?
|
||||
issues.sign_in_require_desc=<a href="%s">Log in</a> om deel te nemen aan deze discussie.
|
||||
issues.edit=Bewerken
|
||||
issues.cancel=Annuleren
|
||||
|
@ -1406,6 +1417,7 @@ issues.error_modifying_due_date=Deadline aanpassen mislukt.
|
|||
issues.error_removing_due_date=Deadline verwijderen mislukt.
|
||||
issues.push_commit_1=toegevoegd %d commit %s
|
||||
issues.push_commits_n=toegevoegd %d commits %s
|
||||
issues.force_push_codes=`force-push %[1]s van <a class="ui sha" href="%[3]s"><code>%[2]s</code></a> naar <a class="ui sha" href="%[5]s"><code>%[4]s</code></a> %[6]s`
|
||||
issues.due_date_form=jjjj-mm-dd
|
||||
issues.due_date_form_add=Vervaldatum toevoegen
|
||||
issues.due_date_form_edit=Bewerk
|
||||
|
@ -1426,6 +1438,7 @@ issues.dependency.remove=Verwijder
|
|||
issues.dependency.remove_info=Verwijder afhankelijkheid
|
||||
issues.dependency.added_dependency=`voegde een nieuwe afhankelijkheid %s toe `
|
||||
issues.dependency.removed_dependency=`verwijderde een afhankelijkheid %s`
|
||||
issues.dependency.pr_closing_blockedby=Het sluiten van deze pull-aanvraag is geblokkeerd door de volgende issues
|
||||
issues.dependency.issue_closing_blockedby=Het sluiten van dit issue is geblokkeerd door de volgende problemen
|
||||
issues.dependency.issue_close_blocks=Deze kwestie blokkeert het sluiten van de volgende kwesties
|
||||
issues.dependency.pr_close_blocks=Deze pull-aanvraag blokkeert het sluiten van de volgende kwesties
|
||||
|
@ -1598,6 +1611,8 @@ pulls.auto_merge_newly_scheduled=De pull-verzoek was gepland om samen te voegen
|
|||
pulls.auto_merge_has_pending_schedule=%[1]s heeft deze pull-verzoek automatisch samengevoegd wanneer alle checks succesvol zijn geweest %[2]s.
|
||||
|
||||
pulls.auto_merge_cancel_schedule=Automatisch samenvoegen annuleren
|
||||
pulls.auto_merge_not_scheduled=Deze pull-aanvraag is niet gepland om automatisch samen te voegen.
|
||||
pulls.auto_merge_canceled_schedule=De automatisch samenvoegen is geannuleerd voor deze pull-aanvraag.
|
||||
|
||||
|
||||
pulls.delete.title=Deze pull-verzoek verwijderen?
|
||||
|
@ -1761,6 +1776,7 @@ settings.hooks=Webhooks
|
|||
settings.githooks=Git-hooks
|
||||
settings.basic_settings=Basis instellingen
|
||||
settings.mirror_settings=Kopie Settings
|
||||
settings.mirror_settings.mirrored_repository=Gespiegelde repository
|
||||
settings.mirror_settings.direction=Richting
|
||||
settings.mirror_settings.direction.pull=Pull
|
||||
settings.mirror_settings.direction.push=Push
|
||||
|
@ -1790,6 +1806,8 @@ settings.tracker_url_format_error=Het URL-formaat van de externe wiki is geen ge
|
|||
settings.tracker_issue_style=Nummerformaat van de externe kwestie-tracker
|
||||
settings.tracker_issue_style.numeric=Nummeriek
|
||||
settings.tracker_issue_style.alphanumeric=Alfanummeriek
|
||||
settings.tracker_issue_style.regexp=Reguliere expressie
|
||||
settings.tracker_issue_style.regexp_pattern=Reguliere expressie patroon
|
||||
settings.tracker_url_format_desc=Gebruik de aanduidingen <code>{user}</code>, <code>{repo}</code> en <code>{index}</code> voor de gebruikersnaam, repositorynaam en kwestie-index.
|
||||
settings.enable_timetracker=Tijdregistratie inschakelen
|
||||
settings.allow_only_contributors_to_track_time=Sta alleen bijdragers toe tijdregistratie te gebruiken
|
||||
|
|
|
@ -1063,6 +1063,7 @@ normal_view=Vista normal
|
|||
line=linha
|
||||
lines=linhas
|
||||
|
||||
editor.add_file=Adicionar ficheiro
|
||||
editor.new_file=Novo ficheiro
|
||||
editor.upload_file=Carregar ficheiro
|
||||
editor.edit_file=Editar ficheiro
|
||||
|
@ -1268,6 +1269,8 @@ issues.filter_milestone=Etapa
|
|||
issues.filter_milestone_no_select=Todas as etapas
|
||||
issues.filter_assignee=Encarregado
|
||||
issues.filter_assginee_no_select=Todos os encarregados
|
||||
issues.filter_poster=Autor(a)
|
||||
issues.filter_poster_no_select=Todos os autores
|
||||
issues.filter_type=Tipo
|
||||
issues.filter_type.all_issues=Todas as questões
|
||||
issues.filter_type.assigned_to_you=Atribuídas a si
|
||||
|
@ -3111,6 +3114,10 @@ npm.dependencies.development=Dependências de desenvolvimento
|
|||
npm.dependencies.peer=Dependências de pares
|
||||
npm.dependencies.optional=Dependências opcionais
|
||||
npm.details.tag=Etiqueta
|
||||
pub.install=Para instalar o pacote usando o Dart, execute o seguinte comando:
|
||||
pub.documentation=Para obter mais informações sobre o registo Pub, consulte <a target="_blank" rel="noopener noreferrer" href="https://docs.gitea.io/en-us/packages/pub/">a documentação</a>.
|
||||
pub.details.repository_site=Página web do repositório
|
||||
pub.details.documentation_site=Página web da documentação
|
||||
pypi.requires=Requer Python
|
||||
pypi.install=Para instalar o pacote usando o pip, execute o seguinte comando:
|
||||
pypi.documentation=Para obter mais informações sobre o registo do PyPI, consulte <a target="_blank" rel="noopener noreferrer" href="https://docs.gitea.io/en-us/packages/pypi/">a documentação</a>.
|
||||
|
|
|
@ -913,8 +913,8 @@ desc.archived=Arşivlenmiş
|
|||
|
||||
template.items=Şablon Öğeleri
|
||||
template.git_content=Git İçeriği (Varsayılan Dal)
|
||||
template.git_hooks=Git İstekleri
|
||||
template.git_hooks_tooltip=Eklendikten sonra Git Hooks'u değiştirmek veya kaldırmak mümkün değildir. Bunu yalnızca şablon deposuna güveniyorsanız seçin.
|
||||
template.git_hooks=Git İstemcileri
|
||||
template.git_hooks_tooltip=Eklendikten sonra Git İstemcilerini değiştirmek veya kaldırmak mümkün değildir. Bunu yalnızca şablon deposuna güveniyorsanız seçin.
|
||||
template.webhooks=Web İstemcileri
|
||||
template.topics=Konular
|
||||
template.avatar=Profil Resmi
|
||||
|
@ -954,6 +954,7 @@ migrate.clone_address_desc=Varolan bir deponun HTTP(S) veya Git 'klonlama' URL's
|
|||
migrate.github_token_desc=GitHub API hız sınırı nedeniyle göçü hızlandırmak için buraya virgülle ayrılmış bir veya daha fazla erişm anahtarı koyabilirsiniz. UYARI: Bu özelliğin kötüye kullanılması, hizmet sağlayıcının politikasını ihlal edebilir ve hesabın engellenmesine yol açabilir.
|
||||
migrate.clone_local_path=veya bir yerel sunucu yolu
|
||||
migrate.permission_denied=Yerel depoları içeri aktarma izniniz yok.
|
||||
migrate.permission_denied_blocked=İzin verilmeyen sunuculardan içe aktaramazsınız, lütfen yöneticiden ALLOWED_DOMAINS/ALLOW_LOCALNETWORKS/BLOCKED_DOMAINS ayarlarını kontrol etmesini isteyin.
|
||||
migrate.invalid_local_path=Yerel yol geçersiz. Mevcut değil veya bir dizin değil.
|
||||
migrate.invalid_lfs_endpoint=LFS Uç noktası geçerli değil.
|
||||
migrate.failed=Göç başarısız: %v
|
||||
|
@ -1001,6 +1002,7 @@ clone_this_repo=Bu depoyu klonla
|
|||
create_new_repo_command=Komut satırında yeni bir depo oluşturuluyor
|
||||
push_exist_repo=Komut satırından mevcut bir depo itiliyor
|
||||
empty_message=Bu depoda herhangi bir içerik yok.
|
||||
broken_message=Bu deponun altındaki Git verisi okunamıyor. Bu sunucunun yöneticisiyle bağlantıya geçin veya bu depoyu silin.
|
||||
|
||||
code=Kod
|
||||
code.desc=Kaynak koda, dosyalara, işlemelere ve dallara eriş.
|
||||
|
@ -1026,6 +1028,7 @@ release=Sürüm
|
|||
releases=Sürüm
|
||||
tag=Etiket
|
||||
released_this=bu sürümü yayınladı
|
||||
file.title=%s dalındaki/etiketindeki %s
|
||||
file_raw=Ham
|
||||
file_history=Geçmiş
|
||||
file_view_source=Kaynağı Görüntüle
|
||||
|
@ -1044,6 +1047,7 @@ line_unicode=`Bu satırda gizli evrensel kod karakterler var`
|
|||
escape_control_characters=Kaçış Karakterli
|
||||
unescape_control_characters=Kaçış Karaktersiz
|
||||
file_copy_permalink=Kalıcı Bağlantıyı Kopyala
|
||||
view_git_blame=Git Suç Görüntüle
|
||||
video_not_supported_in_browser=Tarayıcınız HTML5 'video' etiketini desteklemiyor.
|
||||
audio_not_supported_in_browser=Tarayıcınız HTML5 'audio' etiketini desteklemiyor.
|
||||
stored_lfs=Git LFS ile depolandı
|
||||
|
@ -1059,6 +1063,7 @@ normal_view=Normal Görünüm
|
|||
line=satır
|
||||
lines=satır
|
||||
|
||||
editor.add_file=Dosya Ekle
|
||||
editor.new_file=Yeni dosya
|
||||
editor.upload_file=Dosya Yükle
|
||||
editor.edit_file=Dosyayı Düzenle
|
||||
|
@ -1121,6 +1126,8 @@ editor.cannot_commit_to_protected_branch=Korunan '%s' dalına işleme yapılamı
|
|||
editor.no_commit_to_branch=Doğrudan dala işleme yapılamıyor çünkü:
|
||||
editor.user_no_push_to_branch=Kullanıcı dala gönderemez
|
||||
editor.require_signed_commit=Dal imzalı bir işleme gerektirir
|
||||
editor.cherry_pick=%s şunun üzerine cımbızla:
|
||||
editor.revert=%s şuna geri döndür:
|
||||
|
||||
commits.desc=Kaynak kodu değişiklik geçmişine göz atın.
|
||||
commits.commits=İşleme
|
||||
|
@ -1144,6 +1151,7 @@ commits.ssh_key_fingerprint=SSH Anahtar Parmak İzi
|
|||
commit.actions=Eylemler
|
||||
commit.revert=Geri Al
|
||||
commit.revert-header=Geri al: %s
|
||||
commit.revert-content=Geri almak için dal seçin:
|
||||
commit.cherry-pick=Cımbızla
|
||||
commit.cherry-pick-header=Cımbızla: %s
|
||||
commit.cherry-pick-content=Cımbızlamak için dal seçin:
|
||||
|
@ -1185,6 +1193,7 @@ projects.board.deletion_desc=Bir proje panosunun silinmesi, ilgili tüm konular
|
|||
projects.board.color=Renk
|
||||
projects.open=Aç
|
||||
projects.close=Kapat
|
||||
projects.board.assigned_to=Atanan
|
||||
|
||||
issues.desc=Hata raporlarını, görevleri ve kilometre taşlarını yönetmenizi sağlar.
|
||||
issues.filter_assignees=Atama Süzgeci
|
||||
|
@ -1249,6 +1258,9 @@ issues.add_assignee_at=`%[2]s <b>%[1]s</b> tarafından atandı`
|
|||
issues.remove_assignee_at=`ataması %[2]s <b>%[1]s</b> tarafından kaldırıldı`
|
||||
issues.remove_self_assignment=`atamalarını kaldırdı %s`
|
||||
issues.change_title_at=`başlığı <b><strike>%s</strike></b> iken %s olarak <b>%s</b> değiştirdi`
|
||||
issues.change_ref_at=`<b><strike>%s</strike></b> referans <b>%s</b> %s olarak değiştirildi`
|
||||
issues.remove_ref_at=`<b>%s</b> referansı %s tarihinde kaldırıldı`
|
||||
issues.add_ref_at=`<b>%s</b> referansı %s tarihinde eklendi`
|
||||
issues.delete_branch_at=`<b>%s</b> dalı silindi %s`
|
||||
issues.filter_label=Etiket
|
||||
issues.filter_label_exclude=`Etiketleri hariç tutmak için <code>alt</code> + <code>tıkla/enter</code> kullanın`
|
||||
|
@ -1257,6 +1269,8 @@ issues.filter_milestone=Kilometre Taşı
|
|||
issues.filter_milestone_no_select=Tüm kilometre taşları
|
||||
issues.filter_assignee=Atanan
|
||||
issues.filter_assginee_no_select=Tüm atananlar
|
||||
issues.filter_poster=Yazar
|
||||
issues.filter_poster_no_select=Tüm yazarlar
|
||||
issues.filter_type=Tür
|
||||
issues.filter_type.all_issues=Tüm konular
|
||||
issues.filter_type.assigned_to_you=Size atanan
|
||||
|
@ -1276,6 +1290,7 @@ issues.filter_sort.moststars=En çok yıldızlılar
|
|||
issues.filter_sort.feweststars=En az yıldızlılar
|
||||
issues.filter_sort.mostforks=En çok çatallananlar
|
||||
issues.filter_sort.fewestforks=En az çatallananlar
|
||||
issues.keyword_search_unavailable=Anahtar kelime ile arama şu an mevcut değil. Lütfen site yöneticisiyle iletişime geçin.
|
||||
issues.action_open=Açık
|
||||
issues.action_close=Kapat
|
||||
issues.action_label=Etiket
|
||||
|
@ -1284,7 +1299,11 @@ issues.action_milestone_no_select=Kilometre Taşı Yok
|
|||
issues.action_assignee=Atanan
|
||||
issues.action_assignee_no_select=Atanan yok
|
||||
issues.opened_by=<a href="%[2]s">%[3]s</a> tarafından %[1]s açıldı
|
||||
pulls.merged_by=%[1]s <a href="%[2]s">%[3]s</a> tarafından açılan istek birleştirildi
|
||||
pulls.merged_by_fake=%[2]s tarafından açılan istek %[1]s birleştirildi
|
||||
issues.closed_by=<a href="%[2]s">%[3]s</a> tarafından %[1]s kapatıldı
|
||||
issues.opened_by_fake=%[2]s tarafından %[1]s açıldı
|
||||
issues.closed_by_fake=%[2]s tarafından %[1]s kapatıldı
|
||||
issues.previous=Önceki
|
||||
issues.next=Sonraki
|
||||
issues.open_title=Açık
|
||||
|
@ -1405,7 +1424,8 @@ issues.due_date_form_edit=Düzenle
|
|||
issues.due_date_form_remove=Kaldır
|
||||
issues.due_date_not_writer=Bir konunun bitiş tarihini değiştirmek için depoda yazma hakkınız olmalıdır.
|
||||
issues.due_date_not_set=Bitiş tarihi atanmadı.
|
||||
issues.due_date_added=%[2]s %[1]s bitiş tarihini ekledi
|
||||
issues.due_date_added=bitiş tarihini %s olarak %s ekledi
|
||||
issues.due_date_modified=bitiş tarihini %[2]s iken %[1]s olarak %[3]s değiştirdi
|
||||
issues.due_date_remove=%[2]s %[1]s bitiş tarihini kaldırdı
|
||||
issues.due_date_overdue=Süresi Geçmiş
|
||||
issues.due_date_invalid=Bitiş tarihi geçersiz veya aralık dışında. Lütfen 'yyyy-aa-gg' biçimini kullanın.
|
||||
|
@ -1467,6 +1487,7 @@ issues.content_history.deleted=silindi
|
|||
issues.content_history.edited=düzenlendi
|
||||
issues.content_history.created=oluşturuldu
|
||||
issues.content_history.delete_from_history=Geçmişten kaldır
|
||||
issues.content_history.delete_from_history_confirm=Geçmişten kaldırılsın mı?
|
||||
issues.content_history.options=Seçenekler
|
||||
issues.reference_link=Referans: %s
|
||||
|
||||
|
@ -1477,6 +1498,8 @@ pulls.desc=Değişiklik isteklerini ve kod incelemelerini etkinleştir.
|
|||
pulls.new=Yeni Değişiklik İsteği
|
||||
pulls.view=Değişiklik İsteği Görüntüle
|
||||
pulls.compare_changes=Yeni Değişiklik İsteği
|
||||
pulls.allow_edits_from_maintainers=Bakımcıların düzenlemelerine izin ver
|
||||
pulls.allow_edits_from_maintainers_desc=Ana dala yazma hakkı olan kullanıcılar bu dala da gönderebilirler
|
||||
pulls.allow_edits_from_maintainers_err=Güncelleme başarısız oldu
|
||||
pulls.compare_changes_desc=Birleştirmek için hedef ve kaynak dalı seçin.
|
||||
pulls.has_viewed_file=Görüldü
|
||||
|
@ -1559,7 +1582,10 @@ pulls.rebase_conflict_summary=Hata Mesajı
|
|||
; </summary><code>%[2]s<br>%[3]s</code></details>
|
||||
pulls.unrelated_histories=Birleştirme Başarısız: Birleştirme başlığı ve tabanı ortak bir geçmişi paylaşmıyor. İpucu: Farklı bir strateji deneyin
|
||||
pulls.merge_out_of_date=Birleştirme Başarısız: Birleştirme oluşturulurken, taban güncellendi. İpucu: Tekrar deneyin.
|
||||
pulls.head_out_of_date=Birleştirme Başarısız: Birleştirme oluşturulurken, ana güncellendi. İpucu: Tekrar deneyin.
|
||||
pulls.push_rejected=Birleştirme Başarısız Oldu: Gönderme reddedildi. Bu depo için Git İstemcilerini inceleyin.
|
||||
pulls.push_rejected_summary=Tam Red Mesajı
|
||||
pulls.push_rejected_no_message=Birleştirme başarısız oldu: Gönderme reddedildi, ancak uzak bir mesaj yoktu.<br>Bu depo için Git İstemcilerini inceleyin
|
||||
pulls.open_unmerged_pull_exists=`Aynı özelliklere sahip bekleyen bir değişiklik isteği (#%d) olduğundan yeniden açma işlemini gerçekleştiremezsiniz.`
|
||||
pulls.status_checking=Bazı denetlemeler beklemede
|
||||
pulls.status_checks_success=Tüm denetlemeler başarılı oldu
|
||||
|
@ -1582,9 +1608,17 @@ pulls.merge_instruction_step2_desc=Gitea'daki değişiklikleri ve güncellemeler
|
|||
pulls.auto_merge_button_when_succeed=(Denetlemeler başarılı olduğunda)
|
||||
pulls.auto_merge_when_succeed=Tüm denetlemeler başarılı olduğundan otomatik olarak birleştir
|
||||
pulls.auto_merge_newly_scheduled=Değişiklik İsteği tüm denetlemeler başarılı olduğunda birleştirilecek şekilde ayarlanmış.
|
||||
pulls.auto_merge_has_pending_schedule=%[1]s, bu değişiklik isteğini tüm denetlemeler başarılı olduğunda %[2]s, otomatik olarak birleşecek şekilde ayarlamış.
|
||||
|
||||
pulls.auto_merge_cancel_schedule=Otomatik birleştirmeyi iptal et
|
||||
pulls.auto_merge_not_scheduled=Bu değişiklik isteği için otomatik birleştirme zamanlanmamış.
|
||||
pulls.auto_merge_canceled_schedule=Bu değişiklik isteği için otomatik birleştirme iptal edildi.
|
||||
|
||||
pulls.auto_merge_newly_scheduled_comment=`bu değişiklik isteği, tüm denetlemeler başarılı olduğunda %[1]s, otomatik olarak birleşecek şekilde ayarlandı`
|
||||
pulls.auto_merge_canceled_schedule_comment=`bu değişiklik isteğinin, tüm denetlemeler başarılı olduğunda %[1]s, otomatik birleştirmesi iptal edildi`
|
||||
|
||||
pulls.delete.title=Bu değişiklik isteği silinsin mi?
|
||||
pulls.delete.text=Bu değişiklik isteğini gerçekten silmek istiyor musunuz? (Bu işlem tüm içeriği kalıcı olarak silecektir. Arşivde tutma niyetiniz varsa silmek yerine kapatmayı düşünün)
|
||||
|
||||
milestones.new=Yeni Kilometre Taşı
|
||||
milestones.closed=Kapalı %s
|
||||
|
@ -1630,6 +1664,7 @@ signing.wont_sign.commitssigned=İlişkili tüm işlemeler imzalanmadığı içi
|
|||
signing.wont_sign.approved=Değişiklik İsteği onaylanmadığı için birleştirme imzalanmayacak
|
||||
signing.wont_sign.not_signed_in=Oturum açmadınız
|
||||
|
||||
ext_wiki=Harici Vikiye Erişim
|
||||
ext_wiki.desc=Harici bir wiki'ye bağlantı.
|
||||
|
||||
wiki=Wiki
|
||||
|
@ -1654,6 +1689,7 @@ wiki.page_already_exists=Aynı isimde bir Wiki sayfası zaten var.
|
|||
wiki.reserved_page='%s' wiki sayfa adı rezerve edilmiştir.
|
||||
wiki.pages=Sayfalar
|
||||
wiki.last_updated=Son güncelleme %s
|
||||
wiki.page_name_desc=Bu Viki sayfası için bir ad girin. Bazı özel isimler 'Home', '_Sidebar' ve '_Footer' şeklindedir.
|
||||
|
||||
activity=Aktivite
|
||||
activity.period.filter_label=Dönem:
|
||||
|
@ -1726,6 +1762,8 @@ search.search_repo=Depo ara
|
|||
search.fuzzy=Belirsiz
|
||||
search.match=Eşleştir
|
||||
search.results="%s" için <a href="%s">%s</a> içinde sonuçları ara
|
||||
search.code_no_results=Arama teriminizle eşleşen bir kaynak kod bulunamadı.
|
||||
search.code_search_unavailable=Kod arama şu an mevcut değil. Lütfen site yöneticisiyle iletişime geçin.
|
||||
|
||||
settings=Ayarlar
|
||||
settings.desc=Ayarlar, depo için ayarları yönetebileceğiniz yerdir
|
||||
|
@ -1737,7 +1775,7 @@ settings.collaboration.read=Oku
|
|||
settings.collaboration.owner=Sahibi
|
||||
settings.collaboration.undefined=Belirsiz
|
||||
settings.hooks=Web İstemcileri
|
||||
settings.githooks=Git İstekleri
|
||||
settings.githooks=Git İstemcileri
|
||||
settings.basic_settings=Temel Ayarlar
|
||||
settings.mirror_settings=Yansıma Ayarları
|
||||
settings.mirror_settings.docs=Projenizi, değişiklikleri başka bir depoya/depodan otomatik olarak gönderecek ve/veya çekecek şekilde ayarlayın. Dallar, etiketler ve işlemeler otomatik olarak senkronize edilecektir. <a target="_blank" rel="noopener noreferrer" href="https://docs.gitea.io/en-us/repo-mirror/">Depoları nasıl yansıtrım?</a>
|
||||
|
@ -1772,6 +1810,9 @@ settings.tracker_url_format_error=Harici konu izleyici URL biçimi geçerli bir
|
|||
settings.tracker_issue_style=Harici Konu İzleyici Numara Biçimi
|
||||
settings.tracker_issue_style.numeric=Sayısal
|
||||
settings.tracker_issue_style.alphanumeric=Alfanumerik
|
||||
settings.tracker_issue_style.regexp=Düzenli ifade
|
||||
settings.tracker_issue_style.regexp_pattern=Düzenli İfade Kalıbı
|
||||
settings.tracker_issue_style.regexp_pattern_desc=<code>{index}</code> yerine ilk eşleşen grup kullanılacaktır.
|
||||
settings.tracker_url_format_desc=Kullanıcı adı, depo adı ve yayın dizini için <code>{user}</code>, <code>{repo}</code> ve <code>{index}</code> yer tutucularını kullanın.
|
||||
settings.enable_timetracker=Zaman Takibini Etkinleştir
|
||||
settings.allow_only_contributors_to_track_time=Sadece Katkıcılar İçin Zaman Takibine İzin Ver
|
||||
|
@ -1783,10 +1824,18 @@ settings.pulls.allow_rebase_merge_commit=Açık birleştirme işlemeleri ile Yen
|
|||
settings.pulls.allow_squash_commits=İşlemeleri Birleştirmek için Ezmeyi Etkinleştir
|
||||
settings.pulls.allow_manual_merge=Dİ'yi elle birleştirilmiş olarak işaretlemeyi etkinleştir
|
||||
settings.pulls.enable_autodetect_manual_merge=Kendiliğinden algılamalı elle birleştirmeyi etkinleştir (Not: Bazı özel durumlarda yanlış kararlar olabilir)
|
||||
settings.pulls.allow_rebase_update=Değişiklik isteği dalının yeniden yapılandırmayla güncellenmesine izin ver
|
||||
settings.pulls.default_delete_branch_after_merge=Varsayılan olarak birleştirmeden sonra değişiklik isteği dalını sil
|
||||
settings.packages_desc=Depo Paket Kütüğünü Etkinleştir
|
||||
settings.projects_desc=Depo Projelerini Etkinleştir
|
||||
settings.admin_settings=Yönetici Ayarları
|
||||
settings.admin_enable_health_check=Depo Sağlık Kontrollerini Etkinleştir (git fsck)
|
||||
settings.admin_code_indexer=Kod Dizinleyici
|
||||
settings.admin_stats_indexer=Kod İstatistiği Dizinleyici
|
||||
settings.admin_indexer_commit_sha=Son Dizinlenen SHA
|
||||
settings.admin_indexer_unindexed=Dizinlenmemiş
|
||||
settings.reindex_button=Yeniden Dizinleme Kuyruğuna Ekle
|
||||
settings.reindex_requested=Yeniden Dizinleme İstendi
|
||||
settings.admin_enable_close_issues_via_commit_in_any_branch=Varsayılan olmayan bir dalda yapılan bir işlemeyle konuyu kapat
|
||||
settings.danger_zone=Tehlike Alanı
|
||||
settings.new_owner_has_same_repo=Yeni sahibin aynı isimde başka bir deposu var. Lütfen farklı bir isim seçin.
|
||||
|
@ -1875,6 +1924,9 @@ settings.webhook.response=Cevaplar
|
|||
settings.webhook.headers=Başlıklar
|
||||
settings.webhook.payload=İçerik
|
||||
settings.webhook.body=Gövde
|
||||
settings.webhook.replay.description=Bu web kancasını tekrar çalıştır.
|
||||
settings.webhook.delivery.success=Teslim kuyruğuna bir olay eklendi. Teslim geçmişinde görünmesi birkaç saniye alabilir.
|
||||
settings.githooks_desc=Git İstemcileri Git'in kendisi tarafından desteklenmektedir. Özel işlemler ayarlamak için aşağıdaki istemci dosyalarını düzenleyebilirsiniz.
|
||||
settings.githook_edit_desc=İstek aktif değilse örnek içerik sunulacaktır. İçeriği boş bırakmak, isteği devre dışı bırakmayı beraberinde getirecektir.
|
||||
settings.githook_name=İstek İsmi
|
||||
settings.githook_content=İstek İçeriği
|
||||
|
@ -1886,6 +1938,7 @@ settings.content_type=POST İçerik Türü
|
|||
settings.secret=Gizli
|
||||
settings.slack_username=Kullanıcı Adı
|
||||
settings.slack_icon_url=Simge Bağlantısı
|
||||
settings.slack_color=Renk
|
||||
settings.discord_username=Kullanıcı adı
|
||||
settings.discord_icon_url=Simge URL'si
|
||||
settings.event_desc=Tetikleyici Açık:
|
||||
|
@ -1946,6 +1999,7 @@ settings.hook_type=İstek Türü
|
|||
settings.slack_token=Erişim Anahtarı
|
||||
settings.slack_domain=Alan Adı
|
||||
settings.slack_channel=Kanal
|
||||
settings.add_web_hook_desc=<a target="_blank" rel="noreferrer" href="%s">%s</a> web kancasını deponuza ekleyin.
|
||||
settings.web_hook_name_gitea=Gitea
|
||||
settings.web_hook_name_gogs=Gogs
|
||||
settings.web_hook_name_slack=Slack
|
||||
|
@ -2492,6 +2546,18 @@ users.purge_help=Kullanıcıyı ve sahip olduğu herhangi bir depoyu, organizasy
|
|||
users.still_own_packages=Kullanıcının bir veya daha fazla paketi var. Önce bu paketleri silin.
|
||||
users.deletion_success=Kullanıcı hesabı silindi.
|
||||
users.reset_2fa=2FD'yi sıfırla
|
||||
users.list_status_filter.menu_text=Filtre
|
||||
users.list_status_filter.reset=Sıfırla
|
||||
users.list_status_filter.is_active=Etkin
|
||||
users.list_status_filter.not_active=Etkin değil
|
||||
users.list_status_filter.is_admin=Yönetici
|
||||
users.list_status_filter.not_admin=Yönetici Değil
|
||||
users.list_status_filter.is_restricted=Kısıtlanmış
|
||||
users.list_status_filter.not_restricted=Kısıtlanmamış
|
||||
users.list_status_filter.is_prohibit_login=Oturum Açmayı Önle
|
||||
users.list_status_filter.not_prohibit_login=Oturum Açmaya İzin Ver
|
||||
users.list_status_filter.is_2fa_enabled=2FA Etkin
|
||||
users.list_status_filter.not_2fa_enabled=2FA Devre Dışı
|
||||
|
||||
emails.email_manage_panel=Kullanıcı E-posta Yönetimi
|
||||
emails.primary=Birincil
|
||||
|
@ -2524,6 +2590,16 @@ repos.forks=Çatallar
|
|||
repos.issues=Konular
|
||||
repos.size=Boyut
|
||||
|
||||
packages.package_manage_panel=Paket Yönetimi
|
||||
packages.total_size=Toplam Boyut: %s
|
||||
packages.owner=Sahibi
|
||||
packages.creator=Oluşturan
|
||||
packages.name=İsim
|
||||
packages.version=Sürüm
|
||||
packages.type=Tür
|
||||
packages.repository=Depo
|
||||
packages.size=Boyut
|
||||
packages.published=Yayınlandı
|
||||
|
||||
defaulthooks=Varsayılan Web İstemcileri
|
||||
defaulthooks.desc=Web İstemcileri, belirli Gitea olayları tetiklendiğinde otomatik olarak HTTP POST isteklerini sunucuya yapar. Burada tanımlanan Web İstemcileri varsayılandır ve tüm yeni depolara kopyalanır. <a target="_blank" rel="noopener" href="https://docs.gitea.io/en-us/webhooks/">web istemcileri kılavuzunda</a> daha fazla bilgi edinin.
|
||||
|
@ -2567,9 +2643,13 @@ auths.filter=Kullanıcı Filtresi
|
|||
auths.admin_filter=Yönetici Filtresi
|
||||
auths.restricted_filter=Kısıtlı Süzgeç
|
||||
auths.restricted_filter_helper=Hiçbir kullanıcıyı kısıtlı olarak ayarlamamak için boş bırakın. Yönetici Süzgeci ile eşleşmeyen tüm kullanıcıları kısıtlanmış olarak ayarlamak için yıldız işareti ('*') kullanın.
|
||||
auths.verify_group_membership=LDAP'ta grup üyeliğini doğrula (atlamak için filtreyi boş bırakın)
|
||||
auths.group_search_base=Grup Arama Tabanı DN
|
||||
auths.group_attribute_list_users=Kullanıcı Listesi İçeren Grup Özelliği
|
||||
auths.user_attribute_in_group=Grupta Listelenen Kullanıcı Özelliği
|
||||
auths.map_group_to_team=LDAP gruplarını Organizasyon takımlarına eşle (atlamak için bu alanı boş bırakın)
|
||||
auths.map_group_to_team_removal=Eğer kullanıcı ilişkili LDAP grubuna ait değilse, kullanıcıları eşleşmiş takımlardan çıkarın
|
||||
auths.enable_ldap_groups=LDAP gruplarını etkinleştir
|
||||
auths.ms_ad_sa=MS AD Arama Nitelikleri
|
||||
auths.smtp_auth=SMTP Yetkilendirme Türü
|
||||
auths.smtphost=SMTP Sunucusu
|
||||
|
@ -2597,6 +2677,14 @@ auths.oauth2_emailURL=E-posta URL'si
|
|||
auths.skip_local_two_fa=Yerel 2FA'yı atla
|
||||
auths.skip_local_two_fa_helper=Bunu seçmediğinizde, 2FA ayarlamış olan yerel kullanıcıların, giriş yapabilmek için 2FA'yı yine de geçmeleri gerekiyor
|
||||
auths.oauth2_tenant=Kiracı
|
||||
auths.oauth2_scopes=Ek Kapsamlar
|
||||
auths.oauth2_required_claim_name=Gerekli Talep İsmi
|
||||
auths.oauth2_required_claim_name_helper=Bu ismi, bu kaynağa oturum açmayı bu isimdeki talebe sahip kullanıcıların girişiyle sınırlamak için ayarlayın
|
||||
auths.oauth2_required_claim_value=Gerekli Talep Değeri
|
||||
auths.oauth2_required_claim_value_helper=Bu değeri, bu kaynağa oturum açmayı bu isimdeki ve değerdeki talebe sahip kullanıcıların girişiyle sınırlamak için ayarlayın
|
||||
auths.oauth2_group_claim_name=Talep ismi bu kaynak için grup isimlerini sağlıyor. (İsteğe bağlı)
|
||||
auths.oauth2_admin_group=Yönetici kullanıcıları için Grup Talep değeri. (İsteğe bağlı, yukarıda talep ismine gerek duyar)
|
||||
auths.oauth2_restricted_group=Kısıtlı kullanıcılar için Grup Talep değeri. (İsteğe bağlı, yukarıda talep ismine gerek duyar)
|
||||
auths.enable_auto_register=Otomatik Kaydolmayı Etkinleştir
|
||||
auths.sspi_auto_create_users=Kullanıcıları otomatik olarak oluştur
|
||||
auths.sspi_auto_create_users_helper=SSPI kimlik doğrulama yönteminin ilk kez oturum açan kullanıcılar için otomatik olarak yeni hesaplar oluşturmasına izin ver
|
||||
|
@ -2644,6 +2732,7 @@ config.app_ver=Gitea Sürümü
|
|||
config.app_url=Gitea Taban URL'si
|
||||
config.custom_conf=Yapılandırma Dosyası Yolu
|
||||
config.custom_file_root_path=Özel Dosya Kök Yolu
|
||||
config.domain=Sunucu Alan Adı
|
||||
config.offline_mode=Yerel Kip
|
||||
config.disable_router_log=Yönlendirici Log'larını Devre Dışı Bırak
|
||||
config.run_user=Şu Kullanıcı Olarak Çalıştır
|
||||
|
@ -2659,6 +2748,7 @@ config.reverse_auth_user=Tersine Yetkilendirme Kullanıcısı
|
|||
config.ssh_config=SSH Yapılandırması
|
||||
config.ssh_enabled=Aktif
|
||||
config.ssh_start_builtin_server=Yerleşik Sunucuyu Kullan
|
||||
config.ssh_domain=SSH Sunucusu Alan Adı
|
||||
config.ssh_port=Bağlantı Noktası
|
||||
config.ssh_listen_port=Port'u Dinle
|
||||
config.ssh_root_path=Kök Yol
|
||||
|
@ -2709,13 +2799,19 @@ config.queue_length=Kuyruk Uzunluğu
|
|||
config.deliver_timeout=Dağıtım Zaman Aşımı
|
||||
config.skip_tls_verify=TLS Doğrulamasını Geç
|
||||
|
||||
config.mailer_config=Mailer Yapılandırması
|
||||
config.mailer_enabled=Aktif
|
||||
config.mailer_enable_helo=HELO'yu etkinleştir
|
||||
config.mailer_name=İsim
|
||||
config.mailer_protocol=Protokol
|
||||
config.mailer_smtp_addr=SMTP Adresi
|
||||
config.mailer_smtp_port=SMTP Portu
|
||||
config.mailer_user=Kullanıcı
|
||||
config.mailer_use_sendmail=Sendmail Kullan
|
||||
config.mailer_sendmail_path=Sendmail Yolu
|
||||
config.mailer_sendmail_args=Sendmail İçin İlave Değişkenler
|
||||
config.mailer_sendmail_timeout=Sendmail Zaman Aşımı
|
||||
config.mailer_use_dummy=Sahte
|
||||
config.test_email_placeholder=E-posta (ör. test@example.com)
|
||||
config.send_test_mail=Test E-postası Gönder
|
||||
config.test_mail_failed='%s' adresine test e-postası gönderilemedi: %v
|
||||
|
@ -2775,12 +2871,16 @@ monitor.next=Sonraki Zaman
|
|||
monitor.previous=Önceki Zaman
|
||||
monitor.execute_times=Çalıştırma
|
||||
monitor.process=Çalışan Süreçler
|
||||
monitor.stacktrace=Yığın izleme
|
||||
monitor.goroutines=%d Gorutinleri
|
||||
monitor.desc=Açıklama
|
||||
monitor.start=Başlangıç Zamanı
|
||||
monitor.execute_time=Çalıştırma Zamanı
|
||||
monitor.last_execution_result=Sonuç
|
||||
monitor.process.cancel=İşlemi iptal et
|
||||
monitor.process.cancel_desc=Bir işlemi iptal etmek veri kaybına neden olabilir
|
||||
monitor.process.cancel_notices=İptal et: <strong>%s</strong>?
|
||||
monitor.process.children=Çocuklar
|
||||
monitor.queues=Kuyruklar
|
||||
monitor.queue=Kuyruk: %s
|
||||
monitor.queue.name=İsim
|
||||
|
@ -2788,6 +2888,7 @@ monitor.queue.type=Tür
|
|||
monitor.queue.exemplar=Örnek Türü
|
||||
monitor.queue.numberworkers=Çalışan Sayısı
|
||||
monitor.queue.maxnumberworkers=En Fazla Çalışan Sayısı
|
||||
monitor.queue.numberinqueue=Kuyruktaki Sayı
|
||||
monitor.queue.review=Yapılandırmayı İncele
|
||||
monitor.queue.review_add=Çalışanları İncele/Ekle
|
||||
monitor.queue.configuration=Başlangıç Yapılandırması
|
||||
|
@ -2807,6 +2908,12 @@ monitor.queue.pool.flush.title=Kuyruk Temizleme
|
|||
monitor.queue.pool.flush.desc=Temizleme, kuyruk boş olduğunda veya zaman aşımına uğradığında sona erecek bir işçi ekler.
|
||||
monitor.queue.pool.flush.submit=Temizleme İşçisi Ekle
|
||||
monitor.queue.pool.flush.added=%[1]s için Temizleme İşçisi eklendi
|
||||
monitor.queue.pool.pause.title=Kuyruğu Duraklat
|
||||
monitor.queue.pool.pause.desc=Kuyruğun duraklatılması veriyi işlemesini önleyecektir
|
||||
monitor.queue.pool.pause.submit=Kuyruğu Duraklat
|
||||
monitor.queue.pool.resume.title=Kuyruğu Sürdür
|
||||
monitor.queue.pool.resume.desc=Bu kuyruğun çalışmasını sürdür
|
||||
monitor.queue.pool.resume.submit=Kuyruğu Sürdür
|
||||
|
||||
monitor.queue.settings.title=Havuz Ayarları
|
||||
monitor.queue.settings.desc=Havuzlar, çalışan kuyruğunun engellenmesine yanıt olarak dinamik bir şekilde büyür. Bu değişiklikler mevcut çalışan gruplarını etkilemeyecektir.
|
||||
|
@ -2852,18 +2959,34 @@ notices.delete_success=Sistem bildirimleri silindi.
|
|||
[action]
|
||||
create_repo=depo <a href="%s">%s</a> oluşturuldu
|
||||
rename_repo=<code>%[1]s</code> olan depo adını <a href="%[2]s">%[3]s</a> buna çevirdi
|
||||
commit_repo=<a href="%[1]s">%[4]s</a> deposuna <a href="%[2]s">%[3]s</a> dalını gönderdi
|
||||
create_issue=`<a href="%[1]s">%[3]s#%[2]s</a> konusunu açtı`
|
||||
close_issue=`<a href="%[1]s">%[3]s#%[2]s</a> konusunu kapattı`
|
||||
reopen_issue=`<a href="%[1]s">%[3]s#%[2]s</a> konusunu tekrar açtı`
|
||||
create_pull_request=`<a href="%[1]s">%[3]s#%[2]s</a> değişiklik isteğini oluşturdu`
|
||||
close_pull_request=`<a href="%[1]s">%[3]s#%[2]s</a> değişiklik isteğini kapattı`
|
||||
reopen_pull_request=`<a href="%[1]s">%[3]s#%[2]s</a> değişiklik isteğini yeniden açtı`
|
||||
comment_issue=`<a href="%[1]s">%[3]s#%[2]s</a> konusuna yorum yaptı`
|
||||
comment_pull=`<a href="%[1]s">%[3]s#%[2]s</a> değişiklik isteğine yorum yaptı`
|
||||
merge_pull_request=`<a href="%[1]s">%[3]s#%[2]s</a> değişiklik isteğini birleştirdi`
|
||||
transfer_repo=depo <code>%s</code> <a href="%s">%s</a>'a aktarıldı
|
||||
push_tag=<a href="%[2]s">%[3]s</a> etiketini <a href="%[1]s">%[4]s</a> dalına gönderdi
|
||||
delete_tag=%[2]s etiketi <a href="%[1]s">%[3]s</a> deposundan silindi
|
||||
delete_branch=<a href="%[1]s">%[3]s</a> deposundan %[2]s dalı silindi
|
||||
compare_branch=Karşılaştır
|
||||
compare_commits=%d işlemeyi karşılaştır
|
||||
compare_commits_general=İşlemeleri karşılaştır
|
||||
mirror_sync_push=yansıdan <a href="%[1]s">%[4]s</a> deposundaki <a href="%[2]s">%[3]s</a> dalına işlemeleri eşitledi
|
||||
mirror_sync_create=<a href="%[2]s">%[3]s</a> yeni referansını, <a href="%[1]s">%[4]s</a> olarak yansıdan eşledi
|
||||
mirror_sync_delete=<a href="%[1]s">%[3]s</a> adresindeki <code>%[2]s</code> referansını eşitledi ve sildi
|
||||
approve_pull_request=`<a href="%[1]s">%[3]s#%[2]s</a> değişiklik isteğini onayladı`
|
||||
reject_pull_request=`<a href="%[1]s">%[3]s#%[2]s</a> için değişiklikler önerdi`
|
||||
publish_release=`<a href="%[1]s">%[3]s</a> deposu için <a href="%[2]s"> "%[4]s" </a> sürümü yayınlandı`
|
||||
review_dismissed=`<a href="%[1]s">%[3]s#%[2]s</a> için <b>%[4]s</b> yorumunu reddetti`
|
||||
review_dismissed_reason=Sebep:
|
||||
create_branch=<a href="%[1]s">%[4]s</a> deposunda <a href="%[2]s">%[3]s</a> dalını oluşturdu
|
||||
starred_repo=<a href="%[1]s">%[2]s</a> deposuna yıldız bıraktı
|
||||
watched_repo=<a href="%[1]s">%[2]s</a> deposunu izlemeye başladı
|
||||
|
||||
[tool]
|
||||
ago=%s önce
|
||||
|
@ -2924,10 +3047,15 @@ error.unit_not_allowed=Bu depo bölümüne erişme izniniz yok.
|
|||
title=Paketler
|
||||
desc=Depo paketlerini yönet.
|
||||
empty=Henüz hiçbir paket yok.
|
||||
empty.documentation=Paket kütüğü hakkında daha fazla bilgi için, <a target="_blank" rel="noopener noreferrer" href="https://docs.gitea.io/en-us/packages/overview">belgeye</a> bakabilirsiniz.
|
||||
empty.repo=Bir paket yüklediniz ama burada gösterilmiyor mu? <a href="%[1]s">Paket ayarları</a>na gidin ve bu depoya bağlantı verin.
|
||||
filter.type=Tür
|
||||
filter.type.all=Tümü
|
||||
filter.no_result=Filtreniz herhangi bir sonuç döndürmedi.
|
||||
filter.container.tagged=Etiketlenmiş
|
||||
filter.container.untagged=Etiketlenmemiş
|
||||
published_by=%[1]s, <a href="%[2]s">%[3]s</a> tarafından yayınlandı
|
||||
published_by_in=%[1]s, <a href="%[2]s">%[3]s</a> tarafından <a href="%[4]s"><strong>%[5]s</strong></a> içerisinde yayınlanmış
|
||||
installation=Kurulum
|
||||
about=Bu paket hakkında
|
||||
requirements=Gereksinimler
|
||||
|
@ -2941,12 +3069,43 @@ assets=Varlıklar
|
|||
versions=Sürümler
|
||||
versions.on=açık
|
||||
versions.view_all=Tümünü görüntüle
|
||||
dependency.id=Kimlik
|
||||
dependency.version=Sürüm
|
||||
composer.registry=Bu kütüğü <code>~/.composer/config.json</code> dosyasında ayarlayın:
|
||||
composer.install=Paketi Composer ile kurmak için, şu komutu çalıştırın:
|
||||
composer.documentation=Composer kütüğü hakkında daha fazla bilgi için, <a target="_blank" rel="noopener noreferrer" href="https://docs.gitea.io/en-us/packages/composer/">belgeye</a> bakabilirsiniz.
|
||||
composer.dependencies=Bağımlılıklar
|
||||
composer.dependencies.development=Geliştirme Bağımlılıkları
|
||||
conan.details.repository=Depo
|
||||
conan.registry=Bu kütüğü komut satırını kullanarak kurun:
|
||||
conan.install=Conan ile paket kurmak için aşağıdaki komutu çalıştırın:
|
||||
conan.documentation=Conan kütüğü hakkında daha fazla bilgi için, <a target="_blank" rel="noopener noreferrer" href="https://docs.gitea.io/en-us/packages/conan/">belgeye</a> bakabilirsiniz.
|
||||
container.details.type=Görüntü Türü
|
||||
container.details.platform=Platform
|
||||
container.details.repository_site=Depo Sitesi
|
||||
container.details.documentation_site=Belge Sitesi
|
||||
container.pull=Görüntüyü komut satırını kullanarak çekin:
|
||||
container.documentation=Taşıyıcı kütüğü hakkında daha fazla bilgi için, <a target="_blank" rel="noopener noreferrer" href="https://docs.gitea.io/en-us/packages/container/">belgeye</a> bakabilirsiniz.
|
||||
container.multi_arch=İşletim Sistemi / Mimari
|
||||
container.layers=Görüntü Katmanları
|
||||
container.labels=Etiketler
|
||||
container.labels.key=Anahtar
|
||||
container.labels.value=Değer
|
||||
generic.download=Paketi komut satırında indirin:
|
||||
generic.documentation=Genel kütük hakkında daha fazla bilgi için, <a target="_blank" rel="noopener noreferrer" href="https://docs.gitea.io/en-us/packages/generic">belgeye</a> bakabilirsiniz.
|
||||
helm.registry=Bu kütüğü komut satırını kullanarak kurun:
|
||||
helm.install=Paketi kurmak için, aşağıdaki komutu çalıştırın:
|
||||
helm.documentation=Helm kütüğü hakkında daha fazla bilgi için, <a target="_blank" rel="noopener noreferrer" href="https://docs.gitea.io/en-us/packages/helm/">belgeye</a> bakabilirsiniz.
|
||||
maven.registry=Bu kütüğü projenizdeki <code>pom.xml</code> dosyasında ayarlayın:
|
||||
maven.install=Paketi kullanmak için aşağıdaki <code>dependencies</code> parçasını <code>pom.xml</code> dosyasınıza ekleyin:
|
||||
maven.install2=Komut satırında çalıştırın:
|
||||
maven.download=Bağımlılığı indirmek için, komut satırında çalıştırın:
|
||||
maven.documentation=Maven kütüğü hakkında daha fazla bilgi için, <a target="_blank" rel="noopener noreferrer" href="https://docs.gitea.io/en-us/packages/maven/">belgeye</a> bakabilirsiniz.
|
||||
nuget.registry=Bu kütüğü komut satırını kullanarak kurun:
|
||||
nuget.install=Paketi NuGet ile kurmak için, şu komutu çalıştırın:
|
||||
nuget.documentation=NuGet kütüğü hakkında daha fazla bilgi için, <a target="_blank" rel="noopener noreferrer" href="https://docs.gitea.io/en-us/packages/nuget/">belgeye</a> bakabilirsiniz.
|
||||
nuget.dependency.framework=Hedef Çerçeve
|
||||
npm.registry=Bu kütüğü projenizdeki <code>.npmrc</code> dosyasında ayarlayın:
|
||||
npm.install=Paketi npm ile kurmak için, şu komutu çalıştırın:
|
||||
npm.install2=veya paketi package.json dosyasına ekleyin:
|
||||
npm.documentation=Npm kütüğü hakkında daha fazla bilgi için, <a target="_blank" rel="noopener noreferrer" href="https://docs.gitea.io/en-us/packages/npm/">belgeye</a> bakabilirsiniz.
|
||||
|
@ -2955,6 +3114,10 @@ npm.dependencies.development=Geliştirme Bağımlılıkları
|
|||
npm.dependencies.peer=Eş Bağımlılıkları
|
||||
npm.dependencies.optional=İsteğe Bağlı Bağımlılıklar
|
||||
npm.details.tag=Etiket
|
||||
pub.install=Paketi Dart ile kurmak için, şu komutu çalıştırın:
|
||||
pub.documentation=Pub kütüğü hakkında daha fazla bilgi için, <a target="_blank" rel="noopener noreferrer" href="https://docs.gitea.io/en-us/packages/pub/">belgeye</a> bakabilirsiniz.
|
||||
pub.details.repository_site=Depo Sitesi
|
||||
pub.details.documentation_site=Belge Sitesi
|
||||
pypi.requires=Gereken Python
|
||||
pypi.install=Paketi pip ile kurmak için, şu komutu çalıştırın:
|
||||
pypi.documentation=PyPI kütüğü hakkında daha fazla bilgi için, <a target="_blank" rel="noopener noreferrer" href="https://docs.gitea.io/en-us/packages/pypi/">belgeye</a> bakabilirsiniz.
|
||||
|
|
|
@ -9,7 +9,7 @@ sign_out=退出
|
|||
sign_up=注册
|
||||
link_account=链接账户
|
||||
register=注册
|
||||
website=官方网站
|
||||
website=网站
|
||||
version=当前版本
|
||||
powered_by=Powered by %s
|
||||
page=页面
|
||||
|
@ -179,6 +179,8 @@ log_root_path_helper=日志文件将写入此目录。
|
|||
|
||||
optional_title=可选设置
|
||||
email_title=电子邮箱设置
|
||||
smtp_addr=SMTP 主机地址
|
||||
smtp_port=SMTP 端口
|
||||
smtp_from=电子邮件发件人
|
||||
smtp_from_helper=电子邮件地址 Gitea 将使用。输入一个普通的电子邮件地址或使用 "名称" <email@example.com> 格式。
|
||||
mailer_user=SMTP 用户名
|
||||
|
@ -798,6 +800,7 @@ email_notifications.enable=启用邮件通知
|
|||
email_notifications.onmention=只在被提到时邮件通知
|
||||
email_notifications.disable=停用邮件通知
|
||||
email_notifications.submit=邮件通知设置
|
||||
email_notifications.andyourown=和您自己的通知
|
||||
|
||||
visibility=用户可见性
|
||||
visibility.public=公开
|
||||
|
@ -931,6 +934,7 @@ form.name_pattern_not_allowed=仓库名称中不允许使用模式 "%s"。
|
|||
need_auth=授权
|
||||
migrate_options=迁移选项
|
||||
migrate_service=迁移服务
|
||||
migrate_options_mirror_helper=该仓库将是一个镜像
|
||||
migrate_options_lfs=迁移 LFS 文件
|
||||
migrate_options_lfs_endpoint.label=LFS 网址
|
||||
migrate_options_lfs_endpoint.description=迁移将尝试使用你的 Git remote 来 <a target="_blank" rel="noopener noreferrer" href="%s">确定 LFS 服务器</a>。如果仓库 LFS 数据存储在其他位置,你还可以指定自定义网址。
|
||||
|
@ -1059,6 +1063,7 @@ normal_view=普通视图
|
|||
line=行
|
||||
lines=行
|
||||
|
||||
editor.add_file=添加文件
|
||||
editor.new_file=新建文件
|
||||
editor.upload_file=上传文件
|
||||
editor.edit_file=编辑文件
|
||||
|
@ -1264,6 +1269,8 @@ issues.filter_milestone=里程碑筛选
|
|||
issues.filter_milestone_no_select=所有里程碑
|
||||
issues.filter_assignee=指派人筛选
|
||||
issues.filter_assginee_no_select=所有指派成员
|
||||
issues.filter_poster=作者
|
||||
issues.filter_poster_no_select=所有作者
|
||||
issues.filter_type=类型筛选
|
||||
issues.filter_type.all_issues=所有工单
|
||||
issues.filter_type.assigned_to_you=指派给您的
|
||||
|
@ -1418,6 +1425,7 @@ issues.due_date_form_remove=删除
|
|||
issues.due_date_not_writer=你需要仓库写入权限来修改工单到期时间。
|
||||
issues.due_date_not_set=未设置到期时间。
|
||||
issues.due_date_added=于 %[2]s 设置到期时间为 %[1]s
|
||||
issues.due_date_modified=将到期日从 %[2]s 修改为 %[1]s %[3]s
|
||||
issues.due_date_remove=于 %[2]s 删除了到期时间 %[1]s
|
||||
issues.due_date_overdue=过期
|
||||
issues.due_date_invalid=到期日期无效或超出范围。请使用 'yyyy-mm-dd' 格式。
|
||||
|
@ -1529,6 +1537,8 @@ pulls.remove_prefix=删除 <strong>%s</strong> 前缀
|
|||
pulls.data_broken=此合并请求因为派生仓库信息缺失而中断。
|
||||
pulls.files_conflicted=此合并请求有变更与目标分支冲突。
|
||||
pulls.is_checking=正在进行合并冲突检测,请稍后再试。
|
||||
pulls.is_ancestor=此分支已经包含在目标分支中,没有什么可以合并。
|
||||
pulls.is_empty=此分支上的更改已经在目标分支上。这将是一个空提交。
|
||||
pulls.required_status_check_failed=一些必要的检查没有成功
|
||||
pulls.required_status_check_missing=缺少一些必要的检查。
|
||||
pulls.required_status_check_administrator=作为管理员,您仍可合并此合并请求
|
||||
|
@ -2203,7 +2213,7 @@ release.stable=稳定
|
|||
release.compare=比较
|
||||
release.edit=编辑
|
||||
release.ahead.commits=<strong>%d</strong> 次提交
|
||||
release.ahead.target=到 %s 自发布后
|
||||
release.ahead.target=在此版本发布后被加入到 %s
|
||||
release.source_code=源代码
|
||||
release.new_subheader=版本发布组织项目的版本。
|
||||
release.edit_subheader=版本发布组织项目的版本。
|
||||
|
@ -2314,7 +2324,7 @@ form.create_org_not_allowed=此账号禁止创建组织
|
|||
settings=组织设置
|
||||
settings.options=组织
|
||||
settings.full_name=组织全名
|
||||
settings.website=官方网站
|
||||
settings.website=网站
|
||||
settings.location=所在地区
|
||||
settings.permission=权限
|
||||
settings.repoadminchangeteam=仓库管理员可以添加或移除团队的访问权限
|
||||
|
@ -2531,6 +2541,8 @@ users.delete_account=删除帐户
|
|||
users.cannot_delete_self=你不能删除自己
|
||||
users.still_own_repo=此用户仍然拥有一个或多个仓库。必须首先删除或转让这些仓库。
|
||||
users.still_has_org=此用户是组织的成员。必须先从组织中删除用户。
|
||||
users.purge=清理用户
|
||||
users.purge_help=强制删除用户和用户拥有的任何仓库、组织和软件包。所有评论也将被删除。
|
||||
users.still_own_packages=此用户仍然拥有一个或多个软件包。请先删除这些软件包。
|
||||
users.deletion_success=用户帐户已被删除。
|
||||
users.reset_2fa=重置两步验证
|
||||
|
@ -2787,13 +2799,19 @@ config.queue_length=队列长度
|
|||
config.deliver_timeout=推送超时
|
||||
config.skip_tls_verify=跳过 TLS 验证
|
||||
|
||||
config.mailer_config=Mailer 配置
|
||||
config.mailer_enabled=启用服务
|
||||
config.mailer_enable_helo=启用HELO
|
||||
config.mailer_name=任务名称
|
||||
config.mailer_protocol=协议
|
||||
config.mailer_smtp_addr=SMTP 地址
|
||||
config.mailer_smtp_port=SMTP 端口
|
||||
config.mailer_user=发送者帐号
|
||||
config.mailer_use_sendmail=使用 Sendmail
|
||||
config.mailer_sendmail_path=Sendmail 路径
|
||||
config.mailer_sendmail_args=Sendmail 的额外参数
|
||||
config.mailer_sendmail_timeout=Sendmail 超时
|
||||
config.mailer_use_dummy=Dummy
|
||||
config.test_email_placeholder=电子邮址 (例如,test@example.com)
|
||||
config.send_test_mail=发送测试邮件
|
||||
config.test_mail_failed=发送测试邮件至 '%s' 时失败:%v
|
||||
|
@ -3030,6 +3048,7 @@ title=软件包
|
|||
desc=管理仓库软件包。
|
||||
empty=还没有软件包。
|
||||
empty.documentation=关于软件包注册中心的更多信息,请参阅 <a target="_blank" rel="noopener noreferrer" href="https://docs.gitea.io/en-us/packages/overview"> 文档 </a>。
|
||||
empty.repo=您上传了一个包,但没有显示在这里吗?转到 <a href="%[1]s">包设置</a> 并将其链接到这个仓库中。
|
||||
filter.type=类型
|
||||
filter.type.all=所有
|
||||
filter.no_result=您的过滤器没有产生任何结果。
|
||||
|
@ -3095,6 +3114,10 @@ npm.dependencies.development=开发依赖
|
|||
npm.dependencies.peer=Peer 依赖
|
||||
npm.dependencies.optional=可选依赖
|
||||
npm.details.tag=标签
|
||||
pub.install=要使用 Dart 安装软件包,请运行以下命令:
|
||||
pub.documentation=关于 Pub 注册中心的信息,请参阅 <a target="_blank" rel="noopener noreferrer" href="https://docs.gitea.io/en-us/packages/pub/">文档</a>。
|
||||
pub.details.repository_site=仓库站点
|
||||
pub.details.documentation_site=文档站点
|
||||
pypi.requires=需要 Python
|
||||
pypi.install=要使用 pip 安装软件包,请运行以下命令:
|
||||
pypi.documentation=关于 PyPI 注册中心的信息,请参阅 <a target="_blank" rel="noopener noreferrer" href="https://docs.gitea.io/en-us/packages/pypi/">文档</a>。
|
||||
|
|
21
package.json
|
@ -8,7 +8,8 @@
|
|||
},
|
||||
"dependencies": {
|
||||
"@claviska/jquery-minicolors": "2.3.6",
|
||||
"@primer/octicons": "17.3.0",
|
||||
"@mcaptcha/vanilla-glue": "0.1.0-alpha-2",
|
||||
"@primer/octicons": "17.4.0",
|
||||
"add-asset-webpack-plugin": "2.0.1",
|
||||
"css-loader": "6.7.1",
|
||||
"dropzone": "6.0.0-beta.2",
|
||||
|
@ -28,7 +29,7 @@
|
|||
"monaco-editor-webpack-plugin": "7.0.1",
|
||||
"pretty-ms": "8.0.0",
|
||||
"sortablejs": "1.15.0",
|
||||
"swagger-ui-dist": "4.13.0",
|
||||
"swagger-ui-dist": "4.13.2",
|
||||
"tippy.js": "6.3.7",
|
||||
"tributejs": "5.1.3",
|
||||
"uint8-to-base64": "0.2.0",
|
||||
|
@ -37,22 +38,22 @@
|
|||
"vue-calendar-heatmap": "0.8.4",
|
||||
"vue-loader": "15.9.8",
|
||||
"vue-template-compiler": "2.6.14",
|
||||
"webpack": "5.73.0",
|
||||
"webpack": "5.74.0",
|
||||
"webpack-cli": "4.10.0",
|
||||
"workbox-routing": "6.5.3",
|
||||
"workbox-strategies": "6.5.3",
|
||||
"workbox-routing": "6.5.4",
|
||||
"workbox-strategies": "6.5.4",
|
||||
"worker-loader": "3.0.8",
|
||||
"wrap-ansi": "8.0.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@happy-dom/jest-environment": "6.0.4",
|
||||
"@stoplight/spectral-cli": "6.4.1",
|
||||
"eslint": "8.20.0",
|
||||
"@stoplight/spectral-cli": "6.5.0",
|
||||
"eslint": "8.21.0",
|
||||
"eslint-plugin-import": "2.26.0",
|
||||
"eslint-plugin-jquery": "1.5.1",
|
||||
"eslint-plugin-sonarjs": "0.13.0",
|
||||
"eslint-plugin-sonarjs": "0.14.0",
|
||||
"eslint-plugin-unicorn": "43.0.2",
|
||||
"eslint-plugin-vue": "9.2.0",
|
||||
"eslint-plugin-vue": "9.3.0",
|
||||
"jest": "28.1.3",
|
||||
"jest-extended": "3.0.1",
|
||||
"markdownlint-cli": "0.32.1",
|
||||
|
@ -60,7 +61,7 @@
|
|||
"stylelint": "14.9.1",
|
||||
"stylelint-config-standard": "26.0.0",
|
||||
"svgo": "2.8.0",
|
||||
"updates": "13.1.2"
|
||||
"updates": "13.1.4"
|
||||
},
|
||||
"browserslist": [
|
||||
"defaults",
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
<svg viewBox="0 0 449 448" class="svg fontawesome-send" width="16" height="16" aria-hidden="true"><path d="M441 2.8c5.3 3.7 7.8 9.7 6.8 16l-64 384A16 16 0 0 1 368 416c-2 0-4-.5-6-1.3l-113.3-46.2-60.4 73.8c-3 3.7-7.6 5.7-12.3 5.7a16 16 0 0 1-16-16v-87.3L376 80 108.7 311.3 10 270.6a15.8 15.8 0 0 1-2-28.4l416-240c2.5-1.5 5.3-2.3 8-2.3 3.3 0 6.5 1 9 2.8z"/></svg>
|
After Width: | Height: | Size: 361 B |
|
@ -0,0 +1 @@
|
|||
<svg viewBox="0 0 24 24" class="svg gitea-exclamation" width="16" height="16" aria-hidden="true"><path d="M12 15.99a2 2 0 0 0 2-2V2.03a2 2 0 0 0-4 0v11.96a2 2 0 0 0 2 2zm0 7.98a2.5 2.5 0 1 0-2.5-2.5 2.5 2.5 0 0 0 2.5 2.5z"/></svg>
|
After Width: | Height: | Size: 230 B |
|
@ -0,0 +1 @@
|
|||
<svg viewBox="0 0 502.87 502.87" class="svg gitea-pub" width="16" height="16" aria-hidden="true"><defs><radialGradient id="gitea-pub__a" cx="251.42" cy="631.97" r="251.4" gradientTransform="translate(0 -380.56)" gradientUnits="userSpaceOnUse"><stop stop-color="#fff" stop-opacity=".1" offset="0"/><stop stop-color="#fff" stop-opacity="0" offset="1"/></radialGradient><style>.gitea-pub__cls-1{fill:#01579b}.gitea-pub__cls-2{fill:#40c4ff}.gitea-pub__cls-4{fill:#fff;opacity:.2;isolation:isolate}</style></defs><path class="gitea-pub__cls-1" d="m102.56 400.31-86-86C6.32 303.82 0 289 0 274.58c0-6.69 3.77-17.16 6.62-23.15L86 86Z"/><path class="gitea-pub__cls-2" d="m397 102.56-86-86C303.49 9 287.85 0 274.61 0c-11.38 0-22.55 2.29-29.76 6.62L86.07 86ZM205.11 502.87h208.44v-89.32l-155.5-49.65-142.26 49.65z"/><path d="M86 354c0 26.54 3.33 33.05 16.53 46.32l13.23 13.24h297.79L268 248.14 86 86Z" style="fill:#29b6f6"/><path class="gitea-pub__cls-1" d="M350.7 86H86l327.55 327.51h89.32V208.4L397 102.52C382.12 87.62 368.92 86 350.7 86Z"/><path class="gitea-pub__cls-4" d="M105.88 403.6c-13.23-13.27-16.52-26.36-16.52-49.6V89.32L86.07 86v268c0 23.25 0 29.69 19.81 49.61l9.91 9.91Z"/><path style="fill:#263238;opacity:.2;isolation:isolate" d="M499.58 205.11v205.11h-89.32l3.29 3.33h89.32V208.4z"/><path class="gitea-pub__cls-4" d="M397 102.56C380.61 86.14 367.19 86 347.41 86H86.07l3.29 3.29h258.05c9.87 0 34.79-1.66 49.61 13.24Z"/><path d="M499.58 205.11 397 102.56l-86-86C303.49 9 287.85 0 274.61 0c-11.38 0-22.55 2.29-29.76 6.62L86.07 86 6.65 251.43C3.81 257.46 0 267.92 0 274.58c0 14.45 6.36 29.2 16.52 39.7L95.83 393a92.42 92.42 0 0 0 6.73 7.32l3.29 3.29 9.9 9.91 86 86 3.29 3.29h208.4v-89.3h89.32V208.4Z" style="fill:url(#gitea-pub__a);opacity:.2;isolation:isolate"/></svg>
|
After Width: | Height: | Size: 1.7 KiB |
|
@ -0,0 +1 @@
|
|||
<svg viewBox="0 0 16 16" class="svg octicon-cache" width="16" height="16" aria-hidden="true"><path fill-rule="evenodd" d="M2.5 5.724c.241.15.503.286.779.407C4.525 6.68 6.195 7 8 7c1.805 0 3.475-.32 4.722-.869.622-.274 1.172-.62 1.578-1.04.408-.426.7-.965.7-1.591s-.292-1.165-.7-1.59c-.406-.422-.956-.767-1.579-1.041C11.476.32 9.806 0 8 0 6.195 0 4.525.32 3.279.869c-.623.274-1.173.62-1.579 1.04-.408.426-.7.965-.7 1.591v9c0 .626.292 1.165.7 1.59.406.422.956.767 1.579 1.041C4.525 15.68 6.195 16 8 16c.45 0 .89-.02 1.317-.058a.75.75 0 1 0-.134-1.494c-.381.034-.777.052-1.183.052-1.647 0-3.102-.295-4.117-.742-.51-.224-.874-.47-1.101-.707-.224-.233-.282-.418-.282-.551v-2.276c.164.102.334.196.507.28 1.102.543 2.582.89 4.204.975a.75.75 0 0 0 .078-1.498c-1.476-.077-2.746-.392-3.62-.822C2.738 8.7 2.5 8.248 2.5 8V5.724zm0-2.224c0-.133.058-.318.282-.55.227-.237.592-.484 1.1-.708C4.899 1.795 6.354 1.5 8 1.5c1.647 0 3.102.295 4.117.742.51.224.874.47 1.101.707.224.233.282.418.282.551 0 .133-.058.318-.282.55-.227.237-.592.484-1.1.708C11.101 5.205 9.646 5.5 8 5.5c-1.647 0-3.102-.295-4.117-.742-.51-.224-.874-.47-1.101-.707-.224-.233-.282-.418-.282-.551z"/><path d="M14.49 7.582a.375.375 0 0 0-.66-.313l-3.625 4.625a.375.375 0 0 0 .295.606h2.127l-.619 2.922a.375.375 0 0 0 .666.304l3.125-4.125A.375.375 0 0 0 15.5 11h-1.778l.769-3.418z"/></svg>
|
After Width: | Height: | Size: 1.3 KiB |
|
@ -0,0 +1 @@
|
|||
<svg viewBox="0 0 16 16" class="svg octicon-checkbox" width="16" height="16" aria-hidden="true"><path fill-rule="evenodd" d="M2.5 2.75a.25.25 0 0 1 .25-.25h10.5a.25.25 0 0 1 .25.25v10.5a.25.25 0 0 1-.25.25H2.75a.25.25 0 0 1-.25-.25V2.75zM2.75 1A1.75 1.75 0 0 0 1 2.75v10.5c0 .966.784 1.75 1.75 1.75h10.5A1.75 1.75 0 0 0 15 13.25V2.75A1.75 1.75 0 0 0 13.25 1H2.75zm9.03 5.28a.75.75 0 0 0-1.06-1.06L6.75 9.19 5.28 7.72a.75.75 0 0 0-1.06 1.06l2 2a.75.75 0 0 0 1.06 0l4.5-4.5z"/></svg>
|
After Width: | Height: | Size: 481 B |
|
@ -0,0 +1 @@
|
|||
<svg viewBox="0 0 16 16" class="svg octicon-command-palette" width="16" height="16" aria-hidden="true"><path d="m6.354 8.04-4.773 4.773a.75.75 0 1 0 1.061 1.06L7.945 8.57a.75.75 0 0 0 0-1.06L2.642 2.206a.75.75 0 0 0-1.06 1.061L6.353 8.04zM8.75 11.5a.75.75 0 0 0 0 1.5h5.5a.75.75 0 0 0 0-1.5h-5.5z"/></svg>
|
After Width: | Height: | Size: 305 B |
|
@ -0,0 +1 @@
|
|||
<svg viewBox="0 0 16 16" class="svg octicon-git-merge-queue" width="16" height="16" aria-hidden="true"><path d="M3.75 4.5a1.25 1.25 0 1 0 0-2.5 1.25 1.25 0 0 0 0 2.5z"/><path fill-rule="evenodd" d="M3 7.75a.75.75 0 0 1 1.5 0v2.878a2.251 2.251 0 1 1-1.5 0V7.75zm.75 5.75a.75.75 0 1 0 0-1.5.75.75 0 0 0 0 1.5z"/><path d="M8.75 5.75a1.25 1.25 0 1 1-2.5 0 1.25 1.25 0 0 1 2.5 0z"/><path fill-rule="evenodd" d="M14.5 8.25a2.25 2.25 0 1 1-4.5 0 2.25 2.25 0 0 1 4.5 0zm-1.5 0a.75.75 0 1 1-1.5 0 .75.75 0 0 1 1.5 0z"/></svg>
|
After Width: | Height: | Size: 516 B |
|
@ -0,0 +1 @@
|
|||
<svg viewBox="0 0 16 16" class="svg octicon-paperclip" width="16" height="16" aria-hidden="true"><path fill-rule="evenodd" d="M12.212 3.02a1.75 1.75 0 0 0-2.478.003l-5.83 5.83a3.007 3.007 0 0 0-.88 2.127c0 .795.315 1.551.88 2.116.567.567 1.333.89 2.126.89.79 0 1.548-.321 2.116-.89l5.48-5.48a.75.75 0 0 1 1.061 1.06l-5.48 5.48a4.494 4.494 0 0 1-3.177 1.33c-1.2 0-2.345-.487-3.187-1.33a4.485 4.485 0 0 1-1.32-3.177c0-1.195.475-2.341 1.32-3.186l5.83-5.83a3.25 3.25 0 0 1 5.553 2.297c0 .863-.343 1.691-.953 2.301L7.439 12.39a2.01 2.01 0 0 1-1.416.593 2 2 0 0 1-1.412-.593 1.991 1.991 0 0 1 0-2.828l5.48-5.48a.75.75 0 0 1 1.06 1.06l-5.48 5.48a.491.491 0 0 0 0 .707.5.5 0 0 0 .352.154.509.509 0 0 0 .356-.154l5.833-5.827a1.755 1.755 0 0 0 0-2.481z"/></svg>
|
After Width: | Height: | Size: 751 B |
|
@ -1 +1 @@
|
|||
<svg viewBox="0 0 16 16" class="svg octicon-table" width="16" height="16" aria-hidden="true"><path fill-rule="evenodd" d="M0 1.75C0 .784.784 0 1.75 0h12.5C15.216 0 16 .784 16 1.75v3.585a.746.746 0 0 1 0 .83v8.085A1.75 1.75 0 0 1 14.25 16H6.309a.748.748 0 0 1-1.118 0H1.75A1.75 1.75 0 0 1 0 14.25V6.165a.746.746 0 0 1 0-.83V1.75zM1.5 6.5v7.75c0 .138.112.25.25.25H5v-8H1.5zM5 5H1.5V1.75a.25.25 0 0 1 .25-.25H5V5zm1.5 1.5v8h7.75a.25.25 0 0 0 .25-.25V6.5h-8zm8-1.5h-8V1.5h7.75a.25.25 0 0 1 .25.25V5z"/></svg>
|
||||
<svg viewBox="0 0 16 16" class="svg octicon-table" width="16" height="16" aria-hidden="true"><path fill-rule="evenodd" d="M0 1.75C0 .784.784 0 1.75 0h12.5C15.216 0 16 .784 16 1.75v12.5A1.75 1.75 0 0 1 14.25 16H1.75A1.75 1.75 0 0 1 0 14.25V1.75zM1.5 6.5v7.75c0 .138.112.25.25.25H5v-8H1.5zM5 5H1.5V1.75a.25.25 0 0 1 .25-.25H5V5zm1.5 1.5v8h7.75a.25.25 0 0 0 .25-.25V6.5h-8zm8-1.5h-8V1.5h7.75a.25.25 0 0 1 .25.25V5z"/></svg>
|
Before Width: | Height: | Size: 504 B After Width: | Height: | Size: 420 B |
|
@ -1 +1 @@
|
|||
<svg viewBox="0 0 16 16" class="svg octicon-tasklist" width="16" height="16" aria-hidden="true"><path fill-rule="evenodd" d="M2.5 2.75a.25.25 0 0 1 .25-.25h10.5a.25.25 0 0 1 .25.25v10.5a.25.25 0 0 1-.25.25H2.75a.25.25 0 0 1-.25-.25V2.75zM2.75 1A1.75 1.75 0 0 0 1 2.75v10.5c0 .966.784 1.75 1.75 1.75h10.5A1.75 1.75 0 0 0 15 13.25V2.75A1.75 1.75 0 0 0 13.25 1H2.75zm9.03 5.28a.75.75 0 0 0-1.06-1.06L6.75 9.19 5.28 7.72a.75.75 0 0 0-1.06 1.06l2 2a.75.75 0 0 0 1.06 0l4.5-4.5z"/></svg>
|
||||
<svg viewBox="0 0 16 16" class="svg octicon-tasklist" width="16" height="16" aria-hidden="true"><path fill-rule="evenodd" d="M2.5 3.5v3h3v-3h-3zM2 2a1 1 0 0 0-1 1v4a1 1 0 0 0 1 1h4a1 1 0 0 0 1-1V3a1 1 0 0 0-1-1H2zm4.655 8.595a.75.75 0 0 1 0 1.06L4.03 14.28a.75.75 0 0 1-1.06 0l-1.5-1.5a.75.75 0 1 1 1.06-1.06l.97.97 2.095-2.095a.75.75 0 0 1 1.06 0zM9.75 2.5a.75.75 0 0 0 0 1.5h5.5a.75.75 0 0 0 0-1.5h-5.5zm0 5a.75.75 0 0 0 0 1.5h5.5a.75.75 0 0 0 0-1.5h-5.5zm0 5a.75.75 0 0 0 0 1.5h5.5a.75.75 0 0 0 0-1.5h-5.5z"/></svg>
|
Before Width: | Height: | Size: 481 B After Width: | Height: | Size: 518 B |
|
@ -21,6 +21,7 @@ import (
|
|||
"code.gitea.io/gitea/routers/api/packages/maven"
|
||||
"code.gitea.io/gitea/routers/api/packages/npm"
|
||||
"code.gitea.io/gitea/routers/api/packages/nuget"
|
||||
"code.gitea.io/gitea/routers/api/packages/pub"
|
||||
"code.gitea.io/gitea/routers/api/packages/pypi"
|
||||
"code.gitea.io/gitea/routers/api/packages/rubygems"
|
||||
"code.gitea.io/gitea/services/auth"
|
||||
|
@ -45,6 +46,7 @@ func Routes() *web.Route {
|
|||
authMethods := []auth.Method{
|
||||
&auth.OAuth2{},
|
||||
&auth.Basic{},
|
||||
&nuget.Auth{},
|
||||
&conan.Auth{},
|
||||
}
|
||||
if setting.Service.EnableReverseProxyAuth {
|
||||
|
@ -155,14 +157,17 @@ func Routes() *web.Route {
|
|||
})
|
||||
})
|
||||
r.Group("/generic", func() {
|
||||
r.Group("/{packagename}/{packageversion}/{filename}", func() {
|
||||
r.Group("/{packagename}/{packageversion}", func() {
|
||||
r.Delete("", reqPackageAccess(perm.AccessModeWrite), generic.DeletePackage)
|
||||
r.Group("/{filename}", func() {
|
||||
r.Get("", generic.DownloadPackageFile)
|
||||
r.Group("", func() {
|
||||
r.Put("", generic.UploadPackage)
|
||||
r.Delete("", generic.DeletePackage)
|
||||
r.Delete("", generic.DeletePackageFile)
|
||||
}, reqPackageAccess(perm.AccessModeWrite))
|
||||
})
|
||||
})
|
||||
})
|
||||
r.Group("/helm", func() {
|
||||
r.Get("/index.yaml", helm.Index)
|
||||
r.Get("/{filename}", helm.DownloadPackageFile)
|
||||
|
@ -194,12 +199,26 @@ func Routes() *web.Route {
|
|||
r.Group("/@{scope}/{id}", func() {
|
||||
r.Get("", npm.PackageMetadata)
|
||||
r.Put("", reqPackageAccess(perm.AccessModeWrite), npm.UploadPackage)
|
||||
r.Get("/-/{version}/{filename}", npm.DownloadPackageFile)
|
||||
r.Group("/-/{version}/{filename}", func() {
|
||||
r.Get("", npm.DownloadPackageFile)
|
||||
r.Delete("/-rev/{revision}", reqPackageAccess(perm.AccessModeWrite), npm.DeletePackageVersion)
|
||||
})
|
||||
r.Group("/-rev/{revision}", func() {
|
||||
r.Delete("", npm.DeletePackage)
|
||||
r.Put("", npm.DeletePreview)
|
||||
}, reqPackageAccess(perm.AccessModeWrite))
|
||||
})
|
||||
r.Group("/{id}", func() {
|
||||
r.Get("", npm.PackageMetadata)
|
||||
r.Put("", reqPackageAccess(perm.AccessModeWrite), npm.UploadPackage)
|
||||
r.Get("/-/{version}/{filename}", npm.DownloadPackageFile)
|
||||
r.Group("/-/{version}/{filename}", func() {
|
||||
r.Get("", npm.DownloadPackageFile)
|
||||
r.Delete("/-rev/{revision}", reqPackageAccess(perm.AccessModeWrite), npm.DeletePackageVersion)
|
||||
})
|
||||
r.Group("/-rev/{revision}", func() {
|
||||
r.Delete("", npm.DeletePackage)
|
||||
r.Put("", npm.DeletePreview)
|
||||
}, reqPackageAccess(perm.AccessModeWrite))
|
||||
})
|
||||
r.Group("/-/package/@{scope}/{id}/dist-tags", func() {
|
||||
r.Get("", npm.ListPackageTags)
|
||||
|
@ -216,6 +235,20 @@ func Routes() *web.Route {
|
|||
}, reqPackageAccess(perm.AccessModeWrite))
|
||||
})
|
||||
})
|
||||
r.Group("/pub", func() {
|
||||
r.Group("/api/packages", func() {
|
||||
r.Group("/versions/new", func() {
|
||||
r.Get("", pub.RequestUpload)
|
||||
r.Post("/upload", pub.UploadPackageFile)
|
||||
r.Get("/finalize/{id}/{version}", pub.FinalizePackage)
|
||||
}, reqPackageAccess(perm.AccessModeWrite))
|
||||
r.Group("/{id}", func() {
|
||||
r.Get("", pub.EnumeratePackageVersions)
|
||||
r.Get("/files/{version}", pub.DownloadPackageFile)
|
||||
r.Get("/{version}", pub.PackageVersionMetadata)
|
||||
})
|
||||
})
|
||||
})
|
||||
r.Group("/pypi", func() {
|
||||
r.Post("/", reqPackageAccess(perm.AccessModeWrite), pypi.UploadPackageFile)
|
||||
r.Get("/files/{id}/{version}/{filename}", pypi.DownloadPackageFile)
|
||||
|
|
|
@ -312,6 +312,9 @@ func createPackageAndVersion(ctx context.Context, mci *manifestCreationInfo, met
|
|||
return nil, err
|
||||
}
|
||||
|
||||
// keep download count on overwrite
|
||||
_pv.DownloadCount = pv.DownloadCount
|
||||
|
||||
if pv, err = packages_model.GetOrInsertVersion(ctx, _pv); err != nil {
|
||||
log.Error("Error inserting package: %v", err)
|
||||
return nil, err
|
||||
|
|
|
@ -31,22 +31,16 @@ func apiError(ctx *context.Context, status int, obj interface{}) {
|
|||
|
||||
// DownloadPackageFile serves the specific generic package.
|
||||
func DownloadPackageFile(ctx *context.Context) {
|
||||
packageName, packageVersion, filename, err := sanitizeParameters(ctx)
|
||||
if err != nil {
|
||||
apiError(ctx, http.StatusBadRequest, err)
|
||||
return
|
||||
}
|
||||
|
||||
s, pf, err := packages_service.GetFileStreamByPackageNameAndVersion(
|
||||
ctx,
|
||||
&packages_service.PackageInfo{
|
||||
Owner: ctx.Package.Owner,
|
||||
PackageType: packages_model.TypeGeneric,
|
||||
Name: packageName,
|
||||
Version: packageVersion,
|
||||
Name: ctx.Params("packagename"),
|
||||
Version: ctx.Params("packageversion"),
|
||||
},
|
||||
&packages_service.PackageFileInfo{
|
||||
Filename: filename,
|
||||
Filename: ctx.Params("filename"),
|
||||
},
|
||||
)
|
||||
if err != nil {
|
||||
|
@ -65,9 +59,17 @@ func DownloadPackageFile(ctx *context.Context) {
|
|||
// UploadPackage uploads the specific generic package.
|
||||
// Duplicated packages get rejected.
|
||||
func UploadPackage(ctx *context.Context) {
|
||||
packageName, packageVersion, filename, err := sanitizeParameters(ctx)
|
||||
if err != nil {
|
||||
apiError(ctx, http.StatusBadRequest, err)
|
||||
packageName := ctx.Params("packagename")
|
||||
filename := ctx.Params("filename")
|
||||
|
||||
if !packageNameRegex.MatchString(packageName) || !filenameRegex.MatchString(filename) {
|
||||
apiError(ctx, http.StatusBadRequest, errors.New("Invalid package name or filename"))
|
||||
return
|
||||
}
|
||||
|
||||
packageVersion := ctx.Params("packageversion")
|
||||
if packageVersion != strings.TrimSpace(packageVersion) {
|
||||
apiError(ctx, http.StatusBadRequest, errors.New("Invalid package version"))
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -88,7 +90,7 @@ func UploadPackage(ctx *context.Context) {
|
|||
}
|
||||
defer buf.Close()
|
||||
|
||||
_, _, err = packages_service.CreatePackageAndAddFile(
|
||||
_, _, err = packages_service.CreatePackageOrAddFileToExisting(
|
||||
&packages_service.PackageCreationInfo{
|
||||
PackageInfo: packages_service.PackageInfo{
|
||||
Owner: ctx.Package.Owner,
|
||||
|
@ -107,8 +109,8 @@ func UploadPackage(ctx *context.Context) {
|
|||
},
|
||||
)
|
||||
if err != nil {
|
||||
if err == packages_model.ErrDuplicatePackageVersion {
|
||||
apiError(ctx, http.StatusBadRequest, err)
|
||||
if err == packages_model.ErrDuplicatePackageFile {
|
||||
apiError(ctx, http.StatusConflict, err)
|
||||
return
|
||||
}
|
||||
apiError(ctx, http.StatusInternalServerError, err)
|
||||
|
@ -120,19 +122,13 @@ func UploadPackage(ctx *context.Context) {
|
|||
|
||||
// DeletePackage deletes the specific generic package.
|
||||
func DeletePackage(ctx *context.Context) {
|
||||
packageName, packageVersion, _, err := sanitizeParameters(ctx)
|
||||
if err != nil {
|
||||
apiError(ctx, http.StatusBadRequest, err)
|
||||
return
|
||||
}
|
||||
|
||||
err = packages_service.RemovePackageVersionByNameAndVersion(
|
||||
err := packages_service.RemovePackageVersionByNameAndVersion(
|
||||
ctx.Doer,
|
||||
&packages_service.PackageInfo{
|
||||
Owner: ctx.Package.Owner,
|
||||
PackageType: packages_model.TypeGeneric,
|
||||
Name: packageName,
|
||||
Version: packageVersion,
|
||||
Name: ctx.Params("packagename"),
|
||||
Version: ctx.Params("packageversion"),
|
||||
},
|
||||
)
|
||||
if err != nil {
|
||||
|
@ -144,21 +140,50 @@ func DeletePackage(ctx *context.Context) {
|
|||
return
|
||||
}
|
||||
|
||||
ctx.Status(http.StatusOK)
|
||||
ctx.Status(http.StatusNoContent)
|
||||
}
|
||||
|
||||
func sanitizeParameters(ctx *context.Context) (string, string, string, error) {
|
||||
packageName := ctx.Params("packagename")
|
||||
filename := ctx.Params("filename")
|
||||
|
||||
if !packageNameRegex.MatchString(packageName) || !filenameRegex.MatchString(filename) {
|
||||
return "", "", "", errors.New("Invalid package name or filename")
|
||||
// DeletePackageFile deletes the specific file of a generic package.
|
||||
func DeletePackageFile(ctx *context.Context) {
|
||||
pv, pf, err := func() (*packages_model.PackageVersion, *packages_model.PackageFile, error) {
|
||||
pv, err := packages_model.GetVersionByNameAndVersion(ctx, ctx.Package.Owner.ID, packages_model.TypeGeneric, ctx.Params("packagename"), ctx.Params("packageversion"))
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
packageVersion := strings.TrimSpace(ctx.Params("packageversion"))
|
||||
if packageVersion == "" {
|
||||
return "", "", "", errors.New("Invalid package version")
|
||||
pf, err := packages_model.GetFileForVersionByName(ctx, pv.ID, ctx.Params("filename"), packages_model.EmptyFileKey)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
return packageName, packageVersion, filename, nil
|
||||
return pv, pf, nil
|
||||
}()
|
||||
if err != nil {
|
||||
if err == packages_model.ErrPackageNotExist || err == packages_model.ErrPackageFileNotExist {
|
||||
apiError(ctx, http.StatusNotFound, err)
|
||||
return
|
||||
}
|
||||
apiError(ctx, http.StatusInternalServerError, err)
|
||||
return
|
||||
}
|
||||
|
||||
pfs, err := packages_model.GetFilesByVersionID(ctx, pv.ID)
|
||||
if err != nil {
|
||||
apiError(ctx, http.StatusInternalServerError, err)
|
||||
return
|
||||
}
|
||||
|
||||
if len(pfs) == 1 {
|
||||
if err := packages_service.RemovePackageVersion(ctx.Doer, pv); err != nil {
|
||||
apiError(ctx, http.StatusInternalServerError, err)
|
||||
return
|
||||
}
|
||||
} else {
|
||||
if err := packages_service.DeletePackageFile(ctx, pf); err != nil {
|
||||
apiError(ctx, http.StatusInternalServerError, err)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
ctx.Status(http.StatusNoContent)
|
||||
}
|
||||
|
|