diff --git a/.air.toml b/.air.toml index 6825118b95..d13f8c4f99 100644 --- a/.air.toml +++ b/.air.toml @@ -2,7 +2,7 @@ root = "." tmp_dir = ".air" [build] -cmd = "make backend" +cmd = "make --no-print-directory backend" bin = "gitea" delay = 1000 include_ext = ["go", "tmpl"] diff --git a/.github/file-filters.yml b/.github/file-filters.yml new file mode 100644 index 0000000000..26231c9364 --- /dev/null +++ b/.github/file-filters.yml @@ -0,0 +1,15 @@ +docs: &docs + - "**/*.md" + - "docs/**" + +backend: &backend + - "**/*.go" + - "**/*.tmpl" + - "go.mod" + - "go.sum" + +frontend: &frontend + - "**/*.js" + - "web_src/**" + - "package.json" + - "package-lock.json" diff --git a/.github/workflows/files-changed.yml b/.github/workflows/files-changed.yml new file mode 100644 index 0000000000..2efd676719 --- /dev/null +++ b/.github/workflows/files-changed.yml @@ -0,0 +1,32 @@ +name: files changed + +on: + workflow_call: + outputs: + docs: + description: "whether docs files changed" + value: ${{ jobs.files-changed.outputs.docs }} + backend: + description: "whether backend files changed" + value: ${{ jobs.files-changed.outputs.backend }} + frontend: + description: "whether frontend files changed" + value: ${{ jobs.files-changed.outputs.frontend }} + +jobs: + files-changed: + name: detect which files changed + runs-on: ubuntu-latest + timeout-minutes: 3 + # Map a step output to a job output + outputs: + docs: ${{ steps.changes.outputs.docs }} + backend: ${{ steps.changes.outputs.backend }} + frontend: ${{ steps.changes.outputs.frontend }} + steps: + - uses: actions/checkout@v3 + - name: Check for backend file changes + uses: dorny/paths-filter@v2 + id: changes + with: + filters: .github/file-filters.yml diff --git a/.github/workflows/pull-compliance-docs.yml b/.github/workflows/pull-compliance-docs.yml index 44db6d67af..0f6720a64d 100644 --- a/.github/workflows/pull-compliance-docs.yml +++ b/.github/workflows/pull-compliance-docs.yml @@ -2,16 +2,18 @@ name: compliance-docs on: pull_request: - paths: - - "docs/**" - - "*.md" concurrency: group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }} cancel-in-progress: true jobs: + files-changed: + uses: ./.github/workflows/files-changed.yml + compliance-docs: + if: needs.files-changed.outputs.docs == 'true' + needs: files-changed runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 @@ -20,3 +22,4 @@ jobs: node-version: 20 - run: make deps-frontend - run: make lint-md + - run: make docs # test if build could succeed diff --git a/.github/workflows/pull-compliance-docsignore.yml b/.github/workflows/pull-compliance-docsignore.yml deleted file mode 100644 index ea0619e122..0000000000 --- a/.github/workflows/pull-compliance-docsignore.yml +++ /dev/null @@ -1,43 +0,0 @@ -name: compliance - -on: - pull_request: - paths: - - "docs/**" - - "*.md" - -jobs: - compliance-docs: - runs-on: ubuntu-latest - steps: - - run: echo "No build required" - - lint-backend: - runs-on: ubuntu-latest - steps: - - run: echo "No build required" - - lint-go-windows: - runs-on: ubuntu-latest - steps: - - run: echo "No build required" - - lint-go-gogit: - runs-on: ubuntu-latest - steps: - - run: echo "No build required" - - checks-backend: - runs-on: ubuntu-latest - steps: - - run: echo "No build required" - - frontend: - runs-on: ubuntu-latest - steps: - - run: echo "No build required" - - backend: - runs-on: ubuntu-latest - steps: - - run: echo "No build required" diff --git a/.github/workflows/pull-compliance.yml b/.github/workflows/pull-compliance.yml index ace2b15a9b..e108379b30 100644 --- a/.github/workflows/pull-compliance.yml +++ b/.github/workflows/pull-compliance.yml @@ -2,16 +2,18 @@ name: compliance on: pull_request: - paths-ignore: - - "docs/**" - - "*.md" concurrency: group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }} cancel-in-progress: true jobs: + files-changed: + uses: ./.github/workflows/files-changed.yml + lint-backend: + if: needs.files-changed.outputs.backend == 'true' + needs: files-changed runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 @@ -24,6 +26,8 @@ jobs: env: TAGS: bindata sqlite sqlite_unlock_notify lint-go-windows: + if: needs.files-changed.outputs.backend == 'true' + needs: files-changed runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 @@ -38,6 +42,8 @@ jobs: GOOS: windows GOARCH: amd64 lint-go-gogit: + if: needs.files-changed.outputs.backend == 'true' + needs: files-changed runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 @@ -50,6 +56,8 @@ jobs: env: TAGS: bindata gogit sqlite sqlite_unlock_notify checks-backend: + if: needs.files-changed.outputs.backend == 'true' + needs: files-changed runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 @@ -60,6 +68,8 @@ jobs: - run: make deps-backend deps-tools - run: make --always-make checks-backend # ensure the "go-licenses" make target runs frontend: + if: needs.files-changed.outputs.frontend == 'true' + needs: files-changed runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 @@ -70,6 +80,8 @@ jobs: - run: make lint-frontend - run: make checks-frontend backend: + if: needs.files-changed.outputs.backend == 'true' + needs: files-changed runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 diff --git a/.github/workflows/pull-db-tests-docsignore.yml b/.github/workflows/pull-db-tests-docsignore.yml deleted file mode 100644 index c04f763c3e..0000000000 --- a/.github/workflows/pull-db-tests-docsignore.yml +++ /dev/null @@ -1,38 +0,0 @@ -name: db-tests - -on: - pull_request: - paths: - - "docs/**" - - "*.md" - -jobs: - test-pgsql: - runs-on: ubuntu-latest - steps: - - run: echo "No build required" - - test-sqlite: - runs-on: ubuntu-latest - steps: - - run: echo "No build required" - - test-unit: - runs-on: ubuntu-latest - steps: - - run: echo "No build required" - - test-mysql5: - runs-on: ubuntu-latest - steps: - - run: echo "No build required" - - test-mysql8: - runs-on: ubuntu-latest - steps: - - run: echo "No build required" - - test-mssql: - runs-on: ubuntu-latest - steps: - - run: echo "No build required" diff --git a/.github/workflows/pull-db-tests.yml b/.github/workflows/pull-db-tests.yml index b3b02f15ca..cf08da1512 100644 --- a/.github/workflows/pull-db-tests.yml +++ b/.github/workflows/pull-db-tests.yml @@ -2,16 +2,18 @@ name: db-tests on: pull_request: - paths-ignore: - - "docs/**" - - "*.md" concurrency: group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }} cancel-in-progress: true jobs: + files-changed: + uses: ./.github/workflows/files-changed.yml + test-pgsql: + if: needs.files-changed.outputs.backend == 'true' || needs.files-changed.outputs.frontend == 'true' + needs: files-changed runs-on: ubuntu-latest services: pgsql: @@ -56,6 +58,8 @@ jobs: USE_REPO_TEST_DIR: 1 test-sqlite: + if: needs.files-changed.outputs.backend == 'true' || needs.files-changed.outputs.frontend == 'true' + needs: files-changed runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 @@ -75,6 +79,8 @@ jobs: USE_REPO_TEST_DIR: 1 test-unit: + if: needs.files-changed.outputs.backend == 'true' + needs: files-changed runs-on: ubuntu-latest services: mysql: @@ -138,6 +144,8 @@ jobs: GITHUB_READ_TOKEN: ${{ secrets.GITHUB_READ_TOKEN }} test-mysql5: + if: needs.files-changed.outputs.backend == 'true' || needs.files-changed.outputs.frontend == 'true' + needs: files-changed runs-on: ubuntu-latest services: mysql: @@ -180,6 +188,8 @@ jobs: TEST_INDEXER_CODE_ES_URL: "http://elastic:changeme@elasticsearch:9200" test-mysql8: + if: needs.files-changed.outputs.backend == 'true' || needs.files-changed.outputs.frontend == 'true' + needs: files-changed runs-on: ubuntu-latest services: mysql8: @@ -207,6 +217,8 @@ jobs: USE_REPO_TEST_DIR: 1 test-mssql: + if: needs.files-changed.outputs.backend == 'true' || needs.files-changed.outputs.frontend == 'true' + needs: files-changed runs-on: ubuntu-latest services: mssql: diff --git a/.github/workflows/pull-docker-dryrun-docsignore.yml b/.github/workflows/pull-docker-dryrun-docsignore.yml deleted file mode 100644 index 7c74efb34a..0000000000 --- a/.github/workflows/pull-docker-dryrun-docsignore.yml +++ /dev/null @@ -1,13 +0,0 @@ -name: docker-dryrun - -on: - pull_request: - paths: - - "docs/**" - - "*.md" - -jobs: - docker-dryrun: - runs-on: ubuntu-latest - steps: - - run: echo "No build required" diff --git a/.github/workflows/pull-docker-dryrun.yml b/.github/workflows/pull-docker-dryrun.yml index c3cdefc7a7..89b0c5253c 100644 --- a/.github/workflows/pull-docker-dryrun.yml +++ b/.github/workflows/pull-docker-dryrun.yml @@ -2,16 +2,18 @@ name: docker-dryrun on: pull_request: - paths-ignore: - - "docs/**" - - "*.md" concurrency: group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }} cancel-in-progress: true jobs: + files-changed: + uses: ./.github/workflows/files-changed.yml + docker-dryrun: + if: needs.files-changed.outputs.backend == 'true' || needs.files-changed.outputs.frontend == 'true' + needs: files-changed runs-on: ubuntu-latest steps: - uses: docker/setup-buildx-action@v2 diff --git a/.github/workflows/pull-e2e-tests-docsignore.yml b/.github/workflows/pull-e2e-tests-docsignore.yml deleted file mode 100644 index e809af7216..0000000000 --- a/.github/workflows/pull-e2e-tests-docsignore.yml +++ /dev/null @@ -1,13 +0,0 @@ -name: e2e-tests - -on: - pull_request: - paths: - - "docs/**" - - "*.md" - -jobs: - test-e2e: - runs-on: ubuntu-latest - steps: - - run: echo "No build required" diff --git a/.github/workflows/pull-e2e-tests.yml b/.github/workflows/pull-e2e-tests.yml index 611a6b0741..cf6af401f5 100644 --- a/.github/workflows/pull-e2e-tests.yml +++ b/.github/workflows/pull-e2e-tests.yml @@ -2,16 +2,18 @@ name: e2e-tests on: pull_request: - paths-ignore: - - "docs/**" - - "*.md" concurrency: group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }} cancel-in-progress: true jobs: + files-changed: + uses: ./.github/workflows/files-changed.yml + test-e2e: + if: needs.files-changed.outputs.backend == 'true' || needs.files-changed.outputs.frontend == 'true' + needs: files-changed runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 diff --git a/MAINTAINERS b/MAINTAINERS index f62660a555..c3ac7b945f 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -51,3 +51,4 @@ Dong Ge (@sillyguodong) Xinyi Gong (@HesterG) wxiaoguang (@wxiaoguang) Gary Moon (@garymoon) +Philip Peterson (@philip-peterson) diff --git a/Makefile b/Makefile index fde7e990c5..16841796b7 100644 --- a/Makefile +++ b/Makefile @@ -35,6 +35,7 @@ SWAGGER_PACKAGE ?= github.com/go-swagger/go-swagger/cmd/swagger@v0.30.4 XGO_PACKAGE ?= src.techknowlogick.com/xgo@latest GO_LICENSES_PACKAGE ?= github.com/google/go-licenses@v1.6.0 GOVULNCHECK_PACKAGE ?= golang.org/x/vuln/cmd/govulncheck@latest +ACTIONLINT_PACKAGE ?= github.com/rhysd/actionlint/cmd/actionlint@latest DOCKER_IMAGE ?= gitea/gitea DOCKER_TAG ?= latest @@ -199,6 +200,7 @@ help: @echo " - deps-tools install tool dependencies" @echo " - lint lint everything" @echo " - lint-fix lint everything and fix issues" + @echo " - lint-actions lint action workflow files" @echo " - lint-frontend lint frontend files" @echo " - lint-frontend-fix lint frontend files and fix issues" @echo " - lint-backend lint backend files" @@ -411,13 +413,17 @@ lint-go-vet: lint-editorconfig: $(GO) run $(EDITORCONFIG_CHECKER_PACKAGE) templates .github/workflows +.PHONY: lint-actions +lint-actions: + $(GO) run $(ACTIONLINT_PACKAGE) + .PHONY: watch watch: - bash build/watch.sh + @bash build/watch.sh .PHONY: watch-frontend watch-frontend: node-check node_modules - rm -rf $(WEBPACK_DEST_ENTRIES) + @rm -rf $(WEBPACK_DEST_ENTRIES) NODE_ENV=development npx webpack --watch --progress .PHONY: watch-backend @@ -908,6 +914,7 @@ deps-tools: $(GO) install $(XGO_PACKAGE) $(GO) install $(GO_LICENSES_PACKAGE) $(GO) install $(GOVULNCHECK_PACKAGE) + $(GO) install $(ACTIONLINT_PACKAGE) node_modules: package-lock.json npm install --no-save diff --git a/build/watch.sh b/build/watch.sh index 61e3dc40a2..5e8defa49c 100644 --- a/build/watch.sh +++ b/build/watch.sh @@ -1,8 +1,8 @@ #!/bin/bash set -euo pipefail -make watch-frontend & -make watch-backend & +make --no-print-directory watch-frontend & +make --no-print-directory watch-backend & trap 'kill $(jobs -p)' EXIT wait diff --git a/cmd/hook.go b/cmd/hook.go index bd5575ab69..6453267832 100644 --- a/cmd/hook.go +++ b/cmd/hook.go @@ -201,7 +201,7 @@ Gitea or set your environment appropriately.`, "") oldCommitIDs := make([]string, hookBatchSize) newCommitIDs := make([]string, hookBatchSize) - refFullNames := make([]string, hookBatchSize) + refFullNames := make([]git.RefName, hookBatchSize) count := 0 total := 0 lastline := 0 @@ -236,14 +236,14 @@ Gitea or set your environment appropriately.`, "") oldCommitID := string(fields[0]) newCommitID := string(fields[1]) - refFullName := string(fields[2]) + refFullName := git.RefName(fields[2]) total++ lastline++ // If the ref is a branch or tag, check if it's protected // if supportProcReceive all ref should be checked because // permission check was delayed - if supportProcReceive || strings.HasPrefix(refFullName, git.BranchPrefix) || strings.HasPrefix(refFullName, git.TagPrefix) { + if supportProcReceive || refFullName.IsBranch() || refFullName.IsTag() { oldCommitIDs[count] = oldCommitID newCommitIDs[count] = newCommitID refFullNames[count] = refFullName @@ -351,7 +351,7 @@ Gitea or set your environment appropriately.`, "") } oldCommitIDs := make([]string, hookBatchSize) newCommitIDs := make([]string, hookBatchSize) - refFullNames := make([]string, hookBatchSize) + refFullNames := make([]git.RefName, hookBatchSize) count := 0 total := 0 wasEmpty := false @@ -373,7 +373,7 @@ Gitea or set your environment appropriately.`, "") fmt.Fprintf(out, ".") oldCommitIDs[count] = string(fields[0]) newCommitIDs[count] = string(fields[1]) - refFullNames[count] = string(fields[2]) + refFullNames[count] = git.RefName(fields[2]) if refFullNames[count] == git.BranchPrefix+"master" && newCommitIDs[count] != git.EmptySHA && count == total { masterPushed = true } @@ -575,7 +575,7 @@ Gitea or set your environment appropriately.`, "") } hookOptions.OldCommitIDs = make([]string, 0, hookBatchSize) hookOptions.NewCommitIDs = make([]string, 0, hookBatchSize) - hookOptions.RefFullNames = make([]string, 0, hookBatchSize) + hookOptions.RefFullNames = make([]git.RefName, 0, hookBatchSize) for { // note: pktLineTypeUnknow means pktLineTypeFlush and pktLineTypeData all allowed @@ -593,7 +593,7 @@ Gitea or set your environment appropriately.`, "") } hookOptions.OldCommitIDs = append(hookOptions.OldCommitIDs, t[0]) hookOptions.NewCommitIDs = append(hookOptions.NewCommitIDs, t[1]) - hookOptions.RefFullNames = append(hookOptions.RefFullNames, t[2]) + hookOptions.RefFullNames = append(hookOptions.RefFullNames, git.RefName(t[2])) } hookOptions.GitPushOptions = make(map[string]string) @@ -640,7 +640,7 @@ Gitea or set your environment appropriately.`, "") for _, rs := range resp.Results { if len(rs.Err) > 0 { - err = writeDataPktLine(ctx, os.Stdout, []byte("ng "+rs.OriginalRef+" "+rs.Err)) + err = writeDataPktLine(ctx, os.Stdout, []byte("ng "+rs.OriginalRef.String()+" "+rs.Err)) if err != nil { return err } @@ -648,7 +648,7 @@ Gitea or set your environment appropriately.`, "") } if rs.IsNotMatched { - err = writeDataPktLine(ctx, os.Stdout, []byte("ok "+rs.OriginalRef)) + err = writeDataPktLine(ctx, os.Stdout, []byte("ok "+rs.OriginalRef.String())) if err != nil { return err } diff --git a/custom/conf/app.example.ini b/custom/conf/app.example.ini index 81954662b2..2f9bd126e7 100644 --- a/custom/conf/app.example.ini +++ b/custom/conf/app.example.ini @@ -49,8 +49,9 @@ APP_NAME = ; Gitea: Git with a cup of tea ;; RUN_USER will automatically detect the current user - but you can set it here change it if you run locally RUN_USER = ; git ;; -;; Application run mode, affects performance and debugging. Either "dev", "prod" or "test", default is "prod" -RUN_MODE = ; prod +;; Application run mode, affects performance and debugging: "dev" or "prod", default is "prod" +;; Mode "dev" makes Gitea easier to develop and debug, values other than "dev" are treated as "prod" which is for production use. +;RUN_MODE = prod ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; @@ -1056,6 +1057,9 @@ LEVEL = Info ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; List of reasons why a Pull Request or Issue can be locked ;LOCK_REASONS = Too heated,Off-topic,Resolved,Spam +;; Maximum number of pinned Issues +;; Set to 0 to disable pinning Issues +;MAX_PINNED = 3 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; @@ -1370,6 +1374,10 @@ LEVEL = Info ;; repo indexer by default disabled, since it uses a lot of disk space ;REPO_INDEXER_ENABLED = false ;; +;; repo indexer units, the items to index, could be `sources`, `forks`, `mirrors`, `templates` or any combination of them separated by a comma. +;; If empty then it defaults to `sources` only, as if you'd like to disable fully please see REPO_INDEXER_ENABLED. +;REPO_INDEXER_REPO_TYPES = sources,forks,mirrors,templates +;; ;; Code search engine type, could be `bleve` or `elasticsearch`. ;REPO_INDEXER_TYPE = bleve ;; diff --git a/docs/content/doc/administration/config-cheat-sheet.en-us.md b/docs/content/doc/administration/config-cheat-sheet.en-us.md index 4210e3ad7a..d0cfca2afd 100644 --- a/docs/content/doc/administration/config-cheat-sheet.en-us.md +++ b/docs/content/doc/administration/config-cheat-sheet.en-us.md @@ -73,7 +73,7 @@ In addition there is _`StaticRootPath`_ which can be set as a built-in at build - `RUN_USER`: **_current OS username_/`$USER`/`$USERNAME` e.g. git**: The user Gitea will run as. This should be a dedicated system (non-user) account. Setting this incorrectly will cause Gitea to not start. -- `RUN_MODE`: **prod**: Application run mode, affects performance and debugging. Either "dev", "prod" or "test". +- `RUN_MODE`: **prod**: Application run mode, affects performance and debugging: `dev` or `prod`, default is `prod`. Mode `dev` makes Gitea easier to develop and debug, values other than `dev` are treated as `prod` which is for production use. ## Repository (`repository`) @@ -144,6 +144,7 @@ limit defined in `REPO_SIZE_LIMIT` or at the repository itself. ### Repository - Issue (`repository.issue`) - `LOCK_REASONS`: **Too heated,Off-topic,Resolved,Spam**: A list of reasons why a Pull Request or Issue can be locked +- `MAX_PINNED`: **3**: Maximum number of pinned Issues. Set to 0 to disable pinning Issues. ### Repository - Upload (`repository.upload`) @@ -468,6 +469,7 @@ relation to port exhaustion. - `ISSUE_INDEXER_PATH`: **indexers/issues.bleve**: Index file used for issue search; available when ISSUE_INDEXER_TYPE is bleve and elasticsearch. Relative paths will be made absolute against _`AppWorkPath`_. - `REPO_INDEXER_ENABLED`: **false**: Enables code search (uses a lot of disk space, about 6 times more than the repository size). +- `REPO_INDEXER_REPO_TYPES`: **sources,forks,mirrors,templates**: Repo indexer units. The items to index could be `sources`, `forks`, `mirrors`, `templates` or any combination of them separated by a comma. If empty then it defaults to `sources` only, as if you'd like to disable fully please see `REPO_INDEXER_ENABLED`. - `REPO_INDEXER_TYPE`: **bleve**: Code search engine type, could be `bleve` or `elasticsearch`. - `REPO_INDEXER_PATH`: **indexers/repos.bleve**: Index file used for code search. - `REPO_INDEXER_CONN_STR`: ****: Code indexer connection string, available when `REPO_INDEXER_TYPE` is elasticsearch. i.e. http://elastic:changeme@localhost:9200 @@ -517,7 +519,7 @@ And the following unique queues: - `INSTALL_LOCK`: **false**: Controls access to the installation page. When set to "true", the installation page is not accessible. - `SECRET_KEY`: **\**: Global secret key. This key is VERY IMPORTANT, if you lost it, the data encrypted by it (like 2FA secret) can't be decrypted anymore. -- `SECRET_KEY_URI`: ****: Instead of defining SECRET_KEY, this option can be used to use the key stored in a file (example value: `file:/etc/gitea/secret_key`). It shouldn't be lost like SECRET_KEY. +- `SECRET_KEY_URI`: **\**: Instead of defining SECRET_KEY, this option can be used to use the key stored in a file (example value: `file:/etc/gitea/secret_key`). It shouldn't be lost like SECRET_KEY. - `LOGIN_REMEMBER_DAYS`: **7**: Cookie lifetime, in days. - `COOKIE_USERNAME`: **gitea\_awesome**: Name of the cookie used to store the current username. - `COOKIE_REMEMBER_NAME`: **gitea\_incredible**: Name of cookie used to store authentication @@ -543,7 +545,7 @@ And the following unique queues: - `ONLY_ALLOW_PUSH_IF_GITEA_ENVIRONMENT_SET`: **true**: Set to `false` to allow local users to push to gitea-repositories without setting up the Gitea environment. This is not recommended and if you want local users to push to Gitea repositories you should set the environment appropriately. - `IMPORT_LOCAL_PATHS`: **false**: Set to `false` to prevent all users (including admin) from importing local path on server. - `INTERNAL_TOKEN`: **\**: Secret used to validate communication within Gitea binary. -- `INTERNAL_TOKEN_URI`: ****: Instead of defining INTERNAL_TOKEN in the configuration, this configuration option can be used to give Gitea a path to a file that contains the internal token (example value: `file:/etc/gitea/internal_token`) +- `INTERNAL_TOKEN_URI`: **\**: Instead of defining INTERNAL_TOKEN in the configuration, this configuration option can be used to give Gitea a path to a file that contains the internal token (example value: `file:/etc/gitea/internal_token`) - `PASSWORD_HASH_ALGO`: **pbkdf2**: The hash algorithm to use \[argon2, pbkdf2, pbkdf2_v1, pbkdf2_hi, scrypt, bcrypt\], argon2 and scrypt will spend significant amounts of memory. - Note: The default parameters for `pbkdf2` hashing have changed - the previous settings are available as `pbkdf2_v1` but are not recommended. - The hash functions may be tuned by using `$` after the algorithm: @@ -574,8 +576,8 @@ And the following unique queues: ## Camo (`camo`) - `ENABLED`: **false**: Enable media proxy, we support images only at the moment. -- `SERVER_URL`: ****: URL of camo server, it **is required** if camo is enabled. -- `HMAC_KEY`: ****: Provide the HMAC key for encoding URLs, it **is required** if camo is enabled. +- `SERVER_URL`: **\**: URL of camo server, it **is required** if camo is enabled. +- `HMAC_KEY`: **\**: Provide the HMAC key for encoding URLs, it **is required** if camo is enabled. - `ALLWAYS`: **false**: Set to true to use camo for both HTTP and HTTPS content, otherwise only non-HTTPS URLs are proxied ## OpenID (`openid`) @@ -1121,7 +1123,7 @@ Gitea can support Markup using external tools. The example below will add a mark ENABLED = true NEED_POSTPROCESS = true FILE_EXTENSIONS = .adoc,.asciidoc -RENDER_COMMAND = "asciidoc --out-file=- -" +RENDER_COMMAND = "asciidoctor --embedded --safe-mode=secure --out-file=- -" IS_INPUT_FILE = false ``` diff --git a/docs/content/doc/administration/config-cheat-sheet.zh-cn.md b/docs/content/doc/administration/config-cheat-sheet.zh-cn.md index c672b61598..ba28b98123 100644 --- a/docs/content/doc/administration/config-cheat-sheet.zh-cn.md +++ b/docs/content/doc/administration/config-cheat-sheet.zh-cn.md @@ -337,7 +337,7 @@ test01.xls: application/vnd.ms-excel; charset=binary ENABLED = false NEED_POSTPROCESS = true FILE_EXTENSIONS = .adoc,.asciidoc -RENDER_COMMAND = "asciidoc --out-file=- -" +RENDER_COMMAND = "asciidoctor --embedded --safe-mode=secure --out-file=- -" IS_INPUT_FILE = false ``` diff --git a/docs/content/doc/contributing/guidelines-backend.en-us.md b/docs/content/doc/contributing/guidelines-backend.en-us.md index fd0f8b0830..283fbdf3ae 100644 --- a/docs/content/doc/contributing/guidelines-backend.en-us.md +++ b/docs/content/doc/contributing/guidelines-backend.en-us.md @@ -37,7 +37,7 @@ To maintain understandable code and avoid circular dependencies it is important - `cmd`: All Gitea actual sub commands includes web, doctor, serv, hooks, admin and etc. `web` will start the web service. `serv` and `hooks` will be invoked by Git or OpenSSH. Other sub commands could help to maintain Gitea. - `tests`: Common test utility functions - `tests/integration`: Integration tests, to test back-end regressions - - `tests/e2e`: E2e tests, to test test front-end <> back-end compatibility and visual regressions. + - `tests/e2e`: E2e tests, to test front-end and back-end compatibility and visual regressions. - `models`: Contains the data structures used by xorm to construct database tables. It also contains functions to query and update the database. Dependencies to other Gitea code should be avoided. You can make exceptions in cases such as logging. - `models/db`: Basic database operations. All other `models/xxx` packages should depend on this package. The `GetEngine` function should only be invoked from `models/`. - `models/fixtures`: Sample data used in unit tests and integration tests. One `yml` file means one table which will be loaded into database when beginning the tests. @@ -72,7 +72,6 @@ So services must be allowed to create a database transaction. Here is some examp // services/repository/repository.go func CreateXXXX() error { return db.WithTx(func(ctx context.Context) error { - e := db.GetEngine(ctx) // do something, if err is returned, it will rollback automatically if err := issues.UpdateIssue(ctx, repoID); err != nil { // ... diff --git a/docs/content/doc/contributing/guidelines-backend.zh-cn.md b/docs/content/doc/contributing/guidelines-backend.zh-cn.md new file mode 100644 index 0000000000..c94d4305e1 --- /dev/null +++ b/docs/content/doc/contributing/guidelines-backend.zh-cn.md @@ -0,0 +1,123 @@ +--- +date: "2023-05-25T23:41:00+08:00" +title: "后端开发指南" +slug: "guidelines-backend" +weight: 20 +toc: false +draft: false +aliases: + - /zh-cn/guidelines-backend +menu: + sidebar: + parent: "contributing" + name: "后端开发指南" + weight: 20 + identifier: "guidelines-backend" +--- + +# 后端开发指南 + +**目录** + +{{< toc >}} + +## 背景 + +Gitea使用Golang作为后端编程语言。它使用了许多第三方包,并且自己也编写了一些包。 +例如,Gitea使用[Chi](https://github.com/go-chi/chi)作为基本的Web框架。[Xorm](https://xorm.io)是一个用于与数据库交互的ORM框架。 +因此,管理这些包非常重要。在开始编写后端代码之前,请参考以下准则。 + +## 包设计准则 + +### 包列表 + +为了保持易于理解的代码并避免循环依赖,拥有良好的代码结构是很重要的。Gitea后端分为以下几个部分: + +- `build`:帮助构建Gitea的脚本。 +- `cmd`:包含所有Gitea的实际子命令,包括web、doctor、serv、hooks、admin等。`web`将启动Web服务。`serv`和`hooks`将被Git或OpenSSH调用。其他子命令可以帮助维护Gitea。 +- `tests`:常用的测试函数 +- `tests/integration`:集成测试,用于测试后端回归。 +- `tests/e2e`:端到端测试,用于测试前端和后端的兼容性和视觉回归。 +- `models`:包含由xorm用于构建数据库表的数据结构。它还包含查询和更新数据库的函数。应避免与其他Gitea代码的依赖关系。在某些情况下,比如日志记录时可以例外。 + - `models/db`:基本的数据库操作。所有其他`models/xxx`包都应依赖于此包。`GetEngine`函数只能从models/中调用。 + - `models/fixtures`:单元测试和集成测试中使用的示例数据。一个`yml`文件表示一个将在测试开始时加载到数据库中的表。 + - `models/migrations`:存储不同版本之间的数据库迁移。修改数据库结构的PR**必须**包含一个迁移步骤。 +- `modules`:在Gitea中处理特定功能的不同模块。工作正在进行中:其中一些模块应该移到`services`中,特别是那些依赖于models的模块,因为它们依赖于数据库。 + - `modules/setting`:存储从ini文件中读取的所有系统配置,并在各处引用。但是在可能的情况下,应将其作为函数参数使用。 + - `modules/git`:用于与`Git`命令行或Gogit包交互的包。 +- `public`:编译后的前端文件(JavaScript、图像、CSS等) +- `routers`:处理服务器请求。由于它使用其他Gitea包来处理请求,因此其他包(models、modules或services)不能依赖于routers。 + - `routers/api`:包含`/api/v1`相关路由,用于处理RESTful API请求。 + - `routers/install`:只能在系统处于安装模式(INSTALL_LOCK=false)时响应。 + - `routers/private`:仅由内部子命令调用,特别是`serv`和`hooks`。 + - `routers/web`:处理来自Web浏览器或Git SMART HTTP协议的HTTP请求。 +- `services`:用于常见路由操作或命令执行的支持函数。使用`models`和`modules`来处理请求。 +- `templates`:用于生成HTML输出的Golang模板。 + +### 包依赖关系 + +由于Golang不支持导入循环,我们必须仔细决定包之间的依赖关系。这些包之间有一些级别。以下是理想的包依赖关系方向。 + +`cmd` -> `routers` -> `services` -> `models` -> `modules` + +从左到右,左侧的包可以依赖于右侧的包,但右侧的包不能依赖于左侧的包。在同一级别的子包中,可以根据该级别的规则进行依赖。 + +**注意事项** + +为什么我们需要在`models`之外使用数据库事务?以及如何使用? +某些操作在数据库记录插入/更新/删除失败时应该允许回滚。 +因此,服务必须能够创建数据库事务。以下是一些示例: + +```go +// services/repository/repository.go +func CreateXXXX() error { + return db.WithTx(func(ctx context.Context) error { + // do something, if err is returned, it will rollback automatically + if err := issues.UpdateIssue(ctx, repoID); err != nil { + // ... + return err + } + // ... + return nil + }) +} +``` + +在`services`中**不应该**直接使用`db.GetEngine(ctx)`,而是应该在`models/`下编写一个函数。 +如果该函数将在事务中使用,请将`context.Context`作为函数的第一个参数。 + +```go +// models/issues/issue.go +func UpdateIssue(ctx context.Context, repoID int64) error { + e := db.GetEngine(ctx) + + // ... +} +``` + +### 包名称 + +对于顶层包,请使用复数作为包名,例如`services`、`models`,对于子包,请使用单数,例如`services/user`、`models/repository`。 + +### 导入别名 + +由于有一些使用相同包名的包,例如`modules/user`、`models/user`和`services/user`,当这些包在一个Go文件中被导入时,很难知道我们使用的是哪个包以及它是变量名还是导入名。因此,我们始终建议使用导入别名。为了与常见的驼峰命名法的包变量区分开,建议使用**snake_case**作为导入别名的命名规则。 +例如:`import user_service "code.gitea.io/gitea/services/user"` + +### 重要注意事项 + +- 永远不要写成`x.Update(exemplar)`,而没有明确的`WHERE`子句: + - 这将导致表中的所有行都被使用exemplar的非零值进行更新,包括ID。 + - 通常应该写成`x.ID(id).Update(exemplar)`。 +- 如果在迁移过程中使用`x.Insert(exemplar)`向表中插入记录,而ID是预设的: + - 对于MSSQL变体,你将需要执行``SET IDENTITY_INSERT `table` ON``(否则迁移将失败) + - 对于PostgreSQL,你还需要更新ID序列,否则迁移将悄无声息地通过,但后续的插入将失败: + ``SELECT setval('table_name_id_seq', COALESCE((SELECT MAX(id)+1 FROM `table_name`), 1), false)`` + +### 未来的任务 + +目前,我们正在进行一些重构,以完成以下任务: + +- 纠正不符合规则的代码。 +- `models`中的文件太多了,所以我们正在将其中的一些移动到子包`models/xxx`中。 +- 由于它们依赖于`models`,因此应将某些`modules`子包移动到`services`中。 diff --git a/docs/content/doc/contributing/guidelines-frontend.en-us.md b/docs/content/doc/contributing/guidelines-frontend.en-us.md index 39a70eee97..fcbd81b26b 100644 --- a/docs/content/doc/contributing/guidelines-frontend.en-us.md +++ b/docs/content/doc/contributing/guidelines-frontend.en-us.md @@ -2,7 +2,7 @@ date: "2021-10-13T16:00:00+02:00" title: "Guidelines for Frontend Development" slug: "guidelines-frontend" -weight: 20 +weight: 30 toc: false draft: false aliases: @@ -11,7 +11,7 @@ menu: sidebar: parent: "contributing" name: "Guidelines for Frontend" - weight: 20 + weight: 30 identifier: "guidelines-frontend" --- diff --git a/docs/content/doc/contributing/guidelines-frontend.zh-cn.md b/docs/content/doc/contributing/guidelines-frontend.zh-cn.md new file mode 100644 index 0000000000..3a58db0c70 --- /dev/null +++ b/docs/content/doc/contributing/guidelines-frontend.zh-cn.md @@ -0,0 +1,138 @@ +--- +date: "2023-05-25T16:00:00+02:00" +title: "前端开发指南" +slug: "guidelines-frontend" +weight: 20 +toc: false +draft: false +aliases: + - /zh-cn/guidelines-frontend +menu: + sidebar: + parent: "contributing" + name: "前端开发指南" + weight: 20 + identifier: "guidelines-frontend" +--- + +# 前端开发指南 + +**目录** + +{{< toc >}} + +## 背景 + +Gitea 在其前端中使用[Fomantic-UI](https://fomantic-ui.com/introduction/getting-started.html)(基于[jQuery](https://api.jquery.com))和 [Vue3](https://vuejs.org/)。 + +HTML 页面由[Go HTML Template](https://pkg.go.dev/html/template)渲染。 + +源文件可以在以下目录中找到: + +* **CSS 样式**: `web_src/css/` +* **JavaScript 文件**: `web_src/js/` +* **Vue 组件**: `web_src/js/components/` +* **Go HTML 模板**: `templates/` + +## 通用准则 + +我们推荐使用[Google HTML/CSS Style Guide](https://google.github.io/styleguide/htmlcssguide.html)和[Google JavaScript Style Guide](https://google.github.io/styleguide/jsguide.html)。 + +## Gitea 特定准则: + +1. 每个功能(Fomantic-UI/jQuery 模块)应放在单独的文件/目录中。 +2. HTML 的 id 和 class 应使用 kebab-case,最好包含2-3个与功能相关的关键词。 +3. 在 JavaScript 中使用的 HTML 的 id 和 class 应在整个项目中是唯一的,并且应包含2-3个与功能相关的关键词。建议在仅在 JavaScript 中使用的 class 中使用 `js-` 前缀。 +4. 不应覆盖框架提供的 class 的 CSS 样式。始终使用具有2-3个与功能相关的关键词的新 class 名称来覆盖框架样式。Gitea 中的帮助 CSS 类在 `helpers.less` 中。 +5. 后端可以通过使用`ctx.PageData["myModuleData"] = map[]{}`将复杂数据传递给前端,但不要将整个模型暴露给前端,以避免泄露敏感数据。 +6. 简单页面和与 SEO 相关的页面使用 Go HTML 模板渲染生成静态的 Fomantic-UI HTML 输出。复杂页面可以使用 Vue3。 +7. 明确变量类型,优先使用`elem.disabled = true`而不是`elem.setAttribute('disabled', 'anything')`,优先使用`$el.prop('checked', var === 'yes')`而不是`$el.prop('checked', var)`。 +8. 使用语义化元素,优先使用` {{else}} - {{end}} diff --git a/templates/repo/editor/commit_form.tmpl b/templates/repo/editor/commit_form.tmpl index db798d92e8..6a3f86f9fc 100644 --- a/templates/repo/editor/commit_form.tmpl +++ b/templates/repo/editor/commit_form.tmpl @@ -41,17 +41,15 @@ {{if not .Repository.IsEmpty}}
- {{$pullRequestEnabled := .Repository.UnitEnabled $.Context $.UnitTypePullRequests}} - {{$prUnit := .Repository.MustGetUnit $.Context $.UnitTypePullRequests}}
- {{if $pullRequestEnabled}} + {{if .CanCreatePullRequest}} {{else}} {{end}}