mirror of
https://codeberg.org/forgejo/forgejo.git
synced 2024-12-27 06:03:51 +03:00
Merge branch 'forgejo' into forgejo-federated-star
This commit is contained in:
commit
94be68725a
287 changed files with 2853 additions and 1355 deletions
|
@ -181,7 +181,6 @@ package "code.gitea.io/gitea/modules/git"
|
||||||
func (ErrExecTimeout).Error
|
func (ErrExecTimeout).Error
|
||||||
func (ErrUnsupportedVersion).Error
|
func (ErrUnsupportedVersion).Error
|
||||||
func SetUpdateHook
|
func SetUpdateHook
|
||||||
func GetObjectFormatOfRepo
|
|
||||||
func openRepositoryWithDefaultContext
|
func openRepositoryWithDefaultContext
|
||||||
func IsTagExist
|
func IsTagExist
|
||||||
func ToEntryMode
|
func ToEntryMode
|
||||||
|
@ -320,8 +319,6 @@ package "code.gitea.io/gitea/routers/web"
|
||||||
|
|
||||||
package "code.gitea.io/gitea/routers/web/org"
|
package "code.gitea.io/gitea/routers/web/org"
|
||||||
func MustEnableProjects
|
func MustEnableProjects
|
||||||
func getActionIssues
|
|
||||||
func UpdateIssueProject
|
|
||||||
|
|
||||||
package "code.gitea.io/gitea/services/context"
|
package "code.gitea.io/gitea/services/context"
|
||||||
func GetPrivateContext
|
func GetPrivateContext
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
{
|
{
|
||||||
"name": "Gitea DevContainer",
|
"name": "Gitea DevContainer",
|
||||||
"image": "mcr.microsoft.com/devcontainers/go:1.21-bullseye",
|
"image": "mcr.microsoft.com/devcontainers/go:1.22-bullseye",
|
||||||
"features": {
|
"features": {
|
||||||
// installs nodejs into container
|
// installs nodejs into container
|
||||||
"ghcr.io/devcontainers/features/node:1": {
|
"ghcr.io/devcontainers/features/node:1": {
|
||||||
"version": "20"
|
"version": "20"
|
||||||
},
|
},
|
||||||
"ghcr.io/devcontainers/features/git-lfs:1.1.0": {},
|
"ghcr.io/devcontainers/features/git-lfs:1.2.0": {},
|
||||||
"ghcr.io/devcontainers-contrib/features/poetry:2": {},
|
"ghcr.io/devcontainers-contrib/features/poetry:2": {},
|
||||||
"ghcr.io/devcontainers/features/python:1": {
|
"ghcr.io/devcontainers/features/python:1": {
|
||||||
"version": "3.12"
|
"version": "3.12"
|
||||||
|
|
|
@ -9,7 +9,7 @@ charset = utf-8
|
||||||
trim_trailing_whitespace = true
|
trim_trailing_whitespace = true
|
||||||
insert_final_newline = true
|
insert_final_newline = true
|
||||||
|
|
||||||
[*.{go,tmpl,html}]
|
[{*.{go,tmpl,html},Makefile,go.mod}]
|
||||||
indent_style = tab
|
indent_style = tab
|
||||||
|
|
||||||
[templates/custom/*.tmpl]
|
[templates/custom/*.tmpl]
|
||||||
|
@ -21,8 +21,8 @@ indent_style = space
|
||||||
[templates/user/auth/oidc_wellknown.tmpl]
|
[templates/user/auth/oidc_wellknown.tmpl]
|
||||||
indent_style = space
|
indent_style = space
|
||||||
|
|
||||||
[Makefile]
|
|
||||||
indent_style = tab
|
|
||||||
|
|
||||||
[*.svg]
|
[*.svg]
|
||||||
insert_final_newline = false
|
insert_final_newline = false
|
||||||
|
|
||||||
|
[options/locale/locale_*.ini]
|
||||||
|
insert_final_newline = false
|
||||||
|
|
|
@ -4,6 +4,7 @@ reportUnusedDisableDirectives: true
|
||||||
ignorePatterns:
|
ignorePatterns:
|
||||||
- /web_src/js/vendor
|
- /web_src/js/vendor
|
||||||
- /web_src/fomantic
|
- /web_src/fomantic
|
||||||
|
- /public/assets/js
|
||||||
|
|
||||||
parserOptions:
|
parserOptions:
|
||||||
sourceType: module
|
sourceType: module
|
||||||
|
|
|
@ -22,7 +22,7 @@ jobs:
|
||||||
|
|
||||||
runs-on: docker
|
runs-on: docker
|
||||||
container:
|
container:
|
||||||
image: ghcr.io/visualon/renovate:37.340.9
|
image: ghcr.io/visualon/renovate:37.359.0
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Load renovate repo cache
|
- name: Load renovate repo cache
|
||||||
|
@ -30,6 +30,7 @@ jobs:
|
||||||
with:
|
with:
|
||||||
path: |
|
path: |
|
||||||
.tmp/cache/renovate/repository
|
.tmp/cache/renovate/repository
|
||||||
|
.tmp/osv
|
||||||
key: repo-cache-${{ github.run_id }}
|
key: repo-cache-${{ github.run_id }}
|
||||||
restore-keys: |
|
restore-keys: |
|
||||||
repo-cache-
|
repo-cache-
|
||||||
|
@ -51,10 +52,13 @@ jobs:
|
||||||
GIT_COMMITTER_NAME: 'Renovate Bot'
|
GIT_COMMITTER_NAME: 'Renovate Bot'
|
||||||
GIT_COMMITTER_EMAIL: 'forgejo-renovate-action@forgejo.org'
|
GIT_COMMITTER_EMAIL: 'forgejo-renovate-action@forgejo.org'
|
||||||
|
|
||||||
|
OSV_OFFLINE_ROOT_DIR: ${{ github.workspace }}/.tmp/osv
|
||||||
|
|
||||||
- name: Save renovate repo cache
|
- name: Save renovate repo cache
|
||||||
if: always() && env.RENOVATE_DRY_RUN != 'full'
|
if: always() && env.RENOVATE_DRY_RUN != 'full'
|
||||||
uses: https://code.forgejo.org/actions/cache/save@0c45773b623bea8c8e75f6c82b208c3cf94ea4f9 # v4.0.2
|
uses: https://code.forgejo.org/actions/cache/save@0c45773b623bea8c8e75f6c82b208c3cf94ea4f9 # v4.0.2
|
||||||
with:
|
with:
|
||||||
path: |
|
path: |
|
||||||
.tmp/cache/renovate/repository
|
.tmp/cache/renovate/repository
|
||||||
|
.tmp/osv
|
||||||
key: repo-cache-${{ github.run_id }}
|
key: repo-cache-${{ github.run_id }}
|
||||||
|
|
31
Makefile
31
Makefile
|
@ -29,11 +29,11 @@ XGO_VERSION := go-1.21.x
|
||||||
AIR_PACKAGE ?= github.com/cosmtrek/air@v1 # renovate: datasource=go
|
AIR_PACKAGE ?= github.com/cosmtrek/air@v1 # renovate: datasource=go
|
||||||
EDITORCONFIG_CHECKER_PACKAGE ?= github.com/editorconfig-checker/editorconfig-checker/v2/cmd/editorconfig-checker@2.8.0 # renovate: datasource=go
|
EDITORCONFIG_CHECKER_PACKAGE ?= github.com/editorconfig-checker/editorconfig-checker/v2/cmd/editorconfig-checker@2.8.0 # renovate: datasource=go
|
||||||
GOFUMPT_PACKAGE ?= mvdan.cc/gofumpt@v0.6.0 # renovate: datasource=go
|
GOFUMPT_PACKAGE ?= mvdan.cc/gofumpt@v0.6.0 # renovate: datasource=go
|
||||||
GOLANGCI_LINT_PACKAGE ?= github.com/golangci/golangci-lint/cmd/golangci-lint@v1.57.2 # renovate: datasource=go
|
GOLANGCI_LINT_PACKAGE ?= github.com/golangci/golangci-lint/cmd/golangci-lint@v1.58.1 # renovate: datasource=go
|
||||||
GXZ_PACKAGE ?= github.com/ulikunitz/xz/cmd/gxz@v0.5.11 # renovate: datasource=go
|
GXZ_PACKAGE ?= github.com/ulikunitz/xz/cmd/gxz@v0.5.11 # renovate: datasource=go
|
||||||
MISSPELL_PACKAGE ?= github.com/golangci/misspell/cmd/misspell@v0.4.1 # renovate: datasource=go
|
MISSPELL_PACKAGE ?= github.com/golangci/misspell/cmd/misspell@v0.5.1 # renovate: datasource=go
|
||||||
SWAGGER_PACKAGE ?= github.com/go-swagger/go-swagger/cmd/swagger@v0.30.6-0.20240201115257-bcc7c78b7786 # renovate: datasource=go
|
SWAGGER_PACKAGE ?= github.com/go-swagger/go-swagger/cmd/swagger@v0.30.6-0.20240201115257-bcc7c78b7786 # renovate: datasource=go
|
||||||
XGO_PACKAGE ?= src.techknowlogick.com/xgo@latest # renovate: datasource=go
|
XGO_PACKAGE ?= src.techknowlogick.com/xgo@latest
|
||||||
GO_LICENSES_PACKAGE ?= github.com/google/go-licenses@v1.6.0 # renovate: datasource=go
|
GO_LICENSES_PACKAGE ?= github.com/google/go-licenses@v1.6.0 # renovate: datasource=go
|
||||||
GOVULNCHECK_PACKAGE ?= golang.org/x/vuln/cmd/govulncheck@v1 # renovate: datasource=go
|
GOVULNCHECK_PACKAGE ?= golang.org/x/vuln/cmd/govulncheck@v1 # renovate: datasource=go
|
||||||
ACTIONLINT_PACKAGE ?= github.com/rhysd/actionlint/cmd/actionlint@v1.6.27 # renovate: datasource=go
|
ACTIONLINT_PACKAGE ?= github.com/rhysd/actionlint/cmd/actionlint@v1.6.27 # renovate: datasource=go
|
||||||
|
@ -223,6 +223,9 @@ help:
|
||||||
@echo " - lint-frontend-fix lint frontend files and fix issues"
|
@echo " - lint-frontend-fix lint frontend files and fix issues"
|
||||||
@echo " - lint-backend lint backend files"
|
@echo " - lint-backend lint backend files"
|
||||||
@echo " - lint-backend-fix lint backend files and fix issues"
|
@echo " - lint-backend-fix lint backend files and fix issues"
|
||||||
|
@echo " - lint-codespell lint typos"
|
||||||
|
@echo " - lint-codespell-fix lint typos and fix them automatically"
|
||||||
|
@echo " - lint-codespell-fix-i lint typos and fix them interactively"
|
||||||
@echo " - lint-go lint go files"
|
@echo " - lint-go lint go files"
|
||||||
@echo " - lint-go-fix lint go files and fix issues"
|
@echo " - lint-go-fix lint go files and fix issues"
|
||||||
@echo " - lint-go-vet lint go files with vet"
|
@echo " - lint-go-vet lint go files with vet"
|
||||||
|
@ -334,8 +337,8 @@ ifneq "$(TAGS)" "$(shell cat $(TAGS_EVIDENCE) 2>/dev/null)"
|
||||||
TAGS_PREREQ := $(TAGS_EVIDENCE)
|
TAGS_PREREQ := $(TAGS_EVIDENCE)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
OAPI_CODEGEN_PACKAGE ?= github.com/deepmap/oapi-codegen/cmd/oapi-codegen@v1.12.4 # renovate: datasource=go
|
OAPI_CODEGEN_PACKAGE ?= github.com/deepmap/oapi-codegen/cmd/oapi-codegen@v1.12.4
|
||||||
KIN_OPENAPI_CODEGEN_PACKAGE ?= github.com/getkin/kin-openapi/cmd/validate@v0.114.0 # renovate: datasource=go
|
KIN_OPENAPI_CODEGEN_PACKAGE ?= github.com/getkin/kin-openapi/cmd/validate@v0.114.0
|
||||||
FORGEJO_API_SERVER = routers/api/forgejo/v1/generated.go
|
FORGEJO_API_SERVER = routers/api/forgejo/v1/generated.go
|
||||||
|
|
||||||
.PHONY: generate-forgejo-api
|
.PHONY: generate-forgejo-api
|
||||||
|
@ -398,6 +401,18 @@ lint-backend: lint-go lint-go-vet lint-editorconfig
|
||||||
.PHONY: lint-backend-fix
|
.PHONY: lint-backend-fix
|
||||||
lint-backend-fix: lint-go-fix lint-go-vet lint-editorconfig
|
lint-backend-fix: lint-go-fix lint-go-vet lint-editorconfig
|
||||||
|
|
||||||
|
.PHONY: lint-codespell
|
||||||
|
lint-codespell:
|
||||||
|
codespell
|
||||||
|
|
||||||
|
.PHONY: lint-codespell-fix
|
||||||
|
lint-codespell-fix:
|
||||||
|
codespell -w
|
||||||
|
|
||||||
|
.PHONY: lint-codespell-fix-i
|
||||||
|
lint-codespell-fix-i:
|
||||||
|
codespell -w -i 3 -C 2
|
||||||
|
|
||||||
.PHONY: lint-js
|
.PHONY: lint-js
|
||||||
lint-js: node_modules
|
lint-js: node_modules
|
||||||
npx eslint --color --max-warnings=0 --ext js,vue $(ESLINT_FILES)
|
npx eslint --color --max-warnings=0 --ext js,vue $(ESLINT_FILES)
|
||||||
|
@ -423,11 +438,11 @@ lint-md: node_modules
|
||||||
npx markdownlint docs *.md
|
npx markdownlint docs *.md
|
||||||
|
|
||||||
.PHONY: lint-spell
|
.PHONY: lint-spell
|
||||||
lint-spell:
|
lint-spell: lint-codespell
|
||||||
@go run $(MISSPELL_PACKAGE) -error $(SPELLCHECK_FILES)
|
@go run $(MISSPELL_PACKAGE) -error $(SPELLCHECK_FILES)
|
||||||
|
|
||||||
.PHONY: lint-spell-fix
|
.PHONY: lint-spell-fix
|
||||||
lint-spell-fix:
|
lint-spell-fix: lint-codespell-fix
|
||||||
@go run $(MISSPELL_PACKAGE) -w $(SPELLCHECK_FILES)
|
@go run $(MISSPELL_PACKAGE) -w $(SPELLCHECK_FILES)
|
||||||
|
|
||||||
.PHONY: lint-go
|
.PHONY: lint-go
|
||||||
|
@ -767,7 +782,7 @@ generate-backend: $(TAGS_PREREQ) generate-go
|
||||||
.PHONY: generate-go
|
.PHONY: generate-go
|
||||||
generate-go: $(TAGS_PREREQ)
|
generate-go: $(TAGS_PREREQ)
|
||||||
@echo "Running go generate..."
|
@echo "Running go generate..."
|
||||||
@CC= GOOS= GOARCH= $(GO) generate -tags '$(TAGS)' ./...
|
@CC= GOOS= GOARCH= CGO_ENABLED=0 $(GO) generate -tags '$(TAGS)' ./...
|
||||||
|
|
||||||
.PHONY: merge-locales
|
.PHONY: merge-locales
|
||||||
merge-locales:
|
merge-locales:
|
||||||
|
|
|
@ -6,7 +6,7 @@ A [patch or minor release](https://semver.org/spec/v2.0.0.html) (e.g. upgrading
|
||||||
|
|
||||||
## Upcoming releases (not available yet)
|
## Upcoming releases (not available yet)
|
||||||
|
|
||||||
- [8.0.0](/release-notes/8.0.0/)
|
- [8.0.0](release-notes/8.0.0/)
|
||||||
|
|
||||||
## 7.0.2
|
## 7.0.2
|
||||||
|
|
||||||
|
@ -512,7 +512,7 @@ This stable release contains a single bug fix for a regression introduced in v1.
|
||||||
|
|
||||||
## 1.21.11-0
|
## 1.21.11-0
|
||||||
|
|
||||||
[The complete list of new commits included in the Forgejo v1.21.11-0 release can be reviewed here](https://codeberg.org/forgejo/forgejo/compare/v1.21.10-0...v1.21.11-0), or from the comand line with:
|
[The complete list of new commits included in the Forgejo v1.21.11-0 release can be reviewed here](https://codeberg.org/forgejo/forgejo/compare/v1.21.10-0...v1.21.11-0), or from the command line with:
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
$ git clone https://codeberg.org/forgejo/forgejo
|
$ git clone https://codeberg.org/forgejo/forgejo
|
||||||
|
@ -580,7 +580,7 @@ Note that there is no `Forgejo v1.21.9-0` release. The release numbering of the
|
||||||
* [Fix paths when finding files via the web interface that were not escaped](https://codeberg.org/forgejo/forgejo/commit/b22be0c03fa4814c1b8b892346de5d4547782ce7).
|
* [Fix paths when finding files via the web interface that were not escaped](https://codeberg.org/forgejo/forgejo/commit/b22be0c03fa4814c1b8b892346de5d4547782ce7).
|
||||||
* [Respect `DEFAULT_ORG_MEMBER_VISIBLE` setting when adding creator to org](https://codeberg.org/forgejo/forgejo/commit/5e5574c7b328e2c500d497517047b8d1fd0ca478).
|
* [Respect `DEFAULT_ORG_MEMBER_VISIBLE` setting when adding creator to org](https://codeberg.org/forgejo/forgejo/commit/5e5574c7b328e2c500d497517047b8d1fd0ca478).
|
||||||
* [Fix duplicate migrated milestones](https://codeberg.org/forgejo/forgejo/commit/706ff7aa9fcfe4c43893dc12e27d064064e80635).
|
* [Fix duplicate migrated milestones](https://codeberg.org/forgejo/forgejo/commit/706ff7aa9fcfe4c43893dc12e27d064064e80635).
|
||||||
* [Fix inline math blocks can't be preceeded/followed by alphanumerical characters](https://codeberg.org/forgejo/forgejo/commit/0d3f446460b22a29c259e7d42ed89f90fd216ca7).
|
* [Fix inline math blocks can't be preceded/followed by alphanumerical characters](https://codeberg.org/forgejo/forgejo/commit/0d3f446460b22a29c259e7d42ed89f90fd216ca7).
|
||||||
|
|
||||||
## 1.21.8-0
|
## 1.21.8-0
|
||||||
|
|
||||||
|
@ -687,7 +687,7 @@ This stable release contains bug fixes and a **security fix**, as explained in t
|
||||||
* [Fix push to create with capitalize repo name](https://codeberg.org/forgejo/forgejo/commit/8782275c9c66ad6fc7c44503d7df9dae7196aa65).
|
* [Fix push to create with capitalize repo name](https://codeberg.org/forgejo/forgejo/commit/8782275c9c66ad6fc7c44503d7df9dae7196aa65).
|
||||||
* In Markdown [don't try to make the link absolute if the link has a schema that's defined in `[markdown].CUSTOM_URL_SCHEMES`](https://codeberg.org/forgejo/forgejo/commit/6c100083c29fb0ccf0cc52e8767e540a260d9468), because they can't be made absolute.
|
* In Markdown [don't try to make the link absolute if the link has a schema that's defined in `[markdown].CUSTOM_URL_SCHEMES`](https://codeberg.org/forgejo/forgejo/commit/6c100083c29fb0ccf0cc52e8767e540a260d9468), because they can't be made absolute.
|
||||||
* [Fix Ctrl+Enter on submitting review comment](https://codeberg.org/forgejo/forgejo/commit/1c3a31d85112d10fb948d6f0b763191ed6f68e90).
|
* [Fix Ctrl+Enter on submitting review comment](https://codeberg.org/forgejo/forgejo/commit/1c3a31d85112d10fb948d6f0b763191ed6f68e90).
|
||||||
* In Git version v2.43.1, the behavior of `GIT_FLUSH` was accidentially flipped. This causes Forgejo to hang on the `check-attr` command, because no output was being flushed. [Workaround this by detecting if Git v2.43.1 is used and set `GIT_FLUSH=0` thus getting the correct behavior](https://codeberg.org/forgejo/forgejo/commit/ff468ab5e426582b068586ce13d5a5348365e783).
|
* In Git version v2.43.1, the behavior of `GIT_FLUSH` was accidentally flipped. This causes Forgejo to hang on the `check-attr` command, because no output was being flushed. [Workaround this by detecting if Git v2.43.1 is used and set `GIT_FLUSH=0` thus getting the correct behavior](https://codeberg.org/forgejo/forgejo/commit/ff468ab5e426582b068586ce13d5a5348365e783).
|
||||||
* [When setting `url.host` on a URL object with no port specified (like is the case of default port), the resulting URL's port will not change. Workaround this quirk in the URL standard by explicitly setting port for the http and https protocols](https://codeberg.org/forgejo/forgejo/commit/628e1036cfbcfae442cb6494249fe11410447056).
|
* [When setting `url.host` on a URL object with no port specified (like is the case of default port), the resulting URL's port will not change. Workaround this quirk in the URL standard by explicitly setting port for the http and https protocols](https://codeberg.org/forgejo/forgejo/commit/628e1036cfbcfae442cb6494249fe11410447056).
|
||||||
* [Fix elasticsearch Request Entity Too Large](https://codeberg.org/forgejo/forgejo/commit/e6f59f6e1489d63d53de0da1de406a7a71a82adb).
|
* [Fix elasticsearch Request Entity Too Large](https://codeberg.org/forgejo/forgejo/commit/e6f59f6e1489d63d53de0da1de406a7a71a82adb).
|
||||||
* [Do not send update/delete release notifications when it is in a draft state](https://codeberg.org/forgejo/forgejo/commit/3c54a1dbf62e56d948feb1008512900140033737).
|
* [Do not send update/delete release notifications when it is in a draft state](https://codeberg.org/forgejo/forgejo/commit/3c54a1dbf62e56d948feb1008512900140033737).
|
||||||
|
@ -777,7 +777,7 @@ This stable release includes security and bug fixes as well as documentation imp
|
||||||
* [Gracefully handle missing branches](https://codeberg.org/forgejo/forgejo/commit/c2fa9c308f5cdb08dd84fb8ec6623a57e75d5152) when a branch is missing from Git but still lingering in the database.
|
* [Gracefully handle missing branches](https://codeberg.org/forgejo/forgejo/commit/c2fa9c308f5cdb08dd84fb8ec6623a57e75d5152) when a branch is missing from Git but still lingering in the database.
|
||||||
* [Fix panic in `canSoftDeleteContentHistory`](https://codeberg.org/forgejo/forgejo/commit/ab1ccc55dca7fd05e59a01343e6dfe53be6195d0)
|
* [Fix panic in `canSoftDeleteContentHistory`](https://codeberg.org/forgejo/forgejo/commit/ab1ccc55dca7fd05e59a01343e6dfe53be6195d0)
|
||||||
* [Check for Commit in opengraph](https://codeberg.org/forgejo/forgejo/commit/b473a44a2bb59591f3e24bfcdeed1d8fbb0f9204)
|
* [Check for Commit in opengraph](https://codeberg.org/forgejo/forgejo/commit/b473a44a2bb59591f3e24bfcdeed1d8fbb0f9204)
|
||||||
* [Handle non-existant commit in Archive request](https://codeberg.org/forgejo/forgejo/commit/0fbf761d1930f9336be6da8d17ae6032203a9381)
|
* [Handle non-existent commit in Archive request](https://codeberg.org/forgejo/forgejo/commit/0fbf761d1930f9336be6da8d17ae6032203a9381)
|
||||||
* [Fix NPE in `ToPullReviewList`](https://codeberg.org/forgejo/forgejo/commit/f5349b66b78968301d7dc4c45e8e08b46910aa6e)
|
* [Fix NPE in `ToPullReviewList`](https://codeberg.org/forgejo/forgejo/commit/f5349b66b78968301d7dc4c45e8e08b46910aa6e)
|
||||||
* [Fix URL in the mail to include the host](https://codeberg.org/forgejo/forgejo/commit/ac889d42903b2ce2129a02ace620a10a6f940920)
|
* [Fix URL in the mail to include the host](https://codeberg.org/forgejo/forgejo/commit/ac889d42903b2ce2129a02ace620a10a6f940920)
|
||||||
* [Fix the event of a scheduled action](https://codeberg.org/forgejo/forgejo/commit/892a8e1f4a5cc09cc3136e0b0e6487c154c5ed2b) to be "schedule" instead of a semi-random event from the default branch.
|
* [Fix the event of a scheduled action](https://codeberg.org/forgejo/forgejo/commit/892a8e1f4a5cc09cc3136e0b0e6487c154c5ed2b) to be "schedule" instead of a semi-random event from the default branch.
|
||||||
|
@ -888,7 +888,7 @@ $ git clone https://codeberg.org/forgejo/forgejo/
|
||||||
$ git -C forgejo log --oneline --no-merges v1.21.1-0..v1.21.2-0
|
$ git -C forgejo log --oneline --no-merges v1.21.1-0..v1.21.2-0
|
||||||
```
|
```
|
||||||
|
|
||||||
This stable release includes bug fixes. It was built with Go v1.21.5 that fixes [CVE-2023-39326](https://groups.google.com/g/golang-announce/c/iLGK3x6yuNo) which a malicious HTTP client can exploit to cause a server to automatically read a large amount of data. It allows for memory exhaustion in the situation that HTTP chuncked encoding requests can reach Forgejo.
|
This stable release includes bug fixes. It was built with Go v1.21.5 that fixes [CVE-2023-39326](https://groups.google.com/g/golang-announce/c/iLGK3x6yuNo) which a malicious HTTP client can exploit to cause a server to automatically read a large amount of data. It allows for memory exhaustion in the situation that HTTP chunked encoding requests can reach Forgejo.
|
||||||
|
|
||||||
* Recommended Action
|
* Recommended Action
|
||||||
|
|
||||||
|
@ -953,7 +953,7 @@ $ git -C forgejo log --oneline --no-merges origin/v1.20/forgejo..origin/v1.21/fo
|
||||||
- [Add](https://codeberg.org/forgejo/forgejo/commit/0d55f64e6cd3de2e1e5c0ee795605823efb14231) support for [recurring actions similar to cron jobs](https://forgejo.org/docs/v1.21/user/actions/#onschedule).
|
- [Add](https://codeberg.org/forgejo/forgejo/commit/0d55f64e6cd3de2e1e5c0ee795605823efb14231) support for [recurring actions similar to cron jobs](https://forgejo.org/docs/v1.21/user/actions/#onschedule).
|
||||||
- [Add](https://codeberg.org/forgejo/forgejo/commit/19872063a3c14256a1d89b2a104d63e7538a3a28) the possibility to [disable workflows from the user interface](https://forgejo.org/docs/v1.21/user/actions/#list-of-runners-and-their-tasks).
|
- [Add](https://codeberg.org/forgejo/forgejo/commit/19872063a3c14256a1d89b2a104d63e7538a3a28) the possibility to [disable workflows from the user interface](https://forgejo.org/docs/v1.21/user/actions/#list-of-runners-and-their-tasks).
|
||||||
- [Add](https://codeberg.org/forgejo/forgejo/commit/460a2b0edffe71d9e64633beaa1071fcf4a33369) automatic [cleanup of artificats](https://forgejo.org/docs/v1.21/user/actions/#artifacts).
|
- [Add](https://codeberg.org/forgejo/forgejo/commit/460a2b0edffe71d9e64633beaa1071fcf4a33369) automatic [cleanup of artificats](https://forgejo.org/docs/v1.21/user/actions/#artifacts).
|
||||||
- [Add](https://codeberg.org/forgejo/forgejo/commit/44781f9f5c4ede618660d8cfe42437f0e8dc22a0) automatic cancelation [of jobs when pushing new commits](https://forgejo.org/docs/v1.21/user/actions/#auto-cancelation-of-workflows) to a PR.
|
- [Add](https://codeberg.org/forgejo/forgejo/commit/44781f9f5c4ede618660d8cfe42437f0e8dc22a0) automatic cancellation [of jobs when pushing new commits](https://forgejo.org/docs/v1.21/user/actions/#auto-cancellation-of-workflows) to a PR.
|
||||||
- [Add](https://codeberg.org/forgejo/forgejo/commit/f3d293d2bbe0b2eab047bdd403046069cffbc0c4) support for [uploading multiple artificats](https://forgejo.org/docs/v1.21/user/actions/#artifacts).
|
- [Add](https://codeberg.org/forgejo/forgejo/commit/f3d293d2bbe0b2eab047bdd403046069cffbc0c4) support for [uploading multiple artificats](https://forgejo.org/docs/v1.21/user/actions/#artifacts).
|
||||||
- [Add](https://codeberg.org/forgejo/forgejo/commit/48e5a74f215d78813a816c57fc5a85a909a003d5) support for the [`pull_request_target` event](https://forgejo.org/docs/v1.21/user/actions/#onpull_request_target) which has access to secrets because it runs using the workflows from the base branch instead of the pull request.
|
- [Add](https://codeberg.org/forgejo/forgejo/commit/48e5a74f215d78813a816c57fc5a85a909a003d5) support for the [`pull_request_target` event](https://forgejo.org/docs/v1.21/user/actions/#onpull_request_target) which has access to secrets because it runs using the workflows from the base branch instead of the pull request.
|
||||||
- [Add](https://codeberg.org/forgejo/forgejo/commit/8228751c55d6a4263f0fec2932ca16181c09c97d) support for reading labels from the runner [instead of specifying them during registration](https://forgejo.org/docs/v1.21/admin/actions/#registration).
|
- [Add](https://codeberg.org/forgejo/forgejo/commit/8228751c55d6a4263f0fec2932ca16181c09c97d) support for reading labels from the runner [instead of specifying them during registration](https://forgejo.org/docs/v1.21/admin/actions/#registration).
|
||||||
|
@ -1268,7 +1268,7 @@ this situation, [follow the instructions in the companion blog post](https://for
|
||||||
* [The CLI exit code now is different from zero when an error occurs](https://codeberg.org/forgejo/forgejo/commit/089af9ab1)
|
* [The CLI exit code now is different from zero when an error occurs](https://codeberg.org/forgejo/forgejo/commit/089af9ab1)
|
||||||
* [Fix error when a Debian package has a double newline character at the end of the control block](https://codeberg.org/forgejo/forgejo/commit/dd7180846)
|
* [Fix error when a Debian package has a double newline character at the end of the control block](https://codeberg.org/forgejo/forgejo/commit/dd7180846)
|
||||||
* [Fix a condition that would cause git related tasks to hang for longer than necessary in the queues and use too many resources as a result](https://codeberg.org/forgejo/forgejo/commit/36f8fbe1b)
|
* [Fix a condition that would cause git related tasks to hang for longer than necessary in the queues and use too many resources as a result](https://codeberg.org/forgejo/forgejo/commit/36f8fbe1b)
|
||||||
* [Fix the topic validation rule and suport dots](https://codeberg.org/forgejo/forgejo/commit/a578b75d7)
|
* [Fix the topic validation rule and support dots](https://codeberg.org/forgejo/forgejo/commit/a578b75d7)
|
||||||
* [Fix pull request check list when there are more than 30](https://codeberg.org/forgejo/forgejo/commit/e226b9646)
|
* [Fix pull request check list when there are more than 30](https://codeberg.org/forgejo/forgejo/commit/e226b9646)
|
||||||
* [Fix attachment clipboard copy on insecure origin](https://codeberg.org/forgejo/forgejo/commit/12ac84c26)
|
* [Fix attachment clipboard copy on insecure origin](https://codeberg.org/forgejo/forgejo/commit/12ac84c26)
|
||||||
* [Fix the profile README rendering](https://codeberg.org/forgejo/forgejo/commit/84c3b60a4) that [was inconsistent with other markdown files renderings](https://codeberg.org/forgejo/forgejo/issues/833)
|
* [Fix the profile README rendering](https://codeberg.org/forgejo/forgejo/commit/84c3b60a4) that [was inconsistent with other markdown files renderings](https://codeberg.org/forgejo/forgejo/issues/833)
|
||||||
|
@ -1297,7 +1297,7 @@ This stable release includes bug fixes and displays [warnings in the administrat
|
||||||
|
|
||||||
The most prominent ones are described here, others can be found in the list of commits included in the release as described above.
|
The most prominent ones are described here, others can be found in the list of commits included in the release as described above.
|
||||||
|
|
||||||
* [Add missing assets to the Forgejo sources tarbal](https://codeberg.org/forgejo/forgejo/commit/e14d239005)
|
* [Add missing assets to the Forgejo sources tarball](https://codeberg.org/forgejo/forgejo/commit/e14d239005)
|
||||||
* [Fix user type selection error when creating a user](https://codeberg.org/forgejo/forgejo/commit/268569b462) and selecting `public` or `private`.
|
* [Fix user type selection error when creating a user](https://codeberg.org/forgejo/forgejo/commit/268569b462) and selecting `public` or `private`.
|
||||||
* [Fix access check for org-level project](https://codeberg.org/forgejo/forgejo/commit/5afb0294f4)
|
* [Fix access check for org-level project](https://codeberg.org/forgejo/forgejo/commit/5afb0294f4)
|
||||||
* [Warn instead of reporting an error when a webhook cannot be found](https://codeberg.org/forgejo/forgejo/commit/4c3dcdf815)
|
* [Warn instead of reporting an error when a webhook cannot be found](https://codeberg.org/forgejo/forgejo/commit/4c3dcdf815)
|
||||||
|
@ -1352,7 +1352,7 @@ $ git -C forgejo log --oneline --no-merges origin/v1.19/forgejo..origin/v1.20/fo
|
||||||
- The storage settings were [refactored](https://codeberg.org/forgejo/forgejo/commit/d6dd6d641b593c54fe1a1041c153111ce81dbc20). Read more about [storage settings](https://forgejo.org/docs/v1.20/admin/storage/).
|
- The storage settings were [refactored](https://codeberg.org/forgejo/forgejo/commit/d6dd6d641b593c54fe1a1041c153111ce81dbc20). Read more about [storage settings](https://forgejo.org/docs/v1.20/admin/storage/).
|
||||||
- [The [repository.editor] PREVIEWABLE_FILE_MODES setting was removed](https://codeberg.org/forgejo/forgejo/commit/84daddc2fa74393cdc13371b0cc44f0444cfdae0). This setting served no practical purpose and was not working correctly. Instead a preview tab is always shown in the file editor when supported.
|
- [The [repository.editor] PREVIEWABLE_FILE_MODES setting was removed](https://codeberg.org/forgejo/forgejo/commit/84daddc2fa74393cdc13371b0cc44f0444cfdae0). This setting served no practical purpose and was not working correctly. Instead a preview tab is always shown in the file editor when supported.
|
||||||
- In addition to the already deprecated options inside [queue], many options have been dropped as well. Those are WRAP_IF_NECESSARY, MAX_ATTEMPTS, TIMEOUT, WORKERS, BLOCK_TIMEOUT, BOOST_TIMEOUT, BOOST_WORKERS. You can remove them from your app.ini now. Additionally, some default values have changed in this section.
|
- In addition to the already deprecated options inside [queue], many options have been dropped as well. Those are WRAP_IF_NECESSARY, MAX_ATTEMPTS, TIMEOUT, WORKERS, BLOCK_TIMEOUT, BOOST_TIMEOUT, BOOST_WORKERS. You can remove them from your app.ini now. Additionally, some default values have changed in this section.
|
||||||
- The default CSS and templates included in Forgejo were heavily refactored and a large number of variables renamed. These changes are not documented and there is a very high chance that a tempate extracted and modified for a particular Forgejo instance will no longer work as it did. Browsing through the git history of the template in the sources is the best way to figure out how and why it was modified.
|
- The default CSS and templates included in Forgejo were heavily refactored and a large number of variables renamed. These changes are not documented and there is a very high chance that a template extracted and modified for a particular Forgejo instance will no longer work as it did. Browsing through the git history of the template in the sources is the best way to figure out how and why it was modified.
|
||||||
- **Moderation:**
|
- **Moderation:**
|
||||||
Blocking another user is desirable if they are acting maliciously or are spamming your repository. When you block a user, Forgejo does not explicitly notify them, but they may learn through an interaction with you that is blocked. [Read more about blocking users](https://forgejo.org/docs/v1.20/user/blocking-user/).
|
Blocking another user is desirable if they are acting maliciously or are spamming your repository. When you block a user, Forgejo does not explicitly notify them, but they may learn through an interaction with you that is blocked. [Read more about blocking users](https://forgejo.org/docs/v1.20/user/blocking-user/).
|
||||||
- **Package:**
|
- **Package:**
|
||||||
|
@ -1360,7 +1360,7 @@ $ git -C forgejo log --oneline --no-merges origin/v1.19/forgejo..origin/v1.20/fo
|
||||||
- **Accessibility:**
|
- **Accessibility:**
|
||||||
numerous improvements for [issue comments](https://codeberg.org/forgejo/forgejo/commit/6c354546547cd3a9595a7db119a6480d9cd506a7), [the menu on the navbar](https://codeberg.org/forgejo/forgejo/commit/a78e0b7dade16bc6509b943fe86e74962f1b95b6), [scoped labels](https://codeberg.org/forgejo/forgejo/commit/e8935606f5f1fff3c59222ebca6d4615ab06fb0b), [checkboxes and dropdowns](https://codeberg.org/forgejo/forgejo/commit/d4f35bd681af0632da988e15306f330e020422b2), [RTL rendering support to Markdown](https://codeberg.org/forgejo/forgejo/commit/32d9c47ec7706d8f06e09b42e09a28d7a0e3c526), [file (re-)views](https://codeberg.org/forgejo/forgejo/commit/e95b42e187cde9ac4bd541cd714bdb4f5c1fd8bc), [interactive tooltips](https://codeberg.org/forgejo/forgejo/commit/87f0f7e670c6c0e6aeab8c4458bfdb9d954eacec), [using a button element](https://codeberg.org/forgejo/forgejo/commit/81fe5d61851c0e586af7d32c29171ceff9a571bb), [repository list](https://codeberg.org/forgejo/forgejo/commit/e82f1b15c7120ad13fd3b67cf7e2c6cb9915c22d) and more.
|
numerous improvements for [issue comments](https://codeberg.org/forgejo/forgejo/commit/6c354546547cd3a9595a7db119a6480d9cd506a7), [the menu on the navbar](https://codeberg.org/forgejo/forgejo/commit/a78e0b7dade16bc6509b943fe86e74962f1b95b6), [scoped labels](https://codeberg.org/forgejo/forgejo/commit/e8935606f5f1fff3c59222ebca6d4615ab06fb0b), [checkboxes and dropdowns](https://codeberg.org/forgejo/forgejo/commit/d4f35bd681af0632da988e15306f330e020422b2), [RTL rendering support to Markdown](https://codeberg.org/forgejo/forgejo/commit/32d9c47ec7706d8f06e09b42e09a28d7a0e3c526), [file (re-)views](https://codeberg.org/forgejo/forgejo/commit/e95b42e187cde9ac4bd541cd714bdb4f5c1fd8bc), [interactive tooltips](https://codeberg.org/forgejo/forgejo/commit/87f0f7e670c6c0e6aeab8c4458bfdb9d954eacec), [using a button element](https://codeberg.org/forgejo/forgejo/commit/81fe5d61851c0e586af7d32c29171ceff9a571bb), [repository list](https://codeberg.org/forgejo/forgejo/commit/e82f1b15c7120ad13fd3b67cf7e2c6cb9915c22d) and more.
|
||||||
- **Time:**
|
- **Time:**
|
||||||
The display and localization of time was improved for [tooltips](https://codeberg.org/forgejo/forgejo/commit/b7b58348317cbe0145dc453d45c886b8e2764b4c), [milestones](https://codeberg.org/forgejo/forgejo/commit/97176754beb4de23fa0f68df715c4737919c93b0), [due date and translations that contain dates](https://codeberg.org/forgejo/forgejo/commit/70bb4984cdad9a15d676708bd345b590aa42d72a), [commit graphs](https://codeberg.org/forgejo/forgejo/commit/5bc9f7fcf9aece92c3fa2a0ea56e5585261a7f28), [runners](https://codeberg.org/forgejo/forgejo/commit/62ca5825f73ad5a25ffeb6c3ef66f0eaf5d30cdf), [webhooks](https://codeberg.org/forgejo/forgejo/commit/dbb37367854d108ebfffcac27837c0afac199a8e), [tests](https://codeberg.org/forgejo/forgejo/commit/3d266dd0f3dbae7e417c0e790e266aebc0078814) and more. Previously each rendered timestamp would be static, now the real time since an event happend is show. If a comment was added 2 minutes before the page rendered it would show as "2 minutes ago" on the initial render and if another 8 minutes have passed, without a page refresh you'd see "10 minutes ago".
|
The display and localization of time was improved for [tooltips](https://codeberg.org/forgejo/forgejo/commit/b7b58348317cbe0145dc453d45c886b8e2764b4c), [milestones](https://codeberg.org/forgejo/forgejo/commit/97176754beb4de23fa0f68df715c4737919c93b0), [due date and translations that contain dates](https://codeberg.org/forgejo/forgejo/commit/70bb4984cdad9a15d676708bd345b590aa42d72a), [commit graphs](https://codeberg.org/forgejo/forgejo/commit/5bc9f7fcf9aece92c3fa2a0ea56e5585261a7f28), [runners](https://codeberg.org/forgejo/forgejo/commit/62ca5825f73ad5a25ffeb6c3ef66f0eaf5d30cdf), [webhooks](https://codeberg.org/forgejo/forgejo/commit/dbb37367854d108ebfffcac27837c0afac199a8e), [tests](https://codeberg.org/forgejo/forgejo/commit/3d266dd0f3dbae7e417c0e790e266aebc0078814) and more. Previously each rendered timestamp would be static, now the real time since an event happened is show. If a comment was added 2 minutes before the page rendered it would show as "2 minutes ago" on the initial render and if another 8 minutes have passed, without a page refresh you'd see "10 minutes ago".
|
||||||
- **[Wiki](https://forgejo.org/docs/v1.20/user/wiki/)**
|
- **[Wiki](https://forgejo.org/docs/v1.20/user/wiki/)**
|
||||||
- Improve the [display of the table of content](https://codeberg.org/forgejo/forgejo/commit/1ab16e48cccc086e7f97fb3ae8a293fe47a3a452)
|
- Improve the [display of the table of content](https://codeberg.org/forgejo/forgejo/commit/1ab16e48cccc086e7f97fb3ae8a293fe47a3a452)
|
||||||
- Fixed a bug [preventing team users who have wiki write permission from deleting a page](https://codeberg.org/forgejo/forgejo/commit/284b41f45244bbe46fc8feee15bbfdf66d150e79)
|
- Fixed a bug [preventing team users who have wiki write permission from deleting a page](https://codeberg.org/forgejo/forgejo/commit/284b41f45244bbe46fc8feee15bbfdf66d150e79)
|
||||||
|
@ -1701,7 +1701,7 @@ $ git -C forgejo log --oneline --no-merges origin/v1.18/forgejo..origin/v1.19/fo
|
||||||
|
|
||||||
Forgejo access token, used with the [API](https://forgejo.org/docs/v1.19/admin/api-usage/) can now have a "scope" that limits what it can access. Existing tokens stored in the database and created before Forgejo v1.19 had unlimited access. For backward compatibility, their access will remain the same and they will continue to work as before. However, **newly created token that do not specify a scope will now only have read-only access to public user profile and public repositories**.
|
Forgejo access token, used with the [API](https://forgejo.org/docs/v1.19/admin/api-usage/) can now have a "scope" that limits what it can access. Existing tokens stored in the database and created before Forgejo v1.19 had unlimited access. For backward compatibility, their access will remain the same and they will continue to work as before. However, **newly created token that do not specify a scope will now only have read-only access to public user profile and public repositories**.
|
||||||
|
|
||||||
For instance, the `/users/{username}/tokens` API endpoint will require the `scopes: ['all', 'sudo']` parameter and the `forgejo admin user generate-access-token` will require the `--scopes all,sudo` argument obtain tokens with ulimited access as before for admin users.
|
For instance, the `/users/{username}/tokens` API endpoint will require the `scopes: ['all', 'sudo']` parameter and the `forgejo admin user generate-access-token` will require the `--scopes all,sudo` argument obtain tokens with unlimited access as before for admin users.
|
||||||
|
|
||||||
[Read more about the scoped tokens](https://forgejo.org/docs/v1.19/user/oauth2-provider/#scoped-tokens).
|
[Read more about the scoped tokens](https://forgejo.org/docs/v1.19/user/oauth2-provider/#scoped-tokens).
|
||||||
|
|
||||||
|
@ -1818,7 +1818,7 @@ $ git -C forgejo log --oneline --no-merges origin/v1.18/forgejo..origin/v1.19/fo
|
||||||
|
|
||||||
It appears for the first time in this Forgejo release but is not yet fit for production. It is not fully implemented and may be insecure. However, as long as it is not enabled, it presents no risk to existing Forgejo instances.
|
It appears for the first time in this Forgejo release but is not yet fit for production. It is not fully implemented and may be insecure. However, as long as it is not enabled, it presents no risk to existing Forgejo instances.
|
||||||
|
|
||||||
If a repository has a file such as `.forgejo/workflows/test.yml`, it will be interpreted, for instance to run tests and verify the code in the repository works as expected (Continuous Integration). It can also be used to create HTML pages for a website and publish them (Continous Deployment). The syntax is similar to GitHub Actions and the jobs can be controled from the Forgejo web interface.
|
If a repository has a file such as `.forgejo/workflows/test.yml`, it will be interpreted, for instance to run tests and verify the code in the repository works as expected (Continuous Integration). It can also be used to create HTML pages for a website and publish them (Continuous Deployment). The syntax is similar to GitHub Actions and the jobs can be controlled from the Forgejo web interface.
|
||||||
|
|
||||||
[Read more about Forgejo Actions](https://forgejo.codeberg.page/2023-02-27-forgejo-actions/)
|
[Read more about Forgejo Actions](https://forgejo.codeberg.page/2023-02-27-forgejo-actions/)
|
||||||
|
|
||||||
|
|
26
assets/go-licenses.json
generated
26
assets/go-licenses.json
generated
File diff suppressed because one or more lines are too long
|
@ -366,6 +366,7 @@ Forgejo or set your environment appropriately.`, "")
|
||||||
isWiki, _ := strconv.ParseBool(os.Getenv(repo_module.EnvRepoIsWiki))
|
isWiki, _ := strconv.ParseBool(os.Getenv(repo_module.EnvRepoIsWiki))
|
||||||
repoName := os.Getenv(repo_module.EnvRepoName)
|
repoName := os.Getenv(repo_module.EnvRepoName)
|
||||||
pusherID, _ := strconv.ParseInt(os.Getenv(repo_module.EnvPusherID), 10, 64)
|
pusherID, _ := strconv.ParseInt(os.Getenv(repo_module.EnvPusherID), 10, 64)
|
||||||
|
prID, _ := strconv.ParseInt(os.Getenv(repo_module.EnvPRID), 10, 64)
|
||||||
pusherName := os.Getenv(repo_module.EnvPusherName)
|
pusherName := os.Getenv(repo_module.EnvPusherName)
|
||||||
|
|
||||||
hookOptions := private.HookOptions{
|
hookOptions := private.HookOptions{
|
||||||
|
@ -375,6 +376,8 @@ Forgejo or set your environment appropriately.`, "")
|
||||||
GitObjectDirectory: os.Getenv(private.GitObjectDirectory),
|
GitObjectDirectory: os.Getenv(private.GitObjectDirectory),
|
||||||
GitQuarantinePath: os.Getenv(private.GitQuarantinePath),
|
GitQuarantinePath: os.Getenv(private.GitQuarantinePath),
|
||||||
GitPushOptions: pushOptions(),
|
GitPushOptions: pushOptions(),
|
||||||
|
PullRequestID: prID,
|
||||||
|
PushTrigger: repo_module.PushTrigger(os.Getenv(repo_module.EnvPushTrigger)),
|
||||||
}
|
}
|
||||||
oldCommitIDs := make([]string, hookBatchSize)
|
oldCommitIDs := make([]string, hookBatchSize)
|
||||||
newCommitIDs := make([]string, hookBatchSize)
|
newCommitIDs := make([]string, hookBatchSize)
|
||||||
|
|
|
@ -34,7 +34,7 @@ var CmdMigrateStorage = &cli.Command{
|
||||||
Name: "type",
|
Name: "type",
|
||||||
Aliases: []string{"t"},
|
Aliases: []string{"t"},
|
||||||
Value: "",
|
Value: "",
|
||||||
Usage: "Type of stored files to copy. Allowed types: 'attachments', 'lfs', 'avatars', 'repo-avatars', 'repo-archivers', 'packages', 'actions-log'",
|
Usage: "Type of stored files to copy. Allowed types: 'attachments', 'lfs', 'avatars', 'repo-avatars', 'repo-archivers', 'packages', 'actions-log', 'actions-artifacts",
|
||||||
},
|
},
|
||||||
&cli.StringFlag{
|
&cli.StringFlag{
|
||||||
Name: "storage",
|
Name: "storage",
|
||||||
|
@ -160,6 +160,13 @@ func migrateActionsLog(ctx context.Context, dstStorage storage.ObjectStorage) er
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func migrateActionsArtifacts(ctx context.Context, dstStorage storage.ObjectStorage) error {
|
||||||
|
return db.Iterate(ctx, nil, func(ctx context.Context, artifact *actions_model.ActionArtifact) error {
|
||||||
|
_, err := storage.Copy(dstStorage, artifact.ArtifactPath, storage.ActionsArtifacts, artifact.ArtifactPath)
|
||||||
|
return err
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
func runMigrateStorage(ctx *cli.Context) error {
|
func runMigrateStorage(ctx *cli.Context) error {
|
||||||
stdCtx, cancel := installSignals()
|
stdCtx, cancel := installSignals()
|
||||||
defer cancel()
|
defer cancel()
|
||||||
|
@ -223,13 +230,14 @@ func runMigrateStorage(ctx *cli.Context) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
migratedMethods := map[string]func(context.Context, storage.ObjectStorage) error{
|
migratedMethods := map[string]func(context.Context, storage.ObjectStorage) error{
|
||||||
"attachments": migrateAttachments,
|
"attachments": migrateAttachments,
|
||||||
"lfs": migrateLFS,
|
"lfs": migrateLFS,
|
||||||
"avatars": migrateAvatars,
|
"avatars": migrateAvatars,
|
||||||
"repo-avatars": migrateRepoAvatars,
|
"repo-avatars": migrateRepoAvatars,
|
||||||
"repo-archivers": migrateRepoArchivers,
|
"repo-archivers": migrateRepoArchivers,
|
||||||
"packages": migratePackages,
|
"packages": migratePackages,
|
||||||
"actions-log": migrateActionsLog,
|
"actions-log": migrateActionsLog,
|
||||||
|
"actions-artifacts": migrateActionsArtifacts,
|
||||||
}
|
}
|
||||||
|
|
||||||
tp := strings.ToLower(ctx.String("type"))
|
tp := strings.ToLower(ctx.String("type"))
|
||||||
|
|
|
@ -11,7 +11,7 @@ The default version will read from `docs/config.yml`. You can override this
|
||||||
using the option `--version`.
|
using the option `--version`.
|
||||||
|
|
||||||
The upstream branches will be fetched, using the remote `origin`. This can
|
The upstream branches will be fetched, using the remote `origin`. This can
|
||||||
be overrided using `--upstream`, and fetching can be avoided using
|
be overridden using `--upstream`, and fetching can be avoided using
|
||||||
`--no-fetch`.
|
`--no-fetch`.
|
||||||
|
|
||||||
By default the branch created will be called `backport-$PR-$VERSION`. You
|
By default the branch created will be called `backport-$PR-$VERSION`. You
|
||||||
|
|
|
@ -150,7 +150,7 @@
|
||||||
|
|
||||||
<p>In general, Your Gitea Instance retains User Personal Information for as long as your account is active, or as needed to provide you service.</p>
|
<p>In general, Your Gitea Instance retains User Personal Information for as long as your account is active, or as needed to provide you service.</p>
|
||||||
|
|
||||||
<p>If you would like to cancel your account or delete your User Personal Information, you may do so in your user profile. We retain and use your information as necessary to comply with our legal obligations, resolve disputes, and enforce our agreements, but barring legal requirements, we will delete your full profile (within reason) within 90 days of your request. Feel free to contact our support to request erasure of the data we process on the bassis of consent within 30 days.</p>
|
<p>If you would like to cancel your account or delete your User Personal Information, you may do so in your user profile. We retain and use your information as necessary to comply with our legal obligations, resolve disputes, and enforce our agreements, but barring legal requirements, we will delete your full profile (within reason) within 90 days of your request. Feel free to contact our support to request erasure of the data we process on the basis of consent within 30 days.</p>
|
||||||
|
|
||||||
<p>After an account has been deleted, certain data, such as contributions to other Users' repositories and comments in others' issues, will remain. However, we will delete or de-identify your User Personal Information, including your username and email address, from the author field of issues, pull requests, and comments by associating them with a ghost user.</p>
|
<p>After an account has been deleted, certain data, such as contributions to other Users' repositories and comments in others' issues, will remain. However, we will delete or de-identify your User Personal Information, including your username and email address, from the author field of issues, pull requests, and comments by associating them with a ghost user.</p>
|
||||||
|
|
||||||
|
|
|
@ -1471,7 +1471,7 @@ LEVEL = Info
|
||||||
;; Batch size to send for batched queues
|
;; Batch size to send for batched queues
|
||||||
;BATCH_LENGTH = 20
|
;BATCH_LENGTH = 20
|
||||||
;;
|
;;
|
||||||
;; Connection string for redis queues this will store the redis or redis-cluster connection string.
|
;; Connection string for redis queues this will store the redis (or Redis cluster) connection string.
|
||||||
;; When `TYPE` is `persistable-channel`, this provides a directory for the underlying leveldb
|
;; When `TYPE` is `persistable-channel`, this provides a directory for the underlying leveldb
|
||||||
;; or additional options of the form `leveldb://path/to/db?option=value&....`, and will override `DATADIR`.
|
;; or additional options of the form `leveldb://path/to/db?option=value&....`, and will override `DATADIR`.
|
||||||
;CONN_STR = "redis://127.0.0.1:6379/0"
|
;CONN_STR = "redis://127.0.0.1:6379/0"
|
||||||
|
@ -1756,9 +1756,8 @@ LEVEL = Info
|
||||||
;; For "memory" only, GC interval in seconds, default is 60
|
;; For "memory" only, GC interval in seconds, default is 60
|
||||||
;INTERVAL = 60
|
;INTERVAL = 60
|
||||||
;;
|
;;
|
||||||
;; For "redis", "redis-cluster" and "memcache", connection host address
|
;; For "redis" and "memcache", connection host address
|
||||||
;; redis: `redis://127.0.0.1:6379/0?pool_size=100&idle_timeout=180s`
|
;; redis: `redis://127.0.0.1:6379/0?pool_size=100&idle_timeout=180s` (or `redis+cluster://127.0.0.1:6379/0?pool_size=100&idle_timeout=180s` for a Redis cluster)
|
||||||
;; redis-cluster: `redis+cluster://127.0.0.1:6379/0?pool_size=100&idle_timeout=180s`
|
|
||||||
;; memcache: `127.0.0.1:11211`
|
;; memcache: `127.0.0.1:11211`
|
||||||
;; twoqueue: `{"size":50000,"recent_ratio":0.25,"ghost_ratio":0.5}` or `50000`
|
;; twoqueue: `{"size":50000,"recent_ratio":0.25,"ghost_ratio":0.5}` or `50000`
|
||||||
;HOST =
|
;HOST =
|
||||||
|
@ -1788,15 +1787,14 @@ LEVEL = Info
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
;;
|
;;
|
||||||
;; Either "memory", "file", "redis", "redis-cluster", "db", "mysql", "couchbase", "memcache" or "postgres"
|
;; Either "memory", "file", "redis", "db", "mysql", "couchbase", "memcache" or "postgres"
|
||||||
;; Default is "memory". "db" will reuse the configuration in [database]
|
;; Default is "memory". "db" will reuse the configuration in [database]
|
||||||
;PROVIDER = memory
|
;PROVIDER = memory
|
||||||
;;
|
;;
|
||||||
;; Provider config options
|
;; Provider config options
|
||||||
;; memory: doesn't have any config yet
|
;; memory: doesn't have any config yet
|
||||||
;; file: session file path, e.g. `data/sessions`
|
;; file: session file path, e.g. `data/sessions`
|
||||||
;; redis: `redis://127.0.0.1:6379/0?pool_size=100&idle_timeout=180s`
|
;; redis: `redis://127.0.0.1:6379/0?pool_size=100&idle_timeout=180s` (or `redis+cluster://127.0.0.1:6379/0?pool_size=100&idle_timeout=180s` for a Redis cluster)
|
||||||
;; redis-cluster: `redis+cluster://127.0.0.1:6379/0?pool_size=100&idle_timeout=180s`
|
|
||||||
;; mysql: go-sql-driver/mysql dsn config string, e.g. `root:password@/session_table`
|
;; mysql: go-sql-driver/mysql dsn config string, e.g. `root:password@/session_table`
|
||||||
;PROVIDER_CONFIG = data/sessions ; Relative paths will be made absolute against _`AppWorkPath`_.
|
;PROVIDER_CONFIG = data/sessions ; Relative paths will be made absolute against _`AppWorkPath`_.
|
||||||
;;
|
;;
|
||||||
|
|
47
go.mod
47
go.mod
|
@ -1,13 +1,14 @@
|
||||||
module code.gitea.io/gitea
|
module code.gitea.io/gitea
|
||||||
|
|
||||||
go 1.22.2
|
go 1.22.3
|
||||||
|
|
||||||
require (
|
require (
|
||||||
|
code.forgejo.org/forgejo/reply v1.0.1
|
||||||
code.gitea.io/actions-proto-go v0.4.0
|
code.gitea.io/actions-proto-go v0.4.0
|
||||||
code.gitea.io/gitea-vet v0.2.3
|
code.gitea.io/gitea-vet v0.2.3
|
||||||
code.gitea.io/sdk/gitea v0.17.1
|
code.gitea.io/sdk/gitea v0.17.1
|
||||||
codeberg.org/gusted/mcaptcha v0.0.0-20220723083913-4f3072e1d570
|
codeberg.org/gusted/mcaptcha v0.0.0-20220723083913-4f3072e1d570
|
||||||
connectrpc.com/connect v1.16.1
|
connectrpc.com/connect v1.16.2
|
||||||
gitea.com/go-chi/binding v0.0.0-20240430071103-39a851e106ed
|
gitea.com/go-chi/binding v0.0.0-20240430071103-39a851e106ed
|
||||||
gitea.com/go-chi/cache v0.2.0
|
gitea.com/go-chi/cache v0.2.0
|
||||||
gitea.com/go-chi/captcha v0.0.0-20240315150714-fb487f629098
|
gitea.com/go-chi/captcha v0.0.0-20240315150714-fb487f629098
|
||||||
|
@ -19,11 +20,10 @@ require (
|
||||||
github.com/PuerkitoBio/goquery v1.9.2
|
github.com/PuerkitoBio/goquery v1.9.2
|
||||||
github.com/alecthomas/chroma/v2 v2.13.0
|
github.com/alecthomas/chroma/v2 v2.13.0
|
||||||
github.com/blakesmith/ar v0.0.0-20190502131153-809d4375e1fb
|
github.com/blakesmith/ar v0.0.0-20190502131153-809d4375e1fb
|
||||||
github.com/blevesearch/bleve/v2 v2.3.10
|
github.com/blevesearch/bleve/v2 v2.4.0
|
||||||
github.com/buildkite/terminal-to-html/v3 v3.10.1
|
github.com/buildkite/terminal-to-html/v3 v3.10.1
|
||||||
github.com/caddyserver/certmagic v0.20.0
|
github.com/caddyserver/certmagic v0.21.0
|
||||||
github.com/chi-middleware/proxy v1.1.1
|
github.com/chi-middleware/proxy v1.1.1
|
||||||
github.com/dimiro1/reply v0.0.0-20200315094148-d0136a4c9e21
|
|
||||||
github.com/djherbis/buffer v1.2.0
|
github.com/djherbis/buffer v1.2.0
|
||||||
github.com/djherbis/nio/v3 v3.0.1
|
github.com/djherbis/nio/v3 v3.0.1
|
||||||
github.com/dsnet/compress v0.0.2-0.20210315054119-f66993602bf5
|
github.com/dsnet/compress v0.0.2-0.20210315054119-f66993602bf5
|
||||||
|
@ -39,7 +39,7 @@ require (
|
||||||
github.com/go-chi/chi/v5 v5.0.11
|
github.com/go-chi/chi/v5 v5.0.11
|
||||||
github.com/go-chi/cors v1.2.1
|
github.com/go-chi/cors v1.2.1
|
||||||
github.com/go-co-op/gocron v1.37.0
|
github.com/go-co-op/gocron v1.37.0
|
||||||
github.com/go-enry/go-enry/v2 v2.8.7
|
github.com/go-enry/go-enry/v2 v2.8.8
|
||||||
github.com/go-fed/httpsig v1.1.1-0.20201223112313-55836744818e
|
github.com/go-fed/httpsig v1.1.1-0.20201223112313-55836744818e
|
||||||
github.com/go-git/go-billy/v5 v5.5.0
|
github.com/go-git/go-billy/v5 v5.5.0
|
||||||
github.com/go-git/go-git/v5 v5.11.0
|
github.com/go-git/go-git/v5 v5.11.0
|
||||||
|
@ -57,6 +57,7 @@ require (
|
||||||
github.com/google/uuid v1.6.0
|
github.com/google/uuid v1.6.0
|
||||||
github.com/gorilla/feeds v1.1.2
|
github.com/gorilla/feeds v1.1.2
|
||||||
github.com/gorilla/sessions v1.2.2
|
github.com/gorilla/sessions v1.2.2
|
||||||
|
github.com/h2non/gock v1.2.0
|
||||||
github.com/hashicorp/go-version v1.6.0
|
github.com/hashicorp/go-version v1.6.0
|
||||||
github.com/hashicorp/golang-lru/v2 v2.0.7
|
github.com/hashicorp/golang-lru/v2 v2.0.7
|
||||||
github.com/huandu/xstrings v1.4.0
|
github.com/huandu/xstrings v1.4.0
|
||||||
|
@ -66,7 +67,7 @@ require (
|
||||||
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51
|
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51
|
||||||
github.com/keybase/go-crypto v0.0.0-20200123153347-de78d2cb44f4
|
github.com/keybase/go-crypto v0.0.0-20200123153347-de78d2cb44f4
|
||||||
github.com/klauspost/compress v1.17.8
|
github.com/klauspost/compress v1.17.8
|
||||||
github.com/klauspost/cpuid/v2 v2.2.6
|
github.com/klauspost/cpuid/v2 v2.2.7
|
||||||
github.com/lib/pq v1.10.9
|
github.com/lib/pq v1.10.9
|
||||||
github.com/markbates/goth v1.78.0
|
github.com/markbates/goth v1.78.0
|
||||||
github.com/mattn/go-isatty v0.0.20
|
github.com/mattn/go-isatty v0.0.20
|
||||||
|
@ -100,13 +101,13 @@ require (
|
||||||
github.com/yuin/goldmark v1.7.0
|
github.com/yuin/goldmark v1.7.0
|
||||||
github.com/yuin/goldmark-highlighting/v2 v2.0.0-20230729083705-37449abec8cc
|
github.com/yuin/goldmark-highlighting/v2 v2.0.0-20230729083705-37449abec8cc
|
||||||
github.com/yuin/goldmark-meta v1.1.0
|
github.com/yuin/goldmark-meta v1.1.0
|
||||||
golang.org/x/crypto v0.22.0
|
golang.org/x/crypto v0.23.0
|
||||||
golang.org/x/image v0.15.0
|
golang.org/x/image v0.15.0
|
||||||
golang.org/x/net v0.24.0
|
golang.org/x/net v0.25.0
|
||||||
golang.org/x/oauth2 v0.16.0
|
golang.org/x/oauth2 v0.16.0
|
||||||
golang.org/x/sys v0.19.0
|
golang.org/x/sys v0.20.0
|
||||||
golang.org/x/text v0.14.0
|
golang.org/x/text v0.15.0
|
||||||
golang.org/x/tools v0.17.0
|
golang.org/x/tools v0.21.0
|
||||||
google.golang.org/grpc v1.60.1
|
google.golang.org/grpc v1.60.1
|
||||||
google.golang.org/protobuf v1.33.0
|
google.golang.org/protobuf v1.33.0
|
||||||
gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df
|
gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df
|
||||||
|
@ -139,12 +140,13 @@ require (
|
||||||
github.com/aymerick/douceur v0.2.0 // indirect
|
github.com/aymerick/douceur v0.2.0 // indirect
|
||||||
github.com/beorn7/perks v1.0.1 // indirect
|
github.com/beorn7/perks v1.0.1 // indirect
|
||||||
github.com/bits-and-blooms/bitset v1.13.0 // indirect
|
github.com/bits-and-blooms/bitset v1.13.0 // indirect
|
||||||
github.com/blevesearch/bleve_index_api v1.1.5 // indirect
|
github.com/blevesearch/bleve_index_api v1.1.6 // indirect
|
||||||
github.com/blevesearch/geo v0.1.19 // indirect
|
github.com/blevesearch/geo v0.1.20 // indirect
|
||||||
|
github.com/blevesearch/go-faiss v1.0.13 // indirect
|
||||||
github.com/blevesearch/go-porterstemmer v1.0.3 // indirect
|
github.com/blevesearch/go-porterstemmer v1.0.3 // indirect
|
||||||
github.com/blevesearch/gtreap v0.1.1 // indirect
|
github.com/blevesearch/gtreap v0.1.1 // indirect
|
||||||
github.com/blevesearch/mmap-go v1.0.4 // indirect
|
github.com/blevesearch/mmap-go v1.0.4 // indirect
|
||||||
github.com/blevesearch/scorch_segment_api/v2 v2.2.6 // indirect
|
github.com/blevesearch/scorch_segment_api/v2 v2.2.9 // indirect
|
||||||
github.com/blevesearch/segment v0.9.1 // indirect
|
github.com/blevesearch/segment v0.9.1 // indirect
|
||||||
github.com/blevesearch/snowballstem v0.9.0 // indirect
|
github.com/blevesearch/snowballstem v0.9.0 // indirect
|
||||||
github.com/blevesearch/upsidedown_store_api v1.0.2 // indirect
|
github.com/blevesearch/upsidedown_store_api v1.0.2 // indirect
|
||||||
|
@ -154,8 +156,10 @@ require (
|
||||||
github.com/blevesearch/zapx/v13 v13.3.10 // indirect
|
github.com/blevesearch/zapx/v13 v13.3.10 // indirect
|
||||||
github.com/blevesearch/zapx/v14 v14.3.10 // indirect
|
github.com/blevesearch/zapx/v14 v14.3.10 // indirect
|
||||||
github.com/blevesearch/zapx/v15 v15.3.13 // indirect
|
github.com/blevesearch/zapx/v15 v15.3.13 // indirect
|
||||||
|
github.com/blevesearch/zapx/v16 v16.0.12 // indirect
|
||||||
github.com/boombuler/barcode v1.0.1 // indirect
|
github.com/boombuler/barcode v1.0.1 // indirect
|
||||||
github.com/bradfitz/gomemcache v0.0.0-20230905024940-24af94b03874 // indirect
|
github.com/bradfitz/gomemcache v0.0.0-20230905024940-24af94b03874 // indirect
|
||||||
|
github.com/caddyserver/zerossl v0.1.2 // indirect
|
||||||
github.com/cention-sany/utf7 v0.0.0-20170124080048-26cad61bd60a // indirect
|
github.com/cention-sany/utf7 v0.0.0-20170124080048-26cad61bd60a // indirect
|
||||||
github.com/cespare/xxhash/v2 v2.2.0 // indirect
|
github.com/cespare/xxhash/v2 v2.2.0 // indirect
|
||||||
github.com/cloudflare/circl v1.3.7 // indirect
|
github.com/cloudflare/circl v1.3.7 // indirect
|
||||||
|
@ -203,6 +207,7 @@ require (
|
||||||
github.com/gorilla/handlers v1.5.2 // indirect
|
github.com/gorilla/handlers v1.5.2 // indirect
|
||||||
github.com/gorilla/mux v1.8.1 // indirect
|
github.com/gorilla/mux v1.8.1 // indirect
|
||||||
github.com/gorilla/securecookie v1.1.2 // indirect
|
github.com/gorilla/securecookie v1.1.2 // indirect
|
||||||
|
github.com/h2non/parth v0.0.0-20190131123155-b4df798d6542 // indirect
|
||||||
github.com/hashicorp/go-cleanhttp v0.5.2 // indirect
|
github.com/hashicorp/go-cleanhttp v0.5.2 // indirect
|
||||||
github.com/hashicorp/go-retryablehttp v0.7.5 // indirect
|
github.com/hashicorp/go-retryablehttp v0.7.5 // indirect
|
||||||
github.com/hashicorp/hcl v1.0.0 // indirect
|
github.com/hashicorp/hcl v1.0.0 // indirect
|
||||||
|
@ -214,14 +219,14 @@ require (
|
||||||
github.com/klauspost/pgzip v1.2.6 // indirect
|
github.com/klauspost/pgzip v1.2.6 // indirect
|
||||||
github.com/kr/pretty v0.3.1 // indirect
|
github.com/kr/pretty v0.3.1 // indirect
|
||||||
github.com/kr/text v0.2.0 // indirect
|
github.com/kr/text v0.2.0 // indirect
|
||||||
github.com/libdns/libdns v0.2.1 // indirect
|
github.com/libdns/libdns v0.2.2 // indirect
|
||||||
github.com/magiconair/properties v1.8.7 // indirect
|
github.com/magiconair/properties v1.8.7 // indirect
|
||||||
github.com/mailru/easyjson v0.7.7 // indirect
|
github.com/mailru/easyjson v0.7.7 // indirect
|
||||||
github.com/markbates/going v1.0.3 // indirect
|
github.com/markbates/going v1.0.3 // indirect
|
||||||
github.com/mattn/go-colorable v0.1.13 // indirect
|
github.com/mattn/go-colorable v0.1.13 // indirect
|
||||||
github.com/mattn/go-runewidth v0.0.15 // indirect
|
github.com/mattn/go-runewidth v0.0.15 // indirect
|
||||||
github.com/mholt/acmez v1.2.0 // indirect
|
github.com/mholt/acmez/v2 v2.0.1 // indirect
|
||||||
github.com/miekg/dns v1.1.58 // indirect
|
github.com/miekg/dns v1.1.59 // indirect
|
||||||
github.com/minio/md5-simd v1.1.2 // indirect
|
github.com/minio/md5-simd v1.1.2 // indirect
|
||||||
github.com/mitchellh/copystructure v1.2.0 // indirect
|
github.com/mitchellh/copystructure v1.2.0 // indirect
|
||||||
github.com/mitchellh/mapstructure v1.5.0 // indirect
|
github.com/mitchellh/mapstructure v1.5.0 // indirect
|
||||||
|
@ -277,10 +282,10 @@ require (
|
||||||
go.opentelemetry.io/otel/trace v1.22.0 // indirect
|
go.opentelemetry.io/otel/trace v1.22.0 // indirect
|
||||||
go.uber.org/atomic v1.11.0 // indirect
|
go.uber.org/atomic v1.11.0 // indirect
|
||||||
go.uber.org/multierr v1.11.0 // indirect
|
go.uber.org/multierr v1.11.0 // indirect
|
||||||
go.uber.org/zap v1.26.0 // indirect
|
go.uber.org/zap v1.27.0 // indirect
|
||||||
golang.org/x/exp v0.0.0-20240119083558-1b970713d09a // indirect
|
golang.org/x/exp v0.0.0-20240119083558-1b970713d09a // indirect
|
||||||
golang.org/x/mod v0.16.0 // indirect
|
golang.org/x/mod v0.17.0 // indirect
|
||||||
golang.org/x/sync v0.6.0 // indirect
|
golang.org/x/sync v0.7.0 // indirect
|
||||||
golang.org/x/time v0.5.0 // indirect
|
golang.org/x/time v0.5.0 // indirect
|
||||||
google.golang.org/appengine v1.6.8 // indirect
|
google.golang.org/appengine v1.6.8 // indirect
|
||||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20240116215550-a9fa1716bcac // indirect
|
google.golang.org/genproto/googleapis/rpc v0.0.0-20240116215550-a9fa1716bcac // indirect
|
||||||
|
|
99
go.sum
99
go.sum
|
@ -35,6 +35,8 @@ cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0Zeo
|
||||||
cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk=
|
cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk=
|
||||||
cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs=
|
cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs=
|
||||||
cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0=
|
cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0=
|
||||||
|
code.forgejo.org/forgejo/reply v1.0.1 h1:usZi5yx7/g0D+xtGPJEM6mCvoDNdWvmtJu5J9/B/KBI=
|
||||||
|
code.forgejo.org/forgejo/reply v1.0.1/go.mod h1:RyZUfzQLc+fuLIGjTSQWDAJWPiL4WtKXB/FifT5fM7U=
|
||||||
code.gitea.io/actions-proto-go v0.4.0 h1:OsPBPhodXuQnsspG1sQ4eRE1PeoZyofd7+i73zCwnsU=
|
code.gitea.io/actions-proto-go v0.4.0 h1:OsPBPhodXuQnsspG1sQ4eRE1PeoZyofd7+i73zCwnsU=
|
||||||
code.gitea.io/actions-proto-go v0.4.0/go.mod h1:mn7Wkqz6JbnTOHQpot3yDeHx+O5C9EGhMEE+htvHBas=
|
code.gitea.io/actions-proto-go v0.4.0/go.mod h1:mn7Wkqz6JbnTOHQpot3yDeHx+O5C9EGhMEE+htvHBas=
|
||||||
code.gitea.io/gitea-vet v0.2.3 h1:gdFmm6WOTM65rE8FUBTRzeQZYzXePKSSB1+r574hWwI=
|
code.gitea.io/gitea-vet v0.2.3 h1:gdFmm6WOTM65rE8FUBTRzeQZYzXePKSSB1+r574hWwI=
|
||||||
|
@ -43,8 +45,8 @@ code.gitea.io/sdk/gitea v0.17.1 h1:3jCPOG2ojbl8AcfaUCRYLT5MUcBMFwS0OSK2mA5Zok8=
|
||||||
code.gitea.io/sdk/gitea v0.17.1/go.mod h1:aCnBqhHpoEWA180gMbaCtdX9Pl6BWBAuuP2miadoTNM=
|
code.gitea.io/sdk/gitea v0.17.1/go.mod h1:aCnBqhHpoEWA180gMbaCtdX9Pl6BWBAuuP2miadoTNM=
|
||||||
codeberg.org/gusted/mcaptcha v0.0.0-20220723083913-4f3072e1d570 h1:TXbikPqa7YRtfU9vS6QJBg77pUvbEb6StRdZO8t1bEY=
|
codeberg.org/gusted/mcaptcha v0.0.0-20220723083913-4f3072e1d570 h1:TXbikPqa7YRtfU9vS6QJBg77pUvbEb6StRdZO8t1bEY=
|
||||||
codeberg.org/gusted/mcaptcha v0.0.0-20220723083913-4f3072e1d570/go.mod h1:IIAjsijsd8q1isWX8MACefDEgTQslQ4stk2AeeTt3kM=
|
codeberg.org/gusted/mcaptcha v0.0.0-20220723083913-4f3072e1d570/go.mod h1:IIAjsijsd8q1isWX8MACefDEgTQslQ4stk2AeeTt3kM=
|
||||||
connectrpc.com/connect v1.16.1 h1:rOdrK/RTI/7TVnn3JsVxt3n028MlTRwmK5Q4heSpjis=
|
connectrpc.com/connect v1.16.2 h1:ybd6y+ls7GOlb7Bh5C8+ghA6SvCBajHwxssO2CGFjqE=
|
||||||
connectrpc.com/connect v1.16.1/go.mod h1:XpZAduBQUySsb4/KO5JffORVkDI4B6/EYPi7N8xpNZw=
|
connectrpc.com/connect v1.16.2/go.mod h1:n2kgwskMHXC+lVqb18wngEpF95ldBHXjZYJussz5FRc=
|
||||||
dario.cat/mergo v1.0.0 h1:AGCNq9Evsj31mOgNPcLyXc+4PNABt905YmuqPYYpBWk=
|
dario.cat/mergo v1.0.0 h1:AGCNq9Evsj31mOgNPcLyXc+4PNABt905YmuqPYYpBWk=
|
||||||
dario.cat/mergo v1.0.0/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk=
|
dario.cat/mergo v1.0.0/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk=
|
||||||
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
|
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
|
||||||
|
@ -128,20 +130,22 @@ github.com/bits-and-blooms/bitset v1.13.0 h1:bAQ9OPNFYbGHV6Nez0tmNI0RiEu7/hxlYJR
|
||||||
github.com/bits-and-blooms/bitset v1.13.0/go.mod h1:7hO7Gc7Pp1vODcmWvKMRA9BNmbv6a/7QIWpPxHddWR8=
|
github.com/bits-and-blooms/bitset v1.13.0/go.mod h1:7hO7Gc7Pp1vODcmWvKMRA9BNmbv6a/7QIWpPxHddWR8=
|
||||||
github.com/blakesmith/ar v0.0.0-20190502131153-809d4375e1fb h1:m935MPodAbYS46DG4pJSv7WO+VECIWUQ7OJYSoTrMh4=
|
github.com/blakesmith/ar v0.0.0-20190502131153-809d4375e1fb h1:m935MPodAbYS46DG4pJSv7WO+VECIWUQ7OJYSoTrMh4=
|
||||||
github.com/blakesmith/ar v0.0.0-20190502131153-809d4375e1fb/go.mod h1:PkYb9DJNAwrSvRx5DYA+gUcOIgTGVMNkfSCbZM8cWpI=
|
github.com/blakesmith/ar v0.0.0-20190502131153-809d4375e1fb/go.mod h1:PkYb9DJNAwrSvRx5DYA+gUcOIgTGVMNkfSCbZM8cWpI=
|
||||||
github.com/blevesearch/bleve/v2 v2.3.10 h1:z8V0wwGoL4rp7nG/O3qVVLYxUqCbEwskMt4iRJsPLgg=
|
github.com/blevesearch/bleve/v2 v2.4.0 h1:2xyg+Wv60CFHYccXc+moGxbL+8QKT/dZK09AewHgKsg=
|
||||||
github.com/blevesearch/bleve/v2 v2.3.10/go.mod h1:RJzeoeHC+vNHsoLR54+crS1HmOWpnH87fL70HAUCzIA=
|
github.com/blevesearch/bleve/v2 v2.4.0/go.mod h1:IhQHoFAbHgWKYavb9rQgQEJJVMuY99cKdQ0wPpst2aY=
|
||||||
github.com/blevesearch/bleve_index_api v1.1.5 h1:0q05mzu6GT/kebzqKywCpou/eUea9wTKa7kfqX7QX+k=
|
github.com/blevesearch/bleve_index_api v1.1.6 h1:orkqDFCBuNU2oHW9hN2YEJmet+TE9orml3FCGbl1cKk=
|
||||||
github.com/blevesearch/bleve_index_api v1.1.5/go.mod h1:PbcwjIcRmjhGbkS/lJCpfgVSMROV6TRubGGAODaK1W8=
|
github.com/blevesearch/bleve_index_api v1.1.6/go.mod h1:PbcwjIcRmjhGbkS/lJCpfgVSMROV6TRubGGAODaK1W8=
|
||||||
github.com/blevesearch/geo v0.1.19 h1:hlX1YpBZ+X+xfjS8hEpmM/tdPUFbqBME3mdAWKHo2s0=
|
github.com/blevesearch/geo v0.1.20 h1:paaSpu2Ewh/tn5DKn/FB5SzvH0EWupxHEIwbCk/QPqM=
|
||||||
github.com/blevesearch/geo v0.1.19/go.mod h1:EPyr3iJCcESYa830PnkFhqzJkOP7/daHT/ocun43WRY=
|
github.com/blevesearch/geo v0.1.20/go.mod h1:DVG2QjwHNMFmjo+ZgzrIq2sfCh6rIHzy9d9d0B59I6w=
|
||||||
|
github.com/blevesearch/go-faiss v1.0.13 h1:zfFs7ZYD0NqXVSY37j0JZjZT1BhE9AE4peJfcx/NB4A=
|
||||||
|
github.com/blevesearch/go-faiss v1.0.13/go.mod h1:jrxHrbl42X/RnDPI+wBoZU8joxxuRwedrxqswQ3xfU8=
|
||||||
github.com/blevesearch/go-porterstemmer v1.0.3 h1:GtmsqID0aZdCSNiY8SkuPJ12pD4jI+DdXTAn4YRcHCo=
|
github.com/blevesearch/go-porterstemmer v1.0.3 h1:GtmsqID0aZdCSNiY8SkuPJ12pD4jI+DdXTAn4YRcHCo=
|
||||||
github.com/blevesearch/go-porterstemmer v1.0.3/go.mod h1:angGc5Ht+k2xhJdZi511LtmxuEf0OVpvUUNrwmM1P7M=
|
github.com/blevesearch/go-porterstemmer v1.0.3/go.mod h1:angGc5Ht+k2xhJdZi511LtmxuEf0OVpvUUNrwmM1P7M=
|
||||||
github.com/blevesearch/gtreap v0.1.1 h1:2JWigFrzDMR+42WGIN/V2p0cUvn4UP3C4Q5nmaZGW8Y=
|
github.com/blevesearch/gtreap v0.1.1 h1:2JWigFrzDMR+42WGIN/V2p0cUvn4UP3C4Q5nmaZGW8Y=
|
||||||
github.com/blevesearch/gtreap v0.1.1/go.mod h1:QaQyDRAT51sotthUWAH4Sj08awFSSWzgYICSZ3w0tYk=
|
github.com/blevesearch/gtreap v0.1.1/go.mod h1:QaQyDRAT51sotthUWAH4Sj08awFSSWzgYICSZ3w0tYk=
|
||||||
github.com/blevesearch/mmap-go v1.0.4 h1:OVhDhT5B/M1HNPpYPBKIEJaD0F3Si+CrEKULGCDPWmc=
|
github.com/blevesearch/mmap-go v1.0.4 h1:OVhDhT5B/M1HNPpYPBKIEJaD0F3Si+CrEKULGCDPWmc=
|
||||||
github.com/blevesearch/mmap-go v1.0.4/go.mod h1:EWmEAOmdAS9z/pi/+Toxu99DnsbhG1TIxUoRmJw/pSs=
|
github.com/blevesearch/mmap-go v1.0.4/go.mod h1:EWmEAOmdAS9z/pi/+Toxu99DnsbhG1TIxUoRmJw/pSs=
|
||||||
github.com/blevesearch/scorch_segment_api/v2 v2.2.6 h1:rewrzgFaCEjjfWovAB9NubMAd4+aCLxD3RaQcPDaoNo=
|
github.com/blevesearch/scorch_segment_api/v2 v2.2.9 h1:3nBaSBRFokjE4FtPW3eUDgcAu3KphBg1GP07zy/6Uyk=
|
||||||
github.com/blevesearch/scorch_segment_api/v2 v2.2.6/go.mod h1:0rv+k/OIjtYCT/g7Z45pCOVweFyta+0AdXO8keKfZxo=
|
github.com/blevesearch/scorch_segment_api/v2 v2.2.9/go.mod h1:ckbeb7knyOOvAdZinn/ASbB7EA3HoagnJkmEV3J7+sg=
|
||||||
github.com/blevesearch/segment v0.9.1 h1:+dThDy+Lvgj5JMxhmOVlgFfkUtZV2kw49xax4+jTfSU=
|
github.com/blevesearch/segment v0.9.1 h1:+dThDy+Lvgj5JMxhmOVlgFfkUtZV2kw49xax4+jTfSU=
|
||||||
github.com/blevesearch/segment v0.9.1/go.mod h1:zN21iLm7+GnBHWTao9I+Au/7MBiL8pPFtJBJTsk6kQw=
|
github.com/blevesearch/segment v0.9.1/go.mod h1:zN21iLm7+GnBHWTao9I+Au/7MBiL8pPFtJBJTsk6kQw=
|
||||||
github.com/blevesearch/snowballstem v0.9.0 h1:lMQ189YspGP6sXvZQ4WZ+MLawfV8wOmPoD/iWeNXm8s=
|
github.com/blevesearch/snowballstem v0.9.0 h1:lMQ189YspGP6sXvZQ4WZ+MLawfV8wOmPoD/iWeNXm8s=
|
||||||
|
@ -160,6 +164,8 @@ github.com/blevesearch/zapx/v14 v14.3.10 h1:SG6xlsL+W6YjhX5N3aEiL/2tcWh3DO75Bnz7
|
||||||
github.com/blevesearch/zapx/v14 v14.3.10/go.mod h1:qqyuR0u230jN1yMmE4FIAuCxmahRQEOehF78m6oTgns=
|
github.com/blevesearch/zapx/v14 v14.3.10/go.mod h1:qqyuR0u230jN1yMmE4FIAuCxmahRQEOehF78m6oTgns=
|
||||||
github.com/blevesearch/zapx/v15 v15.3.13 h1:6EkfaZiPlAxqXz0neniq35my6S48QI94W/wyhnpDHHQ=
|
github.com/blevesearch/zapx/v15 v15.3.13 h1:6EkfaZiPlAxqXz0neniq35my6S48QI94W/wyhnpDHHQ=
|
||||||
github.com/blevesearch/zapx/v15 v15.3.13/go.mod h1:Turk/TNRKj9es7ZpKK95PS7f6D44Y7fAFy8F4LXQtGg=
|
github.com/blevesearch/zapx/v15 v15.3.13/go.mod h1:Turk/TNRKj9es7ZpKK95PS7f6D44Y7fAFy8F4LXQtGg=
|
||||||
|
github.com/blevesearch/zapx/v16 v16.0.12 h1:Uccxvjmn+hQ6ywQP+wIiTpdq9LnAviGoryJOmGwAo/I=
|
||||||
|
github.com/blevesearch/zapx/v16 v16.0.12/go.mod h1:MYnOshRfSm4C4drxx1LGRI+MVFByykJ2anDY1fxdk9Q=
|
||||||
github.com/boombuler/barcode v1.0.1-0.20190219062509-6c824513bacc/go.mod h1:paBWMcWSl3LHKBqUq+rly7CNSldXjb2rDl3JlRe0mD8=
|
github.com/boombuler/barcode v1.0.1-0.20190219062509-6c824513bacc/go.mod h1:paBWMcWSl3LHKBqUq+rly7CNSldXjb2rDl3JlRe0mD8=
|
||||||
github.com/boombuler/barcode v1.0.1 h1:NDBbPmhS+EqABEs5Kg3n/5ZNjy73Pz7SIV+KCeqyXcs=
|
github.com/boombuler/barcode v1.0.1 h1:NDBbPmhS+EqABEs5Kg3n/5ZNjy73Pz7SIV+KCeqyXcs=
|
||||||
github.com/boombuler/barcode v1.0.1/go.mod h1:paBWMcWSl3LHKBqUq+rly7CNSldXjb2rDl3JlRe0mD8=
|
github.com/boombuler/barcode v1.0.1/go.mod h1:paBWMcWSl3LHKBqUq+rly7CNSldXjb2rDl3JlRe0mD8=
|
||||||
|
@ -173,8 +179,10 @@ github.com/bsm/gomega v1.27.10/go.mod h1:JyEr/xRbxbtgWNi8tIEVPUYZ5Dzef52k01W3YH0
|
||||||
github.com/buildkite/terminal-to-html/v3 v3.10.1 h1:znT9eD26LQ59dDJJEpMCwkP4wEptEAPi74hsTBuHdEo=
|
github.com/buildkite/terminal-to-html/v3 v3.10.1 h1:znT9eD26LQ59dDJJEpMCwkP4wEptEAPi74hsTBuHdEo=
|
||||||
github.com/buildkite/terminal-to-html/v3 v3.10.1/go.mod h1:qtuRyYs6/Sw3FS9jUyVEaANHgHGqZsGqMknPLyau5cQ=
|
github.com/buildkite/terminal-to-html/v3 v3.10.1/go.mod h1:qtuRyYs6/Sw3FS9jUyVEaANHgHGqZsGqMknPLyau5cQ=
|
||||||
github.com/bwesterb/go-ristretto v1.2.3/go.mod h1:fUIoIZaG73pV5biE2Blr2xEzDoMj7NFEuV9ekS419A0=
|
github.com/bwesterb/go-ristretto v1.2.3/go.mod h1:fUIoIZaG73pV5biE2Blr2xEzDoMj7NFEuV9ekS419A0=
|
||||||
github.com/caddyserver/certmagic v0.20.0 h1:bTw7LcEZAh9ucYCRXyCpIrSAGplplI0vGYJ4BpCQ/Fc=
|
github.com/caddyserver/certmagic v0.21.0 h1:yDoifClc4hIxhHer3AxUj4buhF+NzRR6torw/AOnuUE=
|
||||||
github.com/caddyserver/certmagic v0.20.0/go.mod h1:N4sXgpICQUskEWpj7zVzvWD41p3NYacrNoZYiRM2jTg=
|
github.com/caddyserver/certmagic v0.21.0/go.mod h1:OgUZNXYV/ylYoFJNmoYVR5nntydLNMQISePPgqZTyhc=
|
||||||
|
github.com/caddyserver/zerossl v0.1.2 h1:tlEu1VzWGoqcCpivs9liKAKhfpJWYJkHEMmlxRbVAxE=
|
||||||
|
github.com/caddyserver/zerossl v0.1.2/go.mod h1:wtiJEHbdvunr40ZzhXlnIkOB8Xj4eKtBKizCcZitJiQ=
|
||||||
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
|
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
|
||||||
github.com/cention-sany/utf7 v0.0.0-20170124080048-26cad61bd60a h1:MISbI8sU/PSK/ztvmWKFcI7UGb5/HQT7B+i3a2myKgI=
|
github.com/cention-sany/utf7 v0.0.0-20170124080048-26cad61bd60a h1:MISbI8sU/PSK/ztvmWKFcI7UGb5/HQT7B+i3a2myKgI=
|
||||||
github.com/cention-sany/utf7 v0.0.0-20170124080048-26cad61bd60a/go.mod h1:2GxOXOlEPAMFPfp014mK1SWq8G8BN8o7/dfYqJrVGn8=
|
github.com/cention-sany/utf7 v0.0.0-20170124080048-26cad61bd60a/go.mod h1:2GxOXOlEPAMFPfp014mK1SWq8G8BN8o7/dfYqJrVGn8=
|
||||||
|
@ -220,8 +228,6 @@ github.com/denisenkom/go-mssqldb v0.12.3 h1:pBSGx9Tq67pBOTLmxNuirNTeB8Vjmf886Kx+
|
||||||
github.com/denisenkom/go-mssqldb v0.12.3/go.mod h1:k0mtMFOnU+AihqFxPMiF05rtiDrorD1Vrm1KEz5hxDo=
|
github.com/denisenkom/go-mssqldb v0.12.3/go.mod h1:k0mtMFOnU+AihqFxPMiF05rtiDrorD1Vrm1KEz5hxDo=
|
||||||
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78=
|
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78=
|
||||||
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc=
|
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc=
|
||||||
github.com/dimiro1/reply v0.0.0-20200315094148-d0136a4c9e21 h1:PdsjTl0Cg+ZJgOx/CFV5NNgO1ThTreqdgKYiDCMHJwA=
|
|
||||||
github.com/dimiro1/reply v0.0.0-20200315094148-d0136a4c9e21/go.mod h1:xJvkyD6Y2rZapGvPJLYo9dyx1s5dxBEDPa8T3YTuOk0=
|
|
||||||
github.com/djherbis/buffer v1.1.0/go.mod h1:VwN8VdFkMY0DCALdY8o00d3IZ6Amz/UNVMWcSaJT44o=
|
github.com/djherbis/buffer v1.1.0/go.mod h1:VwN8VdFkMY0DCALdY8o00d3IZ6Amz/UNVMWcSaJT44o=
|
||||||
github.com/djherbis/buffer v1.2.0 h1:PH5Dd2ss0C7CRRhQCZ2u7MssF+No9ide8Ye71nPHcrQ=
|
github.com/djherbis/buffer v1.2.0 h1:PH5Dd2ss0C7CRRhQCZ2u7MssF+No9ide8Ye71nPHcrQ=
|
||||||
github.com/djherbis/buffer v1.2.0/go.mod h1:fjnebbZjCUpPinBRD+TDwXSOeNQ7fPQWLfGQqiAiUyE=
|
github.com/djherbis/buffer v1.2.0/go.mod h1:fjnebbZjCUpPinBRD+TDwXSOeNQ7fPQWLfGQqiAiUyE=
|
||||||
|
@ -288,8 +294,8 @@ github.com/go-chi/cors v1.2.1 h1:xEC8UT3Rlp2QuWNEr4Fs/c2EAGVKBwy/1vHx3bppil4=
|
||||||
github.com/go-chi/cors v1.2.1/go.mod h1:sSbTewc+6wYHBBCW7ytsFSn836hqM7JxpglAy2Vzc58=
|
github.com/go-chi/cors v1.2.1/go.mod h1:sSbTewc+6wYHBBCW7ytsFSn836hqM7JxpglAy2Vzc58=
|
||||||
github.com/go-co-op/gocron v1.37.0 h1:ZYDJGtQ4OMhTLKOKMIch+/CY70Brbb1dGdooLEhh7b0=
|
github.com/go-co-op/gocron v1.37.0 h1:ZYDJGtQ4OMhTLKOKMIch+/CY70Brbb1dGdooLEhh7b0=
|
||||||
github.com/go-co-op/gocron v1.37.0/go.mod h1:3L/n6BkO7ABj+TrfSVXLRzsP26zmikL4ISkLQ0O8iNY=
|
github.com/go-co-op/gocron v1.37.0/go.mod h1:3L/n6BkO7ABj+TrfSVXLRzsP26zmikL4ISkLQ0O8iNY=
|
||||||
github.com/go-enry/go-enry/v2 v2.8.7 h1:vbab0pcf5Yo1cHQLzbWZ+QomUh3EfEU8EiR5n7W0lnQ=
|
github.com/go-enry/go-enry/v2 v2.8.8 h1:EhfxWpw4DQ3WEFB1Y77X8vKqZL0D0EDUUWYDUAIv9/4=
|
||||||
github.com/go-enry/go-enry/v2 v2.8.7/go.mod h1:9yrj4ES1YrbNb1Wb7/PWYr2bpaCXUGRt0uafN0ISyG8=
|
github.com/go-enry/go-enry/v2 v2.8.8/go.mod h1:9yrj4ES1YrbNb1Wb7/PWYr2bpaCXUGRt0uafN0ISyG8=
|
||||||
github.com/go-enry/go-oniguruma v1.2.1 h1:k8aAMuJfMrqm/56SG2lV9Cfti6tC4x8673aHCcBk+eo=
|
github.com/go-enry/go-oniguruma v1.2.1 h1:k8aAMuJfMrqm/56SG2lV9Cfti6tC4x8673aHCcBk+eo=
|
||||||
github.com/go-enry/go-oniguruma v1.2.1/go.mod h1:bWDhYP+S6xZQgiRL7wlTScFYBe023B6ilRZbCAD5Hf4=
|
github.com/go-enry/go-oniguruma v1.2.1/go.mod h1:bWDhYP+S6xZQgiRL7wlTScFYBe023B6ilRZbCAD5Hf4=
|
||||||
github.com/go-faster/city v1.0.1 h1:4WAxSZ3V2Ws4QRDrscLEDcibJY8uf41H6AhXDrNDcGw=
|
github.com/go-faster/city v1.0.1 h1:4WAxSZ3V2Ws4QRDrscLEDcibJY8uf41H6AhXDrNDcGw=
|
||||||
|
@ -474,6 +480,10 @@ github.com/gorilla/sessions v1.1.1/go.mod h1:8KCfur6+4Mqcc6S0FEfKuN15Vl5MgXW92AE
|
||||||
github.com/gorilla/sessions v1.2.0/go.mod h1:dk2InVEVJ0sfLlnXv9EAgkf6ecYs/i80K/zI+bUmuGM=
|
github.com/gorilla/sessions v1.2.0/go.mod h1:dk2InVEVJ0sfLlnXv9EAgkf6ecYs/i80K/zI+bUmuGM=
|
||||||
github.com/gorilla/sessions v1.2.2 h1:lqzMYz6bOfvn2WriPUjNByzeXIlVzURcPmgMczkmTjY=
|
github.com/gorilla/sessions v1.2.2 h1:lqzMYz6bOfvn2WriPUjNByzeXIlVzURcPmgMczkmTjY=
|
||||||
github.com/gorilla/sessions v1.2.2/go.mod h1:ePLdVu+jbEgHH+KWw8I1z2wqd0BAdAQh/8LRvBeoNcQ=
|
github.com/gorilla/sessions v1.2.2/go.mod h1:ePLdVu+jbEgHH+KWw8I1z2wqd0BAdAQh/8LRvBeoNcQ=
|
||||||
|
github.com/h2non/gock v1.2.0 h1:K6ol8rfrRkUOefooBC8elXoaNGYkpp7y2qcxGG6BzUE=
|
||||||
|
github.com/h2non/gock v1.2.0/go.mod h1:tNhoxHYW2W42cYkYb1WqzdbYIieALC99kpYr7rH/BQk=
|
||||||
|
github.com/h2non/parth v0.0.0-20190131123155-b4df798d6542 h1:2VTzZjLZBgl62/EtslCrtky5vbi9dd7HrQPQIx6wqiw=
|
||||||
|
github.com/h2non/parth v0.0.0-20190131123155-b4df798d6542/go.mod h1:Ow0tF8D4Kplbc8s8sSb3V2oUCygFHVp8gC3Dn6U4MNI=
|
||||||
github.com/hashicorp/go-cleanhttp v0.5.2 h1:035FKYIWjmULyFRBKPs8TBQoi0x6d9G4xc9neXJWAZQ=
|
github.com/hashicorp/go-cleanhttp v0.5.2 h1:035FKYIWjmULyFRBKPs8TBQoi0x6d9G4xc9neXJWAZQ=
|
||||||
github.com/hashicorp/go-cleanhttp v0.5.2/go.mod h1:kO/YDlP8L1346E6Sodw+PrpBSV4/SoxCXGY6BqNFT48=
|
github.com/hashicorp/go-cleanhttp v0.5.2/go.mod h1:kO/YDlP8L1346E6Sodw+PrpBSV4/SoxCXGY6BqNFT48=
|
||||||
github.com/hashicorp/go-hclog v0.9.2/go.mod h1:5CU+agLiy3J7N7QjHK5d05KxGsuXiQLrjA0H7acj2lQ=
|
github.com/hashicorp/go-hclog v0.9.2/go.mod h1:5CU+agLiy3J7N7QjHK5d05KxGsuXiQLrjA0H7acj2lQ=
|
||||||
|
@ -553,8 +563,8 @@ github.com/klauspost/compress v1.17.8/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ib
|
||||||
github.com/klauspost/cpuid v1.2.0/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek=
|
github.com/klauspost/cpuid v1.2.0/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek=
|
||||||
github.com/klauspost/cpuid/v2 v2.0.1/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg=
|
github.com/klauspost/cpuid/v2 v2.0.1/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg=
|
||||||
github.com/klauspost/cpuid/v2 v2.0.12/go.mod h1:g2LTdtYhdyuGPqyWyv7qRAmj1WBqxuObKfj5c0PQa7c=
|
github.com/klauspost/cpuid/v2 v2.0.12/go.mod h1:g2LTdtYhdyuGPqyWyv7qRAmj1WBqxuObKfj5c0PQa7c=
|
||||||
github.com/klauspost/cpuid/v2 v2.2.6 h1:ndNyv040zDGIDh8thGkXYjnFtiN02M1PVVF+JE/48xc=
|
github.com/klauspost/cpuid/v2 v2.2.7 h1:ZWSB3igEs+d0qvnxR/ZBzXVmxkgt8DdzP6m9pfuVLDM=
|
||||||
github.com/klauspost/cpuid/v2 v2.2.6/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws=
|
github.com/klauspost/cpuid/v2 v2.2.7/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws=
|
||||||
github.com/klauspost/pgzip v1.2.5/go.mod h1:Ch1tH69qFZu15pkjo5kYi6mth2Zzwzt50oCQKQE9RUs=
|
github.com/klauspost/pgzip v1.2.5/go.mod h1:Ch1tH69qFZu15pkjo5kYi6mth2Zzwzt50oCQKQE9RUs=
|
||||||
github.com/klauspost/pgzip v1.2.6 h1:8RXeL5crjEUFnR2/Sn6GJNWtSQ3Dk8pq4CL3jvdDyjU=
|
github.com/klauspost/pgzip v1.2.6 h1:8RXeL5crjEUFnR2/Sn6GJNWtSQ3Dk8pq4CL3jvdDyjU=
|
||||||
github.com/klauspost/pgzip v1.2.6/go.mod h1:Ch1tH69qFZu15pkjo5kYi6mth2Zzwzt50oCQKQE9RUs=
|
github.com/klauspost/pgzip v1.2.6/go.mod h1:Ch1tH69qFZu15pkjo5kYi6mth2Zzwzt50oCQKQE9RUs=
|
||||||
|
@ -577,8 +587,8 @@ github.com/lestrrat-go/option v1.0.0/go.mod h1:5ZHFbivi4xwXxhxY9XHDe2FHo6/Z7WWmt
|
||||||
github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
|
github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
|
||||||
github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw=
|
github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw=
|
||||||
github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
|
github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
|
||||||
github.com/libdns/libdns v0.2.1 h1:Wu59T7wSHRgtA0cfxC+n1c/e+O3upJGWytknkmFEDis=
|
github.com/libdns/libdns v0.2.2 h1:O6ws7bAfRPaBsgAYt8MDe2HcNBGC29hkZ9MX2eUSX3s=
|
||||||
github.com/libdns/libdns v0.2.1/go.mod h1:yQCXzk1lEZmmCPa857bnk4TsOiqYasqpyOEeSObbb40=
|
github.com/libdns/libdns v0.2.2/go.mod h1:4Bj9+5CQiNMVGf87wjX4CY3HQJypUHRuLvlsfsZqLWQ=
|
||||||
github.com/lunny/log v0.0.0-20160921050905-7887c61bf0de/go.mod h1:3q8WtuPQsoRbatJuy3nvq/hRSvuBJrHHr+ybPPiNvHQ=
|
github.com/lunny/log v0.0.0-20160921050905-7887c61bf0de/go.mod h1:3q8WtuPQsoRbatJuy3nvq/hRSvuBJrHHr+ybPPiNvHQ=
|
||||||
github.com/lunny/nodb v0.0.0-20160621015157-fc1ef06ad4af/go.mod h1:Cqz6pqow14VObJ7peltM+2n3PWOz7yTrfUuGbVFkzN0=
|
github.com/lunny/nodb v0.0.0-20160621015157-fc1ef06ad4af/go.mod h1:Cqz6pqow14VObJ7peltM+2n3PWOz7yTrfUuGbVFkzN0=
|
||||||
github.com/lunny/vfsgen v0.0.0-20220105142115-2c99e1ffdfa0 h1:F/3FfGmKdiKFa8kL3YrpZ7pe9H4l4AzA1pbaOUnRvPI=
|
github.com/lunny/vfsgen v0.0.0-20220105142115-2c99e1ffdfa0 h1:F/3FfGmKdiKFa8kL3YrpZ7pe9H4l4AzA1pbaOUnRvPI=
|
||||||
|
@ -605,14 +615,14 @@ github.com/mattn/go-sqlite3 v1.14.22 h1:2gZY6PC6kBnID23Tichd1K+Z0oS6nE/XwU+Vz/5o
|
||||||
github.com/mattn/go-sqlite3 v1.14.22/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y=
|
github.com/mattn/go-sqlite3 v1.14.22/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y=
|
||||||
github.com/meilisearch/meilisearch-go v0.26.1 h1:3bmo2uLijX7kvBmiZ9LupVfC95TFcRJDgrRTzbOoE4A=
|
github.com/meilisearch/meilisearch-go v0.26.1 h1:3bmo2uLijX7kvBmiZ9LupVfC95TFcRJDgrRTzbOoE4A=
|
||||||
github.com/meilisearch/meilisearch-go v0.26.1/go.mod h1:SxuSqDcPBIykjWz1PX+KzsYzArNLSCadQodWs8extS0=
|
github.com/meilisearch/meilisearch-go v0.26.1/go.mod h1:SxuSqDcPBIykjWz1PX+KzsYzArNLSCadQodWs8extS0=
|
||||||
github.com/mholt/acmez v1.2.0 h1:1hhLxSgY5FvH5HCnGUuwbKY2VQVo8IU7rxXKSnZ7F30=
|
github.com/mholt/acmez/v2 v2.0.1 h1:3/3N0u1pLjMK4sNEAFSI+bcvzbPhRpY383sy1kLHJ6k=
|
||||||
github.com/mholt/acmez v1.2.0/go.mod h1:VT9YwH1xgNX1kmYY89gY8xPJC84BFAisjo8Egigt4kE=
|
github.com/mholt/acmez/v2 v2.0.1/go.mod h1:fX4c9r5jYwMyMsC+7tkYRxHibkOTgta5DIFGoe67e1U=
|
||||||
github.com/mholt/archiver/v3 v3.5.1 h1:rDjOBX9JSF5BvoJGvjqK479aL70qh9DIpZCl+k7Clwo=
|
github.com/mholt/archiver/v3 v3.5.1 h1:rDjOBX9JSF5BvoJGvjqK479aL70qh9DIpZCl+k7Clwo=
|
||||||
github.com/mholt/archiver/v3 v3.5.1/go.mod h1:e3dqJ7H78uzsRSEACH1joayhuSyhnonssnDhppzS1L4=
|
github.com/mholt/archiver/v3 v3.5.1/go.mod h1:e3dqJ7H78uzsRSEACH1joayhuSyhnonssnDhppzS1L4=
|
||||||
github.com/microcosm-cc/bluemonday v1.0.26 h1:xbqSvqzQMeEHCqMi64VAs4d8uy6Mequs3rQ0k/Khz58=
|
github.com/microcosm-cc/bluemonday v1.0.26 h1:xbqSvqzQMeEHCqMi64VAs4d8uy6Mequs3rQ0k/Khz58=
|
||||||
github.com/microcosm-cc/bluemonday v1.0.26/go.mod h1:JyzOCs9gkyQyjs+6h10UEVSe02CGwkhd72Xdqh78TWs=
|
github.com/microcosm-cc/bluemonday v1.0.26/go.mod h1:JyzOCs9gkyQyjs+6h10UEVSe02CGwkhd72Xdqh78TWs=
|
||||||
github.com/miekg/dns v1.1.58 h1:ca2Hdkz+cDg/7eNF6V56jjzuZ4aCAE+DbVkILdQWG/4=
|
github.com/miekg/dns v1.1.59 h1:C9EXc/UToRwKLhK5wKU/I4QVsBUc8kE6MkHBkeypWZs=
|
||||||
github.com/miekg/dns v1.1.58/go.mod h1:Ypv+3b/KadlvW9vJfXOTf300O4UqaHFzFCuHz+rPkBY=
|
github.com/miekg/dns v1.1.59/go.mod h1:nZpewl5p6IvctfgrckopVx2OlSEHPRO/U4SYkRklrEk=
|
||||||
github.com/minio/md5-simd v1.1.2 h1:Gdi1DZK69+ZVMoNHRXJyNcxrMA4dSxoYHZSQbirFg34=
|
github.com/minio/md5-simd v1.1.2 h1:Gdi1DZK69+ZVMoNHRXJyNcxrMA4dSxoYHZSQbirFg34=
|
||||||
github.com/minio/md5-simd v1.1.2/go.mod h1:MzdKDxYpY2BT9XQFocsiZf/NKVtR7nkE4RoEpN+20RM=
|
github.com/minio/md5-simd v1.1.2/go.mod h1:MzdKDxYpY2BT9XQFocsiZf/NKVtR7nkE4RoEpN+20RM=
|
||||||
github.com/minio/minio-go/v7 v7.0.70 h1:1u9NtMgfK1U42kUxcsl5v0yj6TEOPR497OAQxpJnn2g=
|
github.com/minio/minio-go/v7 v7.0.70 h1:1u9NtMgfK1U42kUxcsl5v0yj6TEOPR497OAQxpJnn2g=
|
||||||
|
@ -638,6 +648,8 @@ github.com/mschoch/smat v0.2.0 h1:8imxQsjDm8yFEAVBe7azKmKSgzSkZXDuKkSq9374khM=
|
||||||
github.com/mschoch/smat v0.2.0/go.mod h1:kc9mz7DoBKqDyiRL7VZN8KvXQMWeTaVnttLRXOlotKw=
|
github.com/mschoch/smat v0.2.0/go.mod h1:kc9mz7DoBKqDyiRL7VZN8KvXQMWeTaVnttLRXOlotKw=
|
||||||
github.com/msteinert/pam v1.2.0 h1:mYfjlvN2KYs2Pb9G6nb/1f/nPfAttT/Jee5Sq9r3bGE=
|
github.com/msteinert/pam v1.2.0 h1:mYfjlvN2KYs2Pb9G6nb/1f/nPfAttT/Jee5Sq9r3bGE=
|
||||||
github.com/msteinert/pam v1.2.0/go.mod h1:d2n0DCUK8rGecChV3JzvmsDjOY4R7AYbsNxAT+ftQl0=
|
github.com/msteinert/pam v1.2.0/go.mod h1:d2n0DCUK8rGecChV3JzvmsDjOY4R7AYbsNxAT+ftQl0=
|
||||||
|
github.com/nbio/st v0.0.0-20140626010706-e9e8d9816f32 h1:W6apQkHrMkS0Muv8G/TipAy/FJl/rCYT0+EuS8+Z0z4=
|
||||||
|
github.com/nbio/st v0.0.0-20140626010706-e9e8d9816f32/go.mod h1:9wM+0iRr9ahx58uYLpLIr5fm8diHn0JbqRycJi6w0Ms=
|
||||||
github.com/niklasfasching/go-org v1.7.0 h1:vyMdcMWWTe/XmANk19F4k8XGBYg0GQ/gJGMimOjGMek=
|
github.com/niklasfasching/go-org v1.7.0 h1:vyMdcMWWTe/XmANk19F4k8XGBYg0GQ/gJGMimOjGMek=
|
||||||
github.com/niklasfasching/go-org v1.7.0/go.mod h1:WuVm4d45oePiE0eX25GqTDQIt/qPW1T9DGkRscqLW5o=
|
github.com/niklasfasching/go-org v1.7.0/go.mod h1:WuVm4d45oePiE0eX25GqTDQIt/qPW1T9DGkRscqLW5o=
|
||||||
github.com/nwaples/rardecode v1.1.0/go.mod h1:5DzqNKiOdpKKBH87u8VlvAnPZMXcGRhxWkRpHbbfGS0=
|
github.com/nwaples/rardecode v1.1.0/go.mod h1:5DzqNKiOdpKKBH87u8VlvAnPZMXcGRhxWkRpHbbfGS0=
|
||||||
|
@ -863,12 +875,12 @@ go.uber.org/atomic v1.9.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
|
||||||
go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE=
|
go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE=
|
||||||
go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0=
|
go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0=
|
||||||
go.uber.org/goleak v1.1.10/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A=
|
go.uber.org/goleak v1.1.10/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A=
|
||||||
go.uber.org/goleak v1.2.1 h1:NBol2c7O1ZokfZ0LEU9K6Whx/KnwvepVetCUhtKja4A=
|
go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
|
||||||
go.uber.org/goleak v1.2.1/go.mod h1:qlT2yGI9QafXHhZZLxlSuNsMw3FFLxBr+tBRlmO1xH4=
|
go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE=
|
||||||
go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0=
|
go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0=
|
||||||
go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y=
|
go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y=
|
||||||
go.uber.org/zap v1.26.0 h1:sI7k6L95XOKS281NhVKOFCUNIvv9e0w4BF8N3u+tCRo=
|
go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8=
|
||||||
go.uber.org/zap v1.26.0/go.mod h1:dtElttAiwGvoJ/vj4IwHBS/gXsEu/pZ50mUIRWuG0so=
|
go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E=
|
||||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||||
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||||
golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||||
|
@ -884,8 +896,8 @@ golang.org/x/crypto v0.3.1-0.20221117191849-2c476679df9a/go.mod h1:hebNnKkNXi2Uz
|
||||||
golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU=
|
golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU=
|
||||||
golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc=
|
golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc=
|
||||||
golang.org/x/crypto v0.17.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4=
|
golang.org/x/crypto v0.17.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4=
|
||||||
golang.org/x/crypto v0.22.0 h1:g1v0xeRhjcugydODzvb3mEM9SQ0HGp9s/nh3COQ/C30=
|
golang.org/x/crypto v0.23.0 h1:dIJU/v2J8Mdglj/8rJ6UUOM3Zc9zLZxVZwwxMooUSAI=
|
||||||
golang.org/x/crypto v0.22.0/go.mod h1:vr6Su+7cTlO45qkww3VDJlzDn0ctJvRgYbC2NvXHt+M=
|
golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8=
|
||||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||||
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||||
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
|
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
|
||||||
|
@ -922,8 +934,8 @@ golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||||
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||||
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
|
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
|
||||||
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
|
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
|
||||||
golang.org/x/mod v0.16.0 h1:QX4fJ0Rr5cPQCF7O9lh9Se4pmwfwskqZfq5moyldzic=
|
golang.org/x/mod v0.17.0 h1:zY54UmvipHiNd+pm+m0x9KhZ9hl1/7QNMyxXbc6ICqA=
|
||||||
golang.org/x/mod v0.16.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
|
golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
|
||||||
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
|
@ -964,8 +976,8 @@ golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
|
||||||
golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc=
|
golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc=
|
||||||
golang.org/x/net v0.9.0/go.mod h1:d48xBJpPfHeWQsugry2m+kC02ZBRGRgulfHnEXEuWns=
|
golang.org/x/net v0.9.0/go.mod h1:d48xBJpPfHeWQsugry2m+kC02ZBRGRgulfHnEXEuWns=
|
||||||
golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
|
golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
|
||||||
golang.org/x/net v0.24.0 h1:1PcaxkF854Fu3+lvBIx5SYn9wRlBzzcnHZSiaFFAb0w=
|
golang.org/x/net v0.25.0 h1:d/OCCoBEUq33pjydKrGQhw7IlUPI2Oylr+8qLx49kac=
|
||||||
golang.org/x/net v0.24.0/go.mod h1:2Q7sJY5mzlzWjKtYUEXSlBWCdyaioyXzRB2RtU8KVE8=
|
golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM=
|
||||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||||
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||||
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||||
|
@ -986,8 +998,8 @@ golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJ
|
||||||
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sync v0.6.0 h1:5BMeUDZ7vkXGfEr1x9B4bRcTH4lpkTkpdh0T/J+qjbQ=
|
golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M=
|
||||||
golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
||||||
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
|
@ -1043,8 +1055,8 @@ golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||||
golang.org/x/sys v0.19.0 h1:q5f1RH2jigJ1MoAWp2KTp3gm5zAGFUTarQZ5U386+4o=
|
golang.org/x/sys v0.20.0 h1:Od9JTbYCk261bKm4M/mw7AklTlFYIa0bIp9BgSm1S8Y=
|
||||||
golang.org/x/sys v0.19.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||||
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
|
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
|
||||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||||
|
@ -1055,8 +1067,8 @@ golang.org/x/term v0.7.0/go.mod h1:P32HKFT3hSsZrRxla30E9HqToFYAQPCMs/zFMBUFqPY=
|
||||||
golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo=
|
golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo=
|
||||||
golang.org/x/term v0.12.0/go.mod h1:owVbMEjm3cBLCHdkQu9b1opXd4ETQWc3BhuQGKgXgvU=
|
golang.org/x/term v0.12.0/go.mod h1:owVbMEjm3cBLCHdkQu9b1opXd4ETQWc3BhuQGKgXgvU=
|
||||||
golang.org/x/term v0.15.0/go.mod h1:BDl952bC7+uMoWR75FIrCDx79TPU9oHkTZ9yRbYOrX0=
|
golang.org/x/term v0.15.0/go.mod h1:BDl952bC7+uMoWR75FIrCDx79TPU9oHkTZ9yRbYOrX0=
|
||||||
golang.org/x/term v0.19.0 h1:+ThwsDv+tYfnJFhF4L8jITxu1tdTWRTZpdsWgEgjL6Q=
|
golang.org/x/term v0.20.0 h1:VnkxpohqXaOBYJtBmEppKUG6mXpi+4O6purfc2+sMhw=
|
||||||
golang.org/x/term v0.19.0/go.mod h1:2CuTdWZ7KHSQwUzKva0cbMg6q2DMI3Mmxp+gKJbskEk=
|
golang.org/x/term v0.20.0/go.mod h1:8UkIAJTvZgivsXaD6/pH6U9ecQzZ45awqEOzuCvwpFY=
|
||||||
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||||
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||||
|
@ -1070,8 +1082,9 @@ golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
||||||
golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
|
golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
|
||||||
golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
|
golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
|
||||||
golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
|
golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
|
||||||
golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ=
|
|
||||||
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
|
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
|
||||||
|
golang.org/x/text v0.15.0 h1:h1V/4gjBv8v9cjcR6+AR5+/cIYK5N/WAgiv4xlsEtAk=
|
||||||
|
golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
|
||||||
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||||
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||||
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||||
|
@ -1127,8 +1140,8 @@ golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4f
|
||||||
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||||
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
|
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
|
||||||
golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
|
golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
|
||||||
golang.org/x/tools v0.17.0 h1:FvmRgNOcs3kOa+T20R1uhfP9F6HgG2mfxDv1vrx1Htc=
|
golang.org/x/tools v0.21.0 h1:qc0xYgIbsSDt9EyWz05J5wfa7LOVW0YTLOXrqdLAWIw=
|
||||||
golang.org/x/tools v0.17.0/go.mod h1:xsh6VxdV005rRVaS6SSAf9oiAqljS7UZUacMZ8Bnsps=
|
golang.org/x/tools v0.21.0/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk=
|
||||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
|
|
|
@ -13,7 +13,7 @@ import (
|
||||||
|
|
||||||
// ActionTasksVersion
|
// ActionTasksVersion
|
||||||
// If both ownerID and repoID is zero, its scope is global.
|
// If both ownerID and repoID is zero, its scope is global.
|
||||||
// If ownerID is not zero and repoID is zero, its scope is org (there is no user-level runner currrently).
|
// If ownerID is not zero and repoID is zero, its scope is org (there is no user-level runner currently).
|
||||||
// If ownerID is zero and repoID is not zero, its scope is repo.
|
// If ownerID is zero and repoID is not zero, its scope is repo.
|
||||||
type ActionTasksVersion struct {
|
type ActionTasksVersion struct {
|
||||||
ID int64 `xorm:"pk autoincr"`
|
ID int64 `xorm:"pk autoincr"`
|
||||||
|
|
|
@ -431,14 +431,15 @@ func (a *Action) GetIssueContent(ctx context.Context) string {
|
||||||
// GetFeedsOptions options for retrieving feeds
|
// GetFeedsOptions options for retrieving feeds
|
||||||
type GetFeedsOptions struct {
|
type GetFeedsOptions struct {
|
||||||
db.ListOptions
|
db.ListOptions
|
||||||
RequestedUser *user_model.User // the user we want activity for
|
RequestedUser *user_model.User // the user we want activity for
|
||||||
RequestedTeam *organization.Team // the team we want activity for
|
RequestedTeam *organization.Team // the team we want activity for
|
||||||
RequestedRepo *repo_model.Repository // the repo we want activity for
|
RequestedRepo *repo_model.Repository // the repo we want activity for
|
||||||
Actor *user_model.User // the user viewing the activity
|
Actor *user_model.User // the user viewing the activity
|
||||||
IncludePrivate bool // include private actions
|
IncludePrivate bool // include private actions
|
||||||
OnlyPerformedBy bool // only actions performed by requested user
|
OnlyPerformedBy bool // only actions performed by requested user
|
||||||
IncludeDeleted bool // include deleted actions
|
OnlyPerformedByActor bool // only actions performed by the original actor
|
||||||
Date string // the day we want activity for: YYYY-MM-DD
|
IncludeDeleted bool // include deleted actions
|
||||||
|
Date string // the day we want activity for: YYYY-MM-DD
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetFeeds returns actions according to the provided options
|
// GetFeeds returns actions according to the provided options
|
||||||
|
@ -481,6 +482,10 @@ func ActivityReadable(user, doer *user_model.User) bool {
|
||||||
func activityQueryCondition(ctx context.Context, opts GetFeedsOptions) (builder.Cond, error) {
|
func activityQueryCondition(ctx context.Context, opts GetFeedsOptions) (builder.Cond, error) {
|
||||||
cond := builder.NewCond()
|
cond := builder.NewCond()
|
||||||
|
|
||||||
|
if opts.OnlyPerformedByActor {
|
||||||
|
cond = cond.And(builder.Expr("`action`.user_id = `action`.act_user_id"))
|
||||||
|
}
|
||||||
|
|
||||||
if opts.RequestedTeam != nil && opts.RequestedUser == nil {
|
if opts.RequestedTeam != nil && opts.RequestedUser == nil {
|
||||||
org, err := user_model.GetUserByID(ctx, opts.RequestedTeam.OrgID)
|
org, err := user_model.GetUserByID(ctx, opts.RequestedTeam.OrgID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -60,7 +60,7 @@ func TestOAuth2Application_ContainsRedirectURI_WithPort(t *testing.T) {
|
||||||
// not loopback
|
// not loopback
|
||||||
assert.False(t, app.ContainsRedirectURI("http://192.168.0.1:9954/"))
|
assert.False(t, app.ContainsRedirectURI("http://192.168.0.1:9954/"))
|
||||||
assert.False(t, app.ContainsRedirectURI("http://intranet:3456/"))
|
assert.False(t, app.ContainsRedirectURI("http://intranet:3456/"))
|
||||||
// unparseable
|
// unparsable
|
||||||
assert.False(t, app.ContainsRedirectURI(":"))
|
assert.False(t, app.ContainsRedirectURI(":"))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -85,7 +85,7 @@ func TestAuthSession(t *testing.T) {
|
||||||
err = auth.DestroySession(db.DefaultContext, key)
|
err = auth.DestroySession(db.DefaultContext, key)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
|
||||||
// Ensure it doens't exists.
|
// Ensure it doesn't exists.
|
||||||
ok, err = auth.ExistSession(db.DefaultContext, key)
|
ok, err = auth.ExistSession(db.DefaultContext, key)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.False(t, ok)
|
assert.False(t, ok)
|
||||||
|
|
|
@ -58,6 +58,7 @@ type Engine interface {
|
||||||
SumInt(bean any, columnName string) (res int64, err error)
|
SumInt(bean any, columnName string) (res int64, err error)
|
||||||
Sync(...any) error
|
Sync(...any) error
|
||||||
Select(string) *xorm.Session
|
Select(string) *xorm.Session
|
||||||
|
SetExpr(string, any) *xorm.Session
|
||||||
NotIn(string, ...any) *xorm.Session
|
NotIn(string, ...any) *xorm.Session
|
||||||
OrderBy(any, ...any) *xorm.Session
|
OrderBy(any, ...any) *xorm.Session
|
||||||
Exist(...any) (bool, error)
|
Exist(...any) (bool, error)
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
-
|
-
|
||||||
id: 1001
|
id: 1001
|
||||||
type: 0 # pull request
|
type: 0 # pull request
|
||||||
status: 2 # mergable
|
status: 2 # mergeable
|
||||||
issue_id: 1001
|
issue_id: 1001
|
||||||
index: 1001
|
index: 1001
|
||||||
head_repo_id: 1
|
head_repo_id: 1
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
repo_id: 1
|
repo_id: 1
|
||||||
state: "warning"
|
state: "warning"
|
||||||
sha: "1234123412341234123412341234123412341234"
|
sha: "1234123412341234123412341234123412341234"
|
||||||
target_url: https://example.com/converage/
|
target_url: https://example.com/coverage/
|
||||||
description: My awesome Coverage service
|
description: My awesome Coverage service
|
||||||
context: cov/awesomeness
|
context: cov/awesomeness
|
||||||
creator_id: 2
|
creator_id: 2
|
||||||
|
@ -26,7 +26,7 @@
|
||||||
repo_id: 1
|
repo_id: 1
|
||||||
state: "success"
|
state: "success"
|
||||||
sha: "1234123412341234123412341234123412341234"
|
sha: "1234123412341234123412341234123412341234"
|
||||||
target_url: https://example.com/converage/
|
target_url: https://example.com/coverage/
|
||||||
description: My awesome Coverage service
|
description: My awesome Coverage service
|
||||||
context: cov/awesomeness
|
context: cov/awesomeness
|
||||||
creator_id: 2
|
creator_id: 2
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
-
|
-
|
||||||
id: 1
|
id: 1
|
||||||
type: 0 # gitea pull request
|
type: 0 # gitea pull request
|
||||||
status: 2 # mergable
|
status: 2 # mergeable
|
||||||
issue_id: 2
|
issue_id: 2
|
||||||
index: 2
|
index: 2
|
||||||
head_repo_id: 1
|
head_repo_id: 1
|
||||||
|
@ -16,7 +16,7 @@
|
||||||
-
|
-
|
||||||
id: 2
|
id: 2
|
||||||
type: 0 # gitea pull request
|
type: 0 # gitea pull request
|
||||||
status: 2 # mergable
|
status: 2 # mergeable
|
||||||
issue_id: 3
|
issue_id: 3
|
||||||
index: 3
|
index: 3
|
||||||
head_repo_id: 1
|
head_repo_id: 1
|
||||||
|
@ -29,7 +29,7 @@
|
||||||
-
|
-
|
||||||
id: 3
|
id: 3
|
||||||
type: 0 # gitea pull request
|
type: 0 # gitea pull request
|
||||||
status: 2 # mergable
|
status: 2 # mergeable
|
||||||
issue_id: 8
|
issue_id: 8
|
||||||
index: 1
|
index: 1
|
||||||
head_repo_id: 11
|
head_repo_id: 11
|
||||||
|
@ -42,7 +42,7 @@
|
||||||
-
|
-
|
||||||
id: 4
|
id: 4
|
||||||
type: 0 # gitea pull request
|
type: 0 # gitea pull request
|
||||||
status: 2 # mergable
|
status: 2 # mergeable
|
||||||
issue_id: 9
|
issue_id: 9
|
||||||
index: 1
|
index: 1
|
||||||
head_repo_id: 48
|
head_repo_id: 48
|
||||||
|
@ -55,7 +55,7 @@
|
||||||
-
|
-
|
||||||
id: 5 # this PR is outdated (one commit behind branch1 )
|
id: 5 # this PR is outdated (one commit behind branch1 )
|
||||||
type: 0 # gitea pull request
|
type: 0 # gitea pull request
|
||||||
status: 2 # mergable
|
status: 2 # mergeable
|
||||||
issue_id: 11
|
issue_id: 11
|
||||||
index: 5
|
index: 5
|
||||||
head_repo_id: 1
|
head_repo_id: 1
|
||||||
|
@ -68,7 +68,7 @@
|
||||||
-
|
-
|
||||||
id: 6
|
id: 6
|
||||||
type: 0 # gitea pull request
|
type: 0 # gitea pull request
|
||||||
status: 2 # mergable
|
status: 2 # mergeable
|
||||||
issue_id: 12
|
issue_id: 12
|
||||||
index: 2
|
index: 2
|
||||||
head_repo_id: 3
|
head_repo_id: 3
|
||||||
|
@ -81,7 +81,7 @@
|
||||||
-
|
-
|
||||||
id: 7
|
id: 7
|
||||||
type: 0 # gitea pull request
|
type: 0 # gitea pull request
|
||||||
status: 2 # mergable
|
status: 2 # mergeable
|
||||||
issue_id: 19
|
issue_id: 19
|
||||||
index: 1
|
index: 1
|
||||||
head_repo_id: 58
|
head_repo_id: 58
|
||||||
|
@ -94,7 +94,7 @@
|
||||||
-
|
-
|
||||||
id: 8
|
id: 8
|
||||||
type: 0 # gitea pull request
|
type: 0 # gitea pull request
|
||||||
status: 2 # mergable
|
status: 2 # mergeable
|
||||||
issue_id: 20
|
issue_id: 20
|
||||||
index: 1
|
index: 1
|
||||||
head_repo_id: 23
|
head_repo_id: 23
|
||||||
|
@ -103,7 +103,7 @@
|
||||||
-
|
-
|
||||||
id: 9
|
id: 9
|
||||||
type: 0 # gitea pull request
|
type: 0 # gitea pull request
|
||||||
status: 2 # mergable
|
status: 2 # mergeable
|
||||||
issue_id: 21
|
issue_id: 21
|
||||||
index: 1
|
index: 1
|
||||||
head_repo_id: 60
|
head_repo_id: 60
|
||||||
|
@ -112,7 +112,7 @@
|
||||||
-
|
-
|
||||||
id: 10
|
id: 10
|
||||||
type: 0 # gitea pull request
|
type: 0 # gitea pull request
|
||||||
status: 2 # mergable
|
status: 2 # mergeable
|
||||||
issue_id: 22
|
issue_id: 22
|
||||||
index: 1
|
index: 1
|
||||||
head_repo_id: 61
|
head_repo_id: 61
|
||||||
|
|
|
@ -362,36 +362,16 @@ func GetLatestCommitStatusForRepoCommitIDs(ctx context.Context, repoID int64, co
|
||||||
|
|
||||||
// FindRepoRecentCommitStatusContexts returns repository's recent commit status contexts
|
// FindRepoRecentCommitStatusContexts returns repository's recent commit status contexts
|
||||||
func FindRepoRecentCommitStatusContexts(ctx context.Context, repoID int64, before time.Duration) ([]string, error) {
|
func FindRepoRecentCommitStatusContexts(ctx context.Context, repoID int64, before time.Duration) ([]string, error) {
|
||||||
type result struct {
|
|
||||||
Index int64
|
|
||||||
SHA string
|
|
||||||
}
|
|
||||||
getBase := func() *xorm.Session {
|
|
||||||
return db.GetEngine(ctx).Table(&CommitStatus{}).Where("repo_id = ?", repoID)
|
|
||||||
}
|
|
||||||
|
|
||||||
start := timeutil.TimeStampNow().AddDuration(-before)
|
start := timeutil.TimeStampNow().AddDuration(-before)
|
||||||
results := make([]result, 0, 10)
|
|
||||||
|
|
||||||
sess := getBase().And("updated_unix >= ?", start).
|
var contexts []string
|
||||||
Select("max( `index` ) as `index`, sha").
|
if err := db.GetEngine(ctx).Table("commit_status").
|
||||||
GroupBy("context_hash, sha").OrderBy("max( `index` ) desc")
|
Where("repo_id = ?", repoID).And("updated_unix >= ?", start).
|
||||||
|
Cols("context").Distinct().Find(&contexts); err != nil {
|
||||||
err := sess.Find(&results)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
contexts := make([]string, 0, len(results))
|
return contexts, nil
|
||||||
if len(results) == 0 {
|
|
||||||
return contexts, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
conds := make([]builder.Cond, 0, len(results))
|
|
||||||
for _, result := range results {
|
|
||||||
conds = append(conds, builder.Eq{"`index`": result.Index, "sha": result.SHA})
|
|
||||||
}
|
|
||||||
return contexts, getBase().And(builder.Or(conds...)).Select("context").Find(&contexts)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewCommitStatusOptions holds options for creating a CommitStatus
|
// NewCommitStatusOptions holds options for creating a CommitStatus
|
||||||
|
|
|
@ -5,11 +5,15 @@ package git_test
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"testing"
|
"testing"
|
||||||
|
"time"
|
||||||
|
|
||||||
"code.gitea.io/gitea/models/db"
|
"code.gitea.io/gitea/models/db"
|
||||||
git_model "code.gitea.io/gitea/models/git"
|
git_model "code.gitea.io/gitea/models/git"
|
||||||
repo_model "code.gitea.io/gitea/models/repo"
|
repo_model "code.gitea.io/gitea/models/repo"
|
||||||
"code.gitea.io/gitea/models/unittest"
|
"code.gitea.io/gitea/models/unittest"
|
||||||
|
user_model "code.gitea.io/gitea/models/user"
|
||||||
|
"code.gitea.io/gitea/modules/git"
|
||||||
|
"code.gitea.io/gitea/modules/gitrepo"
|
||||||
"code.gitea.io/gitea/modules/structs"
|
"code.gitea.io/gitea/modules/structs"
|
||||||
|
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
|
@ -183,3 +187,55 @@ func Test_CalcCommitStatus(t *testing.T) {
|
||||||
assert.Equal(t, kase.expected, git_model.CalcCommitStatus(kase.statuses))
|
assert.Equal(t, kase.expected, git_model.CalcCommitStatus(kase.statuses))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestFindRepoRecentCommitStatusContexts(t *testing.T) {
|
||||||
|
assert.NoError(t, unittest.PrepareTestDatabase())
|
||||||
|
|
||||||
|
repo2 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 2})
|
||||||
|
user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
|
||||||
|
gitRepo, err := gitrepo.OpenRepository(git.DefaultContext, repo2)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
defer gitRepo.Close()
|
||||||
|
|
||||||
|
commit, err := gitRepo.GetBranchCommit(repo2.DefaultBranch)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
|
||||||
|
defer func() {
|
||||||
|
_, err := db.DeleteByBean(db.DefaultContext, &git_model.CommitStatus{
|
||||||
|
RepoID: repo2.ID,
|
||||||
|
CreatorID: user2.ID,
|
||||||
|
SHA: commit.ID.String(),
|
||||||
|
})
|
||||||
|
assert.NoError(t, err)
|
||||||
|
}()
|
||||||
|
|
||||||
|
err = git_model.NewCommitStatus(db.DefaultContext, git_model.NewCommitStatusOptions{
|
||||||
|
Repo: repo2,
|
||||||
|
Creator: user2,
|
||||||
|
SHA: commit.ID,
|
||||||
|
CommitStatus: &git_model.CommitStatus{
|
||||||
|
State: structs.CommitStatusFailure,
|
||||||
|
TargetURL: "https://example.com/tests/",
|
||||||
|
Context: "compliance/lint-backend",
|
||||||
|
},
|
||||||
|
})
|
||||||
|
assert.NoError(t, err)
|
||||||
|
|
||||||
|
err = git_model.NewCommitStatus(db.DefaultContext, git_model.NewCommitStatusOptions{
|
||||||
|
Repo: repo2,
|
||||||
|
Creator: user2,
|
||||||
|
SHA: commit.ID,
|
||||||
|
CommitStatus: &git_model.CommitStatus{
|
||||||
|
State: structs.CommitStatusSuccess,
|
||||||
|
TargetURL: "https://example.com/tests/",
|
||||||
|
Context: "compliance/lint-backend",
|
||||||
|
},
|
||||||
|
})
|
||||||
|
assert.NoError(t, err)
|
||||||
|
|
||||||
|
contexts, err := git_model.FindRepoRecentCommitStatusContexts(db.DefaultContext, repo2.ID, time.Hour)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
if assert.Len(t, contexts, 1) {
|
||||||
|
assert.Equal(t, "compliance/lint-backend", contexts[0])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -5,11 +5,11 @@ package issues
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
|
||||||
|
|
||||||
"code.gitea.io/gitea/models/db"
|
"code.gitea.io/gitea/models/db"
|
||||||
project_model "code.gitea.io/gitea/models/project"
|
project_model "code.gitea.io/gitea/models/project"
|
||||||
user_model "code.gitea.io/gitea/models/user"
|
user_model "code.gitea.io/gitea/models/user"
|
||||||
|
"code.gitea.io/gitea/modules/util"
|
||||||
)
|
)
|
||||||
|
|
||||||
// LoadProject load the project the issue was assigned to
|
// LoadProject load the project the issue was assigned to
|
||||||
|
@ -90,58 +90,73 @@ func LoadIssuesFromBoardList(ctx context.Context, bs project_model.BoardList) (m
|
||||||
return issuesMap, nil
|
return issuesMap, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// ChangeProjectAssign changes the project associated with an issue
|
// IssueAssignOrRemoveProject changes the project associated with an issue
|
||||||
func ChangeProjectAssign(ctx context.Context, issue *Issue, doer *user_model.User, newProjectID int64) error {
|
// If newProjectID is 0, the issue is removed from the project
|
||||||
ctx, committer, err := db.TxContext(ctx)
|
func IssueAssignOrRemoveProject(ctx context.Context, issue *Issue, doer *user_model.User, newProjectID, newColumnID int64) error {
|
||||||
if err != nil {
|
return db.WithTx(ctx, func(ctx context.Context) error {
|
||||||
return err
|
oldProjectID := issue.projectID(ctx)
|
||||||
}
|
|
||||||
defer committer.Close()
|
|
||||||
|
|
||||||
if err := addUpdateIssueProject(ctx, issue, doer, newProjectID); err != nil {
|
if err := issue.LoadRepo(ctx); err != nil {
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
return committer.Commit()
|
|
||||||
}
|
|
||||||
|
|
||||||
func addUpdateIssueProject(ctx context.Context, issue *Issue, doer *user_model.User, newProjectID int64) error {
|
|
||||||
oldProjectID := issue.projectID(ctx)
|
|
||||||
|
|
||||||
if err := issue.LoadRepo(ctx); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Only check if we add a new project and not remove it.
|
|
||||||
if newProjectID > 0 {
|
|
||||||
newProject, err := project_model.GetProjectByID(ctx, newProjectID)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if newProject.RepoID != issue.RepoID && newProject.OwnerID != issue.Repo.OwnerID {
|
|
||||||
return fmt.Errorf("issue's repository is not the same as project's repository")
|
// Only check if we add a new project and not remove it.
|
||||||
|
if newProjectID > 0 {
|
||||||
|
newProject, err := project_model.GetProjectByID(ctx, newProjectID)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if !newProject.CanBeAccessedByOwnerRepo(issue.Repo.OwnerID, issue.Repo) {
|
||||||
|
return util.NewPermissionDeniedErrorf("issue %d can't be accessed by project %d", issue.ID, newProject.ID)
|
||||||
|
}
|
||||||
|
if newColumnID == 0 {
|
||||||
|
newDefaultColumn, err := newProject.GetDefaultBoard(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
newColumnID = newDefaultColumn.ID
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if _, err := db.GetEngine(ctx).Where("project_issue.issue_id=?", issue.ID).Delete(&project_model.ProjectIssue{}); err != nil {
|
if _, err := db.GetEngine(ctx).Where("project_issue.issue_id=?", issue.ID).Delete(&project_model.ProjectIssue{}); err != nil {
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
if oldProjectID > 0 || newProjectID > 0 {
|
|
||||||
if _, err := CreateComment(ctx, &CreateCommentOptions{
|
|
||||||
Type: CommentTypeProject,
|
|
||||||
Doer: doer,
|
|
||||||
Repo: issue.Repo,
|
|
||||||
Issue: issue,
|
|
||||||
OldProjectID: oldProjectID,
|
|
||||||
ProjectID: newProjectID,
|
|
||||||
}); err != nil {
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
return db.Insert(ctx, &project_model.ProjectIssue{
|
if oldProjectID > 0 || newProjectID > 0 {
|
||||||
IssueID: issue.ID,
|
if _, err := CreateComment(ctx, &CreateCommentOptions{
|
||||||
ProjectID: newProjectID,
|
Type: CommentTypeProject,
|
||||||
|
Doer: doer,
|
||||||
|
Repo: issue.Repo,
|
||||||
|
Issue: issue,
|
||||||
|
OldProjectID: oldProjectID,
|
||||||
|
ProjectID: newProjectID,
|
||||||
|
}); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if newProjectID == 0 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
if newColumnID == 0 {
|
||||||
|
panic("newColumnID must not be zero") // shouldn't happen
|
||||||
|
}
|
||||||
|
|
||||||
|
res := struct {
|
||||||
|
MaxSorting int64
|
||||||
|
IssueCount int64
|
||||||
|
}{}
|
||||||
|
if _, err := db.GetEngine(ctx).Select("max(sorting) as max_sorting, count(*) as issue_count").Table("project_issue").
|
||||||
|
Where("project_id=?", newProjectID).
|
||||||
|
And("project_board_id=?", newColumnID).
|
||||||
|
Get(&res); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
newSorting := util.Iif(res.IssueCount > 0, res.MaxSorting+1, 0)
|
||||||
|
return db.Insert(ctx, &project_model.ProjectIssue{
|
||||||
|
IssueID: issue.ID,
|
||||||
|
ProjectID: newProjectID,
|
||||||
|
ProjectBoardID: newColumnID,
|
||||||
|
Sorting: newSorting,
|
||||||
|
})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -450,65 +450,6 @@ func UpdateIssueMentions(ctx context.Context, issueID int64, mentions []*user_mo
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// UpdateIssueByAPI updates all allowed fields of given issue.
|
|
||||||
// If the issue status is changed a statusChangeComment is returned
|
|
||||||
// similarly if the title is changed the titleChanged bool is set to true
|
|
||||||
func UpdateIssueByAPI(ctx context.Context, issue *Issue, doer *user_model.User) (statusChangeComment *Comment, titleChanged bool, err error) {
|
|
||||||
ctx, committer, err := db.TxContext(ctx)
|
|
||||||
if err != nil {
|
|
||||||
return nil, false, err
|
|
||||||
}
|
|
||||||
defer committer.Close()
|
|
||||||
|
|
||||||
if err := issue.LoadRepo(ctx); err != nil {
|
|
||||||
return nil, false, fmt.Errorf("loadRepo: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Reload the issue
|
|
||||||
currentIssue, err := GetIssueByID(ctx, issue.ID)
|
|
||||||
if err != nil {
|
|
||||||
return nil, false, err
|
|
||||||
}
|
|
||||||
|
|
||||||
sess := db.GetEngine(ctx).ID(issue.ID)
|
|
||||||
cols := []string{"name", "content", "milestone_id", "priority", "deadline_unix", "is_locked"}
|
|
||||||
if issue.NoAutoTime {
|
|
||||||
cols = append(cols, "updated_unix")
|
|
||||||
sess.NoAutoTime()
|
|
||||||
}
|
|
||||||
if _, err := sess.Cols(cols...).Update(issue); err != nil {
|
|
||||||
return nil, false, err
|
|
||||||
}
|
|
||||||
|
|
||||||
titleChanged = currentIssue.Title != issue.Title
|
|
||||||
if titleChanged {
|
|
||||||
opts := &CreateCommentOptions{
|
|
||||||
Type: CommentTypeChangeTitle,
|
|
||||||
Doer: doer,
|
|
||||||
Repo: issue.Repo,
|
|
||||||
Issue: issue,
|
|
||||||
OldTitle: currentIssue.Title,
|
|
||||||
NewTitle: issue.Title,
|
|
||||||
}
|
|
||||||
_, err := CreateComment(ctx, opts)
|
|
||||||
if err != nil {
|
|
||||||
return nil, false, fmt.Errorf("createComment: %w", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if currentIssue.IsClosed != issue.IsClosed {
|
|
||||||
statusChangeComment, err = doChangeIssueStatus(ctx, issue, doer, false)
|
|
||||||
if err != nil {
|
|
||||||
return nil, false, err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := issue.AddCrossReferences(ctx, doer, true); err != nil {
|
|
||||||
return nil, false, err
|
|
||||||
}
|
|
||||||
return statusChangeComment, titleChanged, committer.Commit()
|
|
||||||
}
|
|
||||||
|
|
||||||
// UpdateIssueDeadline updates an issue deadline and adds comments. Setting a deadline to 0 means deleting it.
|
// UpdateIssueDeadline updates an issue deadline and adds comments. Setting a deadline to 0 means deleting it.
|
||||||
func UpdateIssueDeadline(ctx context.Context, issue *Issue, deadlineUnix timeutil.TimeStamp, doer *user_model.User) (err error) {
|
func UpdateIssueDeadline(ctx context.Context, issue *Issue, deadlineUnix timeutil.TimeStamp, doer *user_model.User) (err error) {
|
||||||
// if the deadline hasn't changed do nothing
|
// if the deadline hasn't changed do nothing
|
||||||
|
|
|
@ -34,7 +34,7 @@ func TestXRef_AddCrossReferences(t *testing.T) {
|
||||||
|
|
||||||
// Comment on PR to reopen issue #1
|
// Comment on PR to reopen issue #1
|
||||||
content = fmt.Sprintf("content2, reopens #%d", itarget.Index)
|
content = fmt.Sprintf("content2, reopens #%d", itarget.Index)
|
||||||
c := testCreateComment(t, 1, 2, pr.ID, content)
|
c := testCreateComment(t, 2, pr.ID, content)
|
||||||
ref = unittest.AssertExistsAndLoadBean(t, &issues_model.Comment{IssueID: itarget.ID, RefIssueID: pr.ID, RefCommentID: c.ID})
|
ref = unittest.AssertExistsAndLoadBean(t, &issues_model.Comment{IssueID: itarget.ID, RefIssueID: pr.ID, RefCommentID: c.ID})
|
||||||
assert.Equal(t, issues_model.CommentTypeCommentRef, ref.Type)
|
assert.Equal(t, issues_model.CommentTypeCommentRef, ref.Type)
|
||||||
assert.Equal(t, pr.RepoID, ref.RefRepoID)
|
assert.Equal(t, pr.RepoID, ref.RefRepoID)
|
||||||
|
@ -104,18 +104,18 @@ func TestXRef_ResolveCrossReferences(t *testing.T) {
|
||||||
pr := testCreatePR(t, 1, 2, "titlepr", fmt.Sprintf("closes #%d", i1.Index))
|
pr := testCreatePR(t, 1, 2, "titlepr", fmt.Sprintf("closes #%d", i1.Index))
|
||||||
rp := unittest.AssertExistsAndLoadBean(t, &issues_model.Comment{IssueID: i1.ID, RefIssueID: pr.Issue.ID, RefCommentID: 0})
|
rp := unittest.AssertExistsAndLoadBean(t, &issues_model.Comment{IssueID: i1.ID, RefIssueID: pr.Issue.ID, RefCommentID: 0})
|
||||||
|
|
||||||
c1 := testCreateComment(t, 1, 2, pr.Issue.ID, fmt.Sprintf("closes #%d", i2.Index))
|
c1 := testCreateComment(t, 2, pr.Issue.ID, fmt.Sprintf("closes #%d", i2.Index))
|
||||||
r1 := unittest.AssertExistsAndLoadBean(t, &issues_model.Comment{IssueID: i2.ID, RefIssueID: pr.Issue.ID, RefCommentID: c1.ID})
|
r1 := unittest.AssertExistsAndLoadBean(t, &issues_model.Comment{IssueID: i2.ID, RefIssueID: pr.Issue.ID, RefCommentID: c1.ID})
|
||||||
|
|
||||||
// Must be ignored
|
// Must be ignored
|
||||||
c2 := testCreateComment(t, 1, 2, pr.Issue.ID, fmt.Sprintf("mentions #%d", i2.Index))
|
c2 := testCreateComment(t, 2, pr.Issue.ID, fmt.Sprintf("mentions #%d", i2.Index))
|
||||||
unittest.AssertExistsAndLoadBean(t, &issues_model.Comment{IssueID: i2.ID, RefIssueID: pr.Issue.ID, RefCommentID: c2.ID})
|
unittest.AssertExistsAndLoadBean(t, &issues_model.Comment{IssueID: i2.ID, RefIssueID: pr.Issue.ID, RefCommentID: c2.ID})
|
||||||
|
|
||||||
// Must be superseded by c4/r4
|
// Must be superseded by c4/r4
|
||||||
c3 := testCreateComment(t, 1, 2, pr.Issue.ID, fmt.Sprintf("reopens #%d", i3.Index))
|
c3 := testCreateComment(t, 2, pr.Issue.ID, fmt.Sprintf("reopens #%d", i3.Index))
|
||||||
unittest.AssertExistsAndLoadBean(t, &issues_model.Comment{IssueID: i3.ID, RefIssueID: pr.Issue.ID, RefCommentID: c3.ID})
|
unittest.AssertExistsAndLoadBean(t, &issues_model.Comment{IssueID: i3.ID, RefIssueID: pr.Issue.ID, RefCommentID: c3.ID})
|
||||||
|
|
||||||
c4 := testCreateComment(t, 1, 2, pr.Issue.ID, fmt.Sprintf("closes #%d", i3.Index))
|
c4 := testCreateComment(t, 2, pr.Issue.ID, fmt.Sprintf("closes #%d", i3.Index))
|
||||||
r4 := unittest.AssertExistsAndLoadBean(t, &issues_model.Comment{IssueID: i3.ID, RefIssueID: pr.Issue.ID, RefCommentID: c4.ID})
|
r4 := unittest.AssertExistsAndLoadBean(t, &issues_model.Comment{IssueID: i3.ID, RefIssueID: pr.Issue.ID, RefCommentID: c4.ID})
|
||||||
|
|
||||||
refs, err := pr.ResolveCrossReferences(db.DefaultContext)
|
refs, err := pr.ResolveCrossReferences(db.DefaultContext)
|
||||||
|
@ -168,7 +168,7 @@ func testCreatePR(t *testing.T, repo, doer int64, title, content string) *issues
|
||||||
return pr
|
return pr
|
||||||
}
|
}
|
||||||
|
|
||||||
func testCreateComment(t *testing.T, repo, doer, issue int64, content string) *issues_model.Comment {
|
func testCreateComment(t *testing.T, doer, issue int64, content string) *issues_model.Comment {
|
||||||
d := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: doer})
|
d := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: doer})
|
||||||
i := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: issue})
|
i := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: issue})
|
||||||
c := &issues_model.Comment{Type: issues_model.CommentTypeComment, PosterID: doer, Poster: d, IssueID: issue, Issue: i, Content: content}
|
c := &issues_model.Comment{Type: issues_model.CommentTypeComment, PosterID: doer, Poster: d, IssueID: issue, Issue: i, Content: content}
|
||||||
|
|
|
@ -234,7 +234,7 @@ func TestGetLabelsByIssueID(t *testing.T) {
|
||||||
func TestUpdateLabel(t *testing.T) {
|
func TestUpdateLabel(t *testing.T) {
|
||||||
assert.NoError(t, unittest.PrepareTestDatabase())
|
assert.NoError(t, unittest.PrepareTestDatabase())
|
||||||
label := unittest.AssertExistsAndLoadBean(t, &issues_model.Label{ID: 1})
|
label := unittest.AssertExistsAndLoadBean(t, &issues_model.Label{ID: 1})
|
||||||
// make sure update wont overwrite it
|
// make sure update won't overwrite it
|
||||||
update := &issues_model.Label{
|
update := &issues_model.Label{
|
||||||
ID: label.ID,
|
ID: label.ID,
|
||||||
Color: "#ffff00",
|
Color: "#ffff00",
|
||||||
|
|
|
@ -807,7 +807,7 @@ func UpdateAllowEdits(ctx context.Context, pr *PullRequest) error {
|
||||||
|
|
||||||
// Mergeable returns if the pullrequest is mergeable.
|
// Mergeable returns if the pullrequest is mergeable.
|
||||||
func (pr *PullRequest) Mergeable(ctx context.Context) bool {
|
func (pr *PullRequest) Mergeable(ctx context.Context) bool {
|
||||||
// If a pull request isn't mergable if it's:
|
// If a pull request isn't mergeable if it's:
|
||||||
// - Being conflict checked.
|
// - Being conflict checked.
|
||||||
// - Has a conflict.
|
// - Has a conflict.
|
||||||
// - Received a error while being conflict checked.
|
// - Received a error while being conflict checked.
|
||||||
|
|
|
@ -187,8 +187,8 @@ func AddTime(ctx context.Context, user *user_model.User, issue *Issue, amount in
|
||||||
Issue: issue,
|
Issue: issue,
|
||||||
Repo: issue.Repo,
|
Repo: issue.Repo,
|
||||||
Doer: user,
|
Doer: user,
|
||||||
// Content before v1.21 did store the formated string instead of seconds,
|
// Content before v1.21 did store the formatted string instead of seconds,
|
||||||
// so use "|" as delimeter to mark the new format
|
// so use "|" as delimiter to mark the new format
|
||||||
Content: fmt.Sprintf("|%d", amount),
|
Content: fmt.Sprintf("|%d", amount),
|
||||||
Type: CommentTypeAddTimeManual,
|
Type: CommentTypeAddTimeManual,
|
||||||
TimeID: t.ID,
|
TimeID: t.ID,
|
||||||
|
@ -267,8 +267,8 @@ func DeleteIssueUserTimes(ctx context.Context, issue *Issue, user *user_model.Us
|
||||||
Issue: issue,
|
Issue: issue,
|
||||||
Repo: issue.Repo,
|
Repo: issue.Repo,
|
||||||
Doer: user,
|
Doer: user,
|
||||||
// Content before v1.21 did store the formated string instead of seconds,
|
// Content before v1.21 did store the formatted string instead of seconds,
|
||||||
// so use "|" as delimeter to mark the new format
|
// so use "|" as delimiter to mark the new format
|
||||||
Content: fmt.Sprintf("|%d", removedTime),
|
Content: fmt.Sprintf("|%d", removedTime),
|
||||||
Type: CommentTypeDeleteTimeManual,
|
Type: CommentTypeDeleteTimeManual,
|
||||||
}); err != nil {
|
}); err != nil {
|
||||||
|
@ -298,8 +298,8 @@ func DeleteTime(ctx context.Context, t *TrackedTime) error {
|
||||||
Issue: t.Issue,
|
Issue: t.Issue,
|
||||||
Repo: t.Issue.Repo,
|
Repo: t.Issue.Repo,
|
||||||
Doer: t.User,
|
Doer: t.User,
|
||||||
// Content before v1.21 did store the formated string instead of seconds,
|
// Content before v1.21 did store the formatted string instead of seconds,
|
||||||
// so use "|" as delimeter to mark the new format
|
// so use "|" as delimiter to mark the new format
|
||||||
Content: fmt.Sprintf("|%d", t.Time),
|
Content: fmt.Sprintf("|%d", t.Time),
|
||||||
Type: CommentTypeDeleteTimeManual,
|
Type: CommentTypeDeleteTimeManual,
|
||||||
}); err != nil {
|
}); err != nil {
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
-
|
-
|
||||||
id: 1
|
id: 1
|
||||||
|
user_id: 1
|
||||||
|
pull_id: 1
|
||||||
commit_sha: 19fe5caf872476db265596eaac1dc35ad1c6422d
|
commit_sha: 19fe5caf872476db265596eaac1dc35ad1c6422d
|
||||||
|
|
|
@ -4,4 +4,4 @@
|
||||||
package v1_17 //nolint
|
package v1_17 //nolint
|
||||||
|
|
||||||
// This migration added non-ideal indices to the action table which on larger datasets slowed things down
|
// This migration added non-ideal indices to the action table which on larger datasets slowed things down
|
||||||
// it has been superceded by v218.go
|
// it has been superseded by v218.go
|
||||||
|
|
|
@ -19,21 +19,21 @@ func PrepareOldRepository(t *testing.T) (*xorm.Engine, func()) {
|
||||||
|
|
||||||
type CommitStatus struct {
|
type CommitStatus struct {
|
||||||
ID int64
|
ID int64
|
||||||
ContextHash string
|
ContextHash string `xorm:"char(40) index"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type RepoArchiver struct {
|
type RepoArchiver struct {
|
||||||
ID int64
|
ID int64
|
||||||
RepoID int64
|
RepoID int64 `xorm:"index unique(s)"`
|
||||||
Type int
|
Type int `xorm:"unique(s)"`
|
||||||
CommitID string
|
CommitID string `xorm:"VARCHAR(40) unique(s)"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type ReviewState struct {
|
type ReviewState struct {
|
||||||
ID int64
|
ID int64
|
||||||
CommitSHA string
|
UserID int64 `xorm:"NOT NULL UNIQUE(pull_commit_user)"`
|
||||||
UserID int64
|
PullID int64 `xorm:"NOT NULL INDEX UNIQUE(pull_commit_user) DEFAULT 0"`
|
||||||
PullID int64
|
CommitSHA string `xorm:"NOT NULL VARCHAR(40) UNIQUE(pull_commit_user)"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type Comment struct {
|
type Comment struct {
|
||||||
|
|
|
@ -291,15 +291,15 @@ func TestAccessibleReposEnv_CountRepos(t *testing.T) {
|
||||||
func TestAccessibleReposEnv_RepoIDs(t *testing.T) {
|
func TestAccessibleReposEnv_RepoIDs(t *testing.T) {
|
||||||
assert.NoError(t, unittest.PrepareTestDatabase())
|
assert.NoError(t, unittest.PrepareTestDatabase())
|
||||||
org := unittest.AssertExistsAndLoadBean(t, &organization.Organization{ID: 3})
|
org := unittest.AssertExistsAndLoadBean(t, &organization.Organization{ID: 3})
|
||||||
testSuccess := func(userID, _, pageSize int64, expectedRepoIDs []int64) {
|
testSuccess := func(userID int64, expectedRepoIDs []int64) {
|
||||||
env, err := organization.AccessibleReposEnv(db.DefaultContext, org, userID)
|
env, err := organization.AccessibleReposEnv(db.DefaultContext, org, userID)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
repoIDs, err := env.RepoIDs(1, 100)
|
repoIDs, err := env.RepoIDs(1, 100)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.Equal(t, expectedRepoIDs, repoIDs)
|
assert.Equal(t, expectedRepoIDs, repoIDs)
|
||||||
}
|
}
|
||||||
testSuccess(2, 1, 100, []int64{3, 5, 32})
|
testSuccess(2, []int64{3, 5, 32})
|
||||||
testSuccess(4, 0, 100, []int64{3, 32})
|
testSuccess(4, []int64{3, 32})
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestAccessibleReposEnv_Repos(t *testing.T) {
|
func TestAccessibleReposEnv_Repos(t *testing.T) {
|
||||||
|
|
|
@ -5,12 +5,14 @@ package project
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"regexp"
|
"regexp"
|
||||||
|
|
||||||
"code.gitea.io/gitea/models/db"
|
"code.gitea.io/gitea/models/db"
|
||||||
"code.gitea.io/gitea/modules/setting"
|
"code.gitea.io/gitea/modules/setting"
|
||||||
"code.gitea.io/gitea/modules/timeutil"
|
"code.gitea.io/gitea/modules/timeutil"
|
||||||
|
"code.gitea.io/gitea/modules/util"
|
||||||
|
|
||||||
"xorm.io/builder"
|
"xorm.io/builder"
|
||||||
)
|
)
|
||||||
|
@ -82,6 +84,17 @@ func (b *Board) NumIssues(ctx context.Context) int {
|
||||||
return int(c)
|
return int(c)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (b *Board) GetIssues(ctx context.Context) ([]*ProjectIssue, error) {
|
||||||
|
issues := make([]*ProjectIssue, 0, 5)
|
||||||
|
if err := db.GetEngine(ctx).Where("project_id=?", b.ProjectID).
|
||||||
|
And("project_board_id=?", b.ID).
|
||||||
|
OrderBy("sorting, id").
|
||||||
|
Find(&issues); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return issues, nil
|
||||||
|
}
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
db.RegisterModel(new(Board))
|
db.RegisterModel(new(Board))
|
||||||
}
|
}
|
||||||
|
@ -150,12 +163,27 @@ func createBoardsForProjectsType(ctx context.Context, project *Project) error {
|
||||||
return db.Insert(ctx, boards)
|
return db.Insert(ctx, boards)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// maxProjectColumns max columns allowed in a project, this should not bigger than 127
|
||||||
|
// because sorting is int8 in database
|
||||||
|
const maxProjectColumns = 20
|
||||||
|
|
||||||
// NewBoard adds a new project board to a given project
|
// NewBoard adds a new project board to a given project
|
||||||
func NewBoard(ctx context.Context, board *Board) error {
|
func NewBoard(ctx context.Context, board *Board) error {
|
||||||
if len(board.Color) != 0 && !BoardColorPattern.MatchString(board.Color) {
|
if len(board.Color) != 0 && !BoardColorPattern.MatchString(board.Color) {
|
||||||
return fmt.Errorf("bad color code: %s", board.Color)
|
return fmt.Errorf("bad color code: %s", board.Color)
|
||||||
}
|
}
|
||||||
|
res := struct {
|
||||||
|
MaxSorting int64
|
||||||
|
ColumnCount int64
|
||||||
|
}{}
|
||||||
|
if _, err := db.GetEngine(ctx).Select("max(sorting) as max_sorting, count(*) as column_count").Table("project_board").
|
||||||
|
Where("project_id=?", board.ProjectID).Get(&res); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if res.ColumnCount >= maxProjectColumns {
|
||||||
|
return fmt.Errorf("NewBoard: maximum number of columns reached")
|
||||||
|
}
|
||||||
|
board.Sorting = int8(util.Iif(res.ColumnCount > 0, res.MaxSorting+1, 0))
|
||||||
_, err := db.GetEngine(ctx).Insert(board)
|
_, err := db.GetEngine(ctx).Insert(board)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -189,7 +217,17 @@ func deleteBoardByID(ctx context.Context, boardID int64) error {
|
||||||
return fmt.Errorf("deleteBoardByID: cannot delete default board")
|
return fmt.Errorf("deleteBoardByID: cannot delete default board")
|
||||||
}
|
}
|
||||||
|
|
||||||
if err = board.removeIssues(ctx); err != nil {
|
// move all issues to the default column
|
||||||
|
project, err := GetProjectByID(ctx, board.ProjectID)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defaultColumn, err := project.GetDefaultBoard(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if err = board.moveIssuesToAnotherColumn(ctx, defaultColumn); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -242,21 +280,15 @@ func UpdateBoard(ctx context.Context, board *Board) error {
|
||||||
// GetBoards fetches all boards related to a project
|
// GetBoards fetches all boards related to a project
|
||||||
func (p *Project) GetBoards(ctx context.Context) (BoardList, error) {
|
func (p *Project) GetBoards(ctx context.Context) (BoardList, error) {
|
||||||
boards := make([]*Board, 0, 5)
|
boards := make([]*Board, 0, 5)
|
||||||
|
if err := db.GetEngine(ctx).Where("project_id=?", p.ID).OrderBy("sorting, id").Find(&boards); err != nil {
|
||||||
if err := db.GetEngine(ctx).Where("project_id=? AND `default`=?", p.ID, false).OrderBy("sorting").Find(&boards); err != nil {
|
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
defaultB, err := p.getDefaultBoard(ctx)
|
return boards, nil
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return append([]*Board{defaultB}, boards...), nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// getDefaultBoard return default board and ensure only one exists
|
// GetDefaultBoard return default board and ensure only one exists
|
||||||
func (p *Project) getDefaultBoard(ctx context.Context) (*Board, error) {
|
func (p *Project) GetDefaultBoard(ctx context.Context) (*Board, error) {
|
||||||
var board Board
|
var board Board
|
||||||
has, err := db.GetEngine(ctx).
|
has, err := db.GetEngine(ctx).
|
||||||
Where("project_id=? AND `default` = ?", p.ID, true).
|
Where("project_id=? AND `default` = ?", p.ID, true).
|
||||||
|
@ -316,3 +348,42 @@ func UpdateBoardSorting(ctx context.Context, bs BoardList) error {
|
||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func GetColumnsByIDs(ctx context.Context, projectID int64, columnsIDs []int64) (BoardList, error) {
|
||||||
|
columns := make([]*Board, 0, 5)
|
||||||
|
if err := db.GetEngine(ctx).
|
||||||
|
Where("project_id =?", projectID).
|
||||||
|
In("id", columnsIDs).
|
||||||
|
OrderBy("sorting").Find(&columns); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return columns, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// MoveColumnsOnProject sorts columns in a project
|
||||||
|
func MoveColumnsOnProject(ctx context.Context, project *Project, sortedColumnIDs map[int64]int64) error {
|
||||||
|
return db.WithTx(ctx, func(ctx context.Context) error {
|
||||||
|
sess := db.GetEngine(ctx)
|
||||||
|
columnIDs := util.ValuesOfMap(sortedColumnIDs)
|
||||||
|
movedColumns, err := GetColumnsByIDs(ctx, project.ID, columnIDs)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if len(movedColumns) != len(sortedColumnIDs) {
|
||||||
|
return errors.New("some columns do not exist")
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, column := range movedColumns {
|
||||||
|
if column.ProjectID != project.ID {
|
||||||
|
return fmt.Errorf("column[%d]'s projectID is not equal to project's ID [%d]", column.ProjectID, project.ID)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for sorting, columnID := range sortedColumnIDs {
|
||||||
|
if _, err := sess.Exec("UPDATE `project_board` SET sorting=? WHERE id=?", sorting, columnID); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
|
@ -4,6 +4,8 @@
|
||||||
package project
|
package project
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"code.gitea.io/gitea/models/db"
|
"code.gitea.io/gitea/models/db"
|
||||||
|
@ -19,7 +21,7 @@ func TestGetDefaultBoard(t *testing.T) {
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
|
||||||
// check if default board was added
|
// check if default board was added
|
||||||
board, err := projectWithoutDefault.getDefaultBoard(db.DefaultContext)
|
board, err := projectWithoutDefault.GetDefaultBoard(db.DefaultContext)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.Equal(t, int64(5), board.ProjectID)
|
assert.Equal(t, int64(5), board.ProjectID)
|
||||||
assert.Equal(t, "Uncategorized", board.Title)
|
assert.Equal(t, "Uncategorized", board.Title)
|
||||||
|
@ -28,7 +30,7 @@ func TestGetDefaultBoard(t *testing.T) {
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
|
||||||
// check if multiple defaults were removed
|
// check if multiple defaults were removed
|
||||||
board, err = projectWithMultipleDefaults.getDefaultBoard(db.DefaultContext)
|
board, err = projectWithMultipleDefaults.GetDefaultBoard(db.DefaultContext)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.Equal(t, int64(6), board.ProjectID)
|
assert.Equal(t, int64(6), board.ProjectID)
|
||||||
assert.Equal(t, int64(9), board.ID)
|
assert.Equal(t, int64(9), board.ID)
|
||||||
|
@ -42,3 +44,84 @@ func TestGetDefaultBoard(t *testing.T) {
|
||||||
assert.Equal(t, int64(6), board.ProjectID)
|
assert.Equal(t, int64(6), board.ProjectID)
|
||||||
assert.False(t, board.Default)
|
assert.False(t, board.Default)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func Test_moveIssuesToAnotherColumn(t *testing.T) {
|
||||||
|
assert.NoError(t, unittest.PrepareTestDatabase())
|
||||||
|
|
||||||
|
column1 := unittest.AssertExistsAndLoadBean(t, &Board{ID: 1, ProjectID: 1})
|
||||||
|
|
||||||
|
issues, err := column1.GetIssues(db.DefaultContext)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.Len(t, issues, 1)
|
||||||
|
assert.EqualValues(t, 1, issues[0].ID)
|
||||||
|
|
||||||
|
column2 := unittest.AssertExistsAndLoadBean(t, &Board{ID: 2, ProjectID: 1})
|
||||||
|
issues, err = column2.GetIssues(db.DefaultContext)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.Len(t, issues, 1)
|
||||||
|
assert.EqualValues(t, 3, issues[0].ID)
|
||||||
|
|
||||||
|
err = column1.moveIssuesToAnotherColumn(db.DefaultContext, column2)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
|
||||||
|
issues, err = column1.GetIssues(db.DefaultContext)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.Len(t, issues, 0)
|
||||||
|
|
||||||
|
issues, err = column2.GetIssues(db.DefaultContext)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.Len(t, issues, 2)
|
||||||
|
assert.EqualValues(t, 3, issues[0].ID)
|
||||||
|
assert.EqualValues(t, 0, issues[0].Sorting)
|
||||||
|
assert.EqualValues(t, 1, issues[1].ID)
|
||||||
|
assert.EqualValues(t, 1, issues[1].Sorting)
|
||||||
|
}
|
||||||
|
|
||||||
|
func Test_MoveColumnsOnProject(t *testing.T) {
|
||||||
|
assert.NoError(t, unittest.PrepareTestDatabase())
|
||||||
|
|
||||||
|
project1 := unittest.AssertExistsAndLoadBean(t, &Project{ID: 1})
|
||||||
|
columns, err := project1.GetBoards(db.DefaultContext)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.Len(t, columns, 3)
|
||||||
|
assert.EqualValues(t, 0, columns[0].Sorting) // even if there is no default sorting, the code should also work
|
||||||
|
assert.EqualValues(t, 0, columns[1].Sorting)
|
||||||
|
assert.EqualValues(t, 0, columns[2].Sorting)
|
||||||
|
|
||||||
|
err = MoveColumnsOnProject(db.DefaultContext, project1, map[int64]int64{
|
||||||
|
0: columns[1].ID,
|
||||||
|
1: columns[2].ID,
|
||||||
|
2: columns[0].ID,
|
||||||
|
})
|
||||||
|
assert.NoError(t, err)
|
||||||
|
|
||||||
|
columnsAfter, err := project1.GetBoards(db.DefaultContext)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.Len(t, columnsAfter, 3)
|
||||||
|
assert.EqualValues(t, columns[1].ID, columnsAfter[0].ID)
|
||||||
|
assert.EqualValues(t, columns[2].ID, columnsAfter[1].ID)
|
||||||
|
assert.EqualValues(t, columns[0].ID, columnsAfter[2].ID)
|
||||||
|
}
|
||||||
|
|
||||||
|
func Test_NewBoard(t *testing.T) {
|
||||||
|
assert.NoError(t, unittest.PrepareTestDatabase())
|
||||||
|
|
||||||
|
project1 := unittest.AssertExistsAndLoadBean(t, &Project{ID: 1})
|
||||||
|
columns, err := project1.GetBoards(db.DefaultContext)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.Len(t, columns, 3)
|
||||||
|
|
||||||
|
for i := 0; i < maxProjectColumns-3; i++ {
|
||||||
|
err := NewBoard(db.DefaultContext, &Board{
|
||||||
|
Title: fmt.Sprintf("board-%d", i+4),
|
||||||
|
ProjectID: project1.ID,
|
||||||
|
})
|
||||||
|
assert.NoError(t, err)
|
||||||
|
}
|
||||||
|
err = NewBoard(db.DefaultContext, &Board{
|
||||||
|
Title: "board-21",
|
||||||
|
ProjectID: project1.ID,
|
||||||
|
})
|
||||||
|
assert.Error(t, err)
|
||||||
|
assert.True(t, strings.Contains(err.Error(), "maximum number of columns reached"))
|
||||||
|
}
|
||||||
|
|
|
@ -9,6 +9,7 @@ import (
|
||||||
|
|
||||||
"code.gitea.io/gitea/models/db"
|
"code.gitea.io/gitea/models/db"
|
||||||
"code.gitea.io/gitea/modules/log"
|
"code.gitea.io/gitea/modules/log"
|
||||||
|
"code.gitea.io/gitea/modules/util"
|
||||||
)
|
)
|
||||||
|
|
||||||
// ProjectIssue saves relation from issue to a project
|
// ProjectIssue saves relation from issue to a project
|
||||||
|
@ -17,7 +18,7 @@ type ProjectIssue struct { //revive:disable-line:exported
|
||||||
IssueID int64 `xorm:"INDEX"`
|
IssueID int64 `xorm:"INDEX"`
|
||||||
ProjectID int64 `xorm:"INDEX"`
|
ProjectID int64 `xorm:"INDEX"`
|
||||||
|
|
||||||
// If 0, then it has not been added to a specific board in the project
|
// ProjectBoardID should not be zero since 1.22. If it's zero, the issue will not be displayed on UI and it might result in errors.
|
||||||
ProjectBoardID int64 `xorm:"INDEX"`
|
ProjectBoardID int64 `xorm:"INDEX"`
|
||||||
|
|
||||||
// the sorting order on the board
|
// the sorting order on the board
|
||||||
|
@ -79,11 +80,8 @@ func (p *Project) NumOpenIssues(ctx context.Context) int {
|
||||||
func MoveIssuesOnProjectBoard(ctx context.Context, board *Board, sortedIssueIDs map[int64]int64) error {
|
func MoveIssuesOnProjectBoard(ctx context.Context, board *Board, sortedIssueIDs map[int64]int64) error {
|
||||||
return db.WithTx(ctx, func(ctx context.Context) error {
|
return db.WithTx(ctx, func(ctx context.Context) error {
|
||||||
sess := db.GetEngine(ctx)
|
sess := db.GetEngine(ctx)
|
||||||
|
issueIDs := util.ValuesOfMap(sortedIssueIDs)
|
||||||
|
|
||||||
issueIDs := make([]int64, 0, len(sortedIssueIDs))
|
|
||||||
for _, issueID := range sortedIssueIDs {
|
|
||||||
issueIDs = append(issueIDs, issueID)
|
|
||||||
}
|
|
||||||
count, err := sess.Table(new(ProjectIssue)).Where("project_id=?", board.ProjectID).In("issue_id", issueIDs).Count()
|
count, err := sess.Table(new(ProjectIssue)).Where("project_id=?", board.ProjectID).In("issue_id", issueIDs).Count()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -102,7 +100,44 @@ func MoveIssuesOnProjectBoard(ctx context.Context, board *Board, sortedIssueIDs
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *Board) removeIssues(ctx context.Context) error {
|
func (b *Board) moveIssuesToAnotherColumn(ctx context.Context, newColumn *Board) error {
|
||||||
_, err := db.GetEngine(ctx).Exec("UPDATE `project_issue` SET project_board_id = 0 WHERE project_board_id = ? ", b.ID)
|
if b.ProjectID != newColumn.ProjectID {
|
||||||
return err
|
return fmt.Errorf("columns have to be in the same project")
|
||||||
|
}
|
||||||
|
|
||||||
|
if b.ID == newColumn.ID {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
res := struct {
|
||||||
|
MaxSorting int64
|
||||||
|
IssueCount int64
|
||||||
|
}{}
|
||||||
|
if _, err := db.GetEngine(ctx).Select("max(sorting) as max_sorting, count(*) as issue_count").
|
||||||
|
Table("project_issue").
|
||||||
|
Where("project_id=?", newColumn.ProjectID).
|
||||||
|
And("project_board_id=?", newColumn.ID).
|
||||||
|
Get(&res); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
issues, err := b.GetIssues(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if len(issues) == 0 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
nextSorting := util.Iif(res.IssueCount > 0, res.MaxSorting+1, 0)
|
||||||
|
return db.WithTx(ctx, func(ctx context.Context) error {
|
||||||
|
for i, issue := range issues {
|
||||||
|
issue.ProjectBoardID = newColumn.ID
|
||||||
|
issue.Sorting = nextSorting + int64(i)
|
||||||
|
if _, err := db.GetEngine(ctx).ID(issue.ID).Cols("project_board_id", "sorting").Update(issue); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -161,6 +161,13 @@ func (p *Project) IsRepositoryProject() bool {
|
||||||
return p.Type == TypeRepository
|
return p.Type == TypeRepository
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (p *Project) CanBeAccessedByOwnerRepo(ownerID int64, repo *repo_model.Repository) bool {
|
||||||
|
if p.Type == TypeRepository {
|
||||||
|
return repo != nil && p.RepoID == repo.ID // if a project belongs to a repository, then its OwnerID is 0 and can be ignored
|
||||||
|
}
|
||||||
|
return p.OwnerID == ownerID && p.RepoID == 0
|
||||||
|
}
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
db.RegisterModel(new(Project))
|
db.RegisterModel(new(Project))
|
||||||
}
|
}
|
||||||
|
|
|
@ -36,7 +36,7 @@ func CountArchiveDownload(ctx context.Context, repoID, releaseID int64, tp git.A
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// The archive does not esxists in the databse, so let's add it
|
// The archive does not esxists in the database, so let's add it
|
||||||
newCounter := &RepoArchiveDownloadCount{
|
newCounter := &RepoArchiveDownloadCount{
|
||||||
RepoID: repoID,
|
RepoID: repoID,
|
||||||
ReleaseID: releaseID,
|
ReleaseID: releaseID,
|
||||||
|
|
|
@ -8,14 +8,14 @@ import "code.gitea.io/gitea/models/db"
|
||||||
// SearchOrderByMap represents all possible search order
|
// SearchOrderByMap represents all possible search order
|
||||||
var SearchOrderByMap = map[string]map[string]db.SearchOrderBy{
|
var SearchOrderByMap = map[string]map[string]db.SearchOrderBy{
|
||||||
"asc": {
|
"asc": {
|
||||||
"alpha": db.SearchOrderByAlphabetically,
|
"alpha": "owner_name ASC, name ASC",
|
||||||
"created": db.SearchOrderByOldest,
|
"created": db.SearchOrderByOldest,
|
||||||
"updated": db.SearchOrderByLeastUpdated,
|
"updated": db.SearchOrderByLeastUpdated,
|
||||||
"size": db.SearchOrderBySize,
|
"size": db.SearchOrderBySize,
|
||||||
"id": db.SearchOrderByID,
|
"id": db.SearchOrderByID,
|
||||||
},
|
},
|
||||||
"desc": {
|
"desc": {
|
||||||
"alpha": db.SearchOrderByAlphabeticallyReverse,
|
"alpha": "owner_name DESC, name DESC",
|
||||||
"created": db.SearchOrderByNewest,
|
"created": db.SearchOrderByNewest,
|
||||||
"updated": db.SearchOrderByRecentUpdated,
|
"updated": db.SearchOrderByRecentUpdated,
|
||||||
"size": db.SearchOrderBySizeReverse,
|
"size": db.SearchOrderBySizeReverse,
|
||||||
|
|
|
@ -95,7 +95,10 @@ func GetRepoAssignees(ctx context.Context, repo *Repository) (_ []*user_model.Us
|
||||||
// and just waste 1 unit is cheaper than re-allocate memory once.
|
// and just waste 1 unit is cheaper than re-allocate memory once.
|
||||||
users := make([]*user_model.User, 0, len(uniqueUserIDs)+1)
|
users := make([]*user_model.User, 0, len(uniqueUserIDs)+1)
|
||||||
if len(userIDs) > 0 {
|
if len(userIDs) > 0 {
|
||||||
if err = e.In("id", uniqueUserIDs.Values()).OrderBy(user_model.GetOrderByName()).Find(&users); err != nil {
|
if err = e.In("id", uniqueUserIDs.Values()).
|
||||||
|
Where(builder.Eq{"`user`.is_active": true}).
|
||||||
|
OrderBy(user_model.GetOrderByName()).
|
||||||
|
Find(&users); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -117,7 +120,8 @@ func GetReviewers(ctx context.Context, repo *Repository, doerID, posterID int64)
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
cond := builder.And(builder.Neq{"`user`.id": posterID})
|
cond := builder.And(builder.Neq{"`user`.id": posterID}).
|
||||||
|
And(builder.Eq{"`user`.is_active": true})
|
||||||
|
|
||||||
if repo.IsPrivate || repo.Owner.Visibility == api.VisibleTypePrivate {
|
if repo.IsPrivate || repo.Owner.Visibility == api.VisibleTypePrivate {
|
||||||
// This a private repository:
|
// This a private repository:
|
||||||
|
|
|
@ -26,10 +26,17 @@ func TestRepoAssignees(t *testing.T) {
|
||||||
repo21 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 21})
|
repo21 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 21})
|
||||||
users, err = repo_model.GetRepoAssignees(db.DefaultContext, repo21)
|
users, err = repo_model.GetRepoAssignees(db.DefaultContext, repo21)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.Len(t, users, 3)
|
if assert.Len(t, users, 3) {
|
||||||
assert.Equal(t, users[0].ID, int64(15))
|
assert.ElementsMatch(t, []int64{15, 16, 18}, []int64{users[0].ID, users[1].ID, users[2].ID})
|
||||||
assert.Equal(t, users[1].ID, int64(18))
|
}
|
||||||
assert.Equal(t, users[2].ID, int64(16))
|
|
||||||
|
// do not return deactivated users
|
||||||
|
assert.NoError(t, user_model.UpdateUserCols(db.DefaultContext, &user_model.User{ID: 15, IsActive: false}, "is_active"))
|
||||||
|
users, err = repo_model.GetRepoAssignees(db.DefaultContext, repo21)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
if assert.Len(t, users, 2) {
|
||||||
|
assert.NotContains(t, []int64{users[0].ID, users[1].ID}, 15)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestRepoGetReviewers(t *testing.T) {
|
func TestRepoGetReviewers(t *testing.T) {
|
||||||
|
@ -41,17 +48,19 @@ func TestRepoGetReviewers(t *testing.T) {
|
||||||
ctx := db.DefaultContext
|
ctx := db.DefaultContext
|
||||||
reviewers, err := repo_model.GetReviewers(ctx, repo1, 2, 2)
|
reviewers, err := repo_model.GetReviewers(ctx, repo1, 2, 2)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.Len(t, reviewers, 4)
|
if assert.Len(t, reviewers, 3) {
|
||||||
|
assert.ElementsMatch(t, []int64{1, 4, 11}, []int64{reviewers[0].ID, reviewers[1].ID, reviewers[2].ID})
|
||||||
|
}
|
||||||
|
|
||||||
// should include doer if doer is not PR poster.
|
// should include doer if doer is not PR poster.
|
||||||
reviewers, err = repo_model.GetReviewers(ctx, repo1, 11, 2)
|
reviewers, err = repo_model.GetReviewers(ctx, repo1, 11, 2)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.Len(t, reviewers, 4)
|
assert.Len(t, reviewers, 3)
|
||||||
|
|
||||||
// should not include PR poster, if PR poster would be otherwise eligible
|
// should not include PR poster, if PR poster would be otherwise eligible
|
||||||
reviewers, err = repo_model.GetReviewers(ctx, repo1, 11, 4)
|
reviewers, err = repo_model.GetReviewers(ctx, repo1, 11, 4)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.Len(t, reviewers, 3)
|
assert.Len(t, reviewers, 2)
|
||||||
|
|
||||||
// test private user repo
|
// test private user repo
|
||||||
repo2 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 2})
|
repo2 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 2})
|
||||||
|
|
|
@ -8,7 +8,7 @@ const (
|
||||||
SettingsKeyHiddenCommentTypes = "issue.hidden_comment_types"
|
SettingsKeyHiddenCommentTypes = "issue.hidden_comment_types"
|
||||||
// SettingsKeyDiffWhitespaceBehavior is the setting key for whitespace behavior of diff
|
// SettingsKeyDiffWhitespaceBehavior is the setting key for whitespace behavior of diff
|
||||||
SettingsKeyDiffWhitespaceBehavior = "diff.whitespace_behaviour"
|
SettingsKeyDiffWhitespaceBehavior = "diff.whitespace_behaviour"
|
||||||
// SettingsKeyShowOutdatedComments is the setting key wether or not to show outdated comments in PRs
|
// SettingsKeyShowOutdatedComments is the setting key whether or not to show outdated comments in PRs
|
||||||
SettingsKeyShowOutdatedComments = "comment_code.show_outdated"
|
SettingsKeyShowOutdatedComments = "comment_code.show_outdated"
|
||||||
// UserActivityPubPrivPem is user's private key
|
// UserActivityPubPrivPem is user's private key
|
||||||
UserActivityPubPrivPem = "activitypub.priv_pem"
|
UserActivityPubPrivPem = "activitypub.priv_pem"
|
||||||
|
|
|
@ -211,14 +211,14 @@ func detectMatched(gitRepo *git.Repository, commit *git.Commit, triggedEvent web
|
||||||
webhook_module.HookEventIssueAssign,
|
webhook_module.HookEventIssueAssign,
|
||||||
webhook_module.HookEventIssueLabel,
|
webhook_module.HookEventIssueLabel,
|
||||||
webhook_module.HookEventIssueMilestone:
|
webhook_module.HookEventIssueMilestone:
|
||||||
return matchIssuesEvent(commit, payload.(*api.IssuePayload), evt)
|
return matchIssuesEvent(payload.(*api.IssuePayload), evt)
|
||||||
|
|
||||||
case // issue_comment
|
case // issue_comment
|
||||||
webhook_module.HookEventIssueComment,
|
webhook_module.HookEventIssueComment,
|
||||||
// `pull_request_comment` is same as `issue_comment`
|
// `pull_request_comment` is same as `issue_comment`
|
||||||
// See https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#pull_request_comment-use-issue_comment
|
// See https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#pull_request_comment-use-issue_comment
|
||||||
webhook_module.HookEventPullRequestComment:
|
webhook_module.HookEventPullRequestComment:
|
||||||
return matchIssueCommentEvent(commit, payload.(*api.IssueCommentPayload), evt)
|
return matchIssueCommentEvent(payload.(*api.IssueCommentPayload), evt)
|
||||||
|
|
||||||
case // pull_request
|
case // pull_request
|
||||||
webhook_module.HookEventPullRequest,
|
webhook_module.HookEventPullRequest,
|
||||||
|
@ -232,19 +232,19 @@ func detectMatched(gitRepo *git.Repository, commit *git.Commit, triggedEvent web
|
||||||
case // pull_request_review
|
case // pull_request_review
|
||||||
webhook_module.HookEventPullRequestReviewApproved,
|
webhook_module.HookEventPullRequestReviewApproved,
|
||||||
webhook_module.HookEventPullRequestReviewRejected:
|
webhook_module.HookEventPullRequestReviewRejected:
|
||||||
return matchPullRequestReviewEvent(commit, payload.(*api.PullRequestPayload), evt)
|
return matchPullRequestReviewEvent(payload.(*api.PullRequestPayload), evt)
|
||||||
|
|
||||||
case // pull_request_review_comment
|
case // pull_request_review_comment
|
||||||
webhook_module.HookEventPullRequestReviewComment:
|
webhook_module.HookEventPullRequestReviewComment:
|
||||||
return matchPullRequestReviewCommentEvent(commit, payload.(*api.PullRequestPayload), evt)
|
return matchPullRequestReviewCommentEvent(payload.(*api.PullRequestPayload), evt)
|
||||||
|
|
||||||
case // release
|
case // release
|
||||||
webhook_module.HookEventRelease:
|
webhook_module.HookEventRelease:
|
||||||
return matchReleaseEvent(commit, payload.(*api.ReleasePayload), evt)
|
return matchReleaseEvent(payload.(*api.ReleasePayload), evt)
|
||||||
|
|
||||||
case // registry_package
|
case // registry_package
|
||||||
webhook_module.HookEventPackage:
|
webhook_module.HookEventPackage:
|
||||||
return matchPackageEvent(commit, payload.(*api.PackagePayload), evt)
|
return matchPackageEvent(payload.(*api.PackagePayload), evt)
|
||||||
|
|
||||||
default:
|
default:
|
||||||
log.Warn("unsupported event %q", triggedEvent)
|
log.Warn("unsupported event %q", triggedEvent)
|
||||||
|
@ -350,7 +350,7 @@ func matchPushEvent(commit *git.Commit, pushPayload *api.PushPayload, evt *jobpa
|
||||||
return matchTimes == len(evt.Acts())
|
return matchTimes == len(evt.Acts())
|
||||||
}
|
}
|
||||||
|
|
||||||
func matchIssuesEvent(commit *git.Commit, issuePayload *api.IssuePayload, evt *jobparser.Event) bool {
|
func matchIssuesEvent(issuePayload *api.IssuePayload, evt *jobparser.Event) bool {
|
||||||
// with no special filter parameters
|
// with no special filter parameters
|
||||||
if len(evt.Acts()) == 0 {
|
if len(evt.Acts()) == 0 {
|
||||||
return true
|
return true
|
||||||
|
@ -498,7 +498,7 @@ func matchPullRequestEvent(gitRepo *git.Repository, commit *git.Commit, prPayloa
|
||||||
return activityTypeMatched && matchTimes == len(evt.Acts())
|
return activityTypeMatched && matchTimes == len(evt.Acts())
|
||||||
}
|
}
|
||||||
|
|
||||||
func matchIssueCommentEvent(commit *git.Commit, issueCommentPayload *api.IssueCommentPayload, evt *jobparser.Event) bool {
|
func matchIssueCommentEvent(issueCommentPayload *api.IssueCommentPayload, evt *jobparser.Event) bool {
|
||||||
// with no special filter parameters
|
// with no special filter parameters
|
||||||
if len(evt.Acts()) == 0 {
|
if len(evt.Acts()) == 0 {
|
||||||
return true
|
return true
|
||||||
|
@ -530,7 +530,7 @@ func matchIssueCommentEvent(commit *git.Commit, issueCommentPayload *api.IssueCo
|
||||||
return matchTimes == len(evt.Acts())
|
return matchTimes == len(evt.Acts())
|
||||||
}
|
}
|
||||||
|
|
||||||
func matchPullRequestReviewEvent(commit *git.Commit, prPayload *api.PullRequestPayload, evt *jobparser.Event) bool {
|
func matchPullRequestReviewEvent(prPayload *api.PullRequestPayload, evt *jobparser.Event) bool {
|
||||||
// with no special filter parameters
|
// with no special filter parameters
|
||||||
if len(evt.Acts()) == 0 {
|
if len(evt.Acts()) == 0 {
|
||||||
return true
|
return true
|
||||||
|
@ -579,7 +579,7 @@ func matchPullRequestReviewEvent(commit *git.Commit, prPayload *api.PullRequestP
|
||||||
return matchTimes == len(evt.Acts())
|
return matchTimes == len(evt.Acts())
|
||||||
}
|
}
|
||||||
|
|
||||||
func matchPullRequestReviewCommentEvent(commit *git.Commit, prPayload *api.PullRequestPayload, evt *jobparser.Event) bool {
|
func matchPullRequestReviewCommentEvent(prPayload *api.PullRequestPayload, evt *jobparser.Event) bool {
|
||||||
// with no special filter parameters
|
// with no special filter parameters
|
||||||
if len(evt.Acts()) == 0 {
|
if len(evt.Acts()) == 0 {
|
||||||
return true
|
return true
|
||||||
|
@ -628,7 +628,7 @@ func matchPullRequestReviewCommentEvent(commit *git.Commit, prPayload *api.PullR
|
||||||
return matchTimes == len(evt.Acts())
|
return matchTimes == len(evt.Acts())
|
||||||
}
|
}
|
||||||
|
|
||||||
func matchReleaseEvent(commit *git.Commit, payload *api.ReleasePayload, evt *jobparser.Event) bool {
|
func matchReleaseEvent(payload *api.ReleasePayload, evt *jobparser.Event) bool {
|
||||||
// with no special filter parameters
|
// with no special filter parameters
|
||||||
if len(evt.Acts()) == 0 {
|
if len(evt.Acts()) == 0 {
|
||||||
return true
|
return true
|
||||||
|
@ -665,7 +665,7 @@ func matchReleaseEvent(commit *git.Commit, payload *api.ReleasePayload, evt *job
|
||||||
return matchTimes == len(evt.Acts())
|
return matchTimes == len(evt.Acts())
|
||||||
}
|
}
|
||||||
|
|
||||||
func matchPackageEvent(commit *git.Commit, payload *api.PackagePayload, evt *jobparser.Event) bool {
|
func matchPackageEvent(payload *api.PackagePayload, evt *jobparser.Event) bool {
|
||||||
// with no special filter parameters
|
// with no special filter parameters
|
||||||
if len(evt.Acts()) == 0 {
|
if len(evt.Acts()) == 0 {
|
||||||
return true
|
return true
|
||||||
|
|
|
@ -4,12 +4,11 @@
|
||||||
package pwn
|
package pwn
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"math/rand/v2"
|
|
||||||
"net/http"
|
"net/http"
|
||||||
"strings"
|
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/h2non/gock"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -18,86 +17,34 @@ var client = New(WithHTTP(&http.Client{
|
||||||
}))
|
}))
|
||||||
|
|
||||||
func TestPassword(t *testing.T) {
|
func TestPassword(t *testing.T) {
|
||||||
// Check input error
|
defer gock.Off()
|
||||||
_, err := client.CheckPassword("", false)
|
|
||||||
|
count, err := client.CheckPassword("", false)
|
||||||
assert.ErrorIs(t, err, ErrEmptyPassword, "blank input should return ErrEmptyPassword")
|
assert.ErrorIs(t, err, ErrEmptyPassword, "blank input should return ErrEmptyPassword")
|
||||||
|
assert.Equal(t, -1, count)
|
||||||
|
|
||||||
// Should fail
|
gock.New("https://api.pwnedpasswords.com").Get("/range/5c1d8").Times(1).Reply(200).BodyString("EAF2F254732680E8AC339B84F3266ECCBB5:1\r\nFC446EB88938834178CB9322C1EE273C2A7:2")
|
||||||
fail := "password1234"
|
count, err = client.CheckPassword("pwned", false)
|
||||||
count, err := client.CheckPassword(fail, false)
|
|
||||||
assert.NotEmpty(t, count, "%s should fail as a password", fail)
|
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
assert.Equal(t, 1, count)
|
||||||
|
|
||||||
// Should fail (with padding)
|
gock.New("https://api.pwnedpasswords.com").Get("/range/ba189").Times(1).Reply(200).BodyString("FD4CB34F0378BCB15D23F6FFD28F0775C9E:3\r\nFDF342FCD8C3611DAE4D76E8A992A3E4169:4")
|
||||||
failPad := "administrator"
|
count, err = client.CheckPassword("notpwned", false)
|
||||||
count, err = client.CheckPassword(failPad, true)
|
|
||||||
assert.NotEmpty(t, count, "%s should fail as a password", failPad)
|
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
assert.Equal(t, 0, count)
|
||||||
|
|
||||||
// Checking for a "good" password isn't going to be perfect, but we can give it a good try
|
gock.New("https://api.pwnedpasswords.com").Get("/range/a1733").Times(1).Reply(200).BodyString("C4CE0F1F0062B27B9E2F41AF0C08218017C:1\r\nFC446EB88938834178CB9322C1EE273C2A7:2\r\nFE81480327C992FE62065A827429DD1318B:0")
|
||||||
// with hopefully minimal error. Try five times?
|
count, err = client.CheckPassword("paddedpwned", true)
|
||||||
assert.Condition(t, func() bool {
|
assert.NoError(t, err)
|
||||||
for i := 0; i <= 5; i++ {
|
assert.Equal(t, 1, count)
|
||||||
count, err = client.CheckPassword(testPassword(), false)
|
|
||||||
assert.NoError(t, err)
|
|
||||||
if count == 0 {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}, "no generated passwords passed. there is a chance this is a fluke")
|
|
||||||
|
|
||||||
// Again, but with padded responses
|
gock.New("https://api.pwnedpasswords.com").Get("/range/5617b").Times(1).Reply(200).BodyString("FD4CB34F0378BCB15D23F6FFD28F0775C9E:3\r\nFDF342FCD8C3611DAE4D76E8A992A3E4169:4\r\nFE81480327C992FE62065A827429DD1318B:0")
|
||||||
assert.Condition(t, func() bool {
|
count, err = client.CheckPassword("paddednotpwned", true)
|
||||||
for i := 0; i <= 5; i++ {
|
assert.NoError(t, err)
|
||||||
count, err = client.CheckPassword(testPassword(), true)
|
assert.Equal(t, 0, count)
|
||||||
assert.NoError(t, err)
|
|
||||||
if count == 0 {
|
gock.New("https://api.pwnedpasswords.com").Get("/range/79082").Times(1).Reply(200).BodyString("FDF342FCD8C3611DAE4D76E8A992A3E4169:4\r\nFE81480327C992FE62065A827429DD1318B:0\r\nAFEF386F56EB0B4BE314E07696E5E6E6536:0")
|
||||||
return true
|
count, err = client.CheckPassword("paddednotpwnedzero", true)
|
||||||
}
|
assert.NoError(t, err)
|
||||||
}
|
assert.Equal(t, 0, count)
|
||||||
return false
|
|
||||||
}, "no generated passwords passed. there is a chance this is a fluke")
|
|
||||||
}
|
|
||||||
|
|
||||||
// Credit to https://golangbyexample.com/generate-random-password-golang/
|
|
||||||
// DO NOT USE THIS FOR AN ACTUAL PASSWORD GENERATOR
|
|
||||||
var (
|
|
||||||
lowerCharSet = "abcdedfghijklmnopqrst"
|
|
||||||
upperCharSet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
|
||||||
specialCharSet = "!@#$%&*"
|
|
||||||
numberSet = "0123456789"
|
|
||||||
allCharSet = lowerCharSet + upperCharSet + specialCharSet + numberSet
|
|
||||||
)
|
|
||||||
|
|
||||||
func testPassword() string {
|
|
||||||
var password strings.Builder
|
|
||||||
|
|
||||||
// Set special character
|
|
||||||
for i := 0; i < 5; i++ {
|
|
||||||
random := rand.IntN(len(specialCharSet))
|
|
||||||
password.WriteString(string(specialCharSet[random]))
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set numeric
|
|
||||||
for i := 0; i < 5; i++ {
|
|
||||||
random := rand.IntN(len(numberSet))
|
|
||||||
password.WriteString(string(numberSet[random]))
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set uppercase
|
|
||||||
for i := 0; i < 5; i++ {
|
|
||||||
random := rand.IntN(len(upperCharSet))
|
|
||||||
password.WriteString(string(upperCharSet[random]))
|
|
||||||
}
|
|
||||||
|
|
||||||
for i := 0; i < 5; i++ {
|
|
||||||
random := rand.IntN(len(allCharSet))
|
|
||||||
password.WriteString(string(allCharSet[random]))
|
|
||||||
}
|
|
||||||
inRune := []rune(password.String())
|
|
||||||
rand.Shuffle(len(inRune), func(i, j int) {
|
|
||||||
inRune[i], inRune[j] = inRune[j], inRune[i]
|
|
||||||
})
|
|
||||||
return string(inRune)
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -69,7 +69,7 @@ func (i *Identicon) render(c, b1, b2, b1Angle, b2Angle, foreColor int) image.Ima
|
||||||
/*
|
/*
|
||||||
# Algorithm
|
# Algorithm
|
||||||
|
|
||||||
Origin: An image is splitted into 9 areas
|
Origin: An image is split into 9 areas
|
||||||
|
|
||||||
```
|
```
|
||||||
-------------
|
-------------
|
||||||
|
|
|
@ -29,7 +29,7 @@ func (tes Entries) GetCommitsInfo(ctx context.Context, commit *Commit, treePath
|
||||||
var revs map[string]*Commit
|
var revs map[string]*Commit
|
||||||
if commit.repo.LastCommitCache != nil {
|
if commit.repo.LastCommitCache != nil {
|
||||||
var unHitPaths []string
|
var unHitPaths []string
|
||||||
revs, unHitPaths, err = getLastCommitForPathsByCache(ctx, commit.ID.String(), treePath, entryPaths, commit.repo.LastCommitCache)
|
revs, unHitPaths, err = getLastCommitForPathsByCache(commit.ID.String(), treePath, entryPaths, commit.repo.LastCommitCache)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
|
@ -97,7 +97,7 @@ func (tes Entries) GetCommitsInfo(ctx context.Context, commit *Commit, treePath
|
||||||
return commitsInfo, treeCommit, nil
|
return commitsInfo, treeCommit, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func getLastCommitForPathsByCache(ctx context.Context, commitID, treePath string, paths []string, cache *LastCommitCache) (map[string]*Commit, []string, error) {
|
func getLastCommitForPathsByCache(commitID, treePath string, paths []string, cache *LastCommitCache) (map[string]*Commit, []string, error) {
|
||||||
var unHitEntryPaths []string
|
var unHitEntryPaths []string
|
||||||
results := make(map[string]*Commit)
|
results := make(map[string]*Commit)
|
||||||
for _, p := range paths {
|
for _, p := range paths {
|
||||||
|
|
|
@ -29,6 +29,7 @@ type GrepOptions struct {
|
||||||
MaxResultLimit int
|
MaxResultLimit int
|
||||||
ContextLineNumber int
|
ContextLineNumber int
|
||||||
IsFuzzy bool
|
IsFuzzy bool
|
||||||
|
PathSpec []setting.Glob
|
||||||
}
|
}
|
||||||
|
|
||||||
func GrepSearch(ctx context.Context, repo *Repository, search string, opts GrepOptions) ([]*GrepResult, error) {
|
func GrepSearch(ctx context.Context, repo *Repository, search string, opts GrepOptions) ([]*GrepResult, error) {
|
||||||
|
@ -61,15 +62,20 @@ func GrepSearch(ctx context.Context, repo *Repository, search string, opts GrepO
|
||||||
} else {
|
} else {
|
||||||
cmd.AddOptionValues("-e", strings.TrimLeft(search, "-"))
|
cmd.AddOptionValues("-e", strings.TrimLeft(search, "-"))
|
||||||
}
|
}
|
||||||
|
|
||||||
// pathspec
|
// pathspec
|
||||||
files := make([]string, 0, len(setting.Indexer.IncludePatterns)+len(setting.Indexer.ExcludePatterns))
|
files := make([]string, 0,
|
||||||
for _, expr := range setting.Indexer.IncludePatterns {
|
len(setting.Indexer.IncludePatterns)+
|
||||||
files = append(files, expr.Pattern())
|
len(setting.Indexer.ExcludePatterns)+
|
||||||
|
len(opts.PathSpec))
|
||||||
|
for _, expr := range append(setting.Indexer.IncludePatterns, opts.PathSpec...) {
|
||||||
|
files = append(files, ":"+expr.Pattern())
|
||||||
}
|
}
|
||||||
for _, expr := range setting.Indexer.ExcludePatterns {
|
for _, expr := range setting.Indexer.ExcludePatterns {
|
||||||
files = append(files, ":^"+expr.Pattern())
|
files = append(files, ":^"+expr.Pattern())
|
||||||
}
|
}
|
||||||
cmd.AddDynamicArguments(cmp.Or(opts.RefName, "HEAD")).AddDashesAndList(files...)
|
cmd.AddDynamicArguments(cmp.Or(opts.RefName, "HEAD")).AddDashesAndList(files...)
|
||||||
|
|
||||||
opts.MaxResultLimit = cmp.Or(opts.MaxResultLimit, 50)
|
opts.MaxResultLimit = cmp.Or(opts.MaxResultLimit, 50)
|
||||||
stderr := bytes.Buffer{}
|
stderr := bytes.Buffer{}
|
||||||
err = cmd.Run(&RunOpts{
|
err = cmd.Run(&RunOpts{
|
||||||
|
|
|
@ -76,3 +76,33 @@ func TestGrepLongFiles(t *testing.T) {
|
||||||
assert.Len(t, res, 1)
|
assert.Len(t, res, 1)
|
||||||
assert.Len(t, res[0].LineCodes[0], 65*1024)
|
assert.Len(t, res[0].LineCodes[0], 65*1024)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestGrepRefs(t *testing.T) {
|
||||||
|
tmpDir := t.TempDir()
|
||||||
|
|
||||||
|
err := InitRepository(DefaultContext, tmpDir, false, Sha1ObjectFormat.Name())
|
||||||
|
assert.NoError(t, err)
|
||||||
|
|
||||||
|
gitRepo, err := openRepositoryWithDefaultContext(tmpDir)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
defer gitRepo.Close()
|
||||||
|
|
||||||
|
assert.NoError(t, os.WriteFile(path.Join(tmpDir, "README.md"), []byte{'A'}, 0o666))
|
||||||
|
assert.NoError(t, AddChanges(tmpDir, true))
|
||||||
|
|
||||||
|
err = CommitChanges(tmpDir, CommitChangesOptions{Message: "add A"})
|
||||||
|
assert.NoError(t, err)
|
||||||
|
|
||||||
|
assert.NoError(t, gitRepo.CreateTag("v1", "HEAD"))
|
||||||
|
|
||||||
|
assert.NoError(t, os.WriteFile(path.Join(tmpDir, "README.md"), []byte{'A', 'B', 'C', 'D'}, 0o666))
|
||||||
|
assert.NoError(t, AddChanges(tmpDir, true))
|
||||||
|
|
||||||
|
err = CommitChanges(tmpDir, CommitChangesOptions{Message: "add BCD"})
|
||||||
|
assert.NoError(t, err)
|
||||||
|
|
||||||
|
res, err := GrepSearch(context.Background(), gitRepo, "a", GrepOptions{RefName: "v1"})
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.Len(t, res, 1)
|
||||||
|
assert.Equal(t, res[0].LineCodes[0], "A")
|
||||||
|
}
|
||||||
|
|
|
@ -18,7 +18,7 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
// ParseTreeEntries parses the output of a `git ls-tree -l` command.
|
// ParseTreeEntries parses the output of a `git ls-tree -l` command.
|
||||||
func ParseTreeEntries(h ObjectFormat, data []byte) ([]*TreeEntry, error) {
|
func ParseTreeEntries(data []byte) ([]*TreeEntry, error) {
|
||||||
return parseTreeEntries(data, nil)
|
return parseTreeEntries(data, nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -67,7 +67,7 @@ func TestParseTreeEntries(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, testCase := range testCases {
|
for _, testCase := range testCases {
|
||||||
entries, err := ParseTreeEntries(Sha1ObjectFormat, []byte(testCase.Input))
|
entries, err := ParseTreeEntries([]byte(testCase.Input))
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
if len(entries) > 1 {
|
if len(entries) > 1 {
|
||||||
fmt.Println(testCase.Expected[0].ID)
|
fmt.Println(testCase.Expected[0].ID)
|
||||||
|
|
|
@ -17,13 +17,13 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
// ParseTreeEntries parses the output of a `git ls-tree -l` command.
|
// ParseTreeEntries parses the output of a `git ls-tree -l` command.
|
||||||
func ParseTreeEntries(objectFormat ObjectFormat, data []byte) ([]*TreeEntry, error) {
|
func ParseTreeEntries(data []byte) ([]*TreeEntry, error) {
|
||||||
return parseTreeEntries(objectFormat, data, nil)
|
return parseTreeEntries(data, nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
var sepSpace = []byte{' '}
|
var sepSpace = []byte{' '}
|
||||||
|
|
||||||
func parseTreeEntries(objectFormat ObjectFormat, data []byte, ptree *Tree) ([]*TreeEntry, error) {
|
func parseTreeEntries(data []byte, ptree *Tree) ([]*TreeEntry, error) {
|
||||||
var err error
|
var err error
|
||||||
entries := make([]*TreeEntry, 0, bytes.Count(data, []byte{'\n'})+1)
|
entries := make([]*TreeEntry, 0, bytes.Count(data, []byte{'\n'})+1)
|
||||||
for pos := 0; pos < len(data); {
|
for pos := 0; pos < len(data); {
|
||||||
|
|
|
@ -12,8 +12,6 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestParseTreeEntriesLong(t *testing.T) {
|
func TestParseTreeEntriesLong(t *testing.T) {
|
||||||
objectFormat := Sha1ObjectFormat
|
|
||||||
|
|
||||||
testCases := []struct {
|
testCases := []struct {
|
||||||
Input string
|
Input string
|
||||||
Expected []*TreeEntry
|
Expected []*TreeEntry
|
||||||
|
@ -56,7 +54,7 @@ func TestParseTreeEntriesLong(t *testing.T) {
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
for _, testCase := range testCases {
|
for _, testCase := range testCases {
|
||||||
entries, err := ParseTreeEntries(objectFormat, []byte(testCase.Input))
|
entries, err := ParseTreeEntries([]byte(testCase.Input))
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.Len(t, entries, len(testCase.Expected))
|
assert.Len(t, entries, len(testCase.Expected))
|
||||||
for i, entry := range entries {
|
for i, entry := range entries {
|
||||||
|
@ -66,8 +64,6 @@ func TestParseTreeEntriesLong(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestParseTreeEntriesShort(t *testing.T) {
|
func TestParseTreeEntriesShort(t *testing.T) {
|
||||||
objectFormat := Sha1ObjectFormat
|
|
||||||
|
|
||||||
testCases := []struct {
|
testCases := []struct {
|
||||||
Input string
|
Input string
|
||||||
Expected []*TreeEntry
|
Expected []*TreeEntry
|
||||||
|
@ -91,7 +87,7 @@ func TestParseTreeEntriesShort(t *testing.T) {
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
for _, testCase := range testCases {
|
for _, testCase := range testCases {
|
||||||
entries, err := ParseTreeEntries(objectFormat, []byte(testCase.Input))
|
entries, err := ParseTreeEntries([]byte(testCase.Input))
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.Len(t, entries, len(testCase.Expected))
|
assert.Len(t, entries, len(testCase.Expected))
|
||||||
for i, entry := range entries {
|
for i, entry := range entries {
|
||||||
|
@ -102,7 +98,7 @@ func TestParseTreeEntriesShort(t *testing.T) {
|
||||||
|
|
||||||
func TestParseTreeEntriesInvalid(t *testing.T) {
|
func TestParseTreeEntriesInvalid(t *testing.T) {
|
||||||
// there was a panic: "runtime error: slice bounds out of range" when the input was invalid: #20315
|
// there was a panic: "runtime error: slice bounds out of range" when the input was invalid: #20315
|
||||||
entries, err := ParseTreeEntries(Sha1ObjectFormat, []byte("100644 blob ea0d83c9081af9500ac9f804101b3fd0a5c293af"))
|
entries, err := ParseTreeEntries([]byte("100644 blob ea0d83c9081af9500ac9f804101b3fd0a5c293af"))
|
||||||
assert.Error(t, err)
|
assert.Error(t, err)
|
||||||
assert.Len(t, entries, 0)
|
assert.Len(t, entries, 0)
|
||||||
}
|
}
|
||||||
|
|
|
@ -184,7 +184,7 @@ func (ref RefName) RefGroup() string {
|
||||||
}
|
}
|
||||||
|
|
||||||
// RefType returns the simple ref type of the reference, e.g. branch, tag
|
// RefType returns the simple ref type of the reference, e.g. branch, tag
|
||||||
// It's differrent from RefGroup, which is using the name of the directory under .git/refs
|
// It's different from RefGroup, which is using the name of the directory under .git/refs
|
||||||
// Here we using branch but not heads, using tag but not tags
|
// Here we using branch but not heads, using tag but not tags
|
||||||
func (ref RefName) RefType() string {
|
func (ref RefName) RefType() string {
|
||||||
var refType string
|
var refType string
|
||||||
|
|
|
@ -7,7 +7,6 @@ package git
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"context"
|
"context"
|
||||||
"errors"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"net/url"
|
"net/url"
|
||||||
|
@ -63,32 +62,6 @@ func IsRepoURLAccessible(ctx context.Context, url string) bool {
|
||||||
return err == nil
|
return err == nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetObjectFormatOfRepo returns the hash type of repository at a given path
|
|
||||||
func GetObjectFormatOfRepo(ctx context.Context, repoPath string) (ObjectFormat, error) {
|
|
||||||
var stdout, stderr strings.Builder
|
|
||||||
|
|
||||||
err := NewCommand(ctx, "hash-object", "--stdin").Run(&RunOpts{
|
|
||||||
Dir: repoPath,
|
|
||||||
Stdout: &stdout,
|
|
||||||
Stderr: &stderr,
|
|
||||||
Stdin: &strings.Reader{},
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
if stderr.Len() > 0 {
|
|
||||||
return nil, errors.New(stderr.String())
|
|
||||||
}
|
|
||||||
|
|
||||||
h, err := NewIDFromString(strings.TrimRight(stdout.String(), "\n"))
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return h.Type(), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// InitRepository initializes a new Git repository.
|
// InitRepository initializes a new Git repository.
|
||||||
func InitRepository(ctx context.Context, repoPath string, bare bool, objectFormatName string) error {
|
func InitRepository(ctx context.Context, repoPath string, bare bool, objectFormatName string) error {
|
||||||
err := os.MkdirAll(repoPath, os.ModePerm)
|
err := os.MkdirAll(repoPath, os.ModePerm)
|
||||||
|
|
|
@ -113,7 +113,7 @@ func (ca GitAttribute) Bool() optional.Option[bool] {
|
||||||
}
|
}
|
||||||
|
|
||||||
// gitCheckAttrCommand prepares the "git check-attr" command for later use as one-shot or streaming
|
// gitCheckAttrCommand prepares the "git check-attr" command for later use as one-shot or streaming
|
||||||
// instanciation.
|
// instantiation.
|
||||||
func (repo *Repository) gitCheckAttrCommand(treeish string, attributes ...string) (*Command, *RunOpts, context.CancelFunc, error) {
|
func (repo *Repository) gitCheckAttrCommand(treeish string, attributes ...string) (*Command, *RunOpts, context.CancelFunc, error) {
|
||||||
if len(attributes) == 0 {
|
if len(attributes) == 0 {
|
||||||
return nil, nil, nil, fmt.Errorf("no provided attributes to check-attr")
|
return nil, nil, nil, fmt.Errorf("no provided attributes to check-attr")
|
||||||
|
|
|
@ -77,11 +77,8 @@ func (t *Tree) ListEntries() (Entries, error) {
|
||||||
return nil, runErr
|
return nil, runErr
|
||||||
}
|
}
|
||||||
|
|
||||||
objectFormat, err := t.repo.GetObjectFormat()
|
var err error
|
||||||
if err != nil {
|
t.entries, err = parseTreeEntries(stdout, t)
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
t.entries, err = parseTreeEntries(objectFormat, stdout, t)
|
|
||||||
if err == nil {
|
if err == nil {
|
||||||
t.entriesParsed = true
|
t.entriesParsed = true
|
||||||
}
|
}
|
||||||
|
@ -104,11 +101,8 @@ func (t *Tree) listEntriesRecursive(extraArgs TrustedCmdArgs) (Entries, error) {
|
||||||
return nil, runErr
|
return nil, runErr
|
||||||
}
|
}
|
||||||
|
|
||||||
objectFormat, err := t.repo.GetObjectFormat()
|
var err error
|
||||||
if err != nil {
|
t.entriesRecursive, err = parseTreeEntries(stdout, t)
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
t.entriesRecursive, err = parseTreeEntries(objectFormat, stdout, t)
|
|
||||||
if err == nil {
|
if err == nil {
|
||||||
t.entriesRecursiveParsed = true
|
t.entriesRecursiveParsed = true
|
||||||
}
|
}
|
||||||
|
|
|
@ -180,7 +180,7 @@ func (flow *Flow) AddGlyph(row, column int, glyph byte) {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// Glyph represents a co-ordinate and glyph
|
// Glyph represents a coordinate and glyph
|
||||||
type Glyph struct {
|
type Glyph struct {
|
||||||
Row int
|
Row int
|
||||||
Column int
|
Column int
|
||||||
|
@ -234,7 +234,7 @@ func newRefsFromRefNames(refNames []byte) []git.Reference {
|
||||||
return refs
|
return refs
|
||||||
}
|
}
|
||||||
|
|
||||||
// Commit represents a commit at co-ordinate X, Y with the data
|
// Commit represents a commit at coordinate X, Y with the data
|
||||||
type Commit struct {
|
type Commit struct {
|
||||||
Commit *git.Commit
|
Commit *git.Commit
|
||||||
User *user_model.User
|
User *user_model.User
|
||||||
|
|
|
@ -17,11 +17,14 @@ import (
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
charsetModule "code.gitea.io/gitea/modules/charset"
|
charsetModule "code.gitea.io/gitea/modules/charset"
|
||||||
|
"code.gitea.io/gitea/modules/container"
|
||||||
"code.gitea.io/gitea/modules/httpcache"
|
"code.gitea.io/gitea/modules/httpcache"
|
||||||
"code.gitea.io/gitea/modules/log"
|
"code.gitea.io/gitea/modules/log"
|
||||||
"code.gitea.io/gitea/modules/setting"
|
"code.gitea.io/gitea/modules/setting"
|
||||||
"code.gitea.io/gitea/modules/typesniffer"
|
"code.gitea.io/gitea/modules/typesniffer"
|
||||||
"code.gitea.io/gitea/modules/util"
|
"code.gitea.io/gitea/modules/util"
|
||||||
|
|
||||||
|
"github.com/klauspost/compress/gzhttp"
|
||||||
)
|
)
|
||||||
|
|
||||||
type ServeHeaderOptions struct {
|
type ServeHeaderOptions struct {
|
||||||
|
@ -38,6 +41,11 @@ type ServeHeaderOptions struct {
|
||||||
func ServeSetHeaders(w http.ResponseWriter, opts *ServeHeaderOptions) {
|
func ServeSetHeaders(w http.ResponseWriter, opts *ServeHeaderOptions) {
|
||||||
header := w.Header()
|
header := w.Header()
|
||||||
|
|
||||||
|
skipCompressionExts := container.SetOf(".gz", ".bz2", ".zip", ".xz", ".zst", ".deb", ".apk", ".jar", ".png", ".jpg", ".webp")
|
||||||
|
if skipCompressionExts.Contains(strings.ToLower(path.Ext(opts.Filename))) {
|
||||||
|
w.Header().Add(gzhttp.HeaderNoCompression, "1")
|
||||||
|
}
|
||||||
|
|
||||||
contentType := typesniffer.ApplicationOctetStream
|
contentType := typesniffer.ApplicationOctetStream
|
||||||
if opts.ContentType != "" {
|
if opts.ContentType != "" {
|
||||||
if opts.ContentTypeCharset != "" {
|
if opts.ContentTypeCharset != "" {
|
||||||
|
|
|
@ -62,8 +62,8 @@ func isIndexable(entry *git.TreeEntry) bool {
|
||||||
}
|
}
|
||||||
|
|
||||||
// parseGitLsTreeOutput parses the output of a `git ls-tree -r --full-name` command
|
// parseGitLsTreeOutput parses the output of a `git ls-tree -r --full-name` command
|
||||||
func parseGitLsTreeOutput(objectFormat git.ObjectFormat, stdout []byte) ([]internal.FileUpdate, error) {
|
func parseGitLsTreeOutput(stdout []byte) ([]internal.FileUpdate, error) {
|
||||||
entries, err := git.ParseTreeEntries(objectFormat, stdout)
|
entries, err := git.ParseTreeEntries(stdout)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -91,10 +91,8 @@ func genesisChanges(ctx context.Context, repo *repo_model.Repository, revision s
|
||||||
return nil, runErr
|
return nil, runErr
|
||||||
}
|
}
|
||||||
|
|
||||||
objectFormat := git.ObjectFormatFromName(repo.ObjectFormatName)
|
|
||||||
|
|
||||||
var err error
|
var err error
|
||||||
changes.Updates, err = parseGitLsTreeOutput(objectFormat, stdout)
|
changes.Updates, err = parseGitLsTreeOutput(stdout)
|
||||||
return &changes, err
|
return &changes, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -122,7 +120,7 @@ func nonGenesisChanges(ctx context.Context, repo *repo_model.Repository, revisio
|
||||||
}
|
}
|
||||||
fields := strings.Split(line, "\t")
|
fields := strings.Split(line, "\t")
|
||||||
if len(fields) < 2 {
|
if len(fields) < 2 {
|
||||||
log.Warn("Unparseable output for diff --name-status: `%s`)", line)
|
log.Warn("Unparsable output for diff --name-status: `%s`)", line)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
filename := fields[1]
|
filename := fields[1]
|
||||||
|
@ -142,12 +140,12 @@ func nonGenesisChanges(ctx context.Context, repo *repo_model.Repository, revisio
|
||||||
changes.RemovedFilenames = append(changes.RemovedFilenames, filename)
|
changes.RemovedFilenames = append(changes.RemovedFilenames, filename)
|
||||||
case 'R', 'C':
|
case 'R', 'C':
|
||||||
if len(fields) < 3 {
|
if len(fields) < 3 {
|
||||||
log.Warn("Unparseable output for diff --name-status: `%s`)", line)
|
log.Warn("Unparsable output for diff --name-status: `%s`)", line)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
dest := fields[2]
|
dest := fields[2]
|
||||||
if len(dest) == 0 {
|
if len(dest) == 0 {
|
||||||
log.Warn("Unparseable output for diff --name-status: `%s`)", line)
|
log.Warn("Unparsable output for diff --name-status: `%s`)", line)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if dest[0] == '"' {
|
if dest[0] == '"' {
|
||||||
|
@ -172,8 +170,6 @@ func nonGenesisChanges(ctx context.Context, repo *repo_model.Repository, revisio
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
objectFormat := git.ObjectFormatFromName(repo.ObjectFormatName)
|
changes.Updates, err = parseGitLsTreeOutput(lsTreeStdout)
|
||||||
|
|
||||||
changes.Updates, err = parseGitLsTreeOutput(objectFormat, lsTreeStdout)
|
|
||||||
return &changes, err
|
return &changes, err
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,7 +27,7 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
// IndexerMetadata is used to send data to the queue, so it contains only the ids.
|
// IndexerMetadata is used to send data to the queue, so it contains only the ids.
|
||||||
// It may look weired, because it has to be compatible with the old queue data format.
|
// It may look weird, because it has to be compatible with the old queue data format.
|
||||||
// If the IsDelete flag is true, the IDs specify the issues to delete from the index without querying the database.
|
// If the IsDelete flag is true, the IDs specify the issues to delete from the index without querying the database.
|
||||||
// If the IsDelete flag is false, the ID specify the issue to index, so Indexer will query the database to get the issue data.
|
// If the IsDelete flag is false, the ID specify the issue to index, so Indexer will query the database to get the issue data.
|
||||||
// It should be noted that if the id is not existing in the database, it's index will be deleted too even if IsDelete is false.
|
// It should be noted that if the id is not existing in the database, it's index will be deleted too even if IsDelete is false.
|
||||||
|
|
|
@ -138,7 +138,7 @@ var cases = []*testIndexerCase{
|
||||||
{ID: 1002, Comments: []string{"hi", "hello world"}},
|
{ID: 1002, Comments: []string{"hi", "hello world"}},
|
||||||
},
|
},
|
||||||
SearchOptions: &internal.SearchOptions{
|
SearchOptions: &internal.SearchOptions{
|
||||||
Keyword: "hello wrold",
|
Keyword: "hello world",
|
||||||
IsFuzzyKeyword: true,
|
IsFuzzyKeyword: true,
|
||||||
},
|
},
|
||||||
ExpectedIDs: []int64{1002, 1001, 1000},
|
ExpectedIDs: []int64{1002, 1001, 1000},
|
||||||
|
|
|
@ -66,7 +66,7 @@ func TestConvertHits(t *testing.T) {
|
||||||
"id": float64(11),
|
"id": float64(11),
|
||||||
"title": "a title",
|
"title": "a title",
|
||||||
"content": "issue body with no match",
|
"content": "issue body with no match",
|
||||||
"comments": []any{"hey whats up?", "I'm currently bowling", "nice"},
|
"comments": []any{"hey what's up?", "I'm currently bowling", "nice"},
|
||||||
},
|
},
|
||||||
map[string]any{
|
map[string]any{
|
||||||
"id": float64(22),
|
"id": float64(22),
|
||||||
|
|
|
@ -204,7 +204,7 @@ func EventFormatTextMessage(mode *WriterMode, event *Event, msgFormat string, ms
|
||||||
msg = []byte(fmt.Sprintf(msgFormat, msgArgs...))
|
msg = []byte(fmt.Sprintf(msgFormat, msgArgs...))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// try to re-use the pre-formatted simple text message
|
// try to reuse the pre-formatted simple text message
|
||||||
if len(msg) == 0 {
|
if len(msg) == 0 {
|
||||||
msg = []byte(event.MsgSimpleText)
|
msg = []byte(event.MsgSimpleText)
|
||||||
}
|
}
|
||||||
|
|
|
@ -51,7 +51,7 @@ func (g *GitHubLegacyCalloutTransformer) Transform(node *ast.Document, reader te
|
||||||
// color the blockquote
|
// color the blockquote
|
||||||
v.SetAttributeString("class", []byte("attention-header attention-"+calloutType))
|
v.SetAttributeString("class", []byte("attention-header attention-"+calloutType))
|
||||||
|
|
||||||
// Create new parargaph.
|
// Create new paragraph.
|
||||||
attentionParagraph := ast.NewParagraph()
|
attentionParagraph := ast.NewParagraph()
|
||||||
attentionParagraph.SetAttributeString("class", []byte("attention-title"))
|
attentionParagraph.SetAttributeString("class", []byte("attention-title"))
|
||||||
|
|
||||||
|
|
|
@ -58,11 +58,11 @@ func (g *ASTTransformer) Transform(node *ast.Document, reader text.Reader, pc pa
|
||||||
case *ast.Paragraph:
|
case *ast.Paragraph:
|
||||||
g.applyElementDir(v)
|
g.applyElementDir(v)
|
||||||
case *ast.Image:
|
case *ast.Image:
|
||||||
g.transformImage(ctx, v, reader)
|
g.transformImage(ctx, v)
|
||||||
case *ast.Link:
|
case *ast.Link:
|
||||||
g.transformLink(ctx, v, reader)
|
g.transformLink(ctx, v)
|
||||||
case *ast.List:
|
case *ast.List:
|
||||||
g.transformList(ctx, v, reader, rc)
|
g.transformList(ctx, v, rc)
|
||||||
case *ast.Text:
|
case *ast.Text:
|
||||||
if v.SoftLineBreak() && !v.HardLineBreak() {
|
if v.SoftLineBreak() && !v.HardLineBreak() {
|
||||||
if ctx.Metas["mode"] != "document" {
|
if ctx.Metas["mode"] != "document" {
|
||||||
|
|
|
@ -470,7 +470,7 @@ func TestColorPreview(t *testing.T) {
|
||||||
// no backticks
|
// no backticks
|
||||||
"rgb(166, 32, 64)",
|
"rgb(166, 32, 64)",
|
||||||
// typo
|
// typo
|
||||||
"`hsI(0, 100%, 50%)`",
|
"`hsI(0, 100%, 50%)`", // codespell-ignore
|
||||||
// looks like a color but not really
|
// looks like a color but not really
|
||||||
"`hsl(40, 60, 80)`",
|
"`hsl(40, 60, 80)`",
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,7 +13,7 @@ import (
|
||||||
"github.com/yuin/goldmark/util"
|
"github.com/yuin/goldmark/util"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (g *ASTTransformer) transformHeading(ctx *markup.RenderContext, v *ast.Heading, reader text.Reader, tocList *[]markup.Header) {
|
func (g *ASTTransformer) transformHeading(_ *markup.RenderContext, v *ast.Heading, reader text.Reader, tocList *[]markup.Header) {
|
||||||
for _, attr := range v.Attributes() {
|
for _, attr := range v.Attributes() {
|
||||||
if _, ok := attr.Value.([]byte); !ok {
|
if _, ok := attr.Value.([]byte); !ok {
|
||||||
v.SetAttribute(attr.Name, []byte(fmt.Sprintf("%v", attr.Value)))
|
v.SetAttribute(attr.Name, []byte(fmt.Sprintf("%v", attr.Value)))
|
||||||
|
|
|
@ -10,10 +10,9 @@ import (
|
||||||
giteautil "code.gitea.io/gitea/modules/util"
|
giteautil "code.gitea.io/gitea/modules/util"
|
||||||
|
|
||||||
"github.com/yuin/goldmark/ast"
|
"github.com/yuin/goldmark/ast"
|
||||||
"github.com/yuin/goldmark/text"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func (g *ASTTransformer) transformImage(ctx *markup.RenderContext, v *ast.Image, reader text.Reader) {
|
func (g *ASTTransformer) transformImage(ctx *markup.RenderContext, v *ast.Image) {
|
||||||
// Images need two things:
|
// Images need two things:
|
||||||
//
|
//
|
||||||
// 1. Their src needs to munged to be a real value
|
// 1. Their src needs to munged to be a real value
|
||||||
|
|
|
@ -12,10 +12,9 @@ import (
|
||||||
giteautil "code.gitea.io/gitea/modules/util"
|
giteautil "code.gitea.io/gitea/modules/util"
|
||||||
|
|
||||||
"github.com/yuin/goldmark/ast"
|
"github.com/yuin/goldmark/ast"
|
||||||
"github.com/yuin/goldmark/text"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func (g *ASTTransformer) transformLink(ctx *markup.RenderContext, v *ast.Link, reader text.Reader) {
|
func (g *ASTTransformer) transformLink(ctx *markup.RenderContext, v *ast.Link) {
|
||||||
// Links need their href to munged to be a real value
|
// Links need their href to munged to be a real value
|
||||||
link := v.Destination
|
link := v.Destination
|
||||||
|
|
||||||
|
|
|
@ -11,7 +11,6 @@ import (
|
||||||
"github.com/yuin/goldmark/ast"
|
"github.com/yuin/goldmark/ast"
|
||||||
east "github.com/yuin/goldmark/extension/ast"
|
east "github.com/yuin/goldmark/extension/ast"
|
||||||
"github.com/yuin/goldmark/renderer/html"
|
"github.com/yuin/goldmark/renderer/html"
|
||||||
"github.com/yuin/goldmark/text"
|
|
||||||
"github.com/yuin/goldmark/util"
|
"github.com/yuin/goldmark/util"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -50,7 +49,7 @@ func (r *HTMLRenderer) renderTaskCheckBox(w util.BufWriter, source []byte, node
|
||||||
return ast.WalkContinue, nil
|
return ast.WalkContinue, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *ASTTransformer) transformList(ctx *markup.RenderContext, v *ast.List, reader text.Reader, rc *RenderConfig) {
|
func (g *ASTTransformer) transformList(_ *markup.RenderContext, v *ast.List, rc *RenderConfig) {
|
||||||
if v.HasChildren() {
|
if v.HasChildren() {
|
||||||
children := make([]ast.Node, 0, v.ChildCount())
|
children := make([]ast.Node, 0, v.ChildCount())
|
||||||
child := v.FirstChild()
|
child := v.FirstChild()
|
||||||
|
|
|
@ -54,7 +54,7 @@ func (r *stripRenderer) Render(w io.Writer, source []byte, doc ast.Node) error {
|
||||||
}
|
}
|
||||||
return ast.WalkContinue, nil
|
return ast.WalkContinue, nil
|
||||||
case *ast.Link:
|
case *ast.Link:
|
||||||
r.processLink(w, v.Destination)
|
r.processLink(v.Destination)
|
||||||
return ast.WalkSkipChildren, nil
|
return ast.WalkSkipChildren, nil
|
||||||
case *ast.AutoLink:
|
case *ast.AutoLink:
|
||||||
// This could be a reference to an issue or pull - if so convert it
|
// This could be a reference to an issue or pull - if so convert it
|
||||||
|
@ -124,7 +124,7 @@ func (r *stripRenderer) processAutoLink(w io.Writer, link []byte) {
|
||||||
_, _ = w.Write([]byte(parts[4]))
|
_, _ = w.Write([]byte(parts[4]))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *stripRenderer) processLink(w io.Writer, link []byte) {
|
func (r *stripRenderer) processLink(link []byte) {
|
||||||
// Links are processed out of band
|
// Links are processed out of band
|
||||||
r.links = append(r.links, string(link))
|
r.links = append(r.links, string(link))
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,7 +22,7 @@ func TestOption(t *testing.T) {
|
||||||
assert.Equal(t, int(0), none.Value())
|
assert.Equal(t, int(0), none.Value())
|
||||||
assert.Equal(t, int(1), none.ValueOrDefault(1))
|
assert.Equal(t, int(1), none.ValueOrDefault(1))
|
||||||
|
|
||||||
some := optional.Some[int](1)
|
some := optional.Some(1)
|
||||||
assert.True(t, some.Has())
|
assert.True(t, some.Has())
|
||||||
assert.Equal(t, int(1), some.Value())
|
assert.Equal(t, int(1), some.Value())
|
||||||
assert.Equal(t, int(1), some.ValueOrDefault(2))
|
assert.Equal(t, int(1), some.ValueOrDefault(2))
|
||||||
|
|
|
@ -78,6 +78,7 @@ type PackageMetadataVersion struct {
|
||||||
Repository Repository `json:"repository,omitempty"`
|
Repository Repository `json:"repository,omitempty"`
|
||||||
Keywords []string `json:"keywords,omitempty"`
|
Keywords []string `json:"keywords,omitempty"`
|
||||||
Dependencies map[string]string `json:"dependencies,omitempty"`
|
Dependencies map[string]string `json:"dependencies,omitempty"`
|
||||||
|
BundleDependencies []string `json:"bundleDependencies,omitempty"`
|
||||||
DevDependencies map[string]string `json:"devDependencies,omitempty"`
|
DevDependencies map[string]string `json:"devDependencies,omitempty"`
|
||||||
PeerDependencies map[string]string `json:"peerDependencies,omitempty"`
|
PeerDependencies map[string]string `json:"peerDependencies,omitempty"`
|
||||||
Bin map[string]string `json:"bin,omitempty"`
|
Bin map[string]string `json:"bin,omitempty"`
|
||||||
|
@ -218,6 +219,7 @@ func ParsePackage(r io.Reader) (*Package, error) {
|
||||||
ProjectURL: meta.Homepage,
|
ProjectURL: meta.Homepage,
|
||||||
Keywords: meta.Keywords,
|
Keywords: meta.Keywords,
|
||||||
Dependencies: meta.Dependencies,
|
Dependencies: meta.Dependencies,
|
||||||
|
BundleDependencies: meta.BundleDependencies,
|
||||||
DevelopmentDependencies: meta.DevDependencies,
|
DevelopmentDependencies: meta.DevDependencies,
|
||||||
PeerDependencies: meta.PeerDependencies,
|
PeerDependencies: meta.PeerDependencies,
|
||||||
OptionalDependencies: meta.OptionalDependencies,
|
OptionalDependencies: meta.OptionalDependencies,
|
||||||
|
|
|
@ -16,6 +16,7 @@ type Metadata struct {
|
||||||
ProjectURL string `json:"project_url,omitempty"`
|
ProjectURL string `json:"project_url,omitempty"`
|
||||||
Keywords []string `json:"keywords,omitempty"`
|
Keywords []string `json:"keywords,omitempty"`
|
||||||
Dependencies map[string]string `json:"dependencies,omitempty"`
|
Dependencies map[string]string `json:"dependencies,omitempty"`
|
||||||
|
BundleDependencies []string `json:"bundleDependencies,omitempty"`
|
||||||
DevelopmentDependencies map[string]string `json:"development_dependencies,omitempty"`
|
DevelopmentDependencies map[string]string `json:"development_dependencies,omitempty"`
|
||||||
PeerDependencies map[string]string `json:"peer_dependencies,omitempty"`
|
PeerDependencies map[string]string `json:"peer_dependencies,omitempty"`
|
||||||
OptionalDependencies map[string]string `json:"optional_dependencies,omitempty"`
|
OptionalDependencies map[string]string `json:"optional_dependencies,omitempty"`
|
||||||
|
|
|
@ -11,6 +11,7 @@ import (
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"code.gitea.io/gitea/modules/git"
|
"code.gitea.io/gitea/modules/git"
|
||||||
|
"code.gitea.io/gitea/modules/repository"
|
||||||
"code.gitea.io/gitea/modules/setting"
|
"code.gitea.io/gitea/modules/setting"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -53,6 +54,7 @@ type HookOptions struct {
|
||||||
GitQuarantinePath string
|
GitQuarantinePath string
|
||||||
GitPushOptions GitPushOptions
|
GitPushOptions GitPushOptions
|
||||||
PullRequestID int64
|
PullRequestID int64
|
||||||
|
PushTrigger repository.PushTrigger
|
||||||
DeployKeyID int64 // if the pusher is a DeployKey, then UserID is the repo's org user.
|
DeployKeyID int64 // if the pusher is a DeployKey, then UserID is the repo's org user.
|
||||||
IsWiki bool
|
IsWiki bool
|
||||||
ActionPerm int
|
ActionPerm int
|
||||||
|
|
|
@ -134,7 +134,7 @@ func (pm *Manager) AddTypedContext(parent context.Context, description, processT
|
||||||
//
|
//
|
||||||
// Most processes will not need to use the cancel function but there will be cases whereby you want to cancel the process but not immediately remove it from the
|
// Most processes will not need to use the cancel function but there will be cases whereby you want to cancel the process but not immediately remove it from the
|
||||||
// process table.
|
// process table.
|
||||||
func (pm *Manager) AddContextTimeout(parent context.Context, timeout time.Duration, description string) (ctx context.Context, cancel context.CancelFunc, finshed FinishedFunc) {
|
func (pm *Manager) AddContextTimeout(parent context.Context, timeout time.Duration, description string) (ctx context.Context, cancel context.CancelFunc, finished FinishedFunc) {
|
||||||
if timeout <= 0 {
|
if timeout <= 0 {
|
||||||
// it's meaningless to use timeout <= 0, and it must be a bug! so we must panic here to tell developers to make the timeout correct
|
// it's meaningless to use timeout <= 0, and it must be a bug! so we must panic here to tell developers to make the timeout correct
|
||||||
panic("the timeout must be greater than zero, otherwise the context will be cancelled immediately")
|
panic("the timeout must be greater than zero, otherwise the context will be cancelled immediately")
|
||||||
|
@ -142,9 +142,9 @@ func (pm *Manager) AddContextTimeout(parent context.Context, timeout time.Durati
|
||||||
|
|
||||||
ctx, cancel = context.WithTimeout(parent, timeout)
|
ctx, cancel = context.WithTimeout(parent, timeout)
|
||||||
|
|
||||||
ctx, _, finshed = pm.Add(ctx, description, cancel, NormalProcessType, true)
|
ctx, _, finished = pm.Add(ctx, description, cancel, NormalProcessType, true)
|
||||||
|
|
||||||
return ctx, cancel, finshed
|
return ctx, cancel, finished
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add create a new process
|
// Add create a new process
|
||||||
|
|
|
@ -22,7 +22,7 @@
|
||||||
//
|
//
|
||||||
// 4. Handler (represented by HandlerFuncT type):
|
// 4. Handler (represented by HandlerFuncT type):
|
||||||
// - It's the function responsible for processing items. Each active worker will call it.
|
// - It's the function responsible for processing items. Each active worker will call it.
|
||||||
// - If an item or some items are not psuccessfully rocessed, the handler could return them as "unhandled items".
|
// - If an item or some items are not successfully processed, the handler could return them as "unhandled items".
|
||||||
// In such scenarios, the queue system ensures these unhandled items are returned to the base queue after a brief delay.
|
// In such scenarios, the queue system ensures these unhandled items are returned to the base queue after a brief delay.
|
||||||
// This mechanism is particularly beneficial in cases where the processing entity (like a document indexer) is
|
// This mechanism is particularly beneficial in cases where the processing entity (like a document indexer) is
|
||||||
// temporarily unavailable. It ensures that no item is skipped or lost due to transient failures in the processing
|
// temporarily unavailable. It ensures that no item is skipped or lost due to transient failures in the processing
|
||||||
|
|
|
@ -5,6 +5,7 @@ package repository
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"fmt"
|
||||||
|
|
||||||
"code.gitea.io/gitea/models/db"
|
"code.gitea.io/gitea/models/db"
|
||||||
git_model "code.gitea.io/gitea/models/git"
|
git_model "code.gitea.io/gitea/models/git"
|
||||||
|
@ -36,6 +37,15 @@ func SyncRepoBranches(ctx context.Context, repoID, doerID int64) (int64, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
func SyncRepoBranchesWithRepo(ctx context.Context, repo *repo_model.Repository, gitRepo *git.Repository, doerID int64) (int64, error) {
|
func SyncRepoBranchesWithRepo(ctx context.Context, repo *repo_model.Repository, gitRepo *git.Repository, doerID int64) (int64, error) {
|
||||||
|
objFmt, err := gitRepo.GetObjectFormat()
|
||||||
|
if err != nil {
|
||||||
|
return 0, fmt.Errorf("GetObjectFormat: %w", err)
|
||||||
|
}
|
||||||
|
_, err = db.GetEngine(ctx).ID(repo.ID).Update(&repo_model.Repository{ObjectFormatName: objFmt.Name()})
|
||||||
|
if err != nil {
|
||||||
|
return 0, fmt.Errorf("UpdateRepository: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
allBranches := container.Set[string]{}
|
allBranches := container.Set[string]{}
|
||||||
{
|
{
|
||||||
branches, _, err := gitRepo.GetBranchNames(0, 0)
|
branches, _, err := gitRepo.GetBranchNames(0, 0)
|
||||||
|
|
31
modules/repository/branch_test.go
Normal file
31
modules/repository/branch_test.go
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
// Copyright 2024 The Gitea Authors. All rights reserved.
|
||||||
|
// SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
|
package repository
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"code.gitea.io/gitea/models/db"
|
||||||
|
git_model "code.gitea.io/gitea/models/git"
|
||||||
|
repo_model "code.gitea.io/gitea/models/repo"
|
||||||
|
"code.gitea.io/gitea/models/unittest"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestSyncRepoBranches(t *testing.T) {
|
||||||
|
assert.NoError(t, unittest.PrepareTestDatabase())
|
||||||
|
_, err := db.GetEngine(db.DefaultContext).ID(1).Update(&repo_model.Repository{ObjectFormatName: "bad-fmt"})
|
||||||
|
assert.NoError(t, db.TruncateBeans(db.DefaultContext, &git_model.Branch{}))
|
||||||
|
assert.NoError(t, err)
|
||||||
|
repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1})
|
||||||
|
assert.Equal(t, "bad-fmt", repo.ObjectFormatName)
|
||||||
|
_, err = SyncRepoBranches(db.DefaultContext, 1, 0)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
repo = unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1})
|
||||||
|
assert.Equal(t, "sha1", repo.ObjectFormatName)
|
||||||
|
branch, err := git_model.GetBranch(db.DefaultContext, 1, "master")
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.EqualValues(t, "master", branch.Name)
|
||||||
|
}
|
|
@ -25,11 +25,19 @@ const (
|
||||||
EnvKeyID = "GITEA_KEY_ID" // public key ID
|
EnvKeyID = "GITEA_KEY_ID" // public key ID
|
||||||
EnvDeployKeyID = "GITEA_DEPLOY_KEY_ID"
|
EnvDeployKeyID = "GITEA_DEPLOY_KEY_ID"
|
||||||
EnvPRID = "GITEA_PR_ID"
|
EnvPRID = "GITEA_PR_ID"
|
||||||
|
EnvPushTrigger = "GITEA_PUSH_TRIGGER"
|
||||||
EnvIsInternal = "GITEA_INTERNAL_PUSH"
|
EnvIsInternal = "GITEA_INTERNAL_PUSH"
|
||||||
EnvAppURL = "GITEA_ROOT_URL"
|
EnvAppURL = "GITEA_ROOT_URL"
|
||||||
EnvActionPerm = "GITEA_ACTION_PERM"
|
EnvActionPerm = "GITEA_ACTION_PERM"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type PushTrigger string
|
||||||
|
|
||||||
|
const (
|
||||||
|
PushTriggerPRMergeToBase PushTrigger = "pr-merge-to-base"
|
||||||
|
PushTriggerPRUpdateWithBase PushTrigger = "pr-update-with-base"
|
||||||
|
)
|
||||||
|
|
||||||
// InternalPushingEnvironment returns an os environment to switch off hooks on push
|
// InternalPushingEnvironment returns an os environment to switch off hooks on push
|
||||||
// It is recommended to avoid using this unless you are pushing within a transaction
|
// It is recommended to avoid using this unless you are pushing within a transaction
|
||||||
// or if you absolutely are sure that post-receive and pre-receive will do nothing
|
// or if you absolutely are sure that post-receive and pre-receive will do nothing
|
||||||
|
|
|
@ -56,12 +56,12 @@ func loadIncomingEmailFrom(rootCfg ConfigProvider) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := checkReplyToAddress(IncomingEmail.ReplyToAddress); err != nil {
|
if err := checkReplyToAddress(); err != nil {
|
||||||
log.Fatal("Invalid incoming_mail.REPLY_TO_ADDRESS (%s): %v", IncomingEmail.ReplyToAddress, err)
|
log.Fatal("Invalid incoming_mail.REPLY_TO_ADDRESS (%s): %v", IncomingEmail.ReplyToAddress, err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func checkReplyToAddress(address string) error {
|
func checkReplyToAddress() error {
|
||||||
parsed, err := mail.ParseAddress(IncomingEmail.ReplyToAddress)
|
parsed, err := mail.ParseAddress(IncomingEmail.ReplyToAddress)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
|
|
@ -99,7 +99,7 @@ func getStorage(rootCfg ConfigProvider, name, typ string, sec ConfigSection) (*S
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
overrideSec := getStorageOverrideSection(rootCfg, targetSec, sec, tp, name)
|
overrideSec := getStorageOverrideSection(rootCfg, sec, tp, name)
|
||||||
|
|
||||||
targetType := targetSec.Key("STORAGE_TYPE").String()
|
targetType := targetSec.Key("STORAGE_TYPE").String()
|
||||||
switch targetType {
|
switch targetType {
|
||||||
|
@ -191,7 +191,7 @@ func getStorageTargetSection(rootCfg ConfigProvider, name, typ string, sec Confi
|
||||||
}
|
}
|
||||||
|
|
||||||
// getStorageOverrideSection override section will be read SERVE_DIRECT, PATH, MINIO_BASE_PATH, MINIO_BUCKET to override the targetsec when possible
|
// getStorageOverrideSection override section will be read SERVE_DIRECT, PATH, MINIO_BASE_PATH, MINIO_BUCKET to override the targetsec when possible
|
||||||
func getStorageOverrideSection(rootConfig ConfigProvider, targetSec, sec ConfigSection, targetSecType targetSecType, name string) ConfigSection {
|
func getStorageOverrideSection(rootConfig ConfigProvider, sec ConfigSection, targetSecType targetSecType, name string) ConfigSection {
|
||||||
if targetSecType == targetSecIsSec {
|
if targetSecType == targetSecIsSec {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -85,7 +85,7 @@ type CreatePullRequestOption struct {
|
||||||
// EditPullRequestOption options when modify pull request
|
// EditPullRequestOption options when modify pull request
|
||||||
type EditPullRequestOption struct {
|
type EditPullRequestOption struct {
|
||||||
Title string `json:"title"`
|
Title string `json:"title"`
|
||||||
Body string `json:"body"`
|
Body *string `json:"body"`
|
||||||
Base string `json:"base"`
|
Base string `json:"base"`
|
||||||
Assignee string `json:"assignee"`
|
Assignee string `json:"assignee"`
|
||||||
Assignees []string `json:"assignees"`
|
Assignees []string `json:"assignees"`
|
||||||
|
|
34
modules/structs/repo_actions.go
Normal file
34
modules/structs/repo_actions.go
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
// Copyright 2023 The Gitea Authors. All rights reserved.
|
||||||
|
// SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
|
package structs
|
||||||
|
|
||||||
|
import (
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
// ActionTask represents a ActionTask
|
||||||
|
type ActionTask struct {
|
||||||
|
ID int64 `json:"id"`
|
||||||
|
Name string `json:"name"`
|
||||||
|
HeadBranch string `json:"head_branch"`
|
||||||
|
HeadSHA string `json:"head_sha"`
|
||||||
|
RunNumber int64 `json:"run_number"`
|
||||||
|
Event string `json:"event"`
|
||||||
|
DisplayTitle string `json:"display_title"`
|
||||||
|
Status string `json:"status"`
|
||||||
|
WorkflowID string `json:"workflow_id"`
|
||||||
|
URL string `json:"url"`
|
||||||
|
// swagger:strfmt date-time
|
||||||
|
CreatedAt time.Time `json:"created_at"`
|
||||||
|
// swagger:strfmt date-time
|
||||||
|
UpdatedAt time.Time `json:"updated_at"`
|
||||||
|
// swagger:strfmt date-time
|
||||||
|
RunStartedAt time.Time `json:"run_started_at"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// ActionTaskResponse returns a ActionTask
|
||||||
|
type ActionTaskResponse struct {
|
||||||
|
Entries []*ActionTask `json:"workflow_runs"`
|
||||||
|
TotalCount int64 `json:"total_count"`
|
||||||
|
}
|
|
@ -49,9 +49,9 @@ func TestSubjectBodySeparator(t *testing.T) {
|
||||||
test("Multiple\n---\n-------\n---\nSeparators",
|
test("Multiple\n---\n-------\n---\nSeparators",
|
||||||
"Multiple\n",
|
"Multiple\n",
|
||||||
"\n-------\n---\nSeparators")
|
"\n-------\n---\nSeparators")
|
||||||
test("Insuficient\n--\nSeparators",
|
test("Insufficient\n--\nSeparators",
|
||||||
"",
|
"",
|
||||||
"Insuficient\n--\nSeparators")
|
"Insufficient\n--\nSeparators")
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestJSEscapeSafe(t *testing.T) {
|
func TestJSEscapeSafe(t *testing.T) {
|
||||||
|
|
|
@ -248,11 +248,11 @@ var ignoredErrorMessage = []string{
|
||||||
// TestIssuePinMove
|
// TestIssuePinMove
|
||||||
`:IssuePinMove() [E] Issue does not belong to this repository`,
|
`:IssuePinMove() [E] Issue does not belong to this repository`,
|
||||||
// TestLinksLogin
|
// TestLinksLogin
|
||||||
`:GetIssuesAllCommitStatus() [E] getAllCommitStatus: cant get commit statuses of pull [6]: object does not exist [id: refs/pull/2/head, rel_path: ]`,
|
`:GetIssuesAllCommitStatus() [E] getAllCommitStatus: can't get commit statuses of pull [6]: object does not exist [id: refs/pull/2/head, rel_path: ]`,
|
||||||
// TestLinksLogin
|
// TestLinksLogin
|
||||||
`:GetIssuesAllCommitStatus() [E] getAllCommitStatus: cant get commit statuses of pull [6]: object does not exist [id: refs/pull/2/head, rel_path: ]`,
|
`:GetIssuesAllCommitStatus() [E] getAllCommitStatus: can't get commit statuses of pull [6]: object does not exist [id: refs/pull/2/head, rel_path: ]`,
|
||||||
// TestLinksLogin
|
// TestLinksLogin
|
||||||
`:GetIssuesAllCommitStatus() [E] getAllCommitStatus: cant get commit statuses of pull [6]: object does not exist [id: refs/pull/2/head, rel_path: ]`,
|
`:GetIssuesAllCommitStatus() [E] getAllCommitStatus: can't get commit statuses of pull [6]: object does not exist [id: refs/pull/2/head, rel_path: ]`,
|
||||||
// TestLinksLogin
|
// TestLinksLogin
|
||||||
`:GetIssuesAllCommitStatus() [E] Cannot open git repository <Repository 23:org17/big_test_public_4> for issue #1[20]. Error: no such file or directory`,
|
`:GetIssuesAllCommitStatus() [E] Cannot open git repository <Repository 23:org17/big_test_public_4> for issue #1[20]. Error: no such file or directory`,
|
||||||
// TestMigrate
|
// TestMigrate
|
||||||
|
|
|
@ -49,12 +49,12 @@ func TestIsSvgImage(t *testing.T) {
|
||||||
<!-- Comments -->
|
<!-- Comments -->
|
||||||
<svg></svg>`)).IsSvgImage())
|
<svg></svg>`)).IsSvgImage())
|
||||||
assert.True(t, DetectContentType([]byte(`<?xml version="1.0" encoding="UTF-8"?>
|
assert.True(t, DetectContentType([]byte(`<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<!-- Multline
|
<!-- Multiline
|
||||||
Comment -->
|
Comment -->
|
||||||
<svg></svg>`)).IsSvgImage())
|
<svg></svg>`)).IsSvgImage())
|
||||||
assert.True(t, DetectContentType([]byte(`<?xml version="1.0" encoding="UTF-8"?>
|
assert.True(t, DetectContentType([]byte(`<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||||
<!-- Multline
|
<!-- Multiline
|
||||||
Comment -->
|
Comment -->
|
||||||
<svg></svg>`)).IsSvgImage())
|
<svg></svg>`)).IsSvgImage())
|
||||||
|
|
||||||
|
|
|
@ -45,7 +45,7 @@ func PathJoinRel(elem ...string) string {
|
||||||
}
|
}
|
||||||
|
|
||||||
// PathJoinRelX joins the path elements into a single path like PathJoinRel,
|
// PathJoinRelX joins the path elements into a single path like PathJoinRel,
|
||||||
// and covert all backslashes to slashes. (X means "extended", also means the combination of `\` and `/`).
|
// and convert all backslashes to slashes. (X means "extended", also means the combination of `\` and `/`).
|
||||||
// It's caller's duty to make every element not bypass its own directly level, to avoid security issues.
|
// It's caller's duty to make every element not bypass its own directly level, to avoid security issues.
|
||||||
// It returns similar results as PathJoinRel except:
|
// It returns similar results as PathJoinRel except:
|
||||||
//
|
//
|
||||||
|
|
121
options/license/Catharon
Normal file
121
options/license/Catharon
Normal file
|
@ -0,0 +1,121 @@
|
||||||
|
The Catharon Open Source LICENSE
|
||||||
|
----------------------------
|
||||||
|
|
||||||
|
2000-Jul-04
|
||||||
|
|
||||||
|
Copyright (C) 2000 by Catharon Productions, Inc.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Introduction
|
||||||
|
============
|
||||||
|
|
||||||
|
This license applies to source files distributed by Catharon
|
||||||
|
Productions, Inc. in several archive packages. This license
|
||||||
|
applies to all files found in such packages which do not fall
|
||||||
|
under their own explicit license.
|
||||||
|
|
||||||
|
This license was inspired by the BSD, Artistic, and IJG
|
||||||
|
(Independent JPEG Group) licenses, which all encourage inclusion
|
||||||
|
and use of free software in commercial and freeware products
|
||||||
|
alike. As a consequence, its main points are that:
|
||||||
|
|
||||||
|
o We don't promise that this software works. However, we are
|
||||||
|
interested in any kind of bug reports. (`as is' distribution)
|
||||||
|
|
||||||
|
o You can use this software for whatever you want, in parts or
|
||||||
|
full form, without having to pay us. (`royalty-free' usage)
|
||||||
|
|
||||||
|
o You may not pretend that you wrote this software. If you use
|
||||||
|
it, or only parts of it, in a program, you must acknowledge
|
||||||
|
somewhere in your documentation that you have used the
|
||||||
|
Catharon Code. (`credits')
|
||||||
|
|
||||||
|
We specifically permit and encourage the inclusion of this
|
||||||
|
software, with or without modifications, in commercial products.
|
||||||
|
We disclaim all warranties covering the packages distributed by
|
||||||
|
Catharon Productions, Inc. and assume no liability related to
|
||||||
|
their use.
|
||||||
|
|
||||||
|
|
||||||
|
Legal Terms
|
||||||
|
===========
|
||||||
|
|
||||||
|
0. Definitions
|
||||||
|
--------------
|
||||||
|
|
||||||
|
Throughout this license, the terms `Catharon Package', `package',
|
||||||
|
and `Catharon Code' refer to the set of files originally
|
||||||
|
distributed by Catharon Productions, Inc.
|
||||||
|
|
||||||
|
`You' refers to the licensee, or person using the project, where
|
||||||
|
`using' is a generic term including compiling the project's source
|
||||||
|
code as well as linking it to form a `program' or `executable'.
|
||||||
|
This program is referred to as `a program using one of the
|
||||||
|
Catharon Packages'.
|
||||||
|
|
||||||
|
This license applies to all files distributed in the original
|
||||||
|
Catharon Package(s), including all source code, binaries and
|
||||||
|
documentation, unless otherwise stated in the file in its
|
||||||
|
original, unmodified form as distributed in the original archive.
|
||||||
|
If you are unsure whether or not a particular file is covered by
|
||||||
|
this license, you must contact us to verify this.
|
||||||
|
|
||||||
|
The Catharon Packages are copyright (C) 2000 by Catharon
|
||||||
|
Productions, Inc. All rights reserved except as specified below.
|
||||||
|
|
||||||
|
1. No Warranty
|
||||||
|
--------------
|
||||||
|
|
||||||
|
THE CATHARON PACKAGES ARE PROVIDED `AS IS' WITHOUT WARRANTY OF ANY
|
||||||
|
KIND, EITHER EXPRESS OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
|
||||||
|
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||||
|
PURPOSE. IN NO EVENT WILL ANY OF THE AUTHORS OR COPYRIGHT HOLDERS
|
||||||
|
BE LIABLE FOR ANY DAMAGES CAUSED BY THE USE OF OR THE INABILITY TO
|
||||||
|
USE THE CATHARON PACKAGE.
|
||||||
|
|
||||||
|
2. Redistribution
|
||||||
|
-----------------
|
||||||
|
|
||||||
|
This license grants a worldwide, royalty-free, perpetual and
|
||||||
|
irrevocable right and license to use, execute, perform, compile,
|
||||||
|
display, copy, create derivative works of, distribute and
|
||||||
|
sublicense the Catharon Packages (in both source and object code
|
||||||
|
forms) and derivative works thereof for any purpose; and to
|
||||||
|
authorize others to exercise some or all of the rights granted
|
||||||
|
herein, subject to the following conditions:
|
||||||
|
|
||||||
|
o Redistribution of source code must retain this license file
|
||||||
|
(`license.txt') unaltered; any additions, deletions or changes
|
||||||
|
to the original files must be clearly indicated in
|
||||||
|
accompanying documentation. The copyright notices of the
|
||||||
|
unaltered, original files must be preserved in all copies of
|
||||||
|
source files.
|
||||||
|
|
||||||
|
o Redistribution in binary form must provide a disclaimer that
|
||||||
|
states that the software is based in part on the work of
|
||||||
|
Catharon Productions, Inc. in the distribution documentation.
|
||||||
|
|
||||||
|
These conditions apply to any software derived from or based on
|
||||||
|
the Catharon Packages, not just the unmodified files. If you use
|
||||||
|
our work, you must acknowledge us. However, no fee need be paid
|
||||||
|
to us.
|
||||||
|
|
||||||
|
3. Advertising
|
||||||
|
--------------
|
||||||
|
|
||||||
|
Neither Catharon Productions, Inc. and contributors nor you shall
|
||||||
|
use the name of the other for commercial, advertising, or
|
||||||
|
promotional purposes without specific prior written permission.
|
||||||
|
|
||||||
|
We suggest, but do not require, that you use the following phrase
|
||||||
|
to refer to this software in your documentation: 'this software is
|
||||||
|
based in part on the Catharon Typography Project'.
|
||||||
|
|
||||||
|
As you have not signed this license, you are not required to
|
||||||
|
accept it. However, as the Catharon Packages are copyrighted
|
||||||
|
material, only this license, or another one contracted with the
|
||||||
|
authors, grants you the right to use, distribute, and modify it.
|
||||||
|
Therefore, by using, distributing, or modifying the Catharon
|
||||||
|
Packages, you indicate that you understand and accept all the
|
||||||
|
terms of this license.
|
|
@ -1214,7 +1214,7 @@ settings.pulls_desc = فعّل طلب الدمج في المستودع
|
||||||
settings.pulls.ignore_whitespace = تجاهل المسافات في النزاعات
|
settings.pulls.ignore_whitespace = تجاهل المسافات في النزاعات
|
||||||
settings.danger_zone = منطقة الخطر
|
settings.danger_zone = منطقة الخطر
|
||||||
settings.new_owner_has_same_repo = المالك الجديد لديه مستودع بالاسم نفسه؛ برجاء اختيار اسم آخر.
|
settings.new_owner_has_same_repo = المالك الجديد لديه مستودع بالاسم نفسه؛ برجاء اختيار اسم آخر.
|
||||||
settings.transfer = نقل الملكية
|
settings.transfer.title = نقل الملكية
|
||||||
settings.transfer_abort = ألغِ نقل الملكية
|
settings.transfer_abort = ألغِ نقل الملكية
|
||||||
settings.transfer_abort_invalid = لا يمكنك إلغاء عملية غير موجودة لنقل ملكية مستودع.
|
settings.transfer_abort_invalid = لا يمكنك إلغاء عملية غير موجودة لنقل ملكية مستودع.
|
||||||
settings.transfer.success = نجح نقل ملكية المستودع.
|
settings.transfer.success = نجح نقل ملكية المستودع.
|
||||||
|
|
|
@ -570,7 +570,7 @@ issues.role.owner_helper = Този потребител е притежател
|
||||||
settings.delete_notices_2 = - Тази операция ще изтрие перманентно хранилището <strong>%s</strong>, включително кода, задачите, коментарите, данните на уикито и настройките за сътрудници.
|
settings.delete_notices_2 = - Тази операция ще изтрие перманентно хранилището <strong>%s</strong>, включително кода, задачите, коментарите, данните на уикито и настройките за сътрудници.
|
||||||
settings.admin_settings = Администраторски настройки
|
settings.admin_settings = Администраторски настройки
|
||||||
issues.role.owner = Притежател
|
issues.role.owner = Притежател
|
||||||
settings.transfer = Прехвърляне на притежанието
|
settings.transfer.title = Прехвърляне на притежанието
|
||||||
issues.author = Автор
|
issues.author = Автор
|
||||||
issues.closed_at = `затвори тази задача <a id="%[1]s" href="#%[1]s">%[2]s</a>`
|
issues.closed_at = `затвори тази задача <a id="%[1]s" href="#%[1]s">%[2]s</a>`
|
||||||
settings.collaborator_deletion_desc = Премахването на сътрудник ще отнеме достъпа му до това хранилище. Продължаване?
|
settings.collaborator_deletion_desc = Премахването на сътрудник ще отнеме достъпа му до това хранилище. Продължаване?
|
||||||
|
|
31
options/locale/locale_ca.ini
Normal file
31
options/locale/locale_ca.ini
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
[common]
|
||||||
|
home = inici
|
||||||
|
dashboard = Panell de control
|
||||||
|
explore = Explorar
|
||||||
|
help = Ajuda
|
||||||
|
logo = Logo
|
||||||
|
sign_in = Entrar
|
||||||
|
sign_in_with_provider = Entra amb %s
|
||||||
|
sign_in_or = o
|
||||||
|
sign_out = Sortir
|
||||||
|
register = Registrar-se
|
||||||
|
version = Versió
|
||||||
|
powered_by = Creat amb %s
|
||||||
|
page = Pàgina
|
||||||
|
template = Plantilla
|
||||||
|
language = Idioma
|
||||||
|
notifications = Notificacions
|
||||||
|
active_stopwatch = Registre de Temps Actiu
|
||||||
|
create_new = Crear…
|
||||||
|
user_profile_and_more = Perfil i configuració…
|
||||||
|
signed_in_as = Entrat com
|
||||||
|
enable_javascript = Aquest lloc web requereix Javascript.
|
||||||
|
toc = Taula de Continguts
|
||||||
|
licenses = Llicències
|
||||||
|
sign_up = Registrar-se
|
||||||
|
link_account = Vincular un compte
|
||||||
|
tracked_time_summary = Resum del temps registrat basat en filtres del llistat de temes
|
||||||
|
return_to_gitea = Tornar a Forgejo
|
|
@ -146,15 +146,15 @@ sign_in_with_provider = Přihlásit se přes %s
|
||||||
confirm_delete_artifact = Opravdu chcete odstranit artefakt „%s“?
|
confirm_delete_artifact = Opravdu chcete odstranit artefakt „%s“?
|
||||||
toggle_menu = Přepnout nabídku
|
toggle_menu = Přepnout nabídku
|
||||||
filter = Filtr
|
filter = Filtr
|
||||||
filter.is_fork = Forknuto
|
filter.is_fork = Forky
|
||||||
filter.not_fork = Není forknuto
|
filter.not_fork = Nejsou forky
|
||||||
filter.is_mirror = Zrcadleno
|
filter.is_mirror = Zrcadla
|
||||||
filter.is_template = Šablona
|
filter.is_template = Šablony
|
||||||
filter.not_template = Není šablona
|
filter.not_template = Nejsou šablony
|
||||||
filter.public = Veřejné
|
filter.public = Veřejné
|
||||||
filter.private = Soukromé
|
filter.private = Soukromé
|
||||||
filter.is_archived = Archivováno
|
filter.is_archived = Archivováno
|
||||||
filter.not_mirror = Není zrcadleno
|
filter.not_mirror = Nejsou zrcadla
|
||||||
filter.not_archived = Není archivováno
|
filter.not_archived = Není archivováno
|
||||||
filter.clear = Vymazat filtry
|
filter.clear = Vymazat filtry
|
||||||
more_items = Další položky
|
more_items = Další položky
|
||||||
|
@ -996,7 +996,7 @@ access_token_desc = Oprávnění vybraného tokenu omezují autorizaci pouze na
|
||||||
blocked_users_none = Nemáte žádné zablokované uživatele.
|
blocked_users_none = Nemáte žádné zablokované uživatele.
|
||||||
blocked_since = Zablokován od %s
|
blocked_since = Zablokován od %s
|
||||||
hints = Nápovědy
|
hints = Nápovědy
|
||||||
additional_repo_units_hint = Podíbnout k povolení dalších jednotek úložiště
|
additional_repo_units_hint = Navrhnout povolení dalších jednotek úložiště
|
||||||
update_hints = Aktualizovat nápovědy
|
update_hints = Aktualizovat nápovědy
|
||||||
update_hints_success = Nápovědy byly aktualizovány.
|
update_hints_success = Nápovědy byly aktualizovány.
|
||||||
additional_repo_units_hint_description = Zobrazit tlačítko „Přidat další jednotky...“ u repozitářů, které nemají povolené všechny dostupné jednotky.
|
additional_repo_units_hint_description = Zobrazit tlačítko „Přidat další jednotky...“ u repozitářů, které nemají povolené všechny dostupné jednotky.
|
||||||
|
@ -2153,7 +2153,7 @@ settings.convert_fork_desc=Tento fork můžete převést na běžný repozitář
|
||||||
settings.convert_fork_notices_1=Tato operace převede fork na běžný repozitář a nelze ji vrátit zpět.
|
settings.convert_fork_notices_1=Tato operace převede fork na běžný repozitář a nelze ji vrátit zpět.
|
||||||
settings.convert_fork_confirm=Převést repozitář
|
settings.convert_fork_confirm=Převést repozitář
|
||||||
settings.convert_fork_succeed=Fork bylo převeden na běžný repozitář.
|
settings.convert_fork_succeed=Fork bylo převeden na běžný repozitář.
|
||||||
settings.transfer=Předat vlastnictví
|
settings.transfer.title=Předat vlastnictví
|
||||||
settings.transfer.rejected=Převod repozitáře byl zamítnut.
|
settings.transfer.rejected=Převod repozitáře byl zamítnut.
|
||||||
settings.transfer.success=Převod repozitáře byl úspěšný.
|
settings.transfer.success=Převod repozitáře byl úspěšný.
|
||||||
settings.transfer_abort=Zrušit převod
|
settings.transfer_abort=Zrušit převod
|
||||||
|
@ -2721,7 +2721,7 @@ pulls.title_desc_one = žádá o sloučení %[1]d commitu z <code>%[2]s</code> d
|
||||||
pulls.merged_title_desc_one = sloučil %[1]d commit z <code>%[2]s</code> do <code>%[3]s</code> %[4]s
|
pulls.merged_title_desc_one = sloučil %[1]d commit z <code>%[2]s</code> do <code>%[3]s</code> %[4]s
|
||||||
open_with_editor = Otevřít pomocí %s
|
open_with_editor = Otevřít pomocí %s
|
||||||
commits.search_branch = Tato větev
|
commits.search_branch = Tato větev
|
||||||
editor.commit_id_not_matching = ID commitu se neshoduje s ID commitu, který jste upravovali. Proveďte commit do nové větve a poté je slučte.
|
editor.commit_id_not_matching = Tento soubor se během úpravy změnil. Proveďte commit do nové větve a poté je slučte.
|
||||||
pulls.ready_for_review = Připraveni na posouzení?
|
pulls.ready_for_review = Připraveni na posouzení?
|
||||||
settings.rename_branch_failed_protected = Nepodařilo se přejmenovat větev %s, jelikož se jedná o chráněnou větev.
|
settings.rename_branch_failed_protected = Nepodařilo se přejmenovat větev %s, jelikož se jedná o chráněnou větev.
|
||||||
editor.push_out_of_date = Push je nejspíše zastaralý.
|
editor.push_out_of_date = Push je nejspíše zastaralý.
|
||||||
|
@ -2888,6 +2888,7 @@ teams.invite.title=Byli jste pozváni do týmu <strong>%s</strong> v organizaci
|
||||||
teams.invite.by=Pozvání od %s
|
teams.invite.by=Pozvání od %s
|
||||||
teams.invite.description=Pro připojení k týmu klikněte na tlačítko níže.
|
teams.invite.description=Pro připojení k týmu klikněte na tlačítko níže.
|
||||||
follow_blocked_user = Tuto organizaci nemůžete sledovat, protože jste v ní zablokovaní.
|
follow_blocked_user = Tuto organizaci nemůžete sledovat, protože jste v ní zablokovaní.
|
||||||
|
open_dashboard = Otevřít nástěnku
|
||||||
|
|
||||||
[admin]
|
[admin]
|
||||||
dashboard=Přehled
|
dashboard=Přehled
|
||||||
|
@ -3683,6 +3684,7 @@ owner.settings.chef.keypair.description=Pro autentizaci do registru Chef je zapo
|
||||||
rpm.repository.multiple_groups = Tento balíček je dostupný v několika skupinách.
|
rpm.repository.multiple_groups = Tento balíček je dostupný v několika skupinách.
|
||||||
owner.settings.cargo.rebuild.description = Opětovné sestavení může být užitečné, pokud není index synchronizován s uloženými balíčky Cargo.
|
owner.settings.cargo.rebuild.description = Opětovné sestavení může být užitečné, pokud není index synchronizován s uloženými balíčky Cargo.
|
||||||
owner.settings.cargo.rebuild.no_index = Opětovné vytvoření selhalo, nebyl inicializován žádný index.
|
owner.settings.cargo.rebuild.no_index = Opětovné vytvoření selhalo, nebyl inicializován žádný index.
|
||||||
|
npm.dependencies.bundle = Přidružené závislosti
|
||||||
|
|
||||||
[secrets]
|
[secrets]
|
||||||
secrets=Tajné klíče
|
secrets=Tajné klíče
|
||||||
|
|
|
@ -149,10 +149,10 @@ filter.is_archived = Archiviert
|
||||||
filter.not_archived = Nicht archiviert
|
filter.not_archived = Nicht archiviert
|
||||||
filter.is_fork = Geforkt
|
filter.is_fork = Geforkt
|
||||||
filter.not_fork = Nicht geforkt
|
filter.not_fork = Nicht geforkt
|
||||||
filter.is_mirror = Gemirrort
|
filter.is_mirror = Gespiegelt
|
||||||
filter.not_mirror = Nicht gemirrort
|
filter.not_mirror = Nicht gespiegelt
|
||||||
filter.is_template = Vorlage
|
filter.is_template = Vorlagen
|
||||||
filter.not_template = Keine Vorlage
|
filter.not_template = Keine Vorlagen
|
||||||
filter.public = Öffentlich
|
filter.public = Öffentlich
|
||||||
filter.private = Privat
|
filter.private = Privat
|
||||||
more_items = Mehr Einträge
|
more_items = Mehr Einträge
|
||||||
|
@ -993,7 +993,7 @@ blocked_users = Blockierte Benutzer
|
||||||
blocked_since = Blockiert seit %s
|
blocked_since = Blockiert seit %s
|
||||||
change_password = Passwort ändern
|
change_password = Passwort ändern
|
||||||
hints = Hinweise
|
hints = Hinweise
|
||||||
additional_repo_units_hint = Zur Aktivierung zusätzlicher Repository-Einheiten ermutigen
|
additional_repo_units_hint = Aktivierung zusätzlicher Repository-Einheiten vorschlagen
|
||||||
update_hints = Hinweise aktualisieren
|
update_hints = Hinweise aktualisieren
|
||||||
update_hints_success = Hinweise wurden aktualisiert.
|
update_hints_success = Hinweise wurden aktualisiert.
|
||||||
additional_repo_units_hint_description = Einen „Mehr Einheiten hinzufügen …“-Button für Repositorys, welche nicht alle verfügbaren Einheiten aktiviert haben, anzeigen.
|
additional_repo_units_hint_description = Einen „Mehr Einheiten hinzufügen …“-Button für Repositorys, welche nicht alle verfügbaren Einheiten aktiviert haben, anzeigen.
|
||||||
|
@ -2151,7 +2151,7 @@ settings.convert_fork_desc=Du kannst diesen Fork in ein normales Repository umwa
|
||||||
settings.convert_fork_notices_1=Dieser Vorgang konvertiert den Fork in ein normales Repository und kann nicht rückgängig gemacht werden.
|
settings.convert_fork_notices_1=Dieser Vorgang konvertiert den Fork in ein normales Repository und kann nicht rückgängig gemacht werden.
|
||||||
settings.convert_fork_confirm=Repository umwandeln
|
settings.convert_fork_confirm=Repository umwandeln
|
||||||
settings.convert_fork_succeed=Der Fork wurde in ein normales Repository konvertiert.
|
settings.convert_fork_succeed=Der Fork wurde in ein normales Repository konvertiert.
|
||||||
settings.transfer=Besitz übertragen
|
settings.transfer.title=Besitz übertragen
|
||||||
settings.transfer.rejected=Repository-Übertragung wurde abgelehnt.
|
settings.transfer.rejected=Repository-Übertragung wurde abgelehnt.
|
||||||
settings.transfer.success=Repository-Übertragung war erfolgreich.
|
settings.transfer.success=Repository-Übertragung war erfolgreich.
|
||||||
settings.transfer_abort=Übertragung abbrechen
|
settings.transfer_abort=Übertragung abbrechen
|
||||||
|
@ -2712,7 +2712,7 @@ open_with_editor = Öffnen mit %s
|
||||||
commits.search_branch = Dieser Branch
|
commits.search_branch = Dieser Branch
|
||||||
pulls.ready_for_review = Bereit zum Review?
|
pulls.ready_for_review = Bereit zum Review?
|
||||||
settings.rename_branch_failed_protected = Branch %s kann nicht umbenannt werden, weil er ein geschützter Branch ist.
|
settings.rename_branch_failed_protected = Branch %s kann nicht umbenannt werden, weil er ein geschützter Branch ist.
|
||||||
editor.commit_id_not_matching = Die Commit-ID passt nicht zur ID die du bearbeitet hast hast. Committe in einen neuen Branch, dann führe einen Merge durch.
|
editor.commit_id_not_matching = Die Datei wurde geändert, während du sie bearbeitet hast. Committe in einen neuen Branch, dann führe einen Merge durch.
|
||||||
editor.push_out_of_date = Der Push scheint veraltet zu sein.
|
editor.push_out_of_date = Der Push scheint veraltet zu sein.
|
||||||
n_commit_few = %s Commits
|
n_commit_few = %s Commits
|
||||||
n_branch_one = %s Branch
|
n_branch_one = %s Branch
|
||||||
|
@ -2870,6 +2870,7 @@ teams.invite.title=Du wurdest eingeladen, dem Team <strong>%s</strong> in der Or
|
||||||
teams.invite.by=Von %s eingeladen
|
teams.invite.by=Von %s eingeladen
|
||||||
teams.invite.description=Bitte klicke auf die folgende Schaltfläche, um dem Team beizutreten.
|
teams.invite.description=Bitte klicke auf die folgende Schaltfläche, um dem Team beizutreten.
|
||||||
follow_blocked_user = Du kannst dieser Organisation nicht folgen, weil diese Organisation dich blockiert hat.
|
follow_blocked_user = Du kannst dieser Organisation nicht folgen, weil diese Organisation dich blockiert hat.
|
||||||
|
open_dashboard = Übersicht öffnen
|
||||||
|
|
||||||
[admin]
|
[admin]
|
||||||
dashboard=Übersicht
|
dashboard=Übersicht
|
||||||
|
@ -3657,6 +3658,7 @@ rpm.repository = Repository-Info
|
||||||
rpm.repository.multiple_groups = Dieses Paket ist in mehreren Gruppen verfügbar.
|
rpm.repository.multiple_groups = Dieses Paket ist in mehreren Gruppen verfügbar.
|
||||||
rpm.repository.architectures = Architekturen
|
rpm.repository.architectures = Architekturen
|
||||||
owner.settings.cargo.rebuild.no_index = Kann nicht erneut erzeugen, es wurde kein Index initialisiert.
|
owner.settings.cargo.rebuild.no_index = Kann nicht erneut erzeugen, es wurde kein Index initialisiert.
|
||||||
|
npm.dependencies.bundle = Gebündelte Abhängigkeiten
|
||||||
|
|
||||||
[secrets]
|
[secrets]
|
||||||
secrets=Secrets
|
secrets=Secrets
|
||||||
|
|
|
@ -2145,7 +2145,7 @@ settings.convert_fork_desc=Μπορείτε να μετατρέψετε αυτό
|
||||||
settings.convert_fork_notices_1=Αυτή η λειτουργία θα μετατρέψει το fork σε ένα κανονικό αποθετήριο και δεν μπορεί να αναιρεθεί.
|
settings.convert_fork_notices_1=Αυτή η λειτουργία θα μετατρέψει το fork σε ένα κανονικό αποθετήριο και δεν μπορεί να αναιρεθεί.
|
||||||
settings.convert_fork_confirm=Μετατροπή αποθετηρίου
|
settings.convert_fork_confirm=Μετατροπή αποθετηρίου
|
||||||
settings.convert_fork_succeed=Το fork έχει μετατραπεί σε κανονικό αποθετήριο.
|
settings.convert_fork_succeed=Το fork έχει μετατραπεί σε κανονικό αποθετήριο.
|
||||||
settings.transfer=Μεταβίβαση ιδιοκτησίας
|
settings.transfer.title=Μεταβίβαση ιδιοκτησίας
|
||||||
settings.transfer.rejected=Η μεταβίβαση του αποθετηρίου απορρίφθηκε.
|
settings.transfer.rejected=Η μεταβίβαση του αποθετηρίου απορρίφθηκε.
|
||||||
settings.transfer.success=Η μεταβίβαση του αποθετηρίου ήταν επιτυχής.
|
settings.transfer.success=Η μεταβίβαση του αποθετηρίου ήταν επιτυχής.
|
||||||
settings.transfer_abort=Ακύρωση μεταβίβασης
|
settings.transfer_abort=Ακύρωση μεταβίβασης
|
||||||
|
|
|
@ -439,8 +439,8 @@ tab_openid = OpenID
|
||||||
oauth_signup_tab = Register New Account
|
oauth_signup_tab = Register New Account
|
||||||
oauth_signup_title = Complete New Account
|
oauth_signup_title = Complete New Account
|
||||||
oauth_signup_submit = Complete Account
|
oauth_signup_submit = Complete Account
|
||||||
oauth_signin_tab = Link to Existing Account
|
oauth_signin_tab = Link to an existing account
|
||||||
oauth_signin_title = Sign In to Authorize Linked Account
|
oauth_signin_title = Sign in to authorize linked account
|
||||||
oauth_signin_submit = Link Account
|
oauth_signin_submit = Link Account
|
||||||
oauth.signin.error = There was an error processing the authorization request. If this error persists, please contact the site administrator.
|
oauth.signin.error = There was an error processing the authorization request. If this error persists, please contact the site administrator.
|
||||||
oauth.signin.error.access_denied = The authorization request was denied.
|
oauth.signin.error.access_denied = The authorization request was denied.
|
||||||
|
@ -691,13 +691,13 @@ password = Password
|
||||||
security = Security
|
security = Security
|
||||||
avatar = Avatar
|
avatar = Avatar
|
||||||
ssh_gpg_keys = SSH / GPG keys
|
ssh_gpg_keys = SSH / GPG keys
|
||||||
social = Social Accounts
|
social = Social accounts
|
||||||
applications = Applications
|
applications = Applications
|
||||||
orgs = Manage organizations
|
orgs = Organizations
|
||||||
repos = Repositories
|
repos = Repositories
|
||||||
delete = Delete Account
|
delete = Delete Account
|
||||||
twofa = Two-factor authentication (TOTP)
|
twofa = Two-factor authentication (TOTP)
|
||||||
account_link = Linked Accounts
|
account_link = Linked accounts
|
||||||
organization = Organizations
|
organization = Organizations
|
||||||
uid = UID
|
uid = UID
|
||||||
webauthn = Two-factor authentication (Security keys)
|
webauthn = Two-factor authentication (Security keys)
|
||||||
|
@ -726,10 +726,11 @@ change_username_redirect_prompt = The old username will redirect until someone c
|
||||||
continue = Continue
|
continue = Continue
|
||||||
cancel = Cancel
|
cancel = Cancel
|
||||||
language = Language
|
language = Language
|
||||||
|
language.title = Default language
|
||||||
ui = Theme
|
ui = Theme
|
||||||
hints = Hints
|
hints = Hints
|
||||||
|
additional_repo_units_hint = Suggest to enable additional repository units
|
||||||
additional_repo_units_hint_description = Display an "Add more units..." button for repositories that do not have all available units enabled.
|
additional_repo_units_hint_description = Display an "Add more units..." button for repositories that do not have all available units enabled.
|
||||||
additional_repo_units_hint = Encourage enabling additional repository units
|
|
||||||
update_hints = Update hints
|
update_hints = Update hints
|
||||||
update_hints_success = Hints have been updated.
|
update_hints_success = Hints have been updated.
|
||||||
hidden_comment_types = Hidden comment types
|
hidden_comment_types = Hidden comment types
|
||||||
|
@ -776,8 +777,8 @@ change_password_success = Your password has been updated. Sign in using your new
|
||||||
password_change_disabled = Non-local users cannot update their password through the Forgejo web interface.
|
password_change_disabled = Non-local users cannot update their password through the Forgejo web interface.
|
||||||
|
|
||||||
manage_emails = Manage email addresses
|
manage_emails = Manage email addresses
|
||||||
manage_themes = Select default theme
|
manage_themes = Default theme
|
||||||
manage_openid = Manage OpenID addresses
|
manage_openid = OpenID addresses
|
||||||
email_desc = Your primary email address will be used for notifications, password recovery and, provided that it is not hidden, web-based Git operations.
|
email_desc = Your primary email address will be used for notifications, password recovery and, provided that it is not hidden, web-based Git operations.
|
||||||
theme_desc = This will be your default theme across the site.
|
theme_desc = This will be your default theme across the site.
|
||||||
primary = Primary
|
primary = Primary
|
||||||
|
@ -797,7 +798,7 @@ openid_deletion = Remove OpenID Address
|
||||||
openid_deletion_desc = Removing this OpenID address from your account will prevent you from signing in with it. Continue?
|
openid_deletion_desc = Removing this OpenID address from your account will prevent you from signing in with it. Continue?
|
||||||
openid_deletion_success = The OpenID address has been removed.
|
openid_deletion_success = The OpenID address has been removed.
|
||||||
add_new_email = Add email address
|
add_new_email = Add email address
|
||||||
add_new_openid = Add New OpenID URI
|
add_new_openid = Add new OpenID URI
|
||||||
add_email = Add email address
|
add_email = Add email address
|
||||||
add_openid = Add OpenID URI
|
add_openid = Add OpenID URI
|
||||||
add_email_confirmation_sent = A confirmation email has been sent to "%s". Please check your inbox within the next %s to confirm your email address.
|
add_email_confirmation_sent = A confirmation email has been sent to "%s". Please check your inbox within the next %s to confirm your email address.
|
||||||
|
@ -888,7 +889,7 @@ social_desc = These social accounts can be used to sign in to your account. Make
|
||||||
unbind = Unlink
|
unbind = Unlink
|
||||||
unbind_success = The social account has been removed successfully.
|
unbind_success = The social account has been removed successfully.
|
||||||
|
|
||||||
manage_access_token = Manage access tokens
|
manage_access_token = Access tokens
|
||||||
generate_new_token = Generate new token
|
generate_new_token = Generate new token
|
||||||
tokens_desc = These tokens grant access to your account using the Forgejo API.
|
tokens_desc = These tokens grant access to your account using the Forgejo API.
|
||||||
token_name = Token name
|
token_name = Token name
|
||||||
|
@ -970,11 +971,11 @@ webauthn_delete_key_desc = If you remove a security key you can no longer sign i
|
||||||
webauthn_key_loss_warning = If you lose your security keys, you will lose access to your account.
|
webauthn_key_loss_warning = If you lose your security keys, you will lose access to your account.
|
||||||
webauthn_alternative_tip = You may want to configure an additional authentication method.
|
webauthn_alternative_tip = You may want to configure an additional authentication method.
|
||||||
|
|
||||||
manage_account_links = Manage Linked Accounts
|
manage_account_links = Linked accounts
|
||||||
manage_account_links_desc = These external accounts are linked to your Forgejo account.
|
manage_account_links_desc = These external accounts are linked to your Forgejo account.
|
||||||
account_links_not_available = There are currently no external accounts linked to your Forgejo account.
|
account_links_not_available = There are currently no external accounts linked to your Forgejo account.
|
||||||
link_account = Link Account
|
link_account = Link account
|
||||||
remove_account_link = Remove Linked Account
|
remove_account_link = Remove linked account
|
||||||
remove_account_link_desc = Removing a linked account will revoke its access to your Forgejo account. Continue?
|
remove_account_link_desc = Removing a linked account will revoke its access to your Forgejo account. Continue?
|
||||||
remove_account_link_success = The linked account has been removed.
|
remove_account_link_success = The linked account has been removed.
|
||||||
|
|
||||||
|
@ -1353,7 +1354,7 @@ editor.file_editing_no_longer_exists = The file being edited, "%s", no longer ex
|
||||||
editor.file_deleting_no_longer_exists = The file being deleted, "%s", no longer exists in this repository.
|
editor.file_deleting_no_longer_exists = The file being deleted, "%s", no longer exists in this repository.
|
||||||
editor.file_changed_while_editing = The file contents have changed since you started editing. <a target="_blank" rel="noopener noreferrer" href="%s">Click here</a> to see them or <strong>Commit changes again</strong> to overwrite them.
|
editor.file_changed_while_editing = The file contents have changed since you started editing. <a target="_blank" rel="noopener noreferrer" href="%s">Click here</a> to see them or <strong>Commit changes again</strong> to overwrite them.
|
||||||
editor.file_already_exists = A file named "%s" already exists in this repository.
|
editor.file_already_exists = A file named "%s" already exists in this repository.
|
||||||
editor.commit_id_not_matching = The commit ID does not match the one you was editing. Commit to a new branch and then merge.
|
editor.commit_id_not_matching = The file was changed while you were editing it. Commit to a new branch and then merge.
|
||||||
editor.push_out_of_date = The push appears to be out of date.
|
editor.push_out_of_date = The push appears to be out of date.
|
||||||
editor.commit_empty_file_header = Commit an empty file
|
editor.commit_empty_file_header = Commit an empty file
|
||||||
editor.commit_empty_file_text = The file you're about to commit is empty. Proceed?
|
editor.commit_empty_file_text = The file you're about to commit is empty. Proceed?
|
||||||
|
@ -2207,7 +2208,9 @@ settings.convert_fork_desc = You can convert this fork into a regular repository
|
||||||
settings.convert_fork_notices_1 = This operation will convert the fork into a regular repository and cannot be undone.
|
settings.convert_fork_notices_1 = This operation will convert the fork into a regular repository and cannot be undone.
|
||||||
settings.convert_fork_confirm = Convert repository
|
settings.convert_fork_confirm = Convert repository
|
||||||
settings.convert_fork_succeed = The fork has been converted into a regular repository.
|
settings.convert_fork_succeed = The fork has been converted into a regular repository.
|
||||||
settings.transfer = Transfer ownership
|
settings.transfer.title = Transfer ownership
|
||||||
|
settings.transfer.button = Transfer ownership
|
||||||
|
settings.transfer.modal.title = Transfer ownership
|
||||||
settings.transfer.rejected = Repository transfer was rejected.
|
settings.transfer.rejected = Repository transfer was rejected.
|
||||||
settings.transfer.success = Repository transfer was successful.
|
settings.transfer.success = Repository transfer was successful.
|
||||||
settings.transfer_abort = Cancel transfer
|
settings.transfer_abort = Cancel transfer
|
||||||
|
@ -3579,6 +3582,7 @@ npm.install = To install the package using npm, run the following command:
|
||||||
npm.install2 = or add it to the package.json file:
|
npm.install2 = or add it to the package.json file:
|
||||||
npm.dependencies = Dependencies
|
npm.dependencies = Dependencies
|
||||||
npm.dependencies.development = Development Dependencies
|
npm.dependencies.development = Development Dependencies
|
||||||
|
npm.dependencies.bundle = Bundled Dependencies
|
||||||
npm.dependencies.peer = Peer Dependencies
|
npm.dependencies.peer = Peer Dependencies
|
||||||
npm.dependencies.optional = Optional Dependencies
|
npm.dependencies.optional = Optional Dependencies
|
||||||
npm.details.tag = Tag
|
npm.details.tag = Tag
|
||||||
|
@ -3623,7 +3627,7 @@ owner.settings.cargo.rebuild.description = Rebuilding can be useful if the index
|
||||||
owner.settings.cargo.rebuild.error = Failed to rebuild Cargo index: %v
|
owner.settings.cargo.rebuild.error = Failed to rebuild Cargo index: %v
|
||||||
owner.settings.cargo.rebuild.success = The Cargo index was successfully rebuild.
|
owner.settings.cargo.rebuild.success = The Cargo index was successfully rebuild.
|
||||||
owner.settings.cargo.rebuild.no_index = Cannot rebuild, no index is initialized.
|
owner.settings.cargo.rebuild.no_index = Cannot rebuild, no index is initialized.
|
||||||
owner.settings.cleanuprules.title = Manage cleanup rules
|
owner.settings.cleanuprules.title = Cleanup rules
|
||||||
owner.settings.cleanuprules.add = Add cleanup rule
|
owner.settings.cleanuprules.add = Add cleanup rule
|
||||||
owner.settings.cleanuprules.edit = Edit cleanup rule
|
owner.settings.cleanuprules.edit = Edit cleanup rule
|
||||||
owner.settings.cleanuprules.none = There are no cleanup rules yet.
|
owner.settings.cleanuprules.none = There are no cleanup rules yet.
|
||||||
|
|
|
@ -2109,7 +2109,7 @@ settings.convert_fork_desc=Puede convertir este fork en un repositorio normal. E
|
||||||
settings.convert_fork_notices_1=Esta operación convertirá el fork en un repositorio regular y no se puede deshacer.
|
settings.convert_fork_notices_1=Esta operación convertirá el fork en un repositorio regular y no se puede deshacer.
|
||||||
settings.convert_fork_confirm=Convertir repositorio
|
settings.convert_fork_confirm=Convertir repositorio
|
||||||
settings.convert_fork_succeed=El fork se ha convertido en un repositorio normal.
|
settings.convert_fork_succeed=El fork se ha convertido en un repositorio normal.
|
||||||
settings.transfer=Transferir la propiedad
|
settings.transfer.title=Transferir la propiedad
|
||||||
settings.transfer.rejected=La transferencia de repositorio fue rechazada.
|
settings.transfer.rejected=La transferencia de repositorio fue rechazada.
|
||||||
settings.transfer.success=La transferencia del repositorio fue exitosa.
|
settings.transfer.success=La transferencia del repositorio fue exitosa.
|
||||||
settings.transfer_abort=Cancelar transferencia
|
settings.transfer_abort=Cancelar transferencia
|
||||||
|
|
|
@ -1595,7 +1595,7 @@ settings.convert_fork_desc=شما می توانید این انشعاب را ب
|
||||||
settings.convert_fork_notices_1=این عملیات، انشعاب را تبدیل به مخزن عادی خواهد کرد و بازگشت ناپذیر است.
|
settings.convert_fork_notices_1=این عملیات، انشعاب را تبدیل به مخزن عادی خواهد کرد و بازگشت ناپذیر است.
|
||||||
settings.convert_fork_confirm=تبدیل مخزن
|
settings.convert_fork_confirm=تبدیل مخزن
|
||||||
settings.convert_fork_succeed=انشعاب به یک مخزن عادی تبدیل شده است.
|
settings.convert_fork_succeed=انشعاب به یک مخزن عادی تبدیل شده است.
|
||||||
settings.transfer=انتقال مالکیت
|
settings.transfer.title=انتقال مالکیت
|
||||||
settings.transfer.rejected=انتقال انبار رد شده است.
|
settings.transfer.rejected=انتقال انبار رد شده است.
|
||||||
settings.transfer.success=انتقال انبار موفق بود.
|
settings.transfer.success=انتقال انبار موفق بود.
|
||||||
settings.transfer_abort=لغو انتقال
|
settings.transfer_abort=لغو انتقال
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue