diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index b232dfb8cc..236bc4722a 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -10,7 +10,8 @@ "ghcr.io/devcontainers-contrib/features/poetry:2": {}, "ghcr.io/devcontainers/features/python:1": { "version": "3.12" - } + }, + "ghcr.io/warrenbuckley/codespace-features/sqlite:1": {} }, "customizations": { "vscode": { @@ -25,8 +26,9 @@ "Vue.volar", "ms-azuretools.vscode-docker", "vitest.explorer", - "qwtel.sqlite-viewer", - "GitHub.vscode-pull-request-github" + "cweijan.vscode-database-client2", + "GitHub.vscode-pull-request-github", + "Azurite.azurite" ] } }, diff --git a/.gitpod.yml b/.gitpod.yml index f573d55a76..8671edc47c 100644 --- a/.gitpod.yml +++ b/.gitpod.yml @@ -43,7 +43,7 @@ vscode: - Vue.volar - ms-azuretools.vscode-docker - vitest.explorer - - qwtel.sqlite-viewer + - cweijan.vscode-database-client2 - GitHub.vscode-pull-request-github ports: diff --git a/Makefile b/Makefile index 127da4d072..41b051cf9b 100644 --- a/Makefile +++ b/Makefile @@ -38,6 +38,7 @@ GO_LICENSES_PACKAGE ?= github.com/google/go-licenses@v1.6.0 # renovate: datasour GOVULNCHECK_PACKAGE ?= golang.org/x/vuln/cmd/govulncheck@v1 # renovate: datasource=go DEADCODE_PACKAGE ?= golang.org/x/tools/cmd/deadcode@v0.22.0 # renovate: datasource=go GOMOCK_PACKAGE ?= go.uber.org/mock/mockgen@v0.4.0 # renovate: datasource=go +GOPLS_PACKAGE ?= golang.org/x/tools/gopls@v0.15.3 # renovate: datasource=go DOCKER_IMAGE ?= gitea/gitea DOCKER_TAG ?= latest @@ -228,6 +229,7 @@ help: @echo " - lint-go lint go files" @echo " - lint-go-fix lint go files and fix issues" @echo " - lint-go-vet lint go files with vet" + @echo " - lint-go-gopls lint go files with gopls" @echo " - lint-js lint js files" @echo " - lint-js-fix lint js files and fix issues" @echo " - lint-css lint css files" @@ -468,6 +470,11 @@ lint-go-vet: @echo "Running go vet..." @$(GO) vet ./... +.PHONY: lint-go-gopls +lint-go-gopls: + @echo "Running gopls check..." + @GO=$(GO) GOPLS_PACKAGE=$(GOPLS_PACKAGE) tools/lint-go-gopls.sh $(GO_SOURCES_NO_BINDATA) + .PHONY: lint-editorconfig lint-editorconfig: $(GO) run $(EDITORCONFIG_CHECKER_PACKAGE) templates .forgejo/workflows @@ -879,13 +886,14 @@ deps-tools: $(GO) install $(GO_LICENSES_PACKAGE) $(GO) install $(GOVULNCHECK_PACKAGE) $(GO) install $(GOMOCK_PACKAGE) + $(GO) install $(GOPLS_PACKAGE) node_modules: package-lock.json npm install --no-save @touch node_modules .venv: poetry.lock - poetry install --no-root + poetry install @touch .venv .PHONY: fomantic diff --git a/custom/conf/app.example.ini b/custom/conf/app.example.ini index 451742ac06..b1fe38dee1 100644 --- a/custom/conf/app.example.ini +++ b/custom/conf/app.example.ini @@ -1387,6 +1387,9 @@ LEVEL = Info ;; ;; Maximum allowed file size in bytes to render CSV files as table. (Set to 0 for no limit). ;MAX_FILE_SIZE = 524288 +;; +;; Maximum allowed rows to render CSV files. (Set to 0 for no limit) +;MAX_ROWS = 2500 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; @@ -1746,6 +1749,16 @@ LEVEL = Info ;; convert \r\n to \n for Sendmail ;SENDMAIL_CONVERT_CRLF = true +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;[mailer.override_header] +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; This is empty by default, use it only if you know what you need it for. +;Reply-To = test@example.com, test2@example.com +;Content-Type = text/html; charset=utf-8 +;In-Reply-To = + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;[email.incoming] diff --git a/modules/markup/csv/csv.go b/modules/markup/csv/csv.go index 1dd26eb8ac..3d952b0de4 100644 --- a/modules/markup/csv/csv.go +++ b/modules/markup/csv/csv.go @@ -5,8 +5,6 @@ package markup import ( "bufio" - "bytes" - "fmt" "html" "io" "regexp" @@ -15,6 +13,8 @@ import ( "code.gitea.io/gitea/modules/csv" "code.gitea.io/gitea/modules/markup" "code.gitea.io/gitea/modules/setting" + "code.gitea.io/gitea/modules/translation" + "code.gitea.io/gitea/modules/util" ) func init() { @@ -81,86 +81,38 @@ func writeField(w io.Writer, element, class, field string) error { func (r Renderer) Render(ctx *markup.RenderContext, input io.Reader, output io.Writer) error { tmpBlock := bufio.NewWriter(output) maxSize := setting.UI.CSV.MaxFileSize + maxRows := setting.UI.CSV.MaxRows - if maxSize == 0 { - return r.tableRender(ctx, input, tmpBlock) + if maxSize != 0 { + input = io.LimitReader(input, maxSize+1) } - rawBytes, err := io.ReadAll(io.LimitReader(input, maxSize+1)) - if err != nil { - return err - } - - if int64(len(rawBytes)) <= maxSize { - return r.tableRender(ctx, bytes.NewReader(rawBytes), tmpBlock) - } - return r.fallbackRender(io.MultiReader(bytes.NewReader(rawBytes), input), tmpBlock) -} - -func (Renderer) fallbackRender(input io.Reader, tmpBlock *bufio.Writer) error { - _, err := tmpBlock.WriteString("
") - if err != nil { - return err - } - - scan := bufio.NewScanner(input) - scan.Split(bufio.ScanRunes) - for scan.Scan() { - switch scan.Text() { - case `&`: - _, err = tmpBlock.WriteString("&") - case `'`: - _, err = tmpBlock.WriteString("'") // "'" is shorter than "'" and apos was not in HTML until HTML5. - case `<`: - _, err = tmpBlock.WriteString("<") - case `>`: - _, err = tmpBlock.WriteString(">") - case `"`: - _, err = tmpBlock.WriteString(""") // """ is shorter than """. - default: - _, err = tmpBlock.Write(scan.Bytes()) - } - if err != nil { - return err - } - } - if err = scan.Err(); err != nil { - return fmt.Errorf("fallbackRender scan: %w", err) - } - - _, err = tmpBlock.WriteString("") - if err != nil { - return err - } - return tmpBlock.Flush() -} - -func (Renderer) tableRender(ctx *markup.RenderContext, input io.Reader, tmpBlock *bufio.Writer) error { rd, err := csv.CreateReaderAndDetermineDelimiter(ctx, input) if err != nil { return err } - if _, err := tmpBlock.WriteString(`
1,<a>\n2,<b>" - assert.Equal(t, want, buf.String()) - }) } diff --git a/modules/setting/mailer.go b/modules/setting/mailer.go index e9ce640c7f..cfedb4613f 100644 --- a/modules/setting/mailer.go +++ b/modules/setting/mailer.go @@ -18,14 +18,15 @@ import ( // Mailer represents mail service. type Mailer struct { // Mailer - Name string `ini:"NAME"` - From string `ini:"FROM"` - EnvelopeFrom string `ini:"ENVELOPE_FROM"` - OverrideEnvelopeFrom bool `ini:"-"` - FromName string `ini:"-"` - FromEmail string `ini:"-"` - SendAsPlainText bool `ini:"SEND_AS_PLAIN_TEXT"` - SubjectPrefix string `ini:"SUBJECT_PREFIX"` + Name string `ini:"NAME"` + From string `ini:"FROM"` + EnvelopeFrom string `ini:"ENVELOPE_FROM"` + OverrideEnvelopeFrom bool `ini:"-"` + FromName string `ini:"-"` + FromEmail string `ini:"-"` + SendAsPlainText bool `ini:"SEND_AS_PLAIN_TEXT"` + SubjectPrefix string `ini:"SUBJECT_PREFIX"` + OverrideHeader map[string][]string `ini:"-"` // SMTP sender Protocol string `ini:"PROTOCOL"` @@ -159,6 +160,12 @@ func loadMailerFrom(rootCfg ConfigProvider) { log.Fatal("Unable to map [mailer] section on to MailService. Error: %v", err) } + overrideHeader := rootCfg.Section("mailer.override_header").Keys() + MailService.OverrideHeader = make(map[string][]string) + for _, key := range overrideHeader { + MailService.OverrideHeader[key.Name()] = key.Strings(",") + } + // Infer SMTPPort if not set if MailService.SMTPPort == "" { switch MailService.Protocol { diff --git a/modules/setting/ui.go b/modules/setting/ui.go index 47e1393ef3..056d670ba6 100644 --- a/modules/setting/ui.go +++ b/modules/setting/ui.go @@ -53,6 +53,7 @@ var UI = struct { CSV struct { MaxFileSize int64 + MaxRows int } `ini:"ui.csv"` Admin struct { @@ -110,8 +111,10 @@ var UI = struct { }, CSV: struct { MaxFileSize int64 + MaxRows int }{ MaxFileSize: 524288, + MaxRows: 2500, }, Admin: struct { UserPagingNum int diff --git a/modules/structs/activity.go b/modules/structs/activity.go index 6d2ee56b08..ea27fbfd77 100644 --- a/modules/structs/activity.go +++ b/modules/structs/activity.go @@ -6,8 +6,11 @@ package structs import "time" type Activity struct { - ID int64 `json:"id"` - UserID int64 `json:"user_id"` // Receiver user + ID int64 `json:"id"` + UserID int64 `json:"user_id"` // Receiver user + // the type of action + // + // enum: create_repo,rename_repo,star_repo,watch_repo,commit_repo,create_issue,create_pull_request,transfer_repo,push_tag,comment_issue,merge_pull_request,close_issue,reopen_issue,close_pull_request,reopen_pull_request,delete_tag,delete_branch,mirror_sync_push,mirror_sync_create,mirror_sync_delete,approve_pull_request,reject_pull_request,comment_pull,publish_release,pull_review_dismissed,pull_request_ready_for_review,auto_merge_pull_request OpType string `json:"op_type"` ActUserID int64 `json:"act_user_id"` ActUser *User `json:"act_user"` diff --git a/options/gitignore/Alteryx b/options/gitignore/Alteryx new file mode 100644 index 0000000000..a8e1341ffe --- /dev/null +++ b/options/gitignore/Alteryx @@ -0,0 +1,44 @@ +# gitignore template for Alteryx Designer +# website: https://www.alteryx.com/ +# website: https://help.alteryx.com/current/designer/alteryx-file-types + +# Alteryx Data Files +*.yxdb +*.cydb +*.cyidx +*.rptx +*.vvf +*.aws + +# Alteryx Special Files +*.yxwv +*.yxft +*.yxbe +*.bak +*.pcxml +*.log +*.bin +*.yxlang +CASS.ini + +# Alteryx License Files +*.yxlc +*.slc +*.cylc +*.alc +*.gzlc + +## gitignore reference sites +# https://git-scm.com/book/en/v2/Git-Basics-Recording-Changes-to-the-Repository#Ignoring-Files +# https://git-scm.com/docs/gitignore +# https://help.github.com/articles/ignoring-files/ + +## Useful knowledge from stackoverflow +# Even if you haven't tracked the files so far, git seems to be able to "know" about them even after you add them to .gitignore. +# WARNING: First commit your current changes, or you will lose them. +# Then run the following commands from the top folder of your git repo: +# git rm -r --cached . +# git add . +# git commit -m "fixed untracked files" + +# author: Kacper Ksieski \ No newline at end of file diff --git a/options/gitignore/Archives b/options/gitignore/Archives index 4ed9ab8350..8c92521b4c 100644 --- a/options/gitignore/Archives +++ b/options/gitignore/Archives @@ -14,6 +14,8 @@ *.lzma *.cab *.xar +*.zst +*.tzst # Packing-only formats *.iso diff --git a/options/gitignore/Ballerina b/options/gitignore/Ballerina new file mode 100644 index 0000000000..030a350fbf --- /dev/null +++ b/options/gitignore/Ballerina @@ -0,0 +1,11 @@ +# generated files +target/ +generated/ + +# dependencies +Dependencies.toml + +# config files +Config.toml +# the config files used for testing, Uncomment the following line if you want to commit the test config files +#!**/tests/Config.toml diff --git a/options/gitignore/CMake b/options/gitignore/CMake index 46f42f8f3c..11c76431e1 100644 --- a/options/gitignore/CMake +++ b/options/gitignore/CMake @@ -9,3 +9,4 @@ install_manifest.txt compile_commands.json CTestTestfile.cmake _deps +CMakeUserPresets.json diff --git a/options/gitignore/Delphi b/options/gitignore/Delphi index 9532800ba2..8df99b676b 100644 --- a/options/gitignore/Delphi +++ b/options/gitignore/Delphi @@ -26,6 +26,18 @@ #*.obj # +# Default Delphi compiler directories +# Content of this directories are generated with each Compile/Construct of a project. +# Most of the time, files here have not there place in a code repository. +#Win32/ +#Win64/ +#OSX64/ +#OSXARM64/ +#Android/ +#Android64/ +#iOSDevice64/ +#Linux64/ + # Delphi compiler-generated binaries (safe to delete) *.exe *.dll diff --git a/options/gitignore/GitHubPages b/options/gitignore/GitHubPages new file mode 100644 index 0000000000..493e69ba39 --- /dev/null +++ b/options/gitignore/GitHubPages @@ -0,0 +1,18 @@ +# This .gitignore is appropriate for repositories deployed to GitHub Pages and using +# a Gemfile as specified at https://github.com/github/pages-gem#conventional + +# Basic Jekyll gitignores (synchronize to Jekyll.gitignore) +_site/ +.sass-cache/ +.jekyll-cache/ +.jekyll-metadata + +# Additional Ruby/bundler ignore for when you run: bundle install +/vendor + +# Specific ignore for GitHub Pages +# GitHub Pages will always use its own deployed version of pages-gem +# This means GitHub Pages will NOT use your Gemfile.lock and therefore it is +# counterproductive to check this file into the repository. +# Details at https://github.com/github/pages-gem/issues/768 +Gemfile.lock diff --git a/options/gitignore/Go b/options/gitignore/Go index 6f6f5e6adc..6f72f89261 100644 --- a/options/gitignore/Go +++ b/options/gitignore/Go @@ -20,3 +20,6 @@ # Go workspace file go.work go.work.sum + +# env file +.env diff --git a/options/gitignore/Objective-C b/options/gitignore/Objective-C index 7801c93000..9b8cd0706f 100644 --- a/options/gitignore/Objective-C +++ b/options/gitignore/Objective-C @@ -5,23 +5,6 @@ ## User settings xcuserdata/ -## compatibility with Xcode 8 and earlier (ignoring not required starting Xcode 9) -*.xcscmblueprint -*.xccheckout - -## compatibility with Xcode 3 and earlier (ignoring not required starting Xcode 4) -build/ -DerivedData/ -*.moved-aside -*.pbxuser -!default.pbxuser -*.mode1v3 -!default.mode1v3 -*.mode2v3 -!default.mode2v3 -*.perspectivev3 -!default.perspectivev3 - ## Obj-C/Swift specific *.hmap diff --git a/options/gitignore/Rust b/options/gitignore/Rust index 6985cf1bd0..d01bd1a990 100644 --- a/options/gitignore/Rust +++ b/options/gitignore/Rust @@ -12,3 +12,10 @@ Cargo.lock # MSVC Windows builds of rustc generate these, which store debugging information *.pdb + +# RustRover +# JetBrains specific template is maintained in a separate JetBrains.gitignore that can +# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore +# and can be added to the global gitignore or merged into this file. For a more nuclear +# option (not recommended) you can uncomment the following to ignore the entire idea folder. +#.idea/ \ No newline at end of file diff --git a/options/gitignore/Swift b/options/gitignore/Swift index 330d1674f3..52fe2f7102 100644 --- a/options/gitignore/Swift +++ b/options/gitignore/Swift @@ -5,23 +5,6 @@ ## User settings xcuserdata/ -## compatibility with Xcode 8 and earlier (ignoring not required starting Xcode 9) -*.xcscmblueprint -*.xccheckout - -## compatibility with Xcode 3 and earlier (ignoring not required starting Xcode 4) -build/ -DerivedData/ -*.moved-aside -*.pbxuser -!default.pbxuser -*.mode1v3 -!default.mode1v3 -*.mode2v3 -!default.mode2v3 -*.perspectivev3 -!default.perspectivev3 - ## Obj-C/Swift specific *.hmap @@ -66,10 +49,6 @@ playground.xcworkspace Carthage/Build/ -# Accio dependency management -Dependencies/ -.accio/ - # fastlane # # It is recommended to not store the screenshots in the git repo. @@ -81,10 +60,3 @@ fastlane/report.xml fastlane/Preview.html fastlane/screenshots/**/*.png fastlane/test_output - -# Code Injection -# -# After new code Injection tools there's a generated folder /iOSInjectionProject -# https://github.com/johnno1962/injectionforxcode - -iOSInjectionProject/ diff --git a/options/gitignore/TeX b/options/gitignore/TeX index e964244133..a1f5212090 100644 --- a/options/gitignore/TeX +++ b/options/gitignore/TeX @@ -39,6 +39,8 @@ *.synctex.gz *.synctex.gz(busy) *.pdfsync +*.rubbercache +rubber.cache ## Build tool directories for auxiliary files # latexrun @@ -138,6 +140,9 @@ acs-*.bib *.trc *.xref +# hypdoc +*.hd + # hyperref *.brf diff --git a/options/gitignore/Terraform b/options/gitignore/Terraform index 9b8a46e692..15073ca88b 100644 --- a/options/gitignore/Terraform +++ b/options/gitignore/Terraform @@ -23,6 +23,9 @@ override.tf.json *_override.tf *_override.tf.json +# Ignore transient lock info files created by terraform apply +.terraform.tfstate.lock.info + # Include override files you do wish to add to version control using negated pattern # !example_override.tf @@ -32,3 +35,6 @@ override.tf.json # Ignore CLI configuration files .terraformrc terraform.rc + +# Ignore hcl file +.terraform.lock.hcl diff --git a/options/gitignore/UiPath b/options/gitignore/UiPath new file mode 100644 index 0000000000..f0c2267b89 --- /dev/null +++ b/options/gitignore/UiPath @@ -0,0 +1,11 @@ +# gitignore template for RPA development using UiPath Studio +# website: https://www.uipath.com/product/studio +# +# Recommended: n/a + +# Ignore folders that could cause issues if accidentally tracked +**/.local/** +**/.settings/** +**/.objects/** +**/.tmh/** +**/*.log diff --git a/options/gitignore/UnrealEngine b/options/gitignore/UnrealEngine index 6582eaf9a1..6e0d95fb31 100644 --- a/options/gitignore/UnrealEngine +++ b/options/gitignore/UnrealEngine @@ -47,7 +47,7 @@ SourceArt/**/*.tga # Binary Files Binaries/* -Plugins/*/Binaries/* +Plugins/**/Binaries/* # Builds Build/* @@ -68,7 +68,7 @@ Saved/* # Compiled source files for the engine to use Intermediate/* -Plugins/*/Intermediate/* +Plugins/**/Intermediate/* # Cache files for the editor to use DerivedDataCache/* diff --git a/options/gitignore/Xcode b/options/gitignore/Xcode index f87d2f2e74..5073505e08 100644 --- a/options/gitignore/Xcode +++ b/options/gitignore/Xcode @@ -1,6 +1,2 @@ ## User settings xcuserdata/ - -## Xcode 8 and earlier -*.xcscmblueprint -*.xccheckout diff --git a/pyproject.toml b/pyproject.toml index fb92f611aa..cfcc44c4c3 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,8 +1,5 @@ [tool.poetry] -name = "forgejo" -version = "0.0.0" -description = "" -authors = [] +package-mode = false [tool.poetry.dependencies] python = "^3.10" diff --git a/release-notes/8.0.0/feat/4083.md b/release-notes/8.0.0/feat/4083.md new file mode 100644 index 0000000000..ab7501dd43 --- /dev/null +++ b/release-notes/8.0.0/feat/4083.md @@ -0,0 +1,3 @@ +- add [Reviewed-on and Reviewed-by variables](https://codeberg.org/forgejo/forgejo/commit/4ddd9af50fbfcfb2ebf629697a803b3bce56c4af) to the merge template +- [add the `[ui.csv].MAX_ROWS` setting](https://codeberg.org/forgejo/forgejo/commit/433b6c6910f8699dc41787ef8f5148b122b4677e) to avoid displaying a large number of lines (defaults to 2500) +- [add a setting to override or add headers of all outgoing emails](https://codeberg.org/forgejo/forgejo/commit/1d4bff4f65d5e4a3969871ef91d3612daf272b45), for instance `Reply-To` or `In-Reply-To` diff --git a/release-notes/8.0.0/fix/4083.md b/release-notes/8.0.0/fix/4083.md new file mode 100644 index 0000000000..fa4772f672 --- /dev/null +++ b/release-notes/8.0.0/fix/4083.md @@ -0,0 +1 @@ +- [NuGet Package fails `choco info pkgname` when `pkgname` is also a substring of another package Id](https://codeberg.org/forgejo/forgejo/commit/c6e04c3c9eddfa6c4bec541f681c8d300b157cdb) diff --git a/routers/api/packages/nuget/nuget.go b/routers/api/packages/nuget/nuget.go index 26b0ae226e..3633d0d007 100644 --- a/routers/api/packages/nuget/nuget.go +++ b/routers/api/packages/nuget/nuget.go @@ -96,20 +96,34 @@ func FeedCapabilityResource(ctx *context.Context) { xmlResponse(ctx, http.StatusOK, Metadata) } -var searchTermExtract = regexp.MustCompile(`'([^']+)'`) +var ( + searchTermExtract = regexp.MustCompile(`'([^']+)'`) + searchTermExact = regexp.MustCompile(`\s+eq\s+'`) +) -func getSearchTerm(ctx *context.Context) string { +func getSearchTerm(ctx *context.Context) packages_model.SearchValue { searchTerm := strings.Trim(ctx.FormTrim("searchTerm"), "'") - if searchTerm == "" { - // $filter contains a query like: - // (((Id ne null) and substringof('microsoft',tolower(Id))) - // We don't support these queries, just extract the search term. - match := searchTermExtract.FindStringSubmatch(ctx.FormTrim("$filter")) - if len(match) == 2 { - searchTerm = strings.TrimSpace(match[1]) + if searchTerm != "" { + return packages_model.SearchValue{ + Value: searchTerm, + ExactMatch: false, } } - return searchTerm + + // $filter contains a query like: + // (((Id ne null) and substringof('microsoft',tolower(Id))) + // https://www.odata.org/documentation/odata-version-2-0/uri-conventions/ section 4.5 + // We don't support these queries, just extract the search term. + filter := ctx.FormTrim("$filter") + match := searchTermExtract.FindStringSubmatch(filter) + if len(match) == 2 { + return packages_model.SearchValue{ + Value: strings.TrimSpace(match[1]), + ExactMatch: searchTermExact.MatchString(filter), + } + } + + return packages_model.SearchValue{} } // https://github.com/NuGet/NuGet.Client/blob/dev/src/NuGet.Core/NuGet.Protocol/LegacyFeed/V2FeedQueryBuilder.cs @@ -118,11 +132,9 @@ func SearchServiceV2(ctx *context.Context) { paginator := db.NewAbsoluteListOptions(skip, take) pvs, total, err := packages_model.SearchLatestVersions(ctx, &packages_model.PackageSearchOptions{ - OwnerID: ctx.Package.Owner.ID, - Type: packages_model.TypeNuGet, - Name: packages_model.SearchValue{ - Value: getSearchTerm(ctx), - }, + OwnerID: ctx.Package.Owner.ID, + Type: packages_model.TypeNuGet, + Name: getSearchTerm(ctx), IsInternal: optional.Some(false), Paginator: paginator, }) @@ -169,10 +181,8 @@ func SearchServiceV2(ctx *context.Context) { // http://docs.oasis-open.org/odata/odata/v4.0/errata03/os/complete/part2-url-conventions/odata-v4.0-errata03-os-part2-url-conventions-complete.html#_Toc453752351 func SearchServiceV2Count(ctx *context.Context) { count, err := nuget_model.CountPackages(ctx, &packages_model.PackageSearchOptions{ - OwnerID: ctx.Package.Owner.ID, - Name: packages_model.SearchValue{ - Value: getSearchTerm(ctx), - }, + OwnerID: ctx.Package.Owner.ID, + Name: getSearchTerm(ctx), IsInternal: optional.Some(false), }) if err != nil { diff --git a/routers/web/repo/issue_content_history.go b/routers/web/repo/issue_content_history.go index c817d6aa96..31d2de6d53 100644 --- a/routers/web/repo/issue_content_history.go +++ b/routers/web/repo/issue_content_history.go @@ -158,7 +158,7 @@ func GetContentHistoryDetail(ctx *context.Context) { // use chroma to render the diff html diffHTMLBuf := bytes.Buffer{} - diffHTMLBuf.WriteString("
")
+ diffHTMLBuf.WriteString("")
for _, it := range diff {
if it.Type == diffmatchpatch.DiffInsert {
diffHTMLBuf.WriteString("")
diff --git a/services/mailer/mailer.go b/services/mailer/mailer.go
index a9316cca76..0a723f974a 100644
--- a/services/mailer/mailer.go
+++ b/services/mailer/mailer.go
@@ -57,7 +57,7 @@ func (m *Message) ToMessage() *gomail.Message {
msg.SetHeader(header, m.Headers[header]...)
}
- if len(setting.MailService.SubjectPrefix) > 0 {
+ if setting.MailService.SubjectPrefix != "" {
msg.SetHeader("Subject", setting.MailService.SubjectPrefix+" "+m.Subject)
} else {
msg.SetHeader("Subject", m.Subject)
@@ -79,6 +79,14 @@ func (m *Message) ToMessage() *gomail.Message {
if len(msg.GetHeader("Message-ID")) == 0 {
msg.SetHeader("Message-ID", m.generateAutoMessageID())
}
+
+ for k, v := range setting.MailService.OverrideHeader {
+ if len(msg.GetHeader(k)) != 0 {
+ log.Debug("Mailer override header '%s' as per config", k)
+ }
+ msg.SetHeader(k, v...)
+ }
+
return msg
}
diff --git a/services/mailer/mailer_test.go b/services/mailer/mailer_test.go
index 253454e89c..b7b4c28a3c 100644
--- a/services/mailer/mailer_test.go
+++ b/services/mailer/mailer_test.go
@@ -4,22 +4,22 @@
package mailer
import (
+ "strings"
"testing"
"time"
repo_model "code.gitea.io/gitea/models/repo"
"code.gitea.io/gitea/modules/setting"
+ "code.gitea.io/gitea/modules/test"
"github.com/stretchr/testify/assert"
)
func TestGenerateMessageID(t *testing.T) {
- mailService := setting.Mailer{
+ defer test.MockVariableValue(&setting.MailService, &setting.Mailer{
From: "test@gitea.com",
- }
-
- setting.MailService = &mailService
- setting.Domain = "localhost"
+ })()
+ defer test.MockVariableValue(&setting.Domain, "localhost")()
date := time.Date(2000, 1, 2, 3, 4, 5, 6, time.UTC)
m := NewMessageFrom("", "display-name", "from-address", "subject", "body")
@@ -39,7 +39,7 @@ func TestGenerateMessageID(t *testing.T) {
}
func TestGenerateMessageIDForRelease(t *testing.T) {
- setting.Domain = "localhost"
+ defer test.MockVariableValue(&setting.Domain, "localhost")()
rel := repo_model.Release{
ID: 42,
@@ -51,3 +51,77 @@ func TestGenerateMessageIDForRelease(t *testing.T) {
m := createMessageIDForRelease(&rel)
assert.Equal(t, "", m)
}
+
+func TestToMessage(t *testing.T) {
+ defer test.MockVariableValue(&setting.MailService, &setting.Mailer{
+ From: "test@gitea.com",
+ })()
+ defer test.MockVariableValue(&setting.Domain, "localhost")()
+
+ m1 := Message{
+ Info: "info",
+ FromAddress: "test@gitea.com",
+ FromDisplayName: "Test Gitea",
+ To: "a@b.com",
+ Subject: "Issue X Closed",
+ Body: "Some Issue got closed by Y-Man",
+ }
+
+ buf := &strings.Builder{}
+ _, err := m1.ToMessage().WriteTo(buf)
+ assert.NoError(t, err)
+ header, _ := extractMailHeaderAndContent(t, buf.String())
+ assert.EqualValues(t, map[string]string{
+ "Content-Type": "multipart/alternative;",
+ "Date": "Mon, 01 Jan 0001 00:00:00 +0000",
+ "From": "\"Test Gitea\" ",
+ "Message-ID": "",
+ "Mime-Version": "1.0",
+ "Subject": "Issue X Closed",
+ "To": "a@b.com",
+ "X-Auto-Response-Suppress": "All",
+ }, header)
+
+ setting.MailService.OverrideHeader = map[string][]string{
+ "Message-ID": {""}, // delete message id
+ "Auto-Submitted": {"auto-generated"}, // suppress auto replay
+ }
+
+ buf = &strings.Builder{}
+ _, err = m1.ToMessage().WriteTo(buf)
+ assert.NoError(t, err)
+ header, _ = extractMailHeaderAndContent(t, buf.String())
+ assert.EqualValues(t, map[string]string{
+ "Content-Type": "multipart/alternative;",
+ "Date": "Mon, 01 Jan 0001 00:00:00 +0000",
+ "From": "\"Test Gitea\" ",
+ "Message-ID": "",
+ "Mime-Version": "1.0",
+ "Subject": "Issue X Closed",
+ "To": "a@b.com",
+ "X-Auto-Response-Suppress": "All",
+ "Auto-Submitted": "auto-generated",
+ }, header)
+}
+
+func extractMailHeaderAndContent(t *testing.T, mail string) (map[string]string, string) {
+ header := make(map[string]string)
+
+ parts := strings.SplitN(mail, "boundary=", 2)
+ if !assert.Len(t, parts, 2) {
+ return nil, ""
+ }
+ content := strings.TrimSpace("boundary=" + parts[1])
+
+ hParts := strings.Split(parts[0], "\n")
+
+ for _, hPart := range hParts {
+ parts := strings.SplitN(hPart, ":", 2)
+ hk := strings.TrimSpace(parts[0])
+ if hk != "" {
+ header[hk] = strings.TrimSpace(parts[1])
+ }
+ }
+
+ return header, content
+}
diff --git a/services/migrations/migrate.go b/services/migrations/migrate.go
index 367818c0e7..de90c5e98f 100644
--- a/services/migrations/migrate.go
+++ b/services/migrations/migrate.go
@@ -183,7 +183,7 @@ func newDownloader(ctx context.Context, ownerName string, opts base.MigrateOptio
// migrateRepository will download information and then upload it to Uploader, this is a simple
// process for small repository. For a big repository, save all the data to disk
// before upload is better
-func migrateRepository(ctx context.Context, doer *user_model.User, downloader base.Downloader, uploader base.Uploader, opts base.MigrateOptions, messenger base.Messenger) error {
+func migrateRepository(_ context.Context, doer *user_model.User, downloader base.Downloader, uploader base.Uploader, opts base.MigrateOptions, messenger base.Messenger) error {
if messenger == nil {
messenger = base.NilMessenger
}
diff --git a/services/pull/merge.go b/services/pull/merge.go
index 525146833e..0d37daa6ed 100644
--- a/services/pull/merge.go
+++ b/services/pull/merge.go
@@ -46,6 +46,9 @@ func getMergeMessage(ctx context.Context, baseGitRepo *git.Repository, pr *issue
if err := pr.Issue.LoadPoster(ctx); err != nil {
return "", "", err
}
+ if err := pr.Issue.LoadRepo(ctx); err != nil {
+ return "", "", err
+ }
isExternalTracker := pr.BaseRepo.UnitEnabled(ctx, unit.TypeExternalTracker)
issueReference := "#"
@@ -53,6 +56,9 @@ func getMergeMessage(ctx context.Context, baseGitRepo *git.Repository, pr *issue
issueReference = "!"
}
+ reviewedOn := fmt.Sprintf("Reviewed-on: %s/%s", setting.AppURL, pr.Issue.Link())
+ reviewedBy := pr.GetApprovers(ctx)
+
if mergeStyle != "" {
commit, err := baseGitRepo.GetBranchCommit(pr.BaseRepo.DefaultBranch)
if err != nil {
@@ -83,6 +89,8 @@ func getMergeMessage(ctx context.Context, baseGitRepo *git.Repository, pr *issue
"PullRequestPosterName": pr.Issue.Poster.Name,
"PullRequestIndex": strconv.FormatInt(pr.Index, 10),
"PullRequestReference": fmt.Sprintf("%s%d", issueReference, pr.Index),
+ "ReviewedOn": reviewedOn,
+ "ReviewedBy": reviewedBy,
}
if pr.HeadRepo != nil {
vars["HeadRepoOwnerName"] = pr.HeadRepo.OwnerName
@@ -122,20 +130,22 @@ func getMergeMessage(ctx context.Context, baseGitRepo *git.Repository, pr *issue
return "", "", nil
}
+ body = fmt.Sprintf("%s\n%s", reviewedOn, reviewedBy)
+
// Squash merge has a different from other styles.
if mergeStyle == repo_model.MergeStyleSquash {
- return fmt.Sprintf("%s (%s%d)", pr.Issue.Title, issueReference, pr.Issue.Index), "", nil
+ return fmt.Sprintf("%s (%s%d)", pr.Issue.Title, issueReference, pr.Issue.Index), body, nil
}
if pr.BaseRepoID == pr.HeadRepoID {
- return fmt.Sprintf("Merge pull request '%s' (%s%d) from %s into %s", pr.Issue.Title, issueReference, pr.Issue.Index, pr.HeadBranch, pr.BaseBranch), "", nil
+ return fmt.Sprintf("Merge pull request '%s' (%s%d) from %s into %s", pr.Issue.Title, issueReference, pr.Issue.Index, pr.HeadBranch, pr.BaseBranch), body, nil
}
if pr.HeadRepo == nil {
- return fmt.Sprintf("Merge pull request '%s' (%s%d) from :%s into %s", pr.Issue.Title, issueReference, pr.Issue.Index, pr.HeadBranch, pr.BaseBranch), "", nil
+ return fmt.Sprintf("Merge pull request '%s' (%s%d) from :%s into %s", pr.Issue.Title, issueReference, pr.Issue.Index, pr.HeadBranch, pr.BaseBranch), body, nil
}
- return fmt.Sprintf("Merge pull request '%s' (%s%d) from %s:%s into %s", pr.Issue.Title, issueReference, pr.Issue.Index, pr.HeadRepo.FullName(), pr.HeadBranch, pr.BaseBranch), "", nil
+ return fmt.Sprintf("Merge pull request '%s' (%s%d) from %s:%s into %s", pr.Issue.Title, issueReference, pr.Issue.Index, pr.HeadRepo.FullName(), pr.HeadBranch, pr.BaseBranch), body, nil
}
func expandDefaultMergeMessage(template string, vars map[string]string) (message, body string) {
diff --git a/services/repository/transfer.go b/services/repository/transfer.go
index ca6ea6b632..467c85ef6f 100644
--- a/services/repository/transfer.go
+++ b/services/repository/transfer.go
@@ -285,7 +285,7 @@ func transferOwnership(ctx context.Context, doer *user_model.User, newOwnerName
}
// changeRepositoryName changes all corresponding setting from old repository name to new one.
-func changeRepositoryName(ctx context.Context, doer *user_model.User, repo *repo_model.Repository, newRepoName string) (err error) {
+func changeRepositoryName(ctx context.Context, repo *repo_model.Repository, newRepoName string) (err error) {
oldRepoName := repo.Name
newRepoName = strings.ToLower(newRepoName)
if err = repo_model.IsUsableRepoName(newRepoName); err != nil {
@@ -347,7 +347,7 @@ func ChangeRepositoryName(ctx context.Context, doer *user_model.User, repo *repo
// local copy's origin accordingly.
repoWorkingPool.CheckIn(fmt.Sprint(repo.ID))
- if err := changeRepositoryName(ctx, doer, repo, newRepoName); err != nil {
+ if err := changeRepositoryName(ctx, repo, newRepoName); err != nil {
repoWorkingPool.CheckOut(fmt.Sprint(repo.ID))
return err
}
diff --git a/tailwind.config.js b/tailwind.config.js
index 94dfdbced4..8f3e8c8251 100644
--- a/tailwind.config.js
+++ b/tailwind.config.js
@@ -1,6 +1,7 @@
import {readFileSync} from 'node:fs';
import {env} from 'node:process';
import {parse} from 'postcss';
+import plugin from 'tailwindcss/plugin.js';
const isProduction = env.NODE_ENV !== 'development';
@@ -98,4 +99,26 @@ export default {
})),
},
},
+ plugins: [
+ plugin(({addUtilities}) => {
+ addUtilities({
+ // tw-hidden must win all other "display: xxx !important" classes to get the chance to "hide" an element.
+ // do not use:
+ // * "[hidden]" attribute: it's too weak, can not be applied to an element with "display: flex"
+ // * ".hidden" class: it has been polluted by Fomantic UI in many cases
+ // * inline style="display: none": it's difficult to tweak
+ // * jQuery's show/hide/toggle: it can not show/hide elements with "display: xxx !important"
+ // only use:
+ // * this ".tw-hidden" class
+ // * showElem/hideElem/toggleElem functions in "utils/dom.js"
+ '.hidden.hidden': {
+ 'display': 'none',
+ },
+ // proposed class from https://github.com/tailwindlabs/tailwindcss/pull/12128
+ '.break-anywhere': {
+ 'overflow-wrap': 'anywhere',
+ },
+ });
+ }),
+ ],
};
diff --git a/templates/admin/packages/list.tmpl b/templates/admin/packages/list.tmpl
index d111c57378..4ff49b8c43 100644
--- a/templates/admin/packages/list.tmpl
+++ b/templates/admin/packages/list.tmpl
@@ -5,7 +5,7 @@
{{ctx.Locale.Tr "admin.packages.total_size" (ctx.Locale.TrSize .TotalBlobSize)}},
{{ctx.Locale.Tr "admin.packages.unreferenced_size" (ctx.Locale.TrSize .TotalUnreferencedBlobSize)}})
-
diff --git a/templates/devtest/fetch-action.tmpl b/templates/devtest/fetch-action.tmpl
index 7b0bbba554..be15a5389f 100644
--- a/templates/devtest/fetch-action.tmpl
+++ b/templates/devtest/fetch-action.tmpl
@@ -25,7 +25,7 @@
-
diff --git a/templates/projects/view.tmpl b/templates/projects/view.tmpl
index 47f214a44e..df52dbbf9c 100644
--- a/templates/projects/view.tmpl
+++ b/templates/projects/view.tmpl
@@ -66,7 +66,7 @@
{{range .Columns}}
-
+
diff --git a/templates/repo/code/recently_pushed_new_branches.tmpl b/templates/repo/code/recently_pushed_new_branches.tmpl
index f6f595a00f..d996acc5b2 100644
--- a/templates/repo/code/recently_pushed_new_branches.tmpl
+++ b/templates/repo/code/recently_pushed_new_branches.tmpl
@@ -1,6 +1,6 @@
{{range .RecentlyPushedNewBranches}}
-