From 7866a6e0e25cf87b298e046bb38f4d68c35529a7 Mon Sep 17 00:00:00 2001 From: KN4CK3R Date: Fri, 28 Jul 2023 09:54:31 +0200 Subject: [PATCH 001/200] Prevent primary key update on migration (#26192) Fixes #25918 The migration fails on MSSQL because xorm tries to update the primary key column. xorm prevents this if the column is marked as auto increment: https://gitea.com/xorm/xorm/src/commit/c622cdaf893fbfe3f40a6b79f6bc17ee10f53865/internal/statements/update.go#L38-L40 I think it would be better if xorm would check for primary key columns here because updating such columns is bad practice. It looks like if that auto increment check should do the same. fyi @lunny --- models/migrations/v1_20/v250.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/models/migrations/v1_20/v250.go b/models/migrations/v1_20/v250.go index e05646e5c6..a09957b291 100644 --- a/models/migrations/v1_20/v250.go +++ b/models/migrations/v1_20/v250.go @@ -20,7 +20,7 @@ func ChangeContainerMetadataMultiArch(x *xorm.Engine) error { } type PackageVersion struct { - ID int64 `xorm:"pk"` + ID int64 `xorm:"pk autoincr"` MetadataJSON string `xorm:"metadata_json"` } From d88fed0db12813b36c065f9602a793f3f5884dab Mon Sep 17 00:00:00 2001 From: wxiaoguang Date: Fri, 28 Jul 2023 23:05:24 +0800 Subject: [PATCH 002/200] Hide branch/tag icon if branches/tags are empty (#26204) The branch/tag icons aren't hidden correctly if there is no branch/tag. This PR fixes it. --- web_src/js/features/repo-diff-commit.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/web_src/js/features/repo-diff-commit.js b/web_src/js/features/repo-diff-commit.js index 968f318e63..bc591fa37d 100644 --- a/web_src/js/features/repo-diff-commit.js +++ b/web_src/js/features/repo-diff-commit.js @@ -16,7 +16,7 @@ async function loadBranchesAndTags(area, loadingButton) { function addTags(area, tags) { const tagArea = area.querySelector('.tag-area'); - toggleElem(tagArea, tags.length > 0); + toggleElem(tagArea.parentElement, tags.length > 0); for (const tag of tags) { addLink(tagArea, tag.web_link, tag.name); } @@ -25,7 +25,7 @@ function addTags(area, tags) { function addBranches(area, branches, defaultBranch) { const defaultBranchTooltip = area.getAttribute('data-text-default-branch-tooltip'); const branchArea = area.querySelector('.branch-area'); - toggleElem(branchArea, branches.length > 0); + toggleElem(branchArea.parentElement, branches.length > 0); for (const branch of branches) { const tooltip = defaultBranch === branch.name ? defaultBranchTooltip : null; addLink(branchArea, branch.web_link, branch.name, tooltip); From ce27de4d486884745bd944c56fc0365b2d588e54 Mon Sep 17 00:00:00 2001 From: Lunny Xiao Date: Sat, 29 Jul 2023 00:15:39 +0800 Subject: [PATCH 003/200] Fix allowed user types setting problem (#26200) Fix #25951 --- modules/setting/service.go | 30 +++++++++--- modules/setting/service_test.go | 86 +++++++++++++++++++++++++++++++++ 2 files changed, 110 insertions(+), 6 deletions(-) diff --git a/modules/setting/service.go b/modules/setting/service.go index 03225f566b..597fecee1d 100644 --- a/modules/setting/service.go +++ b/modules/setting/service.go @@ -188,15 +188,33 @@ func loadServiceFrom(rootCfg ConfigProvider) { Service.EnableUserHeatmap = sec.Key("ENABLE_USER_HEATMAP").MustBool(true) Service.AutoWatchNewRepos = sec.Key("AUTO_WATCH_NEW_REPOS").MustBool(true) Service.AutoWatchOnChanges = sec.Key("AUTO_WATCH_ON_CHANGES").MustBool(false) - Service.DefaultUserVisibility = sec.Key("DEFAULT_USER_VISIBILITY").In("public", structs.ExtractKeysFromMapString(structs.VisibilityModes)) - Service.DefaultUserVisibilityMode = structs.VisibilityModes[Service.DefaultUserVisibility] - Service.AllowedUserVisibilityModes = sec.Key("ALLOWED_USER_VISIBILITY_MODES").Strings(",") - if len(Service.AllowedUserVisibilityModes) != 0 { + modes := sec.Key("ALLOWED_USER_VISIBILITY_MODES").Strings(",") + if len(modes) != 0 { + Service.AllowedUserVisibilityModes = []string{} Service.AllowedUserVisibilityModesSlice = []bool{false, false, false} - for _, sMode := range Service.AllowedUserVisibilityModes { - Service.AllowedUserVisibilityModesSlice[structs.VisibilityModes[sMode]] = true + for _, sMode := range modes { + if tp, ok := structs.VisibilityModes[sMode]; ok { // remove unsupported modes + Service.AllowedUserVisibilityModes = append(Service.AllowedUserVisibilityModes, sMode) + Service.AllowedUserVisibilityModesSlice[tp] = true + } else { + log.Warn("ALLOWED_USER_VISIBILITY_MODES %s is unsupported", sMode) + } } } + + if len(Service.AllowedUserVisibilityModes) == 0 { + Service.AllowedUserVisibilityModes = []string{"public", "limited", "private"} + Service.AllowedUserVisibilityModesSlice = []bool{true, true, true} + } + + Service.DefaultUserVisibility = sec.Key("DEFAULT_USER_VISIBILITY").String() + if Service.DefaultUserVisibility == "" { + Service.DefaultUserVisibility = Service.AllowedUserVisibilityModes[0] + } else if !Service.AllowedUserVisibilityModesSlice[structs.VisibilityModes[Service.DefaultUserVisibility]] { + log.Warn("DEFAULT_USER_VISIBILITY %s is wrong or not in ALLOWED_USER_VISIBILITY_MODES, using first allowed", Service.DefaultUserVisibility) + Service.DefaultUserVisibility = Service.AllowedUserVisibilityModes[0] + } + Service.DefaultUserVisibilityMode = structs.VisibilityModes[Service.DefaultUserVisibility] Service.DefaultOrgVisibility = sec.Key("DEFAULT_ORG_VISIBILITY").In("public", structs.ExtractKeysFromMapString(structs.VisibilityModes)) Service.DefaultOrgVisibilityMode = structs.VisibilityModes[Service.DefaultOrgVisibility] Service.DefaultOrgMemberVisible = sec.Key("DEFAULT_ORG_MEMBER_VISIBLE").MustBool() diff --git a/modules/setting/service_test.go b/modules/setting/service_test.go index 656e759f42..1647bcec16 100644 --- a/modules/setting/service_test.go +++ b/modules/setting/service_test.go @@ -6,6 +6,8 @@ package setting import ( "testing" + "code.gitea.io/gitea/modules/structs" + "github.com/gobwas/glob" "github.com/stretchr/testify/assert" ) @@ -44,3 +46,87 @@ EMAIL_DOMAIN_BLOCKLIST = d3, *.b assert.True(t, match(Service.EmailDomainBlockList, "foo.b")) assert.False(t, match(Service.EmailDomainBlockList, "d1")) } + +func TestLoadServiceVisibilityModes(t *testing.T) { + oldService := Service + defer func() { + Service = oldService + }() + + kases := map[string]func(){ + ` +[service] +DEFAULT_USER_VISIBILITY = public +ALLOWED_USER_VISIBILITY_MODES = public,limited,private +`: func() { + assert.Equal(t, "public", Service.DefaultUserVisibility) + assert.Equal(t, structs.VisibleTypePublic, Service.DefaultUserVisibilityMode) + assert.Equal(t, []string{"public", "limited", "private"}, Service.AllowedUserVisibilityModes) + }, + ` + [service] + DEFAULT_USER_VISIBILITY = public + `: func() { + assert.Equal(t, "public", Service.DefaultUserVisibility) + assert.Equal(t, structs.VisibleTypePublic, Service.DefaultUserVisibilityMode) + assert.Equal(t, []string{"public", "limited", "private"}, Service.AllowedUserVisibilityModes) + }, + ` + [service] + DEFAULT_USER_VISIBILITY = limited + `: func() { + assert.Equal(t, "limited", Service.DefaultUserVisibility) + assert.Equal(t, structs.VisibleTypeLimited, Service.DefaultUserVisibilityMode) + assert.Equal(t, []string{"public", "limited", "private"}, Service.AllowedUserVisibilityModes) + }, + ` +[service] +ALLOWED_USER_VISIBILITY_MODES = public,limited,private +`: func() { + assert.Equal(t, "public", Service.DefaultUserVisibility) + assert.Equal(t, structs.VisibleTypePublic, Service.DefaultUserVisibilityMode) + assert.Equal(t, []string{"public", "limited", "private"}, Service.AllowedUserVisibilityModes) + }, + ` +[service] +DEFAULT_USER_VISIBILITY = public +ALLOWED_USER_VISIBILITY_MODES = limited,private +`: func() { + assert.Equal(t, "limited", Service.DefaultUserVisibility) + assert.Equal(t, structs.VisibleTypeLimited, Service.DefaultUserVisibilityMode) + assert.Equal(t, []string{"limited", "private"}, Service.AllowedUserVisibilityModes) + }, + ` +[service] +DEFAULT_USER_VISIBILITY = my_type +ALLOWED_USER_VISIBILITY_MODES = limited,private +`: func() { + assert.Equal(t, "limited", Service.DefaultUserVisibility) + assert.Equal(t, structs.VisibleTypeLimited, Service.DefaultUserVisibilityMode) + assert.Equal(t, []string{"limited", "private"}, Service.AllowedUserVisibilityModes) + }, + ` +[service] +DEFAULT_USER_VISIBILITY = public +ALLOWED_USER_VISIBILITY_MODES = public, limit, privated +`: func() { + assert.Equal(t, "public", Service.DefaultUserVisibility) + assert.Equal(t, structs.VisibleTypePublic, Service.DefaultUserVisibilityMode) + assert.Equal(t, []string{"public"}, Service.AllowedUserVisibilityModes) + }, + } + + for kase, fun := range kases { + t.Run(kase, func(t *testing.T) { + cfg, err := NewConfigProviderFromData(kase) + assert.NoError(t, err) + loadServiceFrom(cfg) + fun() + // reset + Service.AllowedUserVisibilityModesSlice = []bool{true, true, true} + Service.AllowedUserVisibilityModes = []string{} + Service.DefaultUserVisibility = "" + Service.DefaultUserVisibilityMode = structs.VisibleTypePublic + }) + } +} From 1d8d90fd3727ffdf0500c8dd474b85e0c285d064 Mon Sep 17 00:00:00 2001 From: puni9869 <80308335+puni9869@users.noreply.github.com> Date: Fri, 28 Jul 2023 22:42:44 +0530 Subject: [PATCH 004/200] Fixing the align of commit stats in commit_page template. (#26161) Fixing the align center to row and space around for commit_page template. --- templates/repo/diff/box.tmpl | 4 ++-- web_src/css/repo.css | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/templates/repo/diff/box.tmpl b/templates/repo/diff/box.tmpl index 1bc79ad2ab..72e6731254 100644 --- a/templates/repo/diff/box.tmpl +++ b/templates/repo/diff/box.tmpl @@ -1,5 +1,5 @@
-
+
{{if not .DiffNotAvailable}}
{{if not .DiffNotAvailable}} + {{if and .IsShowingOnlySingleCommit .PageIsPullFiles}} +
+
{{.locale.Tr "repo.pulls.showing_only_single_commit" (ShortSha .BeforeCommitID)}} - {{.locale.Tr "repo.pulls.show_all_commits"}}
+
+ {{else if and (not .IsShowingAllCommits) .PageIsPullFiles}} +
+
{{.locale.Tr "repo.pulls.showing_specified_commit_range" (ShortSha .BeforeCommitID) (ShortSha .AfterCommitID)}} - {{.locale.Tr "repo.pulls.show_all_commits"}}
+
+ {{end}} + diff --git a/web_src/js/features/repo-diff-commitselect.js b/web_src/js/features/repo-diff-commitselect.js new file mode 100644 index 0000000000..ebac64e855 --- /dev/null +++ b/web_src/js/features/repo-diff-commitselect.js @@ -0,0 +1,10 @@ +import {createApp} from 'vue'; +import DiffCommitSelector from '../components/DiffCommitSelector.vue'; + +export function initDiffCommitSelect() { + const el = document.getElementById('diff-commit-select'); + if (!el) return; + + const commitSelect = createApp(DiffCommitSelector); + commitSelect.mount(el); +} diff --git a/web_src/js/features/repo-diff.js b/web_src/js/features/repo-diff.js index f4bb724fe5..b79ca0f5b1 100644 --- a/web_src/js/features/repo-diff.js +++ b/web_src/js/features/repo-diff.js @@ -2,6 +2,7 @@ import $ from 'jquery'; import {initCompReactionSelector} from './comp/ReactionSelector.js'; import {initRepoIssueContentHistory} from './repo-issue-content.js'; import {initDiffFileTree} from './repo-diff-filetree.js'; +import {initDiffCommitSelect} from './repo-diff-commitselect.js'; import {validateTextareaNonEmpty} from './comp/ComboMarkdownEditor.js'; import {initViewedCheckboxListenerFor, countAndUpdateViewedFiles, initExpandAndCollapseFilesButton} from './pull-view-file.js'; import {initImageDiff} from './imagediff.js'; @@ -188,6 +189,7 @@ export function initRepoDiffView() { const diffFileList = $('#diff-file-list'); if (diffFileList.length === 0) return; initDiffFileTree(); + initDiffCommitSelect(); initRepoDiffShowMore(); initRepoDiffReviewButton(); initRepoDiffFileViewToggle(); diff --git a/web_src/js/svg.js b/web_src/js/svg.js index 2ef839aa21..46372e7d62 100644 --- a/web_src/js/svg.js +++ b/web_src/js/svg.js @@ -29,6 +29,7 @@ import octiconFileDirectoryFill from '../../public/assets/img/svg/octicon-file-d import octiconFilter from '../../public/assets/img/svg/octicon-filter.svg'; import octiconGear from '../../public/assets/img/svg/octicon-gear.svg'; import octiconGitBranch from '../../public/assets/img/svg/octicon-git-branch.svg'; +import octiconGitCommit from '../../public/assets/img/svg/octicon-git-commit.svg'; import octiconGitMerge from '../../public/assets/img/svg/octicon-git-merge.svg'; import octiconGitPullRequest from '../../public/assets/img/svg/octicon-git-pull-request.svg'; import octiconHeading from '../../public/assets/img/svg/octicon-heading.svg'; @@ -99,6 +100,7 @@ const svgs = { 'octicon-filter': octiconFilter, 'octicon-gear': octiconGear, 'octicon-git-branch': octiconGitBranch, + 'octicon-git-commit': octiconGitCommit, 'octicon-git-merge': octiconGitMerge, 'octicon-git-pull-request': octiconGitPullRequest, 'octicon-heading': octiconHeading, From e01824f2b8a9749759c300588617d07d98d4f2e4 Mon Sep 17 00:00:00 2001 From: delvh Date: Sat, 29 Jul 2023 09:07:03 +0200 Subject: [PATCH 007/200] Add changelog for 1.20.2 (#26208) Co-authored-by: techknowlogick Co-authored-by: wxiaoguang --- CHANGELOG.md | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index c08834645c..c6699a6bfa 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,34 @@ This changelog goes through all the changes that have been made in each release without substantial changes to our git log; to see the highlights of what has been added to each release, please refer to the [blog](https://blog.gitea.io). +## [1.20.2](https://github.com/go-gitea/gitea/releases/tag/1.20.2) - 2023-07-29 + +* ENHANCEMENTS + * Calculate MAX_WORKERS default value by CPU number (#26177) (#26183) + * Display deprecated warning in admin panel pages as well as in the log file (#26094) (#26154) +* BUGFIXES + * Fix allowed user types setting problem (#26200) (#26206) + * Fix handling of plenty Nuget package versions (#26075) (#26173) + * Fix UI regression of asciinema player (#26159) (#26162) + * Fix LFS object list style (#26133) (#26147) + * Fix allowed user types setting problem (#26200) (#26206) + * Prevent primary key update on migration (#26192) (#26199) + * Fix bug when pushing to a pull request which enabled dismiss approval automatically (#25882) (#26158) + * Fix bugs in LFS meta garbage collection (#26122) (#26157) + * Update xorm version (#26128) (#26150) + * Remove "misc" scope check from public API endpoints (#26134) (#26149) + * Fix CLI allowing creation of access tokens with existing name (#26071) (#26144) + * Fix incorrect router logger (#26137) (#26143) + * Improve commit graph alignment and truncating (#26112) (#26127) + * Avoid writing config file if not installed (#26107) (#26113) + * Fix escape problems in the branch selector (#25875) (#26103) + * Fix handling of Debian files with trailing slash (#26087) (#26098) + * Fix Missing 404 swagger response docs for /admin/users/{username} (#26086) (#26089) + * Use stderr as fallback if the log file can't be opened (#26074) (#26083) + * Increase table cell horizontal padding (#26140) (#26142) + * Fix wrong workflow status when rerun a job in an already finished workflow (#26119) (#26124) + * Fix duplicated url prefix on issue context menu (#26066) (#26067) + ## [1.20.1](https://github.com/go-gitea/gitea/releases/tag/1.20.1) - 2023-07-22 * SECURITY From 1c89f15f42411e2271d809e0d4c311cc145a4d75 Mon Sep 17 00:00:00 2001 From: "Panagiotis \"Ivory\" Vasilopoulos" Date: Sat, 29 Jul 2023 11:34:49 +0000 Subject: [PATCH 008/200] Use calendar icon for `Joined on...` in profiles (#26215) --- templates/explore/organizations.tmpl | 2 +- templates/explore/users.tmpl | 2 +- templates/repo/user_cards.tmpl | 2 +- templates/shared/user/profile_big_avatar.tmpl | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/templates/explore/organizations.tmpl b/templates/explore/organizations.tmpl index a20dd755ea..ecf7f21bdd 100644 --- a/templates/explore/organizations.tmpl +++ b/templates/explore/organizations.tmpl @@ -23,7 +23,7 @@ {{svg "octicon-link"}} {{.Website}} {{end}} - {{svg "octicon-clock"}} {{$.locale.Tr "user.joined_on" (DateTime "short" .CreatedUnix) | Safe}} + {{svg "octicon-calendar"}} {{$.locale.Tr "user.joined_on" (DateTime "short" .CreatedUnix) | Safe}}
diff --git a/templates/explore/users.tmpl b/templates/explore/users.tmpl index 1f3b944f5e..e3318479bb 100644 --- a/templates/explore/users.tmpl +++ b/templates/explore/users.tmpl @@ -18,7 +18,7 @@ {{svg "octicon-mail"}} {{.Email}} {{end}} - {{svg "octicon-clock"}} {{$.locale.Tr "user.joined_on" (DateTime "short" .CreatedUnix) | Safe}} + {{svg "octicon-calendar"}} {{$.locale.Tr "user.joined_on" (DateTime "short" .CreatedUnix) | Safe}} diff --git a/templates/repo/user_cards.tmpl b/templates/repo/user_cards.tmpl index e956f65e9f..29864462e6 100644 --- a/templates/repo/user_cards.tmpl +++ b/templates/repo/user_cards.tmpl @@ -18,7 +18,7 @@ {{else if .Location}} {{svg "octicon-location"}} {{.Location}} {{else}} - {{svg "octicon-clock"}} {{$.locale.Tr "user.joined_on" (DateTime "short" .CreatedUnix) | Safe}} + {{svg "octicon-calendar"}} {{$.locale.Tr "user.joined_on" (DateTime "short" .CreatedUnix) | Safe}} {{end}} diff --git a/templates/shared/user/profile_big_avatar.tmpl b/templates/shared/user/profile_big_avatar.tmpl index 5a1e43b88e..62b317cdd4 100644 --- a/templates/shared/user/profile_big_avatar.tmpl +++ b/templates/shared/user/profile_big_avatar.tmpl @@ -69,7 +69,7 @@ {{end}} {{end}} -
  • {{svg "octicon-clock"}} {{.locale.Tr "user.joined_on" (DateTime "short" .ContextUser.CreatedUnix) | Safe}}
  • +
  • {{svg "octicon-calendar"}} {{.locale.Tr "user.joined_on" (DateTime "short" .ContextUser.CreatedUnix) | Safe}}
  • {{if and .Orgs .HasOrgsVisible}}
    • From 05d0b7ca91893b749f3e70e828f9777690ecf5f1 Mon Sep 17 00:00:00 2001 From: Kerwin Bryant Date: Sat, 29 Jul 2023 21:34:22 +0800 Subject: [PATCH 009/200] Fixed incorrect locale references (#26218) Fixed two incorrect headers for setting the page navigation bar: * User settings page, should not use the title "`org.settings`" * Repo settings page, should not use the title "`org.settings`" --- templates/repo/settings/navbar.tmpl | 2 +- templates/user/settings/navbar.tmpl | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/templates/repo/settings/navbar.tmpl b/templates/repo/settings/navbar.tmpl index 5426a1b1fa..390cc5022d 100644 --- a/templates/repo/settings/navbar.tmpl +++ b/templates/repo/settings/navbar.tmpl @@ -1,6 +1,6 @@
    -
    - {{$.locale.Tr "settings.added_on" (DateTime "short" .CreatedUnix) | Safe}} — {{svg "octicon-info"}} {{if .HasUsed}}{{$.locale.Tr "settings.last_used"}} {{DateTime "short" .UpdatedUnix}}{{else}}{{$.locale.Tr "settings.no_activity"}}{{end}} +
    + {{$.locale.Tr "settings.added_on" (DateTime "short" .CreatedUnix) | Safe}} — {{svg "octicon-info"}} {{if .HasUsed}}{{$.locale.Tr "settings.last_used"}} {{DateTime "short" .UpdatedUnix}}{{else}}{{$.locale.Tr "settings.no_activity"}}{{end}}
    +
    + +
    {{end}} diff --git a/templates/user/settings/applications_oauth2_list.tmpl b/templates/user/settings/applications_oauth2_list.tmpl index 3ffe317512..be6569c03c 100644 --- a/templates/user/settings/applications_oauth2_list.tmpl +++ b/templates/user/settings/applications_oauth2_list.tmpl @@ -1,24 +1,31 @@
    -
    -
    +
    +
    {{.locale.Tr "settings.oauth2_application_create_description"}}
    - {{range $app := .Applications}} -
    - diff --git a/templates/user/settings/grants_oauth2.tmpl b/templates/user/settings/grants_oauth2.tmpl index b769020c62..dbe7d0409f 100644 --- a/templates/user/settings/grants_oauth2.tmpl +++ b/templates/user/settings/grants_oauth2.tmpl @@ -2,27 +2,27 @@ {{.locale.Tr "settings.authorized_oauth2_applications"}}
    -
    -
    +
    +
    {{.locale.Tr "settings.authorized_oauth2_applications_description"}}
    - {{range $grant := .Grants}} -
    -
    + {{range .Grants}} +
    +
    + {{svg "octicon-key" 32}} +
    +
    +
    {{.Application.Name}}
    +
    + {{$.locale.Tr "settings.added_on" (DateTime "short" .CreatedUnix) | Safe}} +
    +
    +
    -
    - {{svg "octicon-key"}} -
    -
    - {{$grant.Application.Name}} -
    - {{$.locale.Tr "settings.added_on" (DateTime "short" $grant.CreatedUnix) | Safe}} -
    -
    {{end}}
    diff --git a/templates/user/settings/keys_gpg.tmpl b/templates/user/settings/keys_gpg.tmpl index ecbcf265ff..5ab96eb63a 100644 --- a/templates/user/settings/keys_gpg.tmpl +++ b/templates/user/settings/keys_gpg.tmpl @@ -39,13 +39,33 @@
    -
    -
    +
    +
    {{.locale.Tr "settings.gpg_desc"}}
    {{range .GPGKeys}} -
    -
    +
    +
    + {{svg "octicon-key" 32}} +
    +
    + {{if .Verified}} + {{svg "octicon-verified"}} {{$.locale.Tr "settings.gpg_key_verified"}} + {{end}} + {{if gt (len .Emails) 0}} + {{svg "octicon-mail"}} {{$.locale.Tr "settings.gpg_key_matched_identities"}} {{range .Emails}}{{.Email}} {{end}} + {{end}} +
    + {{$.locale.Tr "settings.key_id"}}: {{.PaddedKeyID}} + {{$.locale.Tr "settings.subkeys"}}: {{range .SubsKey}} {{.PaddedKeyID}} {{end}} +
    +
    + {{$.locale.Tr "settings.added_on" (DateTime "short" .AddedUnix) | Safe}} + - + {{if not .ExpiredUnix.IsZero}}{{$.locale.Tr "settings.valid_until_date" (DateTime "short" .ExpiredUnix) | Safe}}{{else}}{{$.locale.Tr "settings.valid_forever"}}{{end}} +
    +
    +
    @@ -53,26 +73,6 @@ {{$.locale.Tr "settings.gpg_key_verify"}} {{end}}
    -
    - {{svg "octicon-key" 32}} -
    -
    - {{if .Verified}} - {{svg "octicon-verified"}} {{$.locale.Tr "settings.gpg_key_verified"}} - {{end}} - {{if gt (len .Emails) 0}} - {{svg "octicon-mail"}} {{$.locale.Tr "settings.gpg_key_matched_identities"}} {{range .Emails}}{{.Email}} {{end}} - {{end}} -
    - {{$.locale.Tr "settings.key_id"}}: {{.PaddedKeyID}} - {{$.locale.Tr "settings.subkeys"}}: {{range .SubsKey}} {{.PaddedKeyID}} {{end}} -
    -
    - {{$.locale.Tr "settings.added_on" (DateTime "short" .AddedUnix) | Safe}} - - - {{if not .ExpiredUnix.IsZero}}{{$.locale.Tr "settings.valid_until_date" (DateTime "short" .ExpiredUnix) | Safe}}{{else}}{{$.locale.Tr "settings.valid_forever"}}{{end}} -
    -
    {{if and (not .Verified) (eq $.VerifyingID .KeyID)}}
    diff --git a/templates/user/settings/keys_principal.tmpl b/templates/user/settings/keys_principal.tmpl index 7dda6665bd..42c21373d5 100644 --- a/templates/user/settings/keys_principal.tmpl +++ b/templates/user/settings/keys_principal.tmpl @@ -10,24 +10,26 @@
    -
    -
    +
    +
    {{.locale.Tr "settings.principal_desc"}}
    {{range .Principals}} -
    -
    +
    +
    + {{svg "octicon-key" 32}} +
    +
    +
    {{.Name}}
    +
    + {{$.locale.Tr "settings.added_on" (DateTime "short" .CreatedUnix) | Safe}} — {{svg "octicon-info" 16}} {{if .HasUsed}}{{$.locale.Tr "settings.last_used"}} {{DateTime "short" .UpdatedUnix}}{{else}}{{$.locale.Tr "settings.no_activity"}}{{end}} +
    +
    +
    - {{svg "octicon-key" 36}} -
    - {{.Name}} -
    - {{$.locale.Tr "settings.added_on" (DateTime "short" .CreatedUnix) | Safe}} — {{svg "octicon-info" 16}} {{if .HasUsed}}{{$.locale.Tr "settings.last_used"}} {{DateTime "short" .UpdatedUnix}}{{else}}{{$.locale.Tr "settings.no_activity"}}{{end}} -
    -
    {{end}}
    diff --git a/templates/user/settings/keys_ssh.tmpl b/templates/user/settings/keys_ssh.tmpl index 0a47c44bd8..0d2916d30c 100644 --- a/templates/user/settings/keys_ssh.tmpl +++ b/templates/user/settings/keys_ssh.tmpl @@ -27,40 +27,39 @@
    -
    -
    +
    +
    {{.locale.Tr "settings.ssh_desc"}}
    {{if .DisableSSH}} -
    +
    {{.locale.Tr "settings.ssh_signonly"}}
    {{end}} {{range $index, $key := .Keys}} -
    -
    +
    +
    + {{svg "octicon-key" 32}} +
    +
    + {{if .Verified}} +
    {{svg "octicon-verified"}}{{$.locale.Tr "settings.ssh_key_verified"}}
    + {{end}} +
    {{.Name}}
    +
    + {{.Fingerprint}} +
    +
    + {{$.locale.Tr "settings.added_on" (DateTime "short" .CreatedUnix) | Safe}} — {{svg "octicon-info"}} {{if .HasUsed}}{{$.locale.Tr "settings.last_used"}} {{DateTime "short" .UpdatedUnix}}{{else}}{{$.locale.Tr "settings.no_activity"}}{{end}} +
    +
    +
    {{if and (not .Verified) (ne $.VerifyingFingerprint .Fingerprint)}} {{$.locale.Tr "settings.ssh_key_verify"}} {{end}} - -
    -
    - {{svg "octicon-key" 32}} -
    -
    - {{if .Verified}} - {{svg "octicon-verified"}} {{$.locale.Tr "settings.ssh_key_verified"}} - {{end}} - {{.Name}} -
    - {{.Fingerprint}} -
    -
    - {{$.locale.Tr "settings.added_on" (DateTime "short" .CreatedUnix) | Safe}} — {{svg "octicon-info"}} {{if .HasUsed}}{{$.locale.Tr "settings.last_used"}} {{DateTime "short" .UpdatedUnix}}{{else}}{{$.locale.Tr "settings.no_activity"}}{{end}} -
    {{if and (not .Verified) (eq $.VerifyingFingerprint .Fingerprint)}} diff --git a/templates/user/settings/organization.tmpl b/templates/user/settings/organization.tmpl index 9b6d0f66c5..7a4ea17cb2 100644 --- a/templates/user/settings/organization.tmpl +++ b/templates/user/settings/organization.tmpl @@ -10,10 +10,19 @@
    {{if .Orgs}} -
    +
    {{range .Orgs}} -
    -
    +
    +
    + {{avatar $.Context . 28 "mini"}} +
    +
    +
    {{template "shared/user/name" .}}
    +
    + {{.Description}} +
    +
    +
    {{$.CsrfTokenHtml}}
    -
    - {{avatar $.Context . 28 "mini"}} - {{.Name}} -
    {{end}}
    diff --git a/templates/user/settings/security/accountlinks.tmpl b/templates/user/settings/security/accountlinks.tmpl index 515806d7a8..f64277b5af 100644 --- a/templates/user/settings/security/accountlinks.tmpl +++ b/templates/user/settings/security/accountlinks.tmpl @@ -21,21 +21,29 @@
    -
    -
    +
    +
    {{.locale.Tr "settings.manage_account_links_desc"}}
    {{range $loginSource, $provider := .AccountLinks}} -
    -
    - - {{$loginSource.Name}} - {{if $loginSource.IsActive}}{{$.locale.Tr "repo.settings.active"}}{{end}} - +
    + {{$providerData := index $.OAuth2Providers $loginSource.Name}} +
    + {{$providerData.IconHTML}} +
    +
    + + {{$loginSource.Name}} + + {{if $loginSource.IsActive}} + {{$.locale.Tr "repo.settings.active"}} + {{end}} +
    +
    +
    -
    {{end}}
    diff --git a/templates/user/settings/security/openid.tmpl b/templates/user/settings/security/openid.tmpl index dae49dcd89..86cb161bce 100644 --- a/templates/user/settings/security/openid.tmpl +++ b/templates/user/settings/security/openid.tmpl @@ -2,19 +2,20 @@ {{.locale.Tr "settings.manage_openid"}}
    -
    -
    +
    +
    {{.locale.Tr "settings.openid_desc"}}
    {{range .OpenIDs}} -
    -
    - +
    +
    + {{svg "fontawesome-openid" 20}}
    -
    -
    +
    +
    {{.URI}}
    +
    +
    + {{$.CsrfTokenHtml}} {{if .Show}} @@ -28,11 +29,11 @@ {{$.locale.Tr "settings.show_openid"}} {{end}} - -
    -
    - {{.URI}} -
    + + +
    {{end}}
    diff --git a/templates/user/settings/security/webauthn.tmpl b/templates/user/settings/security/webauthn.tmpl index 16551307c1..676754df59 100644 --- a/templates/user/settings/security/webauthn.tmpl +++ b/templates/user/settings/security/webauthn.tmpl @@ -2,18 +2,21 @@

    {{.locale.Tr "settings.webauthn_desc" | Str2html}}

    {{template "user/auth/webauthn_error" .}} -
    +
    {{range .WebAuthnCredentials}} -
    -
    +
    +
    + {{svg "octicon-key" 32}} +
    +
    +
    {{.Name}}
    + {{TimeSinceUnix .CreatedUnix $.locale}} +
    +
    -
    - {{.Name}} -
    - {{TimeSinceUnix .CreatedUnix $.locale}}
    {{end}}
    diff --git a/tests/integration/auth_ldap_test.go b/tests/integration/auth_ldap_test.go index 25395f5721..cf4c66734a 100644 --- a/tests/integration/auth_ldap_test.go +++ b/tests/integration/auth_ldap_test.go @@ -387,7 +387,7 @@ func TestLDAPUserSSHKeySync(t *testing.T) { htmlDoc := NewHTMLParser(t, resp.Body) - divs := htmlDoc.doc.Find(".key.list .print.meta") + divs := htmlDoc.doc.Find("#keys-ssh .flex-item .flex-item-body:not(:last-child)") syncedKeys := make([]string, divs.Length()) for i := 0; i < divs.Length(); i++ { diff --git a/tests/integration/issue_test.go b/tests/integration/issue_test.go index b712e16f29..58577a37ff 100644 --- a/tests/integration/issue_test.go +++ b/tests/integration/issue_test.go @@ -30,9 +30,9 @@ import ( ) func getIssuesSelection(t testing.TB, htmlDoc *HTMLDoc) *goquery.Selection { - issueList := htmlDoc.doc.Find(".issue.list") + issueList := htmlDoc.doc.Find("#issue-list") assert.EqualValues(t, 1, issueList.Length()) - return issueList.Find("li").Find(".title") + return issueList.Find(".flex-item").Find(".issue-title") } func getIssue(t *testing.T, repoID int64, issueSelection *goquery.Selection) *issues_model.Issue { diff --git a/tests/integration/privateactivity_test.go b/tests/integration/privateactivity_test.go index 5d3291bfe3..8c95d7c8a6 100644 --- a/tests/integration/privateactivity_test.go +++ b/tests/integration/privateactivity_test.go @@ -58,7 +58,7 @@ func testPrivateActivityHelperEnablePrivateActivity(t *testing.T) { } func testPrivateActivityHelperHasVisibleActivitiesInHTMLDoc(htmlDoc *HTMLDoc) bool { - return htmlDoc.doc.Find(".feeds").Find(".news").Length() > 0 + return htmlDoc.doc.Find("#activity-feed").Find(".flex-item").Length() > 0 } func testPrivateActivityHelperHasVisibleActivitiesFromSession(t *testing.T, session *TestSession) bool { diff --git a/tests/integration/setting_test.go b/tests/integration/setting_test.go index a824bd7f2f..9dad9ca716 100644 --- a/tests/integration/setting_test.go +++ b/tests/integration/setting_test.go @@ -24,7 +24,7 @@ func TestSettingShowUserEmailExplore(t *testing.T) { resp := session.MakeRequest(t, req, http.StatusOK) htmlDoc := NewHTMLParser(t, resp.Body) assert.Contains(t, - htmlDoc.doc.Find(".ui.user.list").Text(), + htmlDoc.doc.Find(".explore.users").Text(), "user34@example.com", ) @@ -34,7 +34,7 @@ func TestSettingShowUserEmailExplore(t *testing.T) { resp = session.MakeRequest(t, req, http.StatusOK) htmlDoc = NewHTMLParser(t, resp.Body) assert.NotContains(t, - htmlDoc.doc.Find(".ui.user.list").Text(), + htmlDoc.doc.Find(".explore.users").Text(), "user34@example.com", ) diff --git a/web_src/css/actions.css b/web_src/css/actions.css index 31da79cabf..f081698c66 100644 --- a/web_src/css/actions.css +++ b/web_src/css/actions.css @@ -52,3 +52,18 @@ background-color: var(--color-yellow); color: var(--color-white); } + +.run-list-item-right { + flex: 0 0 15%; + display: flex; + flex-direction: column; + gap: 3px; + color: var(--color-text-light); +} + +.run-list-item-right .run-list-meta { + display: flex; + flex-wrap: nowrap; + gap: .25rem; + align-items: center; +} diff --git a/web_src/css/dashboard.css b/web_src/css/dashboard.css index 34428c5999..1eb480845b 100644 --- a/web_src/css/dashboard.css +++ b/web_src/css/dashboard.css @@ -96,61 +96,13 @@ } } -.feeds .news li { - display: flex; - align-items: baseline; - margin-top: 0.5rem; - margin-bottom: 0.5rem; -} - -.feeds .news li img { - align-self: flex-start; -} - -.feeds .news li > * + * { - margin-left: 0.35rem; -} - -.feeds .news > .ui.grid { - margin-left: auto; - margin-right: auto; -} - -.feeds .news .left .ui.avatar { - margin-top: 13px; -} - -.feeds .news .time-since { - font-size: 13px; -} - -.feeds .news .issue.title { - width: 80%; - margin: 0 0 1em; -} - -.feeds .news .push.news .content ul { - line-height: 18px; - font-size: 13px; - list-style: none; - padding-left: 10px; -} - -.feeds .news .push.news .content ul .text.truncate { - width: 80%; -} - -.feeds .news .commit-id { +.feeds .commit-id { font-family: var(--fonts-monospace); } -.feeds .news code { +.feeds code { padding: 2px 4px; border-radius: 3px; background-color: var(--color-markup-code-block); word-break: break-all; } - -.feeds .news:last-of-type .divider { - display: none !important; -} diff --git a/web_src/css/explore.css b/web_src/css/explore.css index 139dfcb19f..08858337c0 100644 --- a/web_src/css/explore.css +++ b/web_src/css/explore.css @@ -10,33 +10,6 @@ margin-right: 5px; } -.ui.repository.list .item { - padding-bottom: 1.5rem; -} - -.ui.repository.list .item:not(:first-child) { - border-top: 1px solid var(--color-secondary); - padding-top: 1.5rem; -} - -.ui.repository.list .item .ui.header { - font-size: 1.5rem; - margin-bottom: 0.5rem; -} - -.ui.repository.list .item .ui.header .name { - word-break: break-all; -} - -.ui.repository.list .item .time { - font-size: 12px; -} - -.ui.repository.list .repo-title .labels { - word-break: normal; - flex-shrink: 0; -} - .ui.repository.branches .info { font-size: 12px; color: var(--color-text-light); @@ -58,27 +31,3 @@ .ui.repository.branches table .ui.popup { text-align: left; } - -.ui.user.list .item { - padding-bottom: 25px; - display: flex; -} - -.ui.user.list .item:not(:first-child) { - border-top: 1px solid var(--color-secondary); - padding-top: 25px; -} - -.ui.user.list .item img.ui.avatar { - width: 40px; - height: 40px; - margin-right: 10px; -} - -.ui.user.list .item .description { - margin-top: 5px; -} - -.ui.user.list .item .description .svg:not(:first-child) { - margin-left: 5px; -} diff --git a/web_src/css/index.css b/web_src/css/index.css index 230e032ac0..55ea67453b 100644 --- a/web_src/css/index.css +++ b/web_src/css/index.css @@ -13,7 +13,7 @@ @import "./modules/svg.css"; @import "./modules/flexcontainer.css"; -@import "./shared/issuelist.css"; +@import "./shared/flex-list.css"; @import "./shared/milestone.css"; @import "./shared/repoorg.css"; @import "./shared/settings.css"; diff --git a/web_src/css/org.css b/web_src/css/org.css index 9e1fa38941..4bb3b0cd57 100644 --- a/web_src/css/org.css +++ b/web_src/css/org.css @@ -133,7 +133,6 @@ padding: 10px 15px; } -.organization.teams .members .ui.avatar, .organization.profile .members .ui.avatar { width: 48px; height: 48px; @@ -161,25 +160,6 @@ height: 100%; } -.organization.members .list .item { - margin-left: 0; - margin-right: 0; - border-bottom: 1px solid var(--color-secondary); -} - -.organization.members .list .item .ui.avatar { - width: 48px; - height: 48px; - margin-right: 1rem; - align-self: flex-start; -} - -.organization.members .list .item .meta { - line-height: 24px; - word-break: break-word; - min-width: 2em; -} - .organization.teams .detail .item { padding: 10px 15px; } @@ -188,22 +168,6 @@ border-bottom: 1px solid var(--color-secondary); } -.organization.teams .repositories .item, -.organization.teams .members .item { - padding: 10px 19px; -} - -.organization.teams .repositories .item:not(:last-child), -.organization.teams .members .item:not(:last-child) { - border-bottom: 1px solid var(--color-secondary); -} - -.organization.teams .repositories .item .button, -.organization.teams .members .item .button { - padding: 9px 10px; - margin: 0; -} - .org-team-navbar .active.item { background: var(--color-box-body) !important; } diff --git a/web_src/css/repo.css b/web_src/css/repo.css index 04cb4eed2d..efa412dc53 100644 --- a/web_src/css/repo.css +++ b/web_src/css/repo.css @@ -584,15 +584,6 @@ min-width: 100px; } -.repository.options .danger .item { - padding: 20px 15px; -} - -.repository.options .danger .ui.divider { - margin: 0; - border-color: var(--color-error-border); -} - .repository.new.issue .comment.form .comment .avatar { width: 3em; } @@ -1927,15 +1918,6 @@ flex-wrap: wrap; } -.repository.settings.collaboration .collaborator.list { - padding: 0; -} - -.repository.settings.collaboration .collaborator.list > .item { - margin: 0; - line-height: 2; -} - .repository.settings.collaboration #repo-collab-form #search-user-box .results { left: 7px; } @@ -2389,15 +2371,6 @@ padding: 10px 0 0; } -.settings .list.key .meta { - padding-top: 5px; - color: var(--color-text-light-2); -} - -.settings .list.collaborator > .item { - padding: 0; -} - .ui.vertical.menu .header.item { font-size: 1.1em; background: var(--color-box-header); diff --git a/web_src/css/repo/issue-list.css b/web_src/css/repo/issue-list.css index 7769a16f5f..2a0a86c081 100644 --- a/web_src/css/repo/issue-list.css +++ b/web_src/css/repo/issue-list.css @@ -32,3 +32,36 @@ order: 2 !important; } } + +#issue-list .flex-item-body .branches { + display: inline-flex; +} + +#issue-list .flex-item-body .branches .branch { + background-color: var(--color-secondary-alpha-40); + border-radius: 3px; + padding: 0 4px; +} + +#issue-list .flex-item-body .branches .truncated-name { + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + max-width: 10em; +} + +#issue-list .flex-item-body .checklist progress { + margin-left: 2px; + width: 80px; + height: 6px; + display: inline-block; + border-radius: 3px; +} + +#issue-list .flex-item-body .checklist progress::-webkit-progress-value { + background-color: var(--color-secondary-dark-4); +} + +#issue-list .flex-item-body .checklist progress::-moz-progress-bar { + background-color: var(--color-secondary-dark-4); +} \ No newline at end of file diff --git a/web_src/css/shared/flex-list.css b/web_src/css/shared/flex-list.css new file mode 100644 index 0000000000..7982241684 --- /dev/null +++ b/web_src/css/shared/flex-list.css @@ -0,0 +1,94 @@ +.flex-list { + list-style: none; +} + +.flex-item { + display: flex; + gap: 8px; + align-items: flex-start; +} + +.flex-item:not(:last-child) { + padding-bottom: 8px; +} + +.flex-item-baseline { + align-items: baseline; +} + +.flex-item-center { + align-items: center; +} + +.flex-item .flex-item-leading { + display: flex; + align-items: flex-start; +} + +.flex-item .flex-item-main { + display: flex; + flex-direction: column; + flex-grow: 1; + min-width: 0; +} + +.flex-item-header { + display: flex; + gap: .25rem; + justify-content: space-between; + flex-wrap: wrap; +} + +.flex-item a:not(.label, .button):hover { + color: var(--color-primary) !important; +} + +.flex-item .flex-item-icon svg { + margin-top: 1px; +} + +.flex-item .flex-item-trailing { + display: flex; + gap: 0.5rem; + align-items: center; + flex-grow: 0; + flex-wrap: wrap; + justify-content: end; + flex-shrink: 2; +} + +.flex-item .flex-item-title { + display: inline-flex; + flex-wrap: wrap; + align-items: center; + gap: .25rem; + max-width: 100%; + color: var(--color-text); + font-size: 16px; + min-width: 0; + font-weight: var(--font-weight-semibold); +} + +.flex-item .flex-item-title a { + color: var(--color-text); + overflow-wrap: anywhere; +} + +.flex-item .flex-item-body { + font-size: 13px; + display: flex; + align-items: center; + flex-wrap: wrap; + gap: .25rem; + color: var(--color-text-light-2); +} + +.flex-item .flex-item-body a { + color: inherit; + overflow-wrap: anywhere; +} + +.flex-list > .flex-item + .flex-item { + border-top: 1px solid var(--color-secondary); + padding-top: 8px; +} diff --git a/web_src/css/shared/issuelist.css b/web_src/css/shared/issuelist.css deleted file mode 100644 index 82fafedec0..0000000000 --- a/web_src/css/shared/issuelist.css +++ /dev/null @@ -1,134 +0,0 @@ -.issue.list { - list-style: none; - margin-top: 1rem; -} - -.issue.list .item { - display: flex; - align-items: baseline; - padding: 8px 0; -} - -.issue.list .item .issue-item-left { - display: flex; - align-items: flex-start; -} - -.issue.list .item .issue-item-main { - display: flex; - flex-direction: column; - width: 100%; -} - -.issue.list .item .issue-item-header { - display: flex; - justify-content: space-between; - align-items: center; - flex-wrap: wrap; -} - -.issue.list a:not(.label):hover { - color: var(--color-primary) !important; -} - -.issue.list > .item .issue-item-icon svg { - margin-right: 0.75rem; - margin-top: 1px; -} - -.issue.list .item .issue-item-right { - display: flex; - gap: 0.5rem; -} - -.issue.list > .action-item { - align-items: normal; -} - -.issue.list > .item .action-item-center { - display: flex; - align-items: center; - padding-left: 4px; - padding-right: 12px; -} - -.issue.list > .item .action-item-right { - flex: 0 0 15%; - display: flex; - flex-direction: column; - gap: 3px; - color: var(--color-text-light); -} - -.issue.list > .item .issue-item-title { - max-width: 100%; - color: var(--color-text); - font-size: 16px; - min-width: 0; - font-weight: var(--font-weight-semibold); -} - -.issue.list > .item .issue-item-title a.index { - max-width: fit-content; - display: -webkit-box; - -webkit-box-orient: vertical; - -webkit-line-clamp: 2; - overflow: hidden; - word-break: break-all; -} - -.issue.list > .item .title { - color: var(--color-text); - overflow-wrap: anywhere; -} - -.issue.list > .item .issue-item-body { - font-size: 13px; - display: flex; - align-items: center; - flex-wrap: wrap; - gap: .25rem; - color: var(--color-text-light-2); -} - -.issue.list > .item .issue-item-body a { - color: inherit; - word-break: break-word; -} - -.issue.list > .item .issue-item-body .checklist progress { - margin-left: 2px; - width: 80px; - height: 6px; - display: inline-block; - border-radius: 3px; -} - -.issue.list > .item .issue-item-body .checklist progress::-webkit-progress-value { - background-color: var(--color-secondary-dark-4); -} - -.issue.list > .item .issue-item-body .checklist progress::-moz-progress-bar { - background-color: var(--color-secondary-dark-4); -} - -.issue.list .branches { - display: inline-flex; -} - -.issue.list .branches .branch { - background-color: var(--color-secondary-alpha-40); - border-radius: 3px; - padding: 0 4px; -} - -.issue.list .branches .truncated-name { - white-space: nowrap; - overflow: hidden; - text-overflow: ellipsis; - max-width: 10em; -} - -.issue.list > .item + .item { - border-top: 1px solid var(--color-secondary); -} diff --git a/web_src/css/user.css b/web_src/css/user.css index ab94c826b2..33e64bbb7c 100644 --- a/web_src/css/user.css +++ b/web_src/css/user.css @@ -58,15 +58,6 @@ } } -.user.profile .ui.repository.list { - margin-top: 25px; -} - -.user.profile .ui.repository.list .repo-title .labels { - word-break: normal; - flex-shrink: 0; -} - .user.profile #loading-heatmap { margin-bottom: 1em; } From 9a65d011f6b289dd6e7acb18a4b86c51d4d388ee Mon Sep 17 00:00:00 2001 From: Zettat123 Date: Tue, 1 Aug 2023 15:25:11 +0800 Subject: [PATCH 029/200] Some fixes of the prompt of new branches (#26257) Related to #26239 This PR makes some fixes: - do not show the prompt for mirror repos and repos with pull request units disabled - use `commit_time` instead of `updated_unix`, as `commit_time` is the real time when the branch was pushed --- models/git/branch.go | 4 ++-- routers/web/repo/view.go | 16 ++++++++++++---- .../repo/code/recently_pushed_new_branches.tmpl | 2 +- 3 files changed, 15 insertions(+), 7 deletions(-) diff --git a/models/git/branch.go b/models/git/branch.go index c68da1be78..6d50fb9fb6 100644 --- a/models/git/branch.go +++ b/models/git/branch.go @@ -395,9 +395,9 @@ func FindRecentlyPushedNewBranches(ctx context.Context, repoID, userID int64, ex Where("pusher_id=? AND is_deleted=?", userID, false). And("name <> ?", excludeBranchName). And("repo_id = ?", repoID). - And("updated_unix >= ?", time.Now().Add(-time.Hour*6).Unix()). + And("commit_time >= ?", time.Now().Add(-time.Hour*6).Unix()). NotIn("name", subQuery). - OrderBy("branch.updated_unix DESC"). + OrderBy("branch.commit_time DESC"). Limit(2). Find(&branches) return branches, err diff --git a/routers/web/repo/view.go b/routers/web/repo/view.go index 9e6b3e7825..15c85f6427 100644 --- a/routers/web/repo/view.go +++ b/routers/web/repo/view.go @@ -999,10 +999,18 @@ func renderCode(ctx *context.Context) { ctx.ServerError("GetBaseRepo", err) return } - ctx.Data["RecentlyPushedNewBranches"], err = git_model.FindRecentlyPushedNewBranches(ctx, ctx.Repo.Repository.ID, ctx.Doer.ID, ctx.Repo.Repository.DefaultBranch) - if err != nil { - ctx.ServerError("GetRecentlyPushedBranches", err) - return + + showRecentlyPushedNewBranches := true + if ctx.Repo.Repository.IsMirror || + !ctx.Repo.Repository.UnitEnabled(ctx, unit_model.TypePullRequests) { + showRecentlyPushedNewBranches = false + } + if showRecentlyPushedNewBranches { + ctx.Data["RecentlyPushedNewBranches"], err = git_model.FindRecentlyPushedNewBranches(ctx, ctx.Repo.Repository.ID, ctx.Doer.ID, ctx.Repo.Repository.DefaultBranch) + if err != nil { + ctx.ServerError("GetRecentlyPushedBranches", err) + return + } } } diff --git a/templates/repo/code/recently_pushed_new_branches.tmpl b/templates/repo/code/recently_pushed_new_branches.tmpl index e936fa4bb4..ad68b15831 100644 --- a/templates/repo/code/recently_pushed_new_branches.tmpl +++ b/templates/repo/code/recently_pushed_new_branches.tmpl @@ -1,7 +1,7 @@ {{range .RecentlyPushedNewBranches}}
    - {{$timeSince := TimeSince .UpdatedUnix.AsTime $.locale}} + {{$timeSince := TimeSince .CommitTime.AsTime $.locale}} {{$.locale.Tr "repo.pulls.recently_pushed_new_branches" (PathEscapeSegments .Name) $timeSince | Safe}}
    From edd93fcfbce72b6f4dd95f347473c4c5721bfd99 Mon Sep 17 00:00:00 2001 From: Yarden Shoham Date: Tue, 1 Aug 2023 17:21:04 +0300 Subject: [PATCH 030/200] Fix due date rendering the wrong date in issue (#26268) Closes #26263 We have to pass the date without the time. # Before ![image](https://github.com/go-gitea/gitea/assets/20454870/6b6cb43d-2b1c-4679-951d-20f48c94bfdd) # After ![image](https://github.com/go-gitea/gitea/assets/20454870/50441baf-2c52-452b-bb0d-6034a407abde) Signed-off-by: Yarden Shoham --- templates/repo/issue/view_content/sidebar.tmpl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/templates/repo/issue/view_content/sidebar.tmpl b/templates/repo/issue/view_content/sidebar.tmpl index c89df8626a..15845665bb 100644 --- a/templates/repo/issue/view_content/sidebar.tmpl +++ b/templates/repo/issue/view_content/sidebar.tmpl @@ -374,7 +374,7 @@
    {{svg "octicon-calendar" 16 "gt-mr-3"}} - {{DateTime "long" .Issue.DeadlineUnix}} + {{DateTime "long" .Issue.DeadlineUnix.FormatDate}}
    {{if and .HasIssuesOrPullsWritePermission (not .Repository.IsArchived)}} From ab0e588217a0338e3dc83547be64febad733117f Mon Sep 17 00:00:00 2001 From: minijaws Date: Tue, 1 Aug 2023 11:28:20 -0400 Subject: [PATCH 031/200] Update Arch linux URL from community to extra (#26273) Arch linux package link has changed from the community repo to the extra repo. The link has been updated. --- docs/content/installation/from-package.en-us.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/content/installation/from-package.en-us.md b/docs/content/installation/from-package.en-us.md index 36f3e2db08..4c29c31efc 100644 --- a/docs/content/installation/from-package.en-us.md +++ b/docs/content/installation/from-package.en-us.md @@ -40,7 +40,7 @@ apk add gitea ## Arch Linux -The rolling release distribution has [Gitea](https://www.archlinux.org/packages/community/x86_64/gitea/) in their official community repository and package updates are provided with new Gitea releases. +The rolling release distribution has [Gitea](https://www.archlinux.org/packages/extra/x86_64/gitea/) in their official extra repository and package updates are provided with new Gitea releases. ```sh pacman -S gitea From ab388deb0e52c058a19dbd844bdd890f7cf84d51 Mon Sep 17 00:00:00 2001 From: puni9869 <80308335+puni9869@users.noreply.github.com> Date: Tue, 1 Aug 2023 21:30:59 +0530 Subject: [PATCH 032/200] Allow editing push mirrors after creation (#26151) Allow users to edit the sync interval for existing push mirrors. Currently, there is no way to modify the interval once the mirror is created.
    Screenshots ## Before Screenshot 2023-07-26 at 9 31 21 AM ## After Screenshot 2023-07-26 at 9 44 40 AM ### On hover image image image ### Edit modal image ### Only valid times are allowed Screenshot 2023-07-26 at 9 50 01 AM image
    Fixes #21295 --------- Co-authored-by: wxiaoguang --- models/repo/pushmirror.go | 6 +++ options/locale/locale_en-US.ini | 2 + routers/web/repo/setting/setting.go | 37 +++++++++++++++++++ templates/repo/settings/options.tmpl | 26 +++++++++---- .../repo/settings/push_mirror_sync_modal.tmpl | 32 ++++++++++++++++ 5 files changed, 96 insertions(+), 7 deletions(-) create mode 100644 templates/repo/settings/push_mirror_sync_modal.tmpl diff --git a/models/repo/pushmirror.go b/models/repo/pushmirror.go index f34484f638..dad9a9d388 100644 --- a/models/repo/pushmirror.go +++ b/models/repo/pushmirror.go @@ -85,6 +85,12 @@ func UpdatePushMirror(ctx context.Context, m *PushMirror) error { return err } +// UpdatePushMirrorInterval updates the push-mirror +func UpdatePushMirrorInterval(ctx context.Context, m *PushMirror) error { + _, err := db.GetEngine(ctx).ID(m.ID).Cols("interval").Update(m) + return err +} + func DeletePushMirrors(ctx context.Context, opts PushMirrorOptions) error { if opts.RepoID > 0 { _, err := db.GetEngine(ctx).Where(opts.toConds()).Delete(&PushMirror{}) diff --git a/options/locale/locale_en-US.ini b/options/locale/locale_en-US.ini index 3256d2ba91..6cb830b6d0 100644 --- a/options/locale/locale_en-US.ini +++ b/options/locale/locale_en-US.ini @@ -1966,6 +1966,8 @@ settings.mirror_settings.last_update = Last update settings.mirror_settings.push_mirror.none = No push mirrors configured settings.mirror_settings.push_mirror.remote_url = Git Remote Repository URL settings.mirror_settings.push_mirror.add = Add Push Mirror +settings.mirror_settings.push_mirror.edit_sync_time = Edit mirror sync interval + settings.sync_mirror = Synchronize Now settings.mirror_sync_in_progress = Mirror synchronization is in progress. Check back in a minute. settings.site = Website diff --git a/routers/web/repo/setting/setting.go b/routers/web/repo/setting/setting.go index b33660ffc9..71c1939f29 100644 --- a/routers/web/repo/setting/setting.go +++ b/routers/web/repo/setting/setting.go @@ -299,6 +299,43 @@ func SettingsPost(ctx *context.Context) { ctx.Flash.Info(ctx.Tr("repo.settings.mirror_sync_in_progress")) ctx.Redirect(repo.Link() + "/settings") + case "push-mirror-update": + if !setting.Mirror.Enabled { + ctx.NotFound("", nil) + return + } + + // This section doesn't require repo_name/RepoName to be set in the form, don't show it + // as an error on the UI for this action + ctx.Data["Err_RepoName"] = nil + + interval, err := time.ParseDuration(form.PushMirrorInterval) + if err != nil || (interval != 0 && interval < setting.Mirror.MinInterval) { + ctx.RenderWithErr(ctx.Tr("repo.mirror_interval_invalid"), tplSettingsOptions, &forms.RepoSettingForm{}) + return + } + + id, err := strconv.ParseInt(form.PushMirrorID, 10, 64) + if err != nil { + ctx.ServerError("UpdatePushMirrorIntervalPushMirrorID", err) + return + } + m := &repo_model.PushMirror{ + ID: id, + Interval: interval, + } + if err := repo_model.UpdatePushMirrorInterval(ctx, m); err != nil { + ctx.ServerError("UpdatePushMirrorInterval", err) + return + } + // Background why we are adding it to Queue + // If we observed its implementation in the context of `push-mirror-sync` where it + // is evident that pushing to the queue is necessary for updates. + // So, there are updates within the given interval, it is necessary to update the queue accordingly. + mirror_module.AddPushMirrorToQueue(m.ID) + ctx.Flash.Success(ctx.Tr("repo.settings.update_settings_success")) + ctx.Redirect(repo.Link() + "/settings") + case "push-mirror-remove": if !setting.Mirror.Enabled { ctx.NotFound("", nil) diff --git a/templates/repo/settings/options.tmpl b/templates/repo/settings/options.tmpl index f0b030dc54..569a576ce6 100644 --- a/templates/repo/settings/options.tmpl +++ b/templates/repo/settings/options.tmpl @@ -203,17 +203,27 @@ {{$.locale.Tr "repo.settings.mirror_settings.direction.push"}} {{if .LastUpdateUnix}}{{DateTime "full" .LastUpdateUnix}}{{else}}{{$.locale.Tr "never"}}{{end}} {{if .LastError}}
    {{$.locale.Tr "error"}}
    {{end}} -
    - {{$.CsrfTokenHtml}} - - - -
    +
    {{$.CsrfTokenHtml}} - + +
    +
    + {{$.CsrfTokenHtml}} + + +
    @@ -980,3 +990,5 @@
    {{end}} {{end}} + +{{template "repo/settings/push_mirror_sync_modal" .}} diff --git a/templates/repo/settings/push_mirror_sync_modal.tmpl b/templates/repo/settings/push_mirror_sync_modal.tmpl new file mode 100644 index 0000000000..a04574add5 --- /dev/null +++ b/templates/repo/settings/push_mirror_sync_modal.tmpl @@ -0,0 +1,32 @@ + From 6ed4626ed594f8b7f0328d45c174c1b14144862a Mon Sep 17 00:00:00 2001 From: Earl Warren <109468362+earl-warren@users.noreply.github.com> Date: Tue, 1 Aug 2023 18:54:54 +0200 Subject: [PATCH 033/200] Merge `templates/projects/list.tmpl` and `templates/repo/projects/list.tmpl` together (#26265) (cherry picked from commit 473862a1d599382ca022482e2e044025872d240b) Refs: https://codeberg.org/forgejo/forgejo/pulls/1126 Co-authored-by: Louis Seubert Co-authored-by: Giteabot --- templates/projects/list.tmpl | 4 +- templates/repo/projects/list.tmpl | 87 +------------------------------ web_src/css/repo.css | 12 ----- 3 files changed, 3 insertions(+), 100 deletions(-) diff --git a/templates/projects/list.tmpl b/templates/projects/list.tmpl index fc8bf60811..e59e279c00 100644 --- a/templates/projects/list.tmpl +++ b/templates/projects/list.tmpl @@ -1,4 +1,4 @@ -{{if .CanWriteProjects}} +{{if and $.CanWriteProjects (not $.Repository.IsArchived)}}
    @@ -72,7 +72,7 @@ {{template "base/paginate" .}}
    -{{if $.CanWriteProjects}} +{{if and $.CanWriteProjects (not $.Repository.IsArchived)}}
  • -

    - {{svg .IconName 16}} - {{.Title}} -

    -
    -
    -
    - {{svg "octicon-issue-opened" 14}} - {{$.locale.PrettyNumber .NumOpenIssues}} {{$.locale.Tr "repo.issues.open_title"}} -
    -
    - {{svg "octicon-check" 14}} - {{$.locale.PrettyNumber .NumClosedIssues}} {{$.locale.Tr "repo.issues.closed_title"}} -
    -
    - {{if and $.CanWriteProjects (not $.Repository.IsArchived)}} - - {{end}} -
    - {{if .Description}} -
    - {{.RenderedContent|Str2html}} -
    - {{end}} -
  • - {{end}} - - {{template "base/paginate" .}} - + {{template "projects/list" .}} - -{{if .CanWriteProjects}} - -{{end}} {{template "base/footer" .}} diff --git a/web_src/css/repo.css b/web_src/css/repo.css index efa412dc53..2b3f4e1efb 100644 --- a/web_src/css/repo.css +++ b/web_src/css/repo.css @@ -87,18 +87,6 @@ } } -.projects-header { - margin-bottom: 1rem; - flex-direction: column; - gap: 8px; -} - -.projects-toolbar { - display: flex; - justify-content: space-between; - padding-left: 4px; -} - .repository .issue-content-right .menu { overflow-x: auto; max-height: 500px; From b1089bdafef1dfb62ecbac99665ac7f7fd5eddce Mon Sep 17 00:00:00 2001 From: Earl Warren <109468362+earl-warren@users.noreply.github.com> Date: Tue, 1 Aug 2023 19:57:11 +0200 Subject: [PATCH 034/200] speed up TestEventSourceManagerRun (#26262) - `setting.UI.Notification.EventSourceUpdateTime` is by default 10 seconds, which adds an 10 second delay before the test succeeds. - Lower the interval to reduce it to at most 3 second delay (the code only send events when they are at least 2 seconds old). (cherry picked from commit 3adb9ae6009ff3ddebaed4875e086343f668ef7b) Refs: https://codeberg.org/forgejo/forgejo/pulls/1166 Co-authored-by: Gusted Co-authored-by: Giteabot --- tests/test_utils.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tests/test_utils.go b/tests/test_utils.go index fc4247eba8..3bcd872d6c 100644 --- a/tests/test_utils.go +++ b/tests/test_utils.go @@ -12,6 +12,7 @@ import ( "path" "path/filepath" "testing" + "time" "code.gitea.io/gitea/models/db" packages_model "code.gitea.io/gitea/models/packages" @@ -43,6 +44,9 @@ func InitTest(requireGitea bool) { exitf("Environment variable $GITEA_ROOT not set") } + // Speedup tests that rely on the event source ticker. + setting.UI.Notification.EventSourceUpdateTime = time.Second + setting.IsInTesting = true setting.AppWorkPath = giteaRoot setting.CustomPath = filepath.Join(setting.AppWorkPath, "custom") From 54c28fddd8a407c3ddea81923bb2978c33ef020d Mon Sep 17 00:00:00 2001 From: wxiaoguang Date: Wed, 2 Aug 2023 02:28:23 +0800 Subject: [PATCH 035/200] Clarify the logger's MODE config option (#26267) 1. Fix the wrong document (add the missing `MODE=`) 2. Add a more friendly log message to tell users to add `MODE=` in their config Co-authored-by: Giteabot --- docs/content/administration/logging-config.en-us.md | 3 +++ modules/setting/log.go | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/docs/content/administration/logging-config.en-us.md b/docs/content/administration/logging-config.en-us.md index d9739e1881..33470ca448 100644 --- a/docs/content/administration/logging-config.en-us.md +++ b/docs/content/administration/logging-config.en-us.md @@ -102,8 +102,11 @@ MODE = file, file-error ; by default, the "file" mode will record logs to %(log.ROOT_PATH)/gitea.log, so we don't need to set it ; [log.file] +; by default, the MODE (actually it's the output writer of this logger) is taken from the section name, so we don't need to set it either +; MODE = file [log.file-error] +MODE = file LEVEL = Error FILE_NAME = file-error.log ``` diff --git a/modules/setting/log.go b/modules/setting/log.go index 66206f8f4b..e404074b72 100644 --- a/modules/setting/log.go +++ b/modules/setting/log.go @@ -165,7 +165,7 @@ func loadLogModeByName(rootCfg ConfigProvider, loggerName, modeName string) (wri writerMode.WriterOption = writerOption default: if !log.HasEventWriter(writerType) { - return "", "", writerMode, fmt.Errorf("invalid log writer type (mode): %s", writerType) + return "", "", writerMode, fmt.Errorf("invalid log writer type (mode): %s, maybe it needs something like 'MODE=file' in [log.%s] section", writerType, modeName) } } From 02d5f422eab2f2b7ba8f61dcdef5bea96950061a Mon Sep 17 00:00:00 2001 From: Earl Warren <109468362+earl-warren@users.noreply.github.com> Date: Thu, 3 Aug 2023 03:37:48 +0200 Subject: [PATCH 036/200] add some Wiki unit tests (#26260) - Just to get 100% coverage on services/wiki/wiki_path.go, nothing special. This is just an formality. (cherry picked from commit 6b3528920fbf18c41d6aeb95498af48443282370) Refs: https://codeberg.org/forgejo/forgejo/pulls/1156 Co-authored-by: Gusted --- services/wiki/wiki_test.go | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/services/wiki/wiki_test.go b/services/wiki/wiki_test.go index ccb230e06f..f126224244 100644 --- a/services/wiki/wiki_test.go +++ b/services/wiki/wiki_test.go @@ -307,3 +307,15 @@ func TestPrepareWikiFileName_FirstPage(t *testing.T) { assert.NoError(t, err) assert.EqualValues(t, "Home.md", newWikiPath) } + +func TestWebPathConversion(t *testing.T) { + assert.Equal(t, "path/wiki", WebPathToURLPath(WebPath("path/wiki"))) + assert.Equal(t, "wiki", WebPathToURLPath(WebPath("wiki"))) + assert.Equal(t, "", WebPathToURLPath(WebPath(""))) +} + +func TestWebPathFromRequest(t *testing.T) { + assert.Equal(t, WebPath("a%2Fb"), WebPathFromRequest("a/b")) + assert.Equal(t, WebPath("a"), WebPathFromRequest("a")) + assert.Equal(t, WebPath("b"), WebPathFromRequest("a/../b")) +} From 7bde2bf80945ef5d0e973e8bb7e7899b020564d7 Mon Sep 17 00:00:00 2001 From: Earl Warren <109468362+earl-warren@users.noreply.github.com> Date: Thu, 3 Aug 2023 03:38:51 +0200 Subject: [PATCH 037/200] add unit test for user renaming (#26261) - The user renaming function has zero test coverage. - This patch brings that up to speed to test for various scenarios and ensure that in a normal workflow the correct things has changed to their respective new value. Most scenarios are to ensure certain things DO NOT happen. (cherry picked from commit 5b9d34ed115c9ef24012b8027959ea0afdcb4e2d) Refs: https://codeberg.org/forgejo/forgejo/pulls/1156 Co-authored-by: Gusted --- services/user/user_test.go | 64 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 64 insertions(+) diff --git a/services/user/user_test.go b/services/user/user_test.go index a25804fceb..3f1bf9a0f8 100644 --- a/services/user/user_test.go +++ b/services/user/user_test.go @@ -4,10 +4,13 @@ package user import ( + "fmt" "path/filepath" + "strings" "testing" "code.gitea.io/gitea/models" + "code.gitea.io/gitea/models/auth" "code.gitea.io/gitea/models/db" "code.gitea.io/gitea/models/organization" repo_model "code.gitea.io/gitea/models/repo" @@ -94,6 +97,67 @@ func TestCreateUser(t *testing.T) { assert.NoError(t, DeleteUser(db.DefaultContext, user, false)) } +func TestRenameUser(t *testing.T) { + assert.NoError(t, unittest.PrepareTestDatabase()) + user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 21}) + + t.Run("Non-Local", func(t *testing.T) { + u := &user_model.User{ + Type: user_model.UserTypeIndividual, + LoginType: auth.OAuth2, + } + assert.ErrorIs(t, RenameUser(db.DefaultContext, u, "user_rename"), user_model.ErrUserIsNotLocal{}) + }) + + t.Run("Same username", func(t *testing.T) { + assert.ErrorIs(t, RenameUser(db.DefaultContext, user, user.Name), user_model.ErrUsernameNotChanged{UID: user.ID, Name: user.Name}) + }) + + t.Run("Non usable username", func(t *testing.T) { + usernames := []string{"--diff", "aa.png", ".well-known", "search", "aaa.atom"} + for _, username := range usernames { + t.Run(username, func(t *testing.T) { + assert.Error(t, user_model.IsUsableUsername(username)) + assert.Error(t, RenameUser(db.DefaultContext, user, username)) + }) + } + }) + + t.Run("Only capitalization", func(t *testing.T) { + caps := strings.ToUpper(user.Name) + unittest.AssertNotExistsBean(t, &user_model.User{ID: user.ID, Name: caps}) + unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{OwnerID: user.ID, OwnerName: user.Name}) + + assert.NoError(t, RenameUser(db.DefaultContext, user, caps)) + + unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: user.ID, Name: caps}) + unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{OwnerID: user.ID, OwnerName: caps}) + }) + + t.Run("Already exists", func(t *testing.T) { + existUser := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1}) + + assert.ErrorIs(t, RenameUser(db.DefaultContext, user, existUser.Name), user_model.ErrUserAlreadyExist{Name: existUser.Name}) + assert.ErrorIs(t, RenameUser(db.DefaultContext, user, existUser.LowerName), user_model.ErrUserAlreadyExist{Name: existUser.LowerName}) + newUsername := fmt.Sprintf("uSEr%d", existUser.ID) + assert.ErrorIs(t, RenameUser(db.DefaultContext, user, newUsername), user_model.ErrUserAlreadyExist{Name: newUsername}) + }) + + t.Run("Normal", func(t *testing.T) { + oldUsername := user.Name + newUsername := "User_Rename" + + assert.NoError(t, RenameUser(db.DefaultContext, user, newUsername)) + unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: user.ID, Name: newUsername, LowerName: strings.ToLower(newUsername)}) + + redirectUID, err := user_model.LookupUserRedirect(oldUsername) + assert.NoError(t, err) + assert.EqualValues(t, user.ID, redirectUID) + + unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{OwnerID: user.ID, OwnerName: user.Name}) + }) +} + func TestCreateUser_Issue5882(t *testing.T) { // Init settings _ = setting.Admin From cad22512b8948fa52e1684ec30bb5a6e5d427d5f Mon Sep 17 00:00:00 2001 From: Lunny Xiao Date: Thu, 3 Aug 2023 16:29:57 +0800 Subject: [PATCH 038/200] Upgrade x/net to 0.13.0 (#26297) --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 5ccf962e16..b1e31c3faa 100644 --- a/go.mod +++ b/go.mod @@ -107,7 +107,7 @@ require ( github.com/yuin/goldmark-meta v1.1.0 golang.org/x/crypto v0.11.0 golang.org/x/image v0.9.0 - golang.org/x/net v0.12.0 + golang.org/x/net v0.13.0 golang.org/x/oauth2 v0.10.0 golang.org/x/sys v0.10.0 golang.org/x/text v0.11.0 diff --git a/go.sum b/go.sum index 67c73cb710..5e942457a5 100644 --- a/go.sum +++ b/go.sum @@ -1216,8 +1216,8 @@ golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= 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.9.0/go.mod h1:d48xBJpPfHeWQsugry2m+kC02ZBRGRgulfHnEXEuWns= -golang.org/x/net v0.12.0 h1:cfawfvKITfUsFCeJIHJrbSxpeu/E81khclypR0GVT50= -golang.org/x/net v0.12.0/go.mod h1:zEVYFnQC7m/vmpQFELhcD1EWkZlX69l4oqgmer6hfKA= +golang.org/x/net v0.13.0 h1:Nvo8UFsZ8X3BhAC9699Z1j7XQ3rsZnUUm7jfBEk1ueY= +golang.org/x/net v0.13.0/go.mod h1:zEVYFnQC7m/vmpQFELhcD1EWkZlX69l4oqgmer6hfKA= 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-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= From 539015403f80326d662e31cf9d3a459b3efefcd7 Mon Sep 17 00:00:00 2001 From: wxiaoguang Date: Thu, 3 Aug 2023 17:18:06 +0800 Subject: [PATCH 039/200] Fix the topic validation rule and suport dots (#26286) 1. Allow leading and trailing spaces by user input, these spaces have already been trimmed at backend 2. Allow using dots in the topic --- models/repo/topic.go | 2 +- models/repo/topic_test.go | 2 ++ options/locale/locale_en-US.ini | 2 +- web_src/js/features/repo-home.js | 2 +- 4 files changed, 5 insertions(+), 3 deletions(-) diff --git a/models/repo/topic.go b/models/repo/topic.go index ec3de869d5..71302388b9 100644 --- a/models/repo/topic.go +++ b/models/repo/topic.go @@ -22,7 +22,7 @@ func init() { db.RegisterModel(new(RepoTopic)) } -var topicPattern = regexp.MustCompile(`^[a-z0-9][a-z0-9-]*$`) +var topicPattern = regexp.MustCompile(`^[a-z0-9][-.a-z0-9]*$`) // Topic represents a topic of repositories type Topic struct { diff --git a/models/repo/topic_test.go b/models/repo/topic_test.go index 8a8728168d..aaed91bdd3 100644 --- a/models/repo/topic_test.go +++ b/models/repo/topic_test.go @@ -69,6 +69,7 @@ func TestAddTopic(t *testing.T) { func TestTopicValidator(t *testing.T) { assert.True(t, repo_model.ValidateTopic("12345")) assert.True(t, repo_model.ValidateTopic("2-test")) + assert.True(t, repo_model.ValidateTopic("foo.bar")) assert.True(t, repo_model.ValidateTopic("test-3")) assert.True(t, repo_model.ValidateTopic("first")) assert.True(t, repo_model.ValidateTopic("second-test-topic")) @@ -77,4 +78,5 @@ func TestTopicValidator(t *testing.T) { assert.False(t, repo_model.ValidateTopic("$fourth-test,topic")) assert.False(t, repo_model.ValidateTopic("-fifth-test-topic")) assert.False(t, repo_model.ValidateTopic("sixth-go-project-topic-with-excess-length")) + assert.False(t, repo_model.ValidateTopic(".foo")) } diff --git a/options/locale/locale_en-US.ini b/options/locale/locale_en-US.ini index 6cb830b6d0..c6379d0fe6 100644 --- a/options/locale/locale_en-US.ini +++ b/options/locale/locale_en-US.ini @@ -2507,7 +2507,7 @@ tag.create_success = Tag "%s" has been created. topic.manage_topics = Manage Topics topic.done = Done topic.count_prompt = You cannot select more than 25 topics -topic.format_prompt = Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long. +topic.format_prompt = Topics must start with a letter or number, can include dashes ('-') and dots ('.'), can be up to 35 characters long. Letters must be lowercase. find_file.go_to_file = Go to file find_file.no_matching = No matching file found diff --git a/web_src/js/features/repo-home.js b/web_src/js/features/repo-home.js index 55a2771054..70c225b4ba 100644 --- a/web_src/js/features/repo-home.js +++ b/web_src/js/features/repo-home.js @@ -166,7 +166,7 @@ export function initRepoTopicBar() { rules: [ { type: 'validateTopic', - value: /^[a-z0-9][a-z0-9-]{0,35}$/, + value: /^\s*[a-z0-9][-.a-z0-9]{0,35}\s*$/, prompt: topicPrompts.formatPrompt }, { From 8ba54a2e16b2abce805346111283360c50fd7428 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C3=A5rd=20Aase?= Date: Thu, 3 Aug 2023 11:20:40 +0100 Subject: [PATCH 040/200] Update Gmail example (#26302) The `IS_TLS_ENABLED` option in the `mailer` section is deprecated. This is specified by setting `PROTOCOL=smtps` --- docs/content/administration/email-setup.en-us.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/docs/content/administration/email-setup.en-us.md b/docs/content/administration/email-setup.en-us.md index 10058d8284..645a7a3f43 100644 --- a/docs/content/administration/email-setup.en-us.md +++ b/docs/content/administration/email-setup.en-us.md @@ -79,8 +79,7 @@ SMTP_PORT = 465 FROM = example.user@gmail.com USER = example.user PASSWD = `***` -PROTOCOL = smtp -IS_TLS_ENABLED = true +PROTOCOL = smtps ``` Note that you'll need to create and use an [App password](https://support.google.com/accounts/answer/185833?hl=en) by enabling 2FA on your Google From 0827fbd49c5cafe09aa58cc32d9794e54602430a Mon Sep 17 00:00:00 2001 From: "Panagiotis \"Ivory\" Vasilopoulos" Date: Thu, 3 Aug 2023 14:16:06 +0000 Subject: [PATCH 041/200] Make confusable character warning less jarring (#25069) This commit assumes that the warning can be made more discreet so as to make it less annoying for the people that do not actually need the warning, without necessarily increasing the risk for those that do need it. This doesn't fix the underlying problem of the warning being shown in certain cases that, say, a certain kind of whitespace character like 0x1E could be absolutely justifiable from a technical perspective. --------- Co-authored-by: delvh --- options/locale/locale_en-US.ini | 8 ++++---- templates/repo/unicode_escape_prompt.tmpl | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/options/locale/locale_en-US.ini b/options/locale/locale_en-US.ini index c6379d0fe6..ef940c83c8 100644 --- a/options/locale/locale_en-US.ini +++ b/options/locale/locale_en-US.ini @@ -1150,10 +1150,10 @@ file_view_rendered = View Rendered file_view_raw = View Raw file_permalink = Permalink file_too_large = The file is too large to be shown. -invisible_runes_header = `This file contains invisible Unicode characters!` -invisible_runes_description = `This file contains invisible Unicode characters that may be processed differently from what appears below. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to reveal hidden characters.` -ambiguous_runes_header = `This file contains ambiguous Unicode characters!` -ambiguous_runes_description = `This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.` +invisible_runes_header = `This file contains invisible Unicode characters` +invisible_runes_description = `This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.` +ambiguous_runes_header = `This file contains ambiguous Unicode characters` +ambiguous_runes_description = `This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.` invisible_runes_line = `This line has invisible unicode characters` ambiguous_runes_line = `This line has ambiguous unicode characters` ambiguous_character = `%[1]c [U+%04[1]X] can be confused with %[2]c [U+%04[2]X]` diff --git a/templates/repo/unicode_escape_prompt.tmpl b/templates/repo/unicode_escape_prompt.tmpl index 961e2370a7..66e00f6a99 100644 --- a/templates/repo/unicode_escape_prompt.tmpl +++ b/templates/repo/unicode_escape_prompt.tmpl @@ -1,6 +1,6 @@ {{if .EscapeStatus}} {{if .EscapeStatus.HasInvisible}} -
    +
    {{$.root.locale.Tr "repo.invisible_runes_header"}} From d74c2228e3f93de502aa37095a00421ca67c4ca9 Mon Sep 17 00:00:00 2001 From: yp05327 <576951401@qq.com> Date: Fri, 4 Aug 2023 02:58:41 +0900 Subject: [PATCH 042/200] Remove nonsense `` for commit status check icon (#26287) We are using `` for commit status check icon with no link. So it is clickable but this is no sense. I think we can convert this to `div`. ![image](https://github.com/go-gitea/gitea/assets/18380374/23db1a11-b0c7-4444-bfa6-fe68aeb1c682) Co-authored-by: Giteabot --- templates/repo/issue/view_content/pull.tmpl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/templates/repo/issue/view_content/pull.tmpl b/templates/repo/issue/view_content/pull.tmpl index 214d77a12d..a2e727c40a 100644 --- a/templates/repo/issue/view_content/pull.tmpl +++ b/templates/repo/issue/view_content/pull.tmpl @@ -2,7 +2,7 @@ {{/* Then the merge box will not be displayed because this page already contains enough information */}} {{else}}
    - {{svg "octicon-git-merge" 40}} + {{- else}}red{{end}}">{{svg "octicon-git-merge" 40}}
    {{template "repo/pulls/status" .}} {{$showGeneralMergeForm := false}} From 70647bd04ccabcedc32bb92a0dd24502b93a4f59 Mon Sep 17 00:00:00 2001 From: sebastian-sauer Date: Thu, 3 Aug 2023 23:28:21 +0200 Subject: [PATCH 043/200] Use yellow if an approved review is stale (#26312) By using a different color it's clear that the review isn't pointing to the latest commit. **Screenshots:** Not stale review: ![image](https://github.com/go-gitea/gitea/assets/1135157/2901ad69-e0d8-4041-b760-277d02dafd45) Stale review: ![image](https://github.com/go-gitea/gitea/assets/1135157/500b306e-a994-42d4-a2fd-1174774ba5ee) fixes #26306 --- models/issues/review.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/models/issues/review.go b/models/issues/review.go index b2736044fc..cae3ef1d39 100644 --- a/models/issues/review.go +++ b/models/issues/review.go @@ -192,6 +192,9 @@ func (r *Review) LoadAttributes(ctx context.Context) (err error) { func (r *Review) HTMLTypeColorName() string { switch r.Type { case ReviewTypeApprove: + if r.Stale { + return "yellow" + } return "green" case ReviewTypeComment: return "grey" From 6832a8eb06e382841e2cf5e52a9624bbd66a6acc Mon Sep 17 00:00:00 2001 From: yp05327 <576951401@qq.com> Date: Fri, 4 Aug 2023 07:07:15 +0900 Subject: [PATCH 044/200] Add locale for deleted head branch (#26296) As title. It will be displayed in: ![image](https://github.com/go-gitea/gitea/assets/18380374/e8507a3b-14f4-4418-a347-a36689707a16) --- options/locale/locale_en-US.ini | 2 ++ routers/web/repo/pull.go | 4 ++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/options/locale/locale_en-US.ini b/options/locale/locale_en-US.ini index ef940c83c8..24087cdd1b 100644 --- a/options/locale/locale_en-US.ini +++ b/options/locale/locale_en-US.ini @@ -1784,6 +1784,8 @@ pulls.delete.text = Do you really want to delete this pull request? (This will p pulls.recently_pushed_new_branches = You pushed on branch %[1]s %[2]s +pull.deleted_branch = (deleted):%s + milestones.new = New Milestone milestones.closed = Closed %s milestones.update_ago = Updated %s diff --git a/routers/web/repo/pull.go b/routers/web/repo/pull.go index d76e90bf24..0be8bede74 100644 --- a/routers/web/repo/pull.go +++ b/routers/web/repo/pull.go @@ -610,7 +610,7 @@ func PrepareViewPullInfo(ctx *context.Context, issue *issues_model.Issue) *git.C if pull.IsSameRepo() { ctx.Data["HeadTarget"] = pull.HeadBranch } else if pull.HeadRepo == nil { - ctx.Data["HeadTarget"] = ":" + pull.HeadBranch + ctx.Data["HeadTarget"] = ctx.Locale.Tr("repo.pull.deleted_branch", pull.HeadBranch) } else { ctx.Data["HeadTarget"] = pull.HeadRepo.OwnerName + ":" + pull.HeadBranch } @@ -654,7 +654,7 @@ func PrepareViewPullInfo(ctx *context.Context, issue *issues_model.Issue) *git.C if pull.IsSameRepo() { ctx.Data["HeadTarget"] = pull.HeadBranch } else if pull.HeadRepo == nil { - ctx.Data["HeadTarget"] = ":" + pull.HeadBranch + ctx.Data["HeadTarget"] = ctx.Locale.Tr("repo.pull.deleted_branch", pull.HeadBranch) } else { ctx.Data["HeadTarget"] = pull.HeadRepo.OwnerName + ":" + pull.HeadBranch } From 907bedaad0301730ee2fbab1f18b54b155dad088 Mon Sep 17 00:00:00 2001 From: GiteaBot Date: Fri, 4 Aug 2023 00:26:21 +0000 Subject: [PATCH 045/200] [skip ci] Updated translations via Crowdin --- options/locale/locale_de-DE.ini | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/options/locale/locale_de-DE.ini b/options/locale/locale_de-DE.ini index ea09964697..b089b9001a 100644 --- a/options/locale/locale_de-DE.ini +++ b/options/locale/locale_de-DE.ini @@ -753,7 +753,7 @@ ssh_token_required=Du musst eine Signatur für den Token unten angeben ssh_token=Token ssh_token_help=Du kannst eine Signatur wie folgt generieren: ssh_token_signature=SSH Textsignatur (armored signature) -key_signature_ssh_placeholder=Beginnt mit „-----BEGIN PGP SIGNATURE-----“ +key_signature_ssh_placeholder=Beginnt mit „-----BEGIN SSH SIGNATURE-----“ verify_ssh_key_success=SSH-Key "%s" wurde verifiziert. subkeys=Unterschlüssel key_id=Schlüssel-ID @@ -908,7 +908,7 @@ owner=Besitzer owner_helper=Einige Organisationen könnten in der Dropdown-Liste nicht angezeigt werden, da die Anzahl an Repositories begrenzt ist. repo_name=Repository-Name repo_name_helper=Ein guter Repository-Name besteht normalerweise aus kurzen, unvergesslichen und einzigartigen Schlagwörtern. -repo_size=Repository Größe +repo_size=Repository-Größe template=Template template_select=Vorlage auswählen template_helper=Repository zu einem Template machen @@ -1672,7 +1672,7 @@ pulls.is_ancestor=Dieser Branch ist bereits im Zielbranch enthalten. Es gibt nic pulls.is_empty=Die Änderungen an diesem Branch sind bereits auf dem Zielbranch. Dies wird ein leerer Commit sein. pulls.required_status_check_failed=Einige erforderliche Prüfungen waren nicht erfolgreich. pulls.required_status_check_missing=Einige erforderliche Prüfungen fehlen. -pulls.required_status_check_administrator=Als Administrator kannst du diesen Pull-Request weiterhin zusammenführen. +pulls.required_status_check_administrator=Als Administrator kannst du diesen Pull-Request weiterhin mergen. pulls.blocked_by_approvals=Dieser Pull-Request hat noch nicht genügend Zustimmungen. %d von %d Zustimmungen erteilt. pulls.blocked_by_rejection=Dieser Pull-Request hat Änderungen, die von einem offiziellen Reviewer angefragt wurden. pulls.blocked_by_official_review_requests=Dieser Pull Request hat offizielle Review-Anfragen. @@ -1706,12 +1706,12 @@ pulls.merge_commit_id=Der Mergecommit ID pulls.require_signed_wont_sign=Der Branch erfordert einen signierten Commit, aber dieser Merge wird nicht signiert pulls.invalid_merge_option=Du kannst diese Mergeoption auf diesen Pull-Request nicht anwenden. -pulls.merge_conflict=Zusammenführen fehlgeschlagen: Beim Zusammenführen gab es einen Konflikt. Hinweis: Probiere eine andere Strategie +pulls.merge_conflict=Merge fehlgeschlagen: Beim Mergen gab es einen Konflikt. Hinweis: Probiere eine andere Strategie pulls.merge_conflict_summary=Fehlermeldung -pulls.rebase_conflict=Zusammenführen fehlgeschlagen: Es gab einen Konflikt beim Rebasing des Commits: %[1]s. Hinweis: Versuche eine andere Strategie +pulls.rebase_conflict=Merge fehlgeschlagen: Es gab einen Konflikt beim Rebasen des Commits: %[1]s. Hinweis: Versuche eine andere Strategie pulls.rebase_conflict_summary=Fehlermeldung -pulls.unrelated_histories=Zusammenführung fehlgeschlagen: Der Head der Zusammenführung und die Basis haben keinen gemeinsamen Verlauf. Hinweis: Versuche eine andere Strategie -pulls.merge_out_of_date=Zusammenführung fehlgeschlagen: Während der Zusammenführung wurde die Basis aktualisiert. Hinweis: Versuche es erneut. +pulls.unrelated_histories=Merge fehlgeschlagen: Der Head des Merges und die Basis haben keinen gemeinsamen Verlauf. Hinweis: Versuche eine andere Strategie +pulls.merge_out_of_date=Merge fehlgeschlagen: Während des Mergens wurde die Basis aktualisiert. Hinweis: Versuche es erneut. pulls.head_out_of_date=Mergen fehlgeschlagen: Der Head wurde aktualisiert während der Merge erstellt wurde. Tipp: Versuche es erneut. pulls.push_rejected=Mergen fehlgeschlagen: Der Push wurde abgelehnt. Überprüfe die Git Hooks für dieses Repository. pulls.push_rejected_summary=Vollständige Ablehnungsmeldung @@ -1872,7 +1872,7 @@ activity.title.releases_n=%d Releases activity.title.releases_published_by=%s von %s veröffentlicht activity.published_release_label=Veröffentlicht activity.no_git_activity=In diesem Zeitraum sind keine Commit-Aktivität vorhanden. -activity.git_stats_exclude_merges=Zusammenführungen ausgenommen, +activity.git_stats_exclude_merges=Merges ausgenommen, activity.git_stats_author_1=%d Autor activity.git_stats_author_n=%d Autoren activity.git_stats_pushed_1=hat @@ -2254,7 +2254,7 @@ settings.block_on_official_review_requests_desc=Mergen ist nicht möglich wenn o settings.block_outdated_branch=Merge blockieren, wenn der Pull-Request veraltet ist settings.block_outdated_branch_desc=Mergen ist nicht möglich, wenn der Head-Branch hinter dem Basis-Branch ist. settings.default_branch_desc=Wähle einen Standardbranch für Pull-Requests und Code-Commits: -settings.merge_style_desc=Styles zusammenführen +settings.merge_style_desc=Merge-Styles settings.default_merge_style_desc=Standard Mergeverhalten für Pull Requests: settings.choose_branch=Wähle einen Branch … settings.no_protected_branch=Es gibt keine geschützten Branches. @@ -3124,13 +3124,13 @@ notices.delete_success=Diese Systemmeldung wurde gelöscht. create_repo=hat das Repository %s erstellt rename_repo=hat das Repository von %[1]s zu %[3]s umbenannt commit_repo=hat %[3]s auf %[4]s gepusht -create_issue=`hat Ticket %[3]s#%[2]s geöffnet` -close_issue=`Ticket %[3]s#%[2]s geschlossen` -reopen_issue=`Ticket %[3]s#%[2]s wiedereröffnet` +create_issue=`hat das Issue %[3]s#%[2]s geöffnet` +close_issue=`hat das Issue %[3]s#%[2]s geschlossen` +reopen_issue=`hat das Issue %[3]s#%[2]s wiedereröffnet` create_pull_request=`hat den Pull-Request %[3]s#%[2]s erstellt` close_pull_request=`Pull-Request %[3]s#%[2]s wurde geschlossen` reopen_pull_request=`Pull-Request %[3]s#%[2]s wurde wiedereröffnet` -comment_issue=`Ticket %[3]s#%[2]s wurde kommentiert` +comment_issue=`hat das Issue %[3]s#%[2]s kommentiert` comment_pull=`Pull-Request %[3]s#%[2]s wurde kommentiert` merge_pull_request=`Pull-Request %[3]s#%[2]s wurde zusammengeführt` auto_merge_pull_request=`Pull-Request %[3]s#%[2]s wurde automatisch zusammengeführt` From 865d2221c0f4b2a8623ff9299930c9bab0da2c78 Mon Sep 17 00:00:00 2001 From: Kerwin Bryant Date: Fri, 4 Aug 2023 10:21:32 +0800 Subject: [PATCH 046/200] Add `Retry` button when creating a mirror-repo fails (#26228) fixed #26156 * Added a retry button in the frontend (only displayed when the status is abnormal) * After clicking Retry, the backend adds the task back to the task queue ![7UJDNM671RI})EA8~~XPL39](https://github.com/go-gitea/gitea/assets/3371163/e088fd63-5dcc-4bc6-8849-7db3086511b7) ![T83F1WL9)VGHR@MB956$VT9](https://github.com/go-gitea/gitea/assets/3371163/744425bb-dde1-4315-be2e-5c99ac3a44d4) --------- Co-authored-by: wxiaoguang --- options/locale/locale_en-US.ini | 1 + routers/web/repo/migrate.go | 9 +++++++++ routers/web/web.go | 6 +++++- services/task/task.go | 24 ++++++++++++++++++++++++ templates/repo/migrate/migrating.tmpl | 5 +++-- web_src/js/features/repo-migrate.js | 16 +++++++++++++++- 6 files changed, 57 insertions(+), 4 deletions(-) diff --git a/options/locale/locale_en-US.ini b/options/locale/locale_en-US.ini index 24087cdd1b..b2eeab617e 100644 --- a/options/locale/locale_en-US.ini +++ b/options/locale/locale_en-US.ini @@ -80,6 +80,7 @@ milestones = Milestones ok = OK cancel = Cancel +retry = Retry rerun = Re-run rerun_all = Re-run all jobs save = Save diff --git a/routers/web/repo/migrate.go b/routers/web/repo/migrate.go index b918650d1d..a6125a1a58 100644 --- a/routers/web/repo/migrate.go +++ b/routers/web/repo/migrate.go @@ -259,6 +259,15 @@ func setMigrationContextData(ctx *context.Context, serviceType structs.GitServic ctx.Data["service"] = serviceType } +func MigrateRetryPost(ctx *context.Context) { + if err := task.RetryMigrateTask(ctx.Repo.Repository.ID); err != nil { + log.Error("Retry task failed: %v", err) + ctx.ServerError("task.RetryMigrateTask", err) + return + } + ctx.JSONOK() +} + func MigrateCancelPost(ctx *context.Context) { migratingTask, err := admin_model.GetMigratingTask(ctx.Repo.Repository.ID) if err != nil { diff --git a/routers/web/web.go b/routers/web/web.go index ca75bd5967..aa3d830f94 100644 --- a/routers/web/web.go +++ b/routers/web/web.go @@ -953,7 +953,11 @@ func registerRoutes(m *web.Route) { addSettingsSecretsRoutes() addSettingVariablesRoutes() }, actions.MustEnableActions) - m.Post("/migrate/cancel", repo.MigrateCancelPost) // this handler must be under "settings", otherwise this incomplete repo can't be accessed + // the follow handler must be under "settings", otherwise this incomplete repo can't be accessed + m.Group("/migrate", func() { + m.Post("/retry", repo.MigrateRetryPost) + m.Post("/cancel", repo.MigrateCancelPost) + }) }, ctxDataSet("PageIsRepoSettings", true, "LFSStartServer", setting.LFS.StartServer)) }, reqSignIn, context.RepoAssignment, context.UnitTypes(), reqRepoAdmin, context.RepoRef()) diff --git a/services/task/task.go b/services/task/task.go index 11a47a68bb..db5c1dd3f8 100644 --- a/services/task/task.go +++ b/services/task/task.go @@ -126,3 +126,27 @@ func CreateMigrateTask(doer, u *user_model.User, opts base.MigrateOptions) (*adm return task, nil } + +// RetryMigrateTask retry a migrate task +func RetryMigrateTask(repoID int64) error { + migratingTask, err := admin_model.GetMigratingTask(repoID) + if err != nil { + log.Error("GetMigratingTask: %v", err) + return err + } + if migratingTask.Status == structs.TaskStatusQueued || migratingTask.Status == structs.TaskStatusRunning { + return nil + } + + // TODO Need to removing the storage/database garbage brought by the failed task + + // Reset task status and messages + migratingTask.Status = structs.TaskStatusQueued + migratingTask.Message = "" + if err = migratingTask.UpdateCols("status", "message"); err != nil { + log.Error("task.UpdateCols failed: %v", err) + return err + } + + return taskQueue.Push(migratingTask) +} diff --git a/templates/repo/migrate/migrating.tmpl b/templates/repo/migrate/migrating.tmpl index 50bff0a937..d1bdc5a90f 100644 --- a/templates/repo/migrate/migrating.tmpl +++ b/templates/repo/migrate/migrating.tmpl @@ -36,10 +36,11 @@
    {{if .Failed}} - + {{else}} - + {{end}} +
    {{end}}
    diff --git a/web_src/js/features/repo-migrate.js b/web_src/js/features/repo-migrate.js index e57348d31b..de9f7b023c 100644 --- a/web_src/js/features/repo-migrate.js +++ b/web_src/js/features/repo-migrate.js @@ -1,12 +1,14 @@ import $ from 'jquery'; import {hideElem, showElem} from '../utils/dom.js'; -const {appSubUrl} = window.config; +const {appSubUrl, csrfToken} = window.config; export function initRepoMigrationStatusChecker() { const $repoMigrating = $('#repo_migrating'); if (!$repoMigrating.length) return; + $('#repo_migrating_retry').on('click', doMigrationRetry); + const task = $repoMigrating.attr('data-migrating-task-id'); // returns true if the refresh still need to be called after a while @@ -31,6 +33,7 @@ export function initRepoMigrationStatusChecker() { if (data.status === 3) { hideElem('#repo_migrating_progress'); hideElem('#repo_migrating'); + showElem('#repo_migrating_retry'); showElem('#repo_migrating_failed'); showElem('#repo_migrating_failed_image'); $('#repo_migrating_failed_error').text(data.message); @@ -53,3 +56,14 @@ export function initRepoMigrationStatusChecker() { syncTaskStatus(); // no await } + +async function doMigrationRetry(e) { + await fetch($(e.target).attr('data-migrating-task-retry-url'), { + method: 'post', + headers: { + 'X-Csrf-Token': csrfToken, + 'Content-Type': 'application/json', + }, + }); + window.location.reload(); +} From 8a2f019d69324f47331afb87d6f7cd85fc1cfe68 Mon Sep 17 00:00:00 2001 From: Zettat123 Date: Fri, 4 Aug 2023 10:53:15 +0800 Subject: [PATCH 047/200] Support getting changed files when commit ID is `EmptySHA` (#26290) Fixes #26270. Co-Author: @wxiaoguang Thanks @lunny for providing this solution As https://github.com/go-gitea/gitea/issues/26270#issuecomment-1661695151 said, at present we cannot get the names of changed files correctly when the `OldCommitID` is `EmptySHA`. In this PR, the `GetCommitFilesChanged` method is added and will be used to get the changed files by commit ID. References: - https://stackoverflow.com/a/424142 --------- Co-authored-by: wxiaoguang --- modules/git/repo_compare.go | 10 +++++++- modules/git/repo_compare_test.go | 39 ++++++++++++++++++++++++++++++++ modules/git/sha1.go | 4 ++-- 3 files changed, 50 insertions(+), 3 deletions(-) diff --git a/modules/git/repo_compare.go b/modules/git/repo_compare.go index e706275856..aad725fa9d 100644 --- a/modules/git/repo_compare.go +++ b/modules/git/repo_compare.go @@ -280,8 +280,16 @@ func (repo *Repository) GetPatch(base, head string, w io.Writer) error { } // GetFilesChangedBetween returns a list of all files that have been changed between the given commits +// If base is undefined empty SHA (zeros), it only returns the files changed in the head commit +// If base is the SHA of an empty tree (EmptyTreeSHA), it returns the files changes from the initial commit to the head commit func (repo *Repository) GetFilesChangedBetween(base, head string) ([]string, error) { - stdout, _, err := NewCommand(repo.Ctx, "diff", "--name-only", "-z").AddDynamicArguments(base + ".." + head).RunStdString(&RunOpts{Dir: repo.Path}) + cmd := NewCommand(repo.Ctx, "diff-tree", "--name-only", "--root", "--no-commit-id", "-r", "-z") + if base == EmptySHA { + cmd.AddDynamicArguments(head) + } else { + cmd.AddDynamicArguments(base, head) + } + stdout, _, err := cmd.RunStdString(&RunOpts{Dir: repo.Path}) if err != nil { return nil, err } diff --git a/modules/git/repo_compare_test.go b/modules/git/repo_compare_test.go index 5b50bc82ad..603aabde42 100644 --- a/modules/git/repo_compare_test.go +++ b/modules/git/repo_compare_test.go @@ -119,3 +119,42 @@ func TestReadWritePullHead(t *testing.T) { err = repo.RemoveReference(PullPrefix + "1/head") assert.NoError(t, err) } + +func TestGetCommitFilesChanged(t *testing.T) { + bareRepo1Path := filepath.Join(testReposDir, "repo1_bare") + repo, err := openRepositoryWithDefaultContext(bareRepo1Path) + assert.NoError(t, err) + defer repo.Close() + + testCases := []struct { + base, head string + files []string + }{ + { + EmptySHA, + "95bb4d39648ee7e325106df01a621c530863a653", + []string{"file1.txt"}, + }, + { + EmptySHA, + "8d92fc957a4d7cfd98bc375f0b7bb189a0d6c9f2", + []string{"file2.txt"}, + }, + { + "95bb4d39648ee7e325106df01a621c530863a653", + "8d92fc957a4d7cfd98bc375f0b7bb189a0d6c9f2", + []string{"file2.txt"}, + }, + { + EmptyTreeSHA, + "8d92fc957a4d7cfd98bc375f0b7bb189a0d6c9f2", + []string{"file1.txt", "file2.txt"}, + }, + } + + for _, tc := range testCases { + changedFiles, err := repo.GetFilesChangedBetween(tc.base, tc.head) + assert.NoError(t, err) + assert.ElementsMatch(t, tc.files, changedFiles) + } +} diff --git a/modules/git/sha1.go b/modules/git/sha1.go index 7d9d9776da..8d6403e865 100644 --- a/modules/git/sha1.go +++ b/modules/git/sha1.go @@ -11,10 +11,10 @@ import ( "strings" ) -// EmptySHA defines empty git SHA +// EmptySHA defines empty git SHA (undefined, non-existent) const EmptySHA = "0000000000000000000000000000000000000000" -// EmptyTreeSHA is the SHA of an empty tree +// EmptyTreeSHA is the SHA of an empty tree, the root of all git repositories const EmptyTreeSHA = "4b825dc642cb6eb9a060e54bf8d69288fbee4904" // SHAFullLength is the full length of a git SHA From 96f151392fec45c7356ce741ab60a602ab75a76e Mon Sep 17 00:00:00 2001 From: Lunny Xiao Date: Fri, 4 Aug 2023 11:41:16 +0800 Subject: [PATCH 048/200] Fix the wrong derive path (#26271) This PR will fix #26264, caused by #23911. The package configuration derive is totally wrong when storage type is local in that PR. This PR fixed the inherit logic when storage type is local with some unit tests. --------- Co-authored-by: wxiaoguang --- modules/setting/storage.go | 73 +++++++++++---- modules/setting/storage_test.go | 159 ++++++++++++++++++++++++++++++++ 2 files changed, 215 insertions(+), 17 deletions(-) diff --git a/modules/setting/storage.go b/modules/setting/storage.go index ed804a910a..c28f2be4ed 100644 --- a/modules/setting/storage.go +++ b/modules/setting/storage.go @@ -84,12 +84,15 @@ func getDefaultStorageSection(rootCfg ConfigProvider) ConfigSection { return storageSec } +// getStorage will find target section and extra special section first and then read override +// items from extra section func getStorage(rootCfg ConfigProvider, name, typ string, sec ConfigSection) (*Storage, error) { if name == "" { return nil, errors.New("no name for storage") } var targetSec ConfigSection + // check typ first if typ != "" { var err error targetSec, err = rootCfg.GetSection(storageSectionName + "." + typ) @@ -111,24 +114,40 @@ func getStorage(rootCfg ConfigProvider, name, typ string, sec ConfigSection) (*S } } - storageNameSec, _ := rootCfg.GetSection(storageSectionName + "." + name) - - if targetSec == nil { - targetSec = sec + if targetSec == nil && sec != nil { + secTyp := sec.Key("STORAGE_TYPE").String() + if IsValidStorageType(StorageType(secTyp)) { + targetSec = sec + } else if secTyp != "" { + targetSec, _ = rootCfg.GetSection(storageSectionName + "." + secTyp) + } } + + targetSecIsStoragename := false + storageNameSec, _ := rootCfg.GetSection(storageSectionName + "." + name) if targetSec == nil { targetSec = storageNameSec + targetSecIsStoragename = storageNameSec != nil } + if targetSec == nil { targetSec = getDefaultStorageSection(rootCfg) } else { targetType := targetSec.Key("STORAGE_TYPE").String() switch { case targetType == "": - if targetSec.Key("PATH").String() == "" { - targetSec = getDefaultStorageSection(rootCfg) + if targetSec != storageNameSec && storageNameSec != nil { + targetSec = storageNameSec + targetSecIsStoragename = true + if targetSec.Key("STORAGE_TYPE").String() == "" { + return nil, fmt.Errorf("storage section %s.%s has no STORAGE_TYPE", storageSectionName, name) + } } else { - targetSec.Key("STORAGE_TYPE").SetValue("local") + if targetSec.Key("PATH").String() == "" { + targetSec = getDefaultStorageSection(rootCfg) + } else { + targetSec.Key("STORAGE_TYPE").SetValue("local") + } } default: newTargetSec, _ := rootCfg.GetSection(storageSectionName + "." + targetType) @@ -153,26 +172,46 @@ func getStorage(rootCfg ConfigProvider, name, typ string, sec ConfigSection) (*S return nil, fmt.Errorf("invalid storage type %q", targetType) } + // extra config section will be read SERVE_DIRECT, PATH, MINIO_BASE_PATH, MINIO_BUCKET to override the targetsec when possible + extraConfigSec := sec + if extraConfigSec == nil { + extraConfigSec = storageNameSec + } + var storage Storage storage.Type = StorageType(targetType) switch targetType { case string(LocalStorageType): - storage.Path = ConfigSectionKeyString(targetSec, "PATH", filepath.Join(AppDataPath, name)) - if !filepath.IsAbs(storage.Path) { - storage.Path = filepath.Join(AppWorkPath, storage.Path) + targetPath := ConfigSectionKeyString(targetSec, "PATH", "") + if targetPath == "" { + targetPath = AppDataPath + } else if !filepath.IsAbs(targetPath) { + targetPath = filepath.Join(AppDataPath, targetPath) } - case string(MinioStorageType): - storage.MinioConfig.BasePath = name + "/" + var fallbackPath string + if targetSecIsStoragename { + fallbackPath = targetPath + } else { + fallbackPath = filepath.Join(targetPath, name) + } + + if extraConfigSec == nil { + storage.Path = fallbackPath + } else { + storage.Path = ConfigSectionKeyString(extraConfigSec, "PATH", fallbackPath) + if !filepath.IsAbs(storage.Path) { + storage.Path = filepath.Join(targetPath, storage.Path) + } + } + + case string(MinioStorageType): if err := targetSec.MapTo(&storage.MinioConfig); err != nil { return nil, fmt.Errorf("map minio config failed: %v", err) } - // extra config section will be read SERVE_DIRECT, PATH, MINIO_BASE_PATH to override the targetsec - extraConfigSec := sec - if extraConfigSec == nil { - extraConfigSec = storageNameSec - } + + storage.MinioConfig.BasePath = name + "/" if extraConfigSec != nil { storage.MinioConfig.ServeDirect = ConfigSectionKeyBool(extraConfigSec, "SERVE_DIRECT", storage.MinioConfig.ServeDirect) diff --git a/modules/setting/storage_test.go b/modules/setting/storage_test.go index 4eda7646e8..9a83f31d91 100644 --- a/modules/setting/storage_test.go +++ b/modules/setting/storage_test.go @@ -4,6 +4,7 @@ package setting import ( + "path/filepath" "testing" "github.com/stretchr/testify/assert" @@ -90,3 +91,161 @@ STORAGE_TYPE = minio assert.EqualValues(t, "gitea", RepoAvatar.Storage.MinioConfig.Bucket) assert.EqualValues(t, "repo-avatars/", RepoAvatar.Storage.MinioConfig.BasePath) } + +type testLocalStoragePathCase struct { + loader func(rootCfg ConfigProvider) error + storagePtr **Storage + expectedPath string +} + +func testLocalStoragePath(t *testing.T, appDataPath, iniStr string, cases []testLocalStoragePathCase) { + cfg, err := NewConfigProviderFromData(iniStr) + assert.NoError(t, err) + AppDataPath = appDataPath + for _, c := range cases { + assert.NoError(t, c.loader(cfg)) + storage := *c.storagePtr + + assert.EqualValues(t, "local", storage.Type) + assert.True(t, filepath.IsAbs(storage.Path)) + assert.EqualValues(t, filepath.Clean(c.expectedPath), filepath.Clean(storage.Path)) + } +} + +func Test_getStorageInheritStorageTypeLocal(t *testing.T) { + testLocalStoragePath(t, "/appdata", ` +[storage] +STORAGE_TYPE = local +`, []testLocalStoragePathCase{ + {loadPackagesFrom, &Packages.Storage, "/appdata/packages"}, + {loadRepoArchiveFrom, &RepoArchive.Storage, "/appdata/repo-archive"}, + {loadActionsFrom, &Actions.LogStorage, "/appdata/actions_log"}, + {loadAvatarsFrom, &Avatar.Storage, "/appdata/avatars"}, + {loadRepoAvatarFrom, &RepoAvatar.Storage, "/appdata/repo-avatars"}, + }) +} + +func Test_getStorageInheritStorageTypeLocalPath(t *testing.T) { + testLocalStoragePath(t, "/appdata", ` +[storage] +STORAGE_TYPE = local +PATH = /data/gitea +`, []testLocalStoragePathCase{ + {loadPackagesFrom, &Packages.Storage, "/data/gitea/packages"}, + {loadRepoArchiveFrom, &RepoArchive.Storage, "/data/gitea/repo-archive"}, + {loadActionsFrom, &Actions.LogStorage, "/data/gitea/actions_log"}, + {loadAvatarsFrom, &Avatar.Storage, "/data/gitea/avatars"}, + {loadRepoAvatarFrom, &RepoAvatar.Storage, "/data/gitea/repo-avatars"}, + }) +} + +func Test_getStorageInheritStorageTypeLocalRelativePath(t *testing.T) { + testLocalStoragePath(t, "/appdata", ` +[storage] +STORAGE_TYPE = local +PATH = storages +`, []testLocalStoragePathCase{ + {loadPackagesFrom, &Packages.Storage, "/appdata/storages/packages"}, + {loadRepoArchiveFrom, &RepoArchive.Storage, "/appdata/storages/repo-archive"}, + {loadActionsFrom, &Actions.LogStorage, "/appdata/storages/actions_log"}, + {loadAvatarsFrom, &Avatar.Storage, "/appdata/storages/avatars"}, + {loadRepoAvatarFrom, &RepoAvatar.Storage, "/appdata/storages/repo-avatars"}, + }) +} + +func Test_getStorageInheritStorageTypeLocalPathOverride(t *testing.T) { + testLocalStoragePath(t, "/appdata", ` +[storage] +STORAGE_TYPE = local +PATH = /data/gitea + +[repo-archive] +PATH = /data/gitea/the-archives-dir +`, []testLocalStoragePathCase{ + {loadPackagesFrom, &Packages.Storage, "/data/gitea/packages"}, + {loadRepoArchiveFrom, &RepoArchive.Storage, "/data/gitea/the-archives-dir"}, + {loadActionsFrom, &Actions.LogStorage, "/data/gitea/actions_log"}, + {loadAvatarsFrom, &Avatar.Storage, "/data/gitea/avatars"}, + {loadRepoAvatarFrom, &RepoAvatar.Storage, "/data/gitea/repo-avatars"}, + }) +} + +func Test_getStorageInheritStorageTypeLocalPathOverrideEmpty(t *testing.T) { + testLocalStoragePath(t, "/appdata", ` +[storage] +STORAGE_TYPE = local +PATH = /data/gitea + +[repo-archive] +`, []testLocalStoragePathCase{ + {loadPackagesFrom, &Packages.Storage, "/data/gitea/packages"}, + {loadRepoArchiveFrom, &RepoArchive.Storage, "/data/gitea/repo-archive"}, + {loadActionsFrom, &Actions.LogStorage, "/data/gitea/actions_log"}, + {loadAvatarsFrom, &Avatar.Storage, "/data/gitea/avatars"}, + {loadRepoAvatarFrom, &RepoAvatar.Storage, "/data/gitea/repo-avatars"}, + }) +} + +func Test_getStorageInheritStorageTypeLocalRelativePathOverride(t *testing.T) { + testLocalStoragePath(t, "/appdata", ` +[storage] +STORAGE_TYPE = local +PATH = /data/gitea + +[repo-archive] +PATH = the-archives-dir +`, []testLocalStoragePathCase{ + {loadPackagesFrom, &Packages.Storage, "/data/gitea/packages"}, + {loadRepoArchiveFrom, &RepoArchive.Storage, "/data/gitea/the-archives-dir"}, + {loadActionsFrom, &Actions.LogStorage, "/data/gitea/actions_log"}, + {loadAvatarsFrom, &Avatar.Storage, "/data/gitea/avatars"}, + {loadRepoAvatarFrom, &RepoAvatar.Storage, "/data/gitea/repo-avatars"}, + }) +} + +func Test_getStorageInheritStorageTypeLocalPathOverride3(t *testing.T) { + testLocalStoragePath(t, "/appdata", ` +[storage.repo-archive] +STORAGE_TYPE = local +PATH = /data/gitea/archives +`, []testLocalStoragePathCase{ + {loadPackagesFrom, &Packages.Storage, "/appdata/packages"}, + {loadRepoArchiveFrom, &RepoArchive.Storage, "/data/gitea/archives"}, + {loadActionsFrom, &Actions.LogStorage, "/appdata/actions_log"}, + {loadAvatarsFrom, &Avatar.Storage, "/appdata/avatars"}, + {loadRepoAvatarFrom, &RepoAvatar.Storage, "/appdata/repo-avatars"}, + }) +} + +func Test_getStorageInheritStorageTypeLocalPathOverride4(t *testing.T) { + testLocalStoragePath(t, "/appdata", ` +[storage.repo-archive] +STORAGE_TYPE = local +PATH = /data/gitea/archives + +[repo-archive] +PATH = /tmp/gitea/archives +`, []testLocalStoragePathCase{ + {loadPackagesFrom, &Packages.Storage, "/appdata/packages"}, + {loadRepoArchiveFrom, &RepoArchive.Storage, "/tmp/gitea/archives"}, + {loadActionsFrom, &Actions.LogStorage, "/appdata/actions_log"}, + {loadAvatarsFrom, &Avatar.Storage, "/appdata/avatars"}, + {loadRepoAvatarFrom, &RepoAvatar.Storage, "/appdata/repo-avatars"}, + }) +} + +func Test_getStorageInheritStorageTypeLocalPathOverride5(t *testing.T) { + testLocalStoragePath(t, "/appdata", ` +[storage.repo-archive] +STORAGE_TYPE = local +PATH = /data/gitea/archives + +[repo-archive] +`, []testLocalStoragePathCase{ + {loadPackagesFrom, &Packages.Storage, "/appdata/packages"}, + {loadRepoArchiveFrom, &RepoArchive.Storage, "/data/gitea/archives"}, + {loadActionsFrom, &Actions.LogStorage, "/appdata/actions_log"}, + {loadAvatarsFrom, &Avatar.Storage, "/appdata/avatars"}, + {loadRepoAvatarFrom, &RepoAvatar.Storage, "/appdata/repo-avatars"}, + }) +} From 0da8ebc95b04334d4845f5a50b0404d4b78188aa Mon Sep 17 00:00:00 2001 From: sillyguodong <33891828+sillyguodong@users.noreply.github.com> Date: Fri, 4 Aug 2023 17:06:02 +0800 Subject: [PATCH 049/200] Update documentation for 1.21 actions (#26317) As title. Close #26309 Related to #24724, #24806 --- .../content/usage/actions/act-runner.en-us.md | 32 +++++++++++++++++-- .../content/usage/actions/act-runner.zh-cn.md | 32 +++++++++++++++++-- 2 files changed, 60 insertions(+), 4 deletions(-) diff --git a/docs/content/usage/actions/act-runner.en-us.md b/docs/content/usage/actions/act-runner.en-us.md index 05ed83c2c4..eec8ac6ccc 100644 --- a/docs/content/usage/actions/act-runner.en-us.md +++ b/docs/content/usage/actions/act-runner.en-us.md @@ -245,8 +245,7 @@ You can find more useful images on [act images](https://github.com/nektos/act/bl If you want to run jobs in the host directly, you can change it to `ubuntu-22.04:host` or just `ubuntu-22.04`, the `:host` is optional. However, we suggest you to use a special name like `linux_amd64:host` or `windows:host` to avoid misusing it. -One more thing is that it is recommended to register the runner if you want to change the labels. -It may be annoying to do this, so we may provide a better way to do it in the future. +After Gitea 1.21 released, you can change labels by modfiying `container.labels` in configuration file (if you don't have a configuration file, please refer to [configuration tutorials](#configuration)), and runner will declare the new labels which you defined in configuration file after executing `./act_runner daemon --config config.yaml`. ## Running @@ -261,3 +260,32 @@ After you have registered the runner, you can run it by running the following co The runner will fetch jobs from the Gitea instance and run them automatically. Since act runner is still in development, it is recommended to check the latest version and upgrade it regularly. + +## Configuration variable + +You can create configuration varibales with user, organization, repository level. And the level of the variable depends on which setting panel you created in. + +### Naming conventions + +The following rules apply to variable names: + +- Varibale names can only contain alphanumeric characters (`[a-z]`, `[A-Z]`, `[0-9]`) or underscores (`_`). Spaces are not allowed. + +- Varibale names must not start with the `GITHUB_` and `GITEA_` prefix. + +- Varibale names must not start with a number. + +- Varibale names are not case-sensitive. + +- Varibale names must be unique at the level they are created at. + +- Varibale names must not be 'CI'. + +### Using varibales + +After creating configuration varibales, they will be automatically filled in the `vars` context. They are available to you with expression like `{{ vars.VARIABLE_NAME }}` in workflow. + +### Precedence + +If a variable with the same name exists at multiple levels, the variable at the lowest level takes precedence(the level of organization and user is higher than repository's). +For example, if an organization-level variable has the same name as a repository-level variable, then the repository-level variable takes precedence. diff --git a/docs/content/usage/actions/act-runner.zh-cn.md b/docs/content/usage/actions/act-runner.zh-cn.md index c3978f6361..2f60da50af 100644 --- a/docs/content/usage/actions/act-runner.zh-cn.md +++ b/docs/content/usage/actions/act-runner.zh-cn.md @@ -241,8 +241,7 @@ Runner的标签用于确定Runner可以运行哪些Job以及如何运行它们 如果您想直接在主机上运行Job,您可以将其更改为`ubuntu-22.04:host`或仅`ubuntu-22.04`,`:host`是可选的。 然而,我们建议您使用类似`linux_amd64:host`或`windows:host`的特殊名称,以避免误用。 -还有一点需要注意的是,建议在更改标签时注册Runner。 -这可能会有些麻烦,所以我们可能会在将来提供更好的方法来处理。 +Gitea 1.21 发布后,您可以通过修改配置文件中的 `container.labels` 来更改标签(如果没有配置文件,请参考 [配置教程](#配置)),执行 `./act_runner daemon --config config.yaml` 命令后,它会向 Gitea 声明您在配置文件中定义的新标签。 ## 运行 @@ -257,3 +256,32 @@ Runner的标签用于确定Runner可以运行哪些Job以及如何运行它们 Runner将从Gitea实例获取Job并自动运行它们。 由于Act Runner仍处于开发中,建议定期检查最新版本并进行升级。 + +## 变量 + +您可以创建用户、组织和仓库级别的变量。变量的级别是取决于你在哪个设置面板中创建它们的。 + +### 命名规则 + +以下规则适用于变量名: + +- 变量名称只能包含字母数字字符 (`[a-z]`, `[A-Z]`, `[0-9]`) 或下划线 (`_`)。不允许使用空格。 + +- 变量名称不能以 `GITHUB_` 和 `GITEA_` 前缀开头。 + +- 变量名称不能以数字开头。 + +- 变量名称不区分大小写。 + +- 变量名称在创建它们的级别上必须是唯一的。 + +- 变量名称不能为 “CI”。 + +### 使用 + +创建配置变量后,它们将自动填充到 `vars` 上下文中。您可以在工作流中使用类似 `{{ vars.VARIABLE_NAME }}` 这样的表达式来使用它们。 + +### 优先级 + +如果同名变量存在于多个级别,则级别最低的变量优先(组织和用户的级别高于仓库)。 +比如,如果组织级变量与仓库级变量同名,则仓库变量优先。 From 68c652d8f3df9daa99ce41e0782b44347555a3a5 Mon Sep 17 00:00:00 2001 From: sillyguodong <33891828+sillyguodong@users.noreply.github.com> Date: Fri, 4 Aug 2023 18:04:37 +0800 Subject: [PATCH 050/200] Fix typos and grammer problems for actions documentation (#26328) follow #26317 fix typos and adjust grammer problems. --- .../content/usage/actions/act-runner.en-us.md | 27 ++++++++++--------- .../content/usage/actions/act-runner.zh-cn.md | 8 +++--- 2 files changed, 19 insertions(+), 16 deletions(-) diff --git a/docs/content/usage/actions/act-runner.en-us.md b/docs/content/usage/actions/act-runner.en-us.md index eec8ac6ccc..1be81c5c78 100644 --- a/docs/content/usage/actions/act-runner.en-us.md +++ b/docs/content/usage/actions/act-runner.en-us.md @@ -245,7 +245,8 @@ You can find more useful images on [act images](https://github.com/nektos/act/bl If you want to run jobs in the host directly, you can change it to `ubuntu-22.04:host` or just `ubuntu-22.04`, the `:host` is optional. However, we suggest you to use a special name like `linux_amd64:host` or `windows:host` to avoid misusing it. -After Gitea 1.21 released, you can change labels by modfiying `container.labels` in configuration file (if you don't have a configuration file, please refer to [configuration tutorials](#configuration)), and runner will declare the new labels which you defined in configuration file after executing `./act_runner daemon --config config.yaml`. +Starting with Gitea 1.21, you can change labels by modifying `container.labels` in the runner configuration file (if you don't have a configuration file, please refer to [configuration tutorials](#configuration)). +The runner will use these new labels as soon as you restart it, i.e., by calling `./act_runner daemon --config config.yaml`. ## Running @@ -263,29 +264,31 @@ Since act runner is still in development, it is recommended to check the latest ## Configuration variable -You can create configuration varibales with user, organization, repository level. And the level of the variable depends on which setting panel you created in. +You can create configuration variables on the user, organization and repository level. +The level of the variable depends on where you created it. ### Naming conventions The following rules apply to variable names: -- Varibale names can only contain alphanumeric characters (`[a-z]`, `[A-Z]`, `[0-9]`) or underscores (`_`). Spaces are not allowed. +- Variable names can only contain alphanumeric characters (`[a-z]`, `[A-Z]`, `[0-9]`) or underscores (`_`). Spaces are not allowed. -- Varibale names must not start with the `GITHUB_` and `GITEA_` prefix. +- Variable names must not start with the `GITHUB_` and `GITEA_` prefix. -- Varibale names must not start with a number. +- Variable names must not start with a number. -- Varibale names are not case-sensitive. +- Variable names are case-insensitive. -- Varibale names must be unique at the level they are created at. +- Variable names must be unique at the level they are created at. -- Varibale names must not be 'CI'. +- Variable names must not be `CI`. -### Using varibales +### Using variable -After creating configuration varibales, they will be automatically filled in the `vars` context. They are available to you with expression like `{{ vars.VARIABLE_NAME }}` in workflow. +After creating configuration variables, they will be automatically filled in the `vars` context. +They can be accessed through expressions like `{{ vars.VARIABLE_NAME }}` in the workflow. ### Precedence -If a variable with the same name exists at multiple levels, the variable at the lowest level takes precedence(the level of organization and user is higher than repository's). -For example, if an organization-level variable has the same name as a repository-level variable, then the repository-level variable takes precedence. +If a variable with the same name exists at multiple levels, the variable at the lowest level takes precedence: +A repository variable will always be chosen over an organization/user variable. diff --git a/docs/content/usage/actions/act-runner.zh-cn.md b/docs/content/usage/actions/act-runner.zh-cn.md index 2f60da50af..f1404bf0b4 100644 --- a/docs/content/usage/actions/act-runner.zh-cn.md +++ b/docs/content/usage/actions/act-runner.zh-cn.md @@ -241,7 +241,7 @@ Runner的标签用于确定Runner可以运行哪些Job以及如何运行它们 如果您想直接在主机上运行Job,您可以将其更改为`ubuntu-22.04:host`或仅`ubuntu-22.04`,`:host`是可选的。 然而,我们建议您使用类似`linux_amd64:host`或`windows:host`的特殊名称,以避免误用。 -Gitea 1.21 发布后,您可以通过修改配置文件中的 `container.labels` 来更改标签(如果没有配置文件,请参考 [配置教程](#配置)),执行 `./act_runner daemon --config config.yaml` 命令后,它会向 Gitea 声明您在配置文件中定义的新标签。 +从 Gitea 1.21 开始,您可以通过修改 runner 的配置文件中的 `container.labels` 来更改标签(如果没有配置文件,请参考 [配置教程](#配置)),通过执行 `./act_runner daemon --config config.yaml` 命令重启 runner 之后,这些新定义的标签就会生效。 ## 运行 @@ -259,7 +259,7 @@ Runner将从Gitea实例获取Job并自动运行它们。 ## 变量 -您可以创建用户、组织和仓库级别的变量。变量的级别是取决于你在哪个设置面板中创建它们的。 +您可以创建用户、组织和仓库级别的变量。变量的级别取决于创建它的位置。 ### 命名规则 @@ -283,5 +283,5 @@ Runner将从Gitea实例获取Job并自动运行它们。 ### 优先级 -如果同名变量存在于多个级别,则级别最低的变量优先(组织和用户的级别高于仓库)。 -比如,如果组织级变量与仓库级变量同名,则仓库变量优先。 +如果同名变量存在于多个级别,则级别最低的变量优先。 +仓库级别的变量总是比组织或者用户级别的变量优先被选中。 From 2de0752be7aaab65fe670518d00175be479ea054 Mon Sep 17 00:00:00 2001 From: wxiaoguang Date: Fri, 4 Aug 2023 20:50:41 +0800 Subject: [PATCH 051/200] Make git batch operations use parent context timeout instead of default timeout (#26325) Fix #26064 Some git commands should use parent context, otherwise it would exit too early (by the default timeout, 10m), and the "cmd.Wait" waits till the pipes are closed. --- modules/git/batch_reader.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/modules/git/batch_reader.go b/modules/git/batch_reader.go index 891e8a2384..7a44e6295c 100644 --- a/modules/git/batch_reader.go +++ b/modules/git/batch_reader.go @@ -74,6 +74,8 @@ func CatFileBatchCheck(ctx context.Context, repoPath string) (WriteCloserError, Stdin: batchStdinReader, Stdout: batchStdoutWriter, Stderr: &stderr, + + UseContextTimeout: true, }) if err != nil { _ = batchStdoutWriter.CloseWithError(ConcatenateError(err, (&stderr).String())) @@ -124,6 +126,8 @@ func CatFileBatch(ctx context.Context, repoPath string) (WriteCloserError, *bufi Stdin: batchStdinReader, Stdout: batchStdoutWriter, Stderr: &stderr, + + UseContextTimeout: true, }) if err != nil { _ = batchStdoutWriter.CloseWithError(ConcatenateError(err, (&stderr).String())) From 6151e69d9509c08e25e93743d6b31211371e81d0 Mon Sep 17 00:00:00 2001 From: caicandong <50507092+CaiCandong@users.noreply.github.com> Date: Fri, 4 Aug 2023 21:34:34 +0800 Subject: [PATCH 052/200] Delete `issue_service.CreateComment` (#26298) I noticed that `issue_service.CreateComment` adds transaction operations on `issues_model.CreateComment`, we can merge the two functions and we can avoid calling each other's methods in the `services` layer. Co-authored-by: Giteabot --- models/issues/comment.go | 10 +++++++++- services/issue/comments.go | 24 ++---------------------- services/pull/comment.go | 3 +-- services/pull/pull.go | 4 ++-- services/pull/review.go | 7 +++---- 5 files changed, 17 insertions(+), 31 deletions(-) diff --git a/models/issues/comment.go b/models/issues/comment.go index be020b2e1f..e781931261 100644 --- a/models/issues/comment.go +++ b/models/issues/comment.go @@ -777,6 +777,12 @@ func (c *Comment) LoadPushCommits(ctx context.Context) (err error) { // CreateComment creates comment with context func CreateComment(ctx context.Context, opts *CreateCommentOptions) (_ *Comment, err error) { + ctx, committer, err := db.TxContext(ctx) + if err != nil { + return nil, err + } + defer committer.Close() + e := db.GetEngine(ctx) var LabelID int64 if opts.Label != nil { @@ -832,7 +838,9 @@ func CreateComment(ctx context.Context, opts *CreateCommentOptions) (_ *Comment, if err = comment.AddCrossReferences(ctx, opts.Doer, false); err != nil { return nil, err } - + if err = committer.Commit(); err != nil { + return nil, err + } return comment, nil } diff --git a/services/issue/comments.go b/services/issue/comments.go index ed05f725ff..2c5ef0f5dc 100644 --- a/services/issue/comments.go +++ b/services/issue/comments.go @@ -15,26 +15,6 @@ import ( "code.gitea.io/gitea/modules/timeutil" ) -// CreateComment creates comment of issue or commit. -func CreateComment(ctx context.Context, opts *issues_model.CreateCommentOptions) (comment *issues_model.Comment, err error) { - ctx, committer, err := db.TxContext(ctx) - if err != nil { - return nil, err - } - defer committer.Close() - - comment, err = issues_model.CreateComment(ctx, opts) - if err != nil { - return nil, err - } - - if err = committer.Commit(); err != nil { - return nil, err - } - - return comment, nil -} - // CreateRefComment creates a commit reference comment to issue. func CreateRefComment(ctx context.Context, doer *user_model.User, repo *repo_model.Repository, issue *issues_model.Issue, content, commitSHA string) error { if len(commitSHA) == 0 { @@ -53,7 +33,7 @@ func CreateRefComment(ctx context.Context, doer *user_model.User, repo *repo_mod return nil } - _, err = CreateComment(ctx, &issues_model.CreateCommentOptions{ + _, err = issues_model.CreateComment(ctx, &issues_model.CreateCommentOptions{ Type: issues_model.CommentTypeCommitRef, Doer: doer, Repo: repo, @@ -66,7 +46,7 @@ func CreateRefComment(ctx context.Context, doer *user_model.User, repo *repo_mod // CreateIssueComment creates a plain issue comment. func CreateIssueComment(ctx context.Context, doer *user_model.User, repo *repo_model.Repository, issue *issues_model.Issue, content string, attachments []string) (*issues_model.Comment, error) { - comment, err := CreateComment(ctx, &issues_model.CreateCommentOptions{ + comment, err := issues_model.CreateComment(ctx, &issues_model.CreateCommentOptions{ Type: issues_model.CommentTypeComment, Doer: doer, Repo: repo, diff --git a/services/pull/comment.go b/services/pull/comment.go index 24dfd8af0c..14fba52f1e 100644 --- a/services/pull/comment.go +++ b/services/pull/comment.go @@ -11,7 +11,6 @@ import ( user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/json" - issue_service "code.gitea.io/gitea/services/issue" ) // getCommitIDsFromRepo get commit IDs from repo in between oldCommitID and newCommitID @@ -90,7 +89,7 @@ func CreatePushPullComment(ctx context.Context, pusher *user_model.User, pr *iss ops.Content = string(dataJSON) - comment, err = issue_service.CreateComment(ctx, ops) + comment, err = issues_model.CreateComment(ctx, ops) return comment, err } diff --git a/services/pull/pull.go b/services/pull/pull.go index cf49d2fe20..8730b9684d 100644 --- a/services/pull/pull.go +++ b/services/pull/pull.go @@ -125,7 +125,7 @@ func NewPullRequest(ctx context.Context, repo *repo_model.Repository, pull *issu Content: string(dataJSON), } - _, _ = issue_service.CreateComment(ctx, ops) + _, _ = issues_model.CreateComment(ctx, ops) if !pr.IsWorkInProgress() { if err := issues_model.PullRequestCodeOwnersReview(ctx, pull, pr); err != nil { @@ -231,7 +231,7 @@ func ChangeTargetBranch(ctx context.Context, pr *issues_model.PullRequest, doer OldRef: oldBranch, NewRef: targetBranch, } - if _, err = issue_service.CreateComment(ctx, options); err != nil { + if _, err = issues_model.CreateComment(ctx, options); err != nil { return fmt.Errorf("CreateChangeTargetBranchComment: %w", err) } diff --git a/services/pull/review.go b/services/pull/review.go index 59cc607912..58470142e1 100644 --- a/services/pull/review.go +++ b/services/pull/review.go @@ -20,7 +20,6 @@ import ( "code.gitea.io/gitea/modules/notification" "code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/util" - issue_service "code.gitea.io/gitea/services/issue" ) var notEnoughLines = regexp.MustCompile(`fatal: file .* has only \d+ lines?`) @@ -248,7 +247,7 @@ func createCodeComment(ctx context.Context, doer *user_model.User, repo *repo_mo return nil, err } } - return issue_service.CreateComment(ctx, &issues_model.CreateCommentOptions{ + return issues_model.CreateComment(ctx, &issues_model.CreateCommentOptions{ Type: issues_model.CommentTypeCode, Doer: doer, Repo: repo, @@ -340,7 +339,7 @@ func DismissApprovalReviews(ctx context.Context, doer *user_model.User, pull *is return err } - comment, err := issue_service.CreateComment(ctx, &issues_model.CreateCommentOptions{ + comment, err := issues_model.CreateComment(ctx, &issues_model.CreateCommentOptions{ Doer: doer, Content: "New commits pushed, approval review dismissed automatically according to repository settings", Type: issues_model.CommentTypeDismissReview, @@ -411,7 +410,7 @@ func DismissReview(ctx context.Context, reviewID, repoID int64, message string, return nil, err } - comment, err = issue_service.CreateComment(ctx, &issues_model.CreateCommentOptions{ + comment, err = issues_model.CreateComment(ctx, &issues_model.CreateCommentOptions{ Doer: doer, Content: message, Type: issues_model.CommentTypeDismissReview, From 30eae5a40c33b5bfc16dc4244631da7f1cae1494 Mon Sep 17 00:00:00 2001 From: yp05327 <576951401@qq.com> Date: Fri, 4 Aug 2023 23:14:30 +0900 Subject: [PATCH 053/200] Fix incorrect color of selected assignees when create issue (#26324) Before: ![image](https://github.com/go-gitea/gitea/assets/18380374/75d610b2-3823-4366-be85-c77c9106feff) After: ![image](https://github.com/go-gitea/gitea/assets/18380374/15afc6ac-f5ad-4e24-8983-fea8ace5921f) Co-authored-by: Giteabot --- templates/repo/issue/new_form.tmpl | 2 ++ 1 file changed, 2 insertions(+) diff --git a/templates/repo/issue/new_form.tmpl b/templates/repo/issue/new_form.tmpl index c5da5b0882..aa68021748 100644 --- a/templates/repo/issue/new_form.tmpl +++ b/templates/repo/issue/new_form.tmpl @@ -170,11 +170,13 @@ {{.locale.Tr "repo.issues.new.no_assignees"}} +
    {{if and .PageIsComparePull (not (eq .HeadRepo.FullName .BaseCompareRepo.FullName)) .CanWriteToHeadRepo}}
    From 6a7a5ea32ab61a608b52029f778e8df76b04f489 Mon Sep 17 00:00:00 2001 From: Nicholas Pease <34464552+LAX18@users.noreply.github.com> Date: Fri, 4 Aug 2023 10:45:33 -0400 Subject: [PATCH 054/200] Do not show Profile README when repository is private (#26295) As mentioned in the original thread (#23260) and in the enhancements PR #24753, this PR ensures the .profile repository is public before the README file is shown. Co-authored-by: Lunny Xiao Co-authored-by: Giteabot --- routers/web/shared/user/header.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/routers/web/shared/user/header.go b/routers/web/shared/user/header.go index 516c853b02..0ef93815a3 100644 --- a/routers/web/shared/user/header.go +++ b/routers/web/shared/user/header.go @@ -85,7 +85,7 @@ func PrepareContextForProfileBigAvatar(ctx *context.Context) { func FindUserProfileReadme(ctx *context.Context) (profileGitRepo *git.Repository, profileReadmeBlob *git.Blob, profileClose func()) { profileDbRepo, err := repo_model.GetRepositoryByName(ctx.ContextUser.ID, ".profile") - if err == nil && !profileDbRepo.IsEmpty { + if err == nil && !profileDbRepo.IsEmpty && !profileDbRepo.IsPrivate { if profileGitRepo, err = git.OpenRepository(ctx, profileDbRepo.RepoPath()); err != nil { log.Error("FindUserProfileReadme failed to OpenRepository: %v", err) } else { From 945a0cb96b26d75868e6b52405afeb4e078eb279 Mon Sep 17 00:00:00 2001 From: yp05327 <576951401@qq.com> Date: Sat, 5 Aug 2023 00:16:56 +0900 Subject: [PATCH 055/200] Add highlight to selected repos in milestone dashboard (#26300) Before: ![image](https://github.com/go-gitea/gitea/assets/18380374/d3fa1e15-423a-4216-8a60-b02f5aa4f5d3) After: ![image](https://github.com/go-gitea/gitea/assets/18380374/643df586-ec2f-4480-b7a0-bd252883d761) Co-authored-by: Giteabot --- routers/web/user/home.go | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/routers/web/user/home.go b/routers/web/user/home.go index 77974a84a2..8cc9cccc29 100644 --- a/routers/web/user/home.go +++ b/routers/web/user/home.go @@ -281,6 +281,19 @@ func Milestones(ctx *context.Context) { } } + showRepoIds := make(container.Set[int64], len(showRepos)) + for _, repo := range showRepos { + if repo.ID > 0 { + showRepoIds.Add(repo.ID) + } + } + if len(repoIDs) == 0 { + repoIDs = showRepoIds.Values() + } + repoIDs = util.SliceRemoveAllFunc(repoIDs, func(v int64) bool { + return !showRepoIds.Contains(v) + }) + var pagerCount int if isShowClosed { ctx.Data["State"] = "closed" @@ -298,9 +311,7 @@ func Milestones(ctx *context.Context) { ctx.Data["MilestoneStats"] = milestoneStats ctx.Data["SortType"] = sortType ctx.Data["Keyword"] = keyword - if milestoneStats.Total() != totalMilestoneStats.Total() { - ctx.Data["RepoIDs"] = repoIDs - } + ctx.Data["RepoIDs"] = repoIDs ctx.Data["IsShowClosed"] = isShowClosed pager := context.NewPagination(pagerCount, setting.UI.IssuePagingNum, page, 5) From e5011a0e6d74071adfa17fd806234fd9108cb867 Mon Sep 17 00:00:00 2001 From: yp05327 <576951401@qq.com> Date: Sat, 5 Aug 2023 00:49:43 +0900 Subject: [PATCH 056/200] Remove commit load branches and tags in wiki repo (#26304) If click `load branches and tags`, you will get 500 error from backend, as it is a wiki repo. ![image](https://github.com/go-gitea/gitea/assets/18380374/1eb2a68b-cc72-4607-a1d1-4f74f83623f6) ![image](https://github.com/go-gitea/gitea/assets/18380374/c385de25-0cfb-4084-9452-d7e9d27deea9) Co-authored-by: Giteabot --- templates/repo/commit_load_branches_and_tags.tmpl | 2 ++ 1 file changed, 2 insertions(+) diff --git a/templates/repo/commit_load_branches_and_tags.tmpl b/templates/repo/commit_load_branches_and_tags.tmpl index c19aa55c56..4d90696cb4 100644 --- a/templates/repo/commit_load_branches_and_tags.tmpl +++ b/templates/repo/commit_load_branches_and_tags.tmpl @@ -1,3 +1,4 @@ +{{if not .PageIsWiki}}
    +{{end}} From 12c249c5ca3d719850831c113ec1998d2124b860 Mon Sep 17 00:00:00 2001 From: Lunny Xiao Date: Sat, 5 Aug 2023 10:40:27 +0800 Subject: [PATCH 057/200] Fix bug with sqlite load read (#26305) Possible fix #26280 --- models/activities/notification.go | 11 ++++++----- models/activities/notification_test.go | 14 ++++++++++++++ models/issues/issue_user.go | 4 ++-- models/issues/issue_user_test.go | 6 +++--- 4 files changed, 25 insertions(+), 10 deletions(-) diff --git a/models/activities/notification.go b/models/activities/notification.go index e0af2ee8bb..ef263ef735 100644 --- a/models/activities/notification.go +++ b/models/activities/notification.go @@ -310,7 +310,7 @@ func createIssueNotification(ctx context.Context, userID int64, issue *issues_mo } func updateIssueNotification(ctx context.Context, userID, issueID, commentID, updatedByID int64) error { - notification, err := getIssueNotification(ctx, userID, issueID) + notification, err := GetIssueNotification(ctx, userID, issueID) if err != nil { return err } @@ -331,7 +331,8 @@ func updateIssueNotification(ctx context.Context, userID, issueID, commentID, up return err } -func getIssueNotification(ctx context.Context, userID, issueID int64) (*Notification, error) { +// GetIssueNotification return the notification about an issue +func GetIssueNotification(ctx context.Context, userID, issueID int64) (*Notification, error) { notification := new(Notification) _, err := db.GetEngine(ctx). Where("user_id = ?", userID). @@ -742,7 +743,7 @@ func GetUIDsAndNotificationCounts(since, until timeutil.TimeStamp) ([]UserIDCoun // SetIssueReadBy sets issue to be read by given user. func SetIssueReadBy(ctx context.Context, issueID, userID int64) error { - if err := issues_model.UpdateIssueUserByRead(userID, issueID); err != nil { + if err := issues_model.UpdateIssueUserByRead(ctx, userID, issueID); err != nil { return err } @@ -750,7 +751,7 @@ func SetIssueReadBy(ctx context.Context, issueID, userID int64) error { } func setIssueNotificationStatusReadIfUnread(ctx context.Context, userID, issueID int64) error { - notification, err := getIssueNotification(ctx, userID, issueID) + notification, err := GetIssueNotification(ctx, userID, issueID) // ignore if not exists if err != nil { return nil @@ -762,7 +763,7 @@ func setIssueNotificationStatusReadIfUnread(ctx context.Context, userID, issueID notification.Status = NotificationStatusRead - _, err = db.GetEngine(ctx).ID(notification.ID).Update(notification) + _, err = db.GetEngine(ctx).ID(notification.ID).Cols("status").Update(notification) return err } diff --git a/models/activities/notification_test.go b/models/activities/notification_test.go index 36b63b266b..2d4c369a99 100644 --- a/models/activities/notification_test.go +++ b/models/activities/notification_test.go @@ -4,6 +4,7 @@ package activities_test import ( + "context" "testing" activities_model "code.gitea.io/gitea/models/activities" @@ -109,3 +110,16 @@ func TestUpdateNotificationStatuses(t *testing.T) { unittest.AssertExistsAndLoadBean(t, &activities_model.Notification{ID: notfPinned.ID, Status: activities_model.NotificationStatusPinned}) } + +func TestSetIssueReadBy(t *testing.T) { + assert.NoError(t, unittest.PrepareTestDatabase()) + user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1}) + issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 1}) + assert.NoError(t, db.WithTx(db.DefaultContext, func(ctx context.Context) error { + return activities_model.SetIssueReadBy(ctx, issue.ID, user.ID) + })) + + nt, err := activities_model.GetIssueNotification(db.DefaultContext, user.ID, issue.ID) + assert.NoError(t, err) + assert.EqualValues(t, activities_model.NotificationStatusRead, nt.Status) +} diff --git a/models/issues/issue_user.go b/models/issues/issue_user.go index 47da5c62c4..d053b1d543 100644 --- a/models/issues/issue_user.go +++ b/models/issues/issue_user.go @@ -55,8 +55,8 @@ func NewIssueUsers(ctx context.Context, repo *repo_model.Repository, issue *Issu } // UpdateIssueUserByRead updates issue-user relation for reading. -func UpdateIssueUserByRead(uid, issueID int64) error { - _, err := db.GetEngine(db.DefaultContext).Exec("UPDATE `issue_user` SET is_read=? WHERE uid=? AND issue_id=?", true, uid, issueID) +func UpdateIssueUserByRead(ctx context.Context, uid, issueID int64) error { + _, err := db.GetEngine(ctx).Exec("UPDATE `issue_user` SET is_read=? WHERE uid=? AND issue_id=?", true, uid, issueID) return err } diff --git a/models/issues/issue_user_test.go b/models/issues/issue_user_test.go index 0daace6c9b..ce47adb53a 100644 --- a/models/issues/issue_user_test.go +++ b/models/issues/issue_user_test.go @@ -40,13 +40,13 @@ func TestUpdateIssueUserByRead(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 1}) - assert.NoError(t, issues_model.UpdateIssueUserByRead(4, issue.ID)) + assert.NoError(t, issues_model.UpdateIssueUserByRead(db.DefaultContext, 4, issue.ID)) unittest.AssertExistsAndLoadBean(t, &issues_model.IssueUser{IssueID: issue.ID, UID: 4}, "is_read=1") - assert.NoError(t, issues_model.UpdateIssueUserByRead(4, issue.ID)) + assert.NoError(t, issues_model.UpdateIssueUserByRead(db.DefaultContext, 4, issue.ID)) unittest.AssertExistsAndLoadBean(t, &issues_model.IssueUser{IssueID: issue.ID, UID: 4}, "is_read=1") - assert.NoError(t, issues_model.UpdateIssueUserByRead(unittest.NonexistentID, unittest.NonexistentID)) + assert.NoError(t, issues_model.UpdateIssueUserByRead(db.DefaultContext, unittest.NonexistentID, unittest.NonexistentID)) } func TestUpdateIssueUsersByMentions(t *testing.T) { From 5db4c8db93de9e8792ff4fb07adb8a23b65b7850 Mon Sep 17 00:00:00 2001 From: wxiaoguang Date: Sat, 5 Aug 2023 12:34:59 +0800 Subject: [PATCH 058/200] Refactor backend SVG package and add tests (#26335) Introduce a well-tested `svg.Normalize` function. Make `RenderHTML` faster and more stable. --- modules/html/html.go | 32 +++++++------------ modules/svg/processor.go | 59 +++++++++++++++++++++++++++++++++++ modules/svg/processor_test.go | 29 +++++++++++++++++ modules/svg/svg.go | 33 ++++++++------------ 4 files changed, 113 insertions(+), 40 deletions(-) create mode 100644 modules/svg/processor.go create mode 100644 modules/svg/processor_test.go diff --git a/modules/html/html.go b/modules/html/html.go index 6cb6b847ef..b1ebd584c6 100644 --- a/modules/html/html.go +++ b/modules/html/html.go @@ -6,28 +6,20 @@ package html // ParseSizeAndClass get size and class from string with default values // If present, "others" expects the new size first and then the classes to use func ParseSizeAndClass(defaultSize int, defaultClass string, others ...any) (int, string) { - if len(others) == 0 { - return defaultSize, defaultClass - } - size := defaultSize - _size, ok := others[0].(int) - if ok && _size != 0 { - size = _size - } - - if len(others) == 1 { - return size, defaultClass - } - - class := defaultClass - if _class, ok := others[1].(string); ok && _class != "" { - if defaultClass == "" { - class = _class - } else { - class = defaultClass + " " + _class + if len(others) >= 1 { + if v, ok := others[0].(int); ok && v != 0 { + size = v + } + } + class := defaultClass + if len(others) >= 2 { + if v, ok := others[1].(string); ok && v != "" { + if class != "" { + class += " " + } + class += v } } - return size, class } diff --git a/modules/svg/processor.go b/modules/svg/processor.go new file mode 100644 index 0000000000..82248fb0c1 --- /dev/null +++ b/modules/svg/processor.go @@ -0,0 +1,59 @@ +// Copyright 2023 The Gitea Authors. All rights reserved. +// SPDX-License-Identifier: MIT + +package svg + +import ( + "bytes" + "fmt" + "regexp" + "sync" +) + +type normalizeVarsStruct struct { + reXMLDoc, + reComment, + reAttrXMLNs, + reAttrSize, + reAttrClassPrefix *regexp.Regexp +} + +var ( + normalizeVars *normalizeVarsStruct + normalizeVarsOnce sync.Once +) + +// Normalize normalizes the SVG content: set default width/height, remove unnecessary tags/attributes +// It's designed to work with valid SVG content. For invalid SVG content, the returned content is not guaranteed. +func Normalize(data []byte, size int) []byte { + normalizeVarsOnce.Do(func() { + normalizeVars = &normalizeVarsStruct{ + reXMLDoc: regexp.MustCompile(`(?s)<\?xml.*?>`), + reComment: regexp.MustCompile(`(?s)`), + + reAttrXMLNs: regexp.MustCompile(`(?s)\s+xmlns\s*=\s*"[^"]*"`), + reAttrSize: regexp.MustCompile(`(?s)\s+(width|height)\s*=\s*"[^"]+"`), + reAttrClassPrefix: regexp.MustCompile(`(?s)\s+class\s*=\s*"`), + } + }) + data = normalizeVars.reXMLDoc.ReplaceAll(data, nil) + data = normalizeVars.reComment.ReplaceAll(data, nil) + + data = bytes.TrimSpace(data) + svgTag, svgRemaining, ok := bytes.Cut(data, []byte(">")) + if !ok || !bytes.HasPrefix(svgTag, []byte(`') + normalized = append(normalized, svgRemaining...) + return normalized +} diff --git a/modules/svg/processor_test.go b/modules/svg/processor_test.go new file mode 100644 index 0000000000..a0286666ed --- /dev/null +++ b/modules/svg/processor_test.go @@ -0,0 +1,29 @@ +// Copyright 2023 The Gitea Authors. All rights reserved. +// SPDX-License-Identifier: MIT + +package svg + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestNormalize(t *testing.T) { + res := Normalize([]byte("foo"), 1) + assert.Equal(t, "foo", string(res)) + + res = Normalize([]byte(` + +content`), 1) + assert.Equal(t, `content`, string(res)) + + res = Normalize([]byte(`content`), 16) + + assert.Equal(t, `content`, string(res)) +} diff --git a/modules/svg/svg.go b/modules/svg/svg.go index fc96ea8e6a..016e1dc08b 100644 --- a/modules/svg/svg.go +++ b/modules/svg/svg.go @@ -7,42 +7,35 @@ import ( "fmt" "html/template" "path" - "regexp" "strings" - "code.gitea.io/gitea/modules/html" + gitea_html "code.gitea.io/gitea/modules/html" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/public" ) -var ( - // SVGs contains discovered SVGs - SVGs = map[string]string{} - - widthRe = regexp.MustCompile(`width="[0-9]+?"`) - heightRe = regexp.MustCompile(`height="[0-9]+?"`) -) +var svgIcons map[string]string const defaultSize = 16 -// Init discovers SVGs and populates the `SVGs` variable +// Init discovers SVG icons and populates the `svgIcons` variable func Init() error { - files, err := public.AssetFS().ListFiles("assets/img/svg") + const svgAssetsPath = "assets/img/svg" + files, err := public.AssetFS().ListFiles(svgAssetsPath) if err != nil { return err } - // Remove `xmlns` because inline SVG does not need it - reXmlns := regexp.MustCompile(`(]*?)\s+xmlns="[^"]*"`) + svgIcons = make(map[string]string, len(files)) for _, file := range files { if path.Ext(file) != ".svg" { continue } - bs, err := public.AssetFS().ReadFile("assets/img/svg", file) + bs, err := public.AssetFS().ReadFile(svgAssetsPath, file) if err != nil { log.Error("Failed to read SVG file %s: %v", file, err) } else { - SVGs[file[:len(file)-4]] = reXmlns.ReplaceAllString(string(bs), "$1") + svgIcons[file[:len(file)-4]] = string(Normalize(bs, defaultSize)) } } return nil @@ -50,12 +43,12 @@ func Init() error { // RenderHTML renders icons - arguments icon name (string), size (int), class (string) func RenderHTML(icon string, others ...any) template.HTML { - size, class := html.ParseSizeAndClass(defaultSize, "", others...) - - if svgStr, ok := SVGs[icon]; ok { + size, class := gitea_html.ParseSizeAndClass(defaultSize, "", others...) + if svgStr, ok := svgIcons[icon]; ok { + // the code is somewhat hacky, but it just works, because the SVG contents are all normalized if size != defaultSize { - svgStr = widthRe.ReplaceAllString(svgStr, fmt.Sprintf(`width="%d"`, size)) - svgStr = heightRe.ReplaceAllString(svgStr, fmt.Sprintf(`height="%d"`, size)) + svgStr = strings.Replace(svgStr, fmt.Sprintf(`width="%d"`, defaultSize), fmt.Sprintf(`width="%d"`, size), 1) + svgStr = strings.Replace(svgStr, fmt.Sprintf(`height="%d"`, defaultSize), fmt.Sprintf(`height="%d"`, size), 1) } if class != "" { svgStr = strings.Replace(svgStr, `class="`, fmt.Sprintf(`class="%s `, class), 1) From 9a8af925774327d96953a53c22efc42f24570b91 Mon Sep 17 00:00:00 2001 From: Zettat123 Date: Sat, 5 Aug 2023 14:26:06 +0800 Subject: [PATCH 059/200] Fix the bug when getting files changed for `pull_request_target` event (#26320) Follow #25229 Copy from https://github.com/go-gitea/gitea/pull/26290#issuecomment-1663135186 The bug is that we cannot get changed files for the `pull_request_target` event. This event runs in the context of the base branch, so we won't get any changes if we call `GetFilesChangedSinceCommit` with `PullRequest.Base.Ref`. --- modules/actions/workflows.go | 30 +++++++++---- modules/actions/workflows_test.go | 2 +- services/actions/notifier_helper.go | 4 +- tests/integration/actions_trigger_test.go | 54 ++++++++++++++++++++++- 4 files changed, 77 insertions(+), 13 deletions(-) diff --git a/modules/actions/workflows.go b/modules/actions/workflows.go index 2c7cec5591..de340a74ec 100644 --- a/modules/actions/workflows.go +++ b/modules/actions/workflows.go @@ -95,7 +95,7 @@ func GetEventsFromContent(content []byte) ([]*jobparser.Event, error) { return events, nil } -func DetectWorkflows(commit *git.Commit, triggedEvent webhook_module.HookEventType, payload api.Payloader) ([]*DetectedWorkflow, error) { +func DetectWorkflows(gitRepo *git.Repository, commit *git.Commit, triggedEvent webhook_module.HookEventType, payload api.Payloader) ([]*DetectedWorkflow, error) { entries, err := ListWorkflows(commit) if err != nil { return nil, err @@ -114,7 +114,7 @@ func DetectWorkflows(commit *git.Commit, triggedEvent webhook_module.HookEventTy } for _, evt := range events { log.Trace("detect workflow %q for event %#v matching %q", entry.Name(), evt, triggedEvent) - if detectMatched(commit, triggedEvent, payload, evt) { + if detectMatched(gitRepo, commit, triggedEvent, payload, evt) { dwf := &DetectedWorkflow{ EntryName: entry.Name(), TriggerEvent: evt.Name, @@ -128,7 +128,7 @@ func DetectWorkflows(commit *git.Commit, triggedEvent webhook_module.HookEventTy return workflows, nil } -func detectMatched(commit *git.Commit, triggedEvent webhook_module.HookEventType, payload api.Payloader, evt *jobparser.Event) bool { +func detectMatched(gitRepo *git.Repository, commit *git.Commit, triggedEvent webhook_module.HookEventType, payload api.Payloader, evt *jobparser.Event) bool { if !canGithubEventMatch(evt.Name, triggedEvent) { return false } @@ -168,7 +168,7 @@ func detectMatched(commit *git.Commit, triggedEvent webhook_module.HookEventType webhook_module.HookEventPullRequestSync, webhook_module.HookEventPullRequestAssign, webhook_module.HookEventPullRequestLabel: - return matchPullRequestEvent(commit, payload.(*api.PullRequestPayload), evt) + return matchPullRequestEvent(gitRepo, commit, payload.(*api.PullRequestPayload), evt) case // pull_request_review webhook_module.HookEventPullRequestReviewApproved, @@ -331,7 +331,7 @@ func matchIssuesEvent(commit *git.Commit, issuePayload *api.IssuePayload, evt *j return matchTimes == len(evt.Acts()) } -func matchPullRequestEvent(commit *git.Commit, prPayload *api.PullRequestPayload, evt *jobparser.Event) bool { +func matchPullRequestEvent(gitRepo *git.Repository, commit *git.Commit, prPayload *api.PullRequestPayload, evt *jobparser.Event) bool { acts := evt.Acts() activityTypeMatched := false matchTimes := 0 @@ -370,6 +370,18 @@ func matchPullRequestEvent(commit *git.Commit, prPayload *api.PullRequestPayload } } + var ( + headCommit = commit + err error + ) + if evt.Name == GithubEventPullRequestTarget && (len(acts["paths"]) > 0 || len(acts["paths-ignore"]) > 0) { + headCommit, err = gitRepo.GetCommit(prPayload.PullRequest.Head.Sha) + if err != nil { + log.Error("GetCommit [ref: %s]: %v", prPayload.PullRequest.Head.Sha, err) + return false + } + } + // all acts conditions should be satisfied for cond, vals := range acts { switch cond { @@ -392,9 +404,9 @@ func matchPullRequestEvent(commit *git.Commit, prPayload *api.PullRequestPayload matchTimes++ } case "paths": - filesChanged, err := commit.GetFilesChangedSinceCommit(prPayload.PullRequest.Base.Ref) + filesChanged, err := headCommit.GetFilesChangedSinceCommit(prPayload.PullRequest.Base.Ref) if err != nil { - log.Error("GetFilesChangedSinceCommit [commit_sha1: %s]: %v", commit.ID.String(), err) + log.Error("GetFilesChangedSinceCommit [commit_sha1: %s]: %v", headCommit.ID.String(), err) } else { patterns, err := workflowpattern.CompilePatterns(vals...) if err != nil { @@ -405,9 +417,9 @@ func matchPullRequestEvent(commit *git.Commit, prPayload *api.PullRequestPayload } } case "paths-ignore": - filesChanged, err := commit.GetFilesChangedSinceCommit(prPayload.PullRequest.Base.Ref) + filesChanged, err := headCommit.GetFilesChangedSinceCommit(prPayload.PullRequest.Base.Ref) if err != nil { - log.Error("GetFilesChangedSinceCommit [commit_sha1: %s]: %v", commit.ID.String(), err) + log.Error("GetFilesChangedSinceCommit [commit_sha1: %s]: %v", headCommit.ID.String(), err) } else { patterns, err := workflowpattern.CompilePatterns(vals...) if err != nil { diff --git a/modules/actions/workflows_test.go b/modules/actions/workflows_test.go index ef553c4a57..2d57f19488 100644 --- a/modules/actions/workflows_test.go +++ b/modules/actions/workflows_test.go @@ -125,7 +125,7 @@ func TestDetectMatched(t *testing.T) { evts, err := GetEventsFromContent([]byte(tc.yamlOn)) assert.NoError(t, err) assert.Len(t, evts, 1) - assert.Equal(t, tc.expected, detectMatched(tc.commit, tc.triggedEvent, tc.payload, evts[0])) + assert.Equal(t, tc.expected, detectMatched(nil, tc.commit, tc.triggedEvent, tc.payload, evts[0])) }) } } diff --git a/services/actions/notifier_helper.go b/services/actions/notifier_helper.go index 764d24a7db..0cc2d17f4e 100644 --- a/services/actions/notifier_helper.go +++ b/services/actions/notifier_helper.go @@ -143,7 +143,7 @@ func notify(ctx context.Context, input *notifyInput) error { } var detectedWorkflows []*actions_module.DetectedWorkflow - workflows, err := actions_module.DetectWorkflows(commit, input.Event, input.Payload) + workflows, err := actions_module.DetectWorkflows(gitRepo, commit, input.Event, input.Payload) if err != nil { return fmt.Errorf("DetectWorkflows: %w", err) } @@ -164,7 +164,7 @@ func notify(ctx context.Context, input *notifyInput) error { if err != nil { return fmt.Errorf("gitRepo.GetCommit: %w", err) } - baseWorkflows, err := actions_module.DetectWorkflows(baseCommit, input.Event, input.Payload) + baseWorkflows, err := actions_module.DetectWorkflows(gitRepo, baseCommit, input.Event, input.Payload) if err != nil { return fmt.Errorf("DetectWorkflows: %w", err) } diff --git a/tests/integration/actions_trigger_test.go b/tests/integration/actions_trigger_test.go index 241d6172f7..1c5d2fed61 100644 --- a/tests/integration/actions_trigger_test.go +++ b/tests/integration/actions_trigger_test.go @@ -67,7 +67,7 @@ func TestPullRequestTargetEvent(t *testing.T) { { Operation: "create", TreePath: ".gitea/workflows/pr.yml", - ContentReader: strings.NewReader("name: test\non: pull_request_target\njobs:\n test:\n runs-on: ubuntu-latest\n steps:\n - run: echo helloworld\n"), + ContentReader: strings.NewReader("name: test\non:\n pull_request_target:\n paths:\n - 'file_*.txt'\njobs:\n test:\n runs-on: ubuntu-latest\n steps:\n - run: echo helloworld\n"), }, }, Message: "add workflow", @@ -138,8 +138,60 @@ func TestPullRequestTargetEvent(t *testing.T) { assert.NoError(t, err) // load and compare ActionRun + assert.Equal(t, 1, unittest.GetCount(t, &actions_model.ActionRun{RepoID: baseRepo.ID})) actionRun := unittest.AssertExistsAndLoadBean(t, &actions_model.ActionRun{RepoID: baseRepo.ID}) assert.Equal(t, addFileToForkedResp.Commit.SHA, actionRun.CommitSHA) assert.Equal(t, actions_module.GithubEventPullRequestTarget, actionRun.TriggerEvent) + + // add another file whose name cannot match the specified path + addFileToForkedResp, err = files_service.ChangeRepoFiles(git.DefaultContext, forkedRepo, user3, &files_service.ChangeRepoFilesOptions{ + Files: []*files_service.ChangeRepoFile{ + { + Operation: "create", + TreePath: "foo.txt", + ContentReader: strings.NewReader("foo"), + }, + }, + Message: "add foo.txt", + OldBranch: "main", + NewBranch: "fork-branch-2", + Author: &files_service.IdentityOptions{ + Name: user3.Name, + Email: user3.Email, + }, + Committer: &files_service.IdentityOptions{ + Name: user3.Name, + Email: user3.Email, + }, + Dates: &files_service.CommitDateOptions{ + Author: time.Now(), + Committer: time.Now(), + }, + }) + assert.NoError(t, err) + assert.NotEmpty(t, addFileToForkedResp) + + // create Pull + pullIssue = &issues_model.Issue{ + RepoID: baseRepo.ID, + Title: "A mismatched path cannot trigger pull-request-target-event", + PosterID: user3.ID, + Poster: user3, + IsPull: true, + } + pullRequest = &issues_model.PullRequest{ + HeadRepoID: forkedRepo.ID, + BaseRepoID: baseRepo.ID, + HeadBranch: "fork-branch-2", + BaseBranch: "main", + HeadRepo: forkedRepo, + BaseRepo: baseRepo, + Type: issues_model.PullRequestGitea, + } + err = pull_service.NewPullRequest(git.DefaultContext, baseRepo, pullIssue, nil, nil, pullRequest, nil) + assert.NoError(t, err) + + // the new pull request cannot trigger actions, so there is still only 1 record + assert.Equal(t, 1, unittest.GetCount(t, &actions_model.ActionRun{RepoID: baseRepo.ID})) }) } From 2d3924d0e7c7fd164789b691168cead2d0171bc4 Mon Sep 17 00:00:00 2001 From: KN4CK3R Date: Sat, 5 Aug 2023 10:59:52 +0200 Subject: [PATCH 060/200] Prevent newline errors with Debian packages (#26332) Fixes #26313 --- modules/packages/debian/metadata.go | 21 +++++++++++---------- services/packages/debian/repository.go | 2 +- 2 files changed, 12 insertions(+), 11 deletions(-) diff --git a/modules/packages/debian/metadata.go b/modules/packages/debian/metadata.go index bb77f7524b..32460a84ae 100644 --- a/modules/packages/debian/metadata.go +++ b/modules/packages/debian/metadata.go @@ -172,19 +172,10 @@ func ParseControlFile(r io.Reader) (*Package, error) { value := strings.TrimSpace(parts[1]) switch key { case "Package": - if !namePattern.MatchString(value) { - return nil, ErrInvalidName - } p.Name = value case "Version": - if !versionPattern.MatchString(value) { - return nil, ErrInvalidVersion - } p.Version = value case "Architecture": - if value == "" { - return nil, ErrInvalidArchitecture - } p.Architecture = value case "Maintainer": a, err := mail.ParseAddress(value) @@ -208,13 +199,23 @@ func ParseControlFile(r io.Reader) (*Package, error) { return nil, err } + if !namePattern.MatchString(p.Name) { + return nil, ErrInvalidName + } + if !versionPattern.MatchString(p.Version) { + return nil, ErrInvalidVersion + } + if p.Architecture == "" { + return nil, ErrInvalidArchitecture + } + dependencies := strings.Split(depends.String(), ",") for i := range dependencies { dependencies[i] = strings.TrimSpace(dependencies[i]) } p.Metadata.Dependencies = dependencies - p.Control = control.String() + p.Control = strings.TrimSpace(control.String()) return p, nil } diff --git a/services/packages/debian/repository.go b/services/packages/debian/repository.go index 37ba47bdc3..be82fbed6e 100644 --- a/services/packages/debian/repository.go +++ b/services/packages/debian/repository.go @@ -212,7 +212,7 @@ func buildPackagesIndices(ctx context.Context, ownerID int64, repoVersion *packa } addSeparator = true - fmt.Fprint(w, pfd.Properties.GetByName(debian_module.PropertyControl)) + fmt.Fprintf(w, "%s\n", strings.TrimSpace(pfd.Properties.GetByName(debian_module.PropertyControl))) fmt.Fprintf(w, "Filename: pool/%s/%s/%s\n", distribution, component, pfd.File.Name) fmt.Fprintf(w, "Size: %d\n", pfd.Blob.Size) From 952882fe4ab6950ca0fb33af3885cb3347d46e78 Mon Sep 17 00:00:00 2001 From: cassiozareck <121526696+cassiozareck@users.noreply.github.com> Date: Sat, 5 Aug 2023 06:43:03 -0300 Subject: [PATCH 061/200] Fix log typo in task.go (#26337) Signed-off-by: cassiozareck --- models/actions/task.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/models/actions/task.go b/models/actions/task.go index 9cc0fd0df8..b31afb2126 100644 --- a/models/actions/task.go +++ b/models/actions/task.go @@ -278,7 +278,7 @@ func CreateTaskForRunner(ctx context.Context, runner *ActionRunner) (*ActionTask if gots, err := jobparser.Parse(job.WorkflowPayload); err != nil { return nil, false, fmt.Errorf("parse workflow of job %d: %w", job.ID, err) } else if len(gots) != 1 { - return nil, false, fmt.Errorf("workflow of job %d: not signle workflow", job.ID) + return nil, false, fmt.Errorf("workflow of job %d: not single workflow", job.ID) } else { _, workflowJob = gots[0].Job() } From 9ac6bb053cb2462770dc279b8a59ce944e8da8f6 Mon Sep 17 00:00:00 2001 From: CaiCandong <50507092+CaiCandong@users.noreply.github.com> Date: Sat, 5 Aug 2023 19:04:14 +0800 Subject: [PATCH 062/200] Hide `last indexed SHA` when a repo could not be indexed yet (#26340) Now, for a new repo without any commit, the Last indexed SHA field looks like this: Before: ![image](https://github.com/go-gitea/gitea/assets/50507092/cecc6e24-3366-4093-ae07-c361ea34b373) After: ![image](https://github.com/go-gitea/gitea/assets/50507092/9b6ba703-b0d5-4648-ad6b-9a2341dd60f9) Fixes #26336 --- templates/repo/settings/options.tmpl | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/templates/repo/settings/options.tmpl b/templates/repo/settings/options.tmpl index 569a576ce6..b247e85fa3 100644 --- a/templates/repo/settings/options.tmpl +++ b/templates/repo/settings/options.tmpl @@ -680,9 +680,11 @@ {{end}}

    {{.locale.Tr "repo.settings.admin_stats_indexer"}}

    - + {{if and .StatsIndexerStatus .StatsIndexerStatus.CommitSha}} + + {{end}} - {{if .StatsIndexerStatus}} + {{if and .StatsIndexerStatus .StatsIndexerStatus.CommitSha}} {{ShortSha .StatsIndexerStatus.CommitSha}} From ecb04cc324eb25ffe5649963308307910e39c825 Mon Sep 17 00:00:00 2001 From: Lunny Xiao Date: Sat, 5 Aug 2023 20:48:46 +0800 Subject: [PATCH 063/200] Remove backslashed newlines on markdown (#26344) Fix https://gitea.com/gitea/gitea-docusaurus/issues/56 --- docs/content/usage/agit-support.en-us.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/content/usage/agit-support.en-us.md b/docs/content/usage/agit-support.en-us.md index 25523efe6a..b1643d27b3 100644 --- a/docs/content/usage/agit-support.en-us.md +++ b/docs/content/usage/agit-support.en-us.md @@ -21,8 +21,8 @@ In Gitea `1.13`, support for [agit](https://git-repo.info/en/2020/03/agit-flow-a ## Creating PRs with Agit -Agit allows to create PRs while pushing code to the remote repo. \ -This can be done by pushing to the branch followed by a specific refspec (a location identifier known to git). \ +Agit allows to create PRs while pushing code to the remote repo. +This can be done by pushing to the branch followed by a specific refspec (a location identifier known to git). The following example illustrates this: ```shell From 4f513474dce9788bead4799fefe2ed2fdfa75213 Mon Sep 17 00:00:00 2001 From: wxiaoguang Date: Sat, 5 Aug 2023 21:24:49 +0800 Subject: [PATCH 064/200] Improve CLI and messages (#26341) Follow the CLI refactoring 1. Remove the "checkCommandFlags" helper 2. Unify the web startup message, make them have consistent names as `./gitea help` 3. Fine tune some other messages (see the diff) --- cmd/main.go | 37 +------------------------------------ cmd/web.go | 32 ++++++++++++++++---------------- 2 files changed, 17 insertions(+), 52 deletions(-) diff --git a/cmd/main.go b/cmd/main.go index e44f9382b7..13f9bba013 100644 --- a/cmd/main.go +++ b/cmd/main.go @@ -6,8 +6,6 @@ package cmd import ( "fmt" "os" - "reflect" - "strings" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/setting" @@ -58,7 +56,6 @@ func appGlobalFlags() []cli.Flag { return []cli.Flag{ // make the builtin flags at the top helpFlag, - cli.VersionFlag, // shared configuration flags, they are for global and for each sub-command at the same time // eg: such command is valid: "./gitea --config /tmp/app.ini web --config /tmp/app.ini", while it's discouraged indeed @@ -120,36 +117,6 @@ func prepareWorkPathAndCustomConf(action cli.ActionFunc) func(ctx *cli.Context) } } -func reflectGet(v any, fieldName string) any { - e := reflect.ValueOf(v).Elem() - return e.FieldByName(fieldName).Interface() -} - -// https://cli.urfave.org/migrate-v1-to-v2/#flag-aliases-are-done-differently -// Sadly v2 doesn't warn you if a comma is in the name. (https://github.com/urfave/cli/issues/1103) -func checkCommandFlags(c any) bool { - var cmds []*cli.Command - if app, ok := c.(*cli.App); ok { - cmds = app.Commands - } else { - cmds = c.(*cli.Command).Subcommands - } - ok := true - for _, cmd := range cmds { - for _, flag := range cmd.Flags { - flagName := reflectGet(flag, "Name").(string) - if strings.Contains(flagName, ",") { - ok = false - log.Error("cli.Flag can't have comma in its Name: %q, use Aliases instead", flagName) - } - } - if !checkCommandFlags(cmd) { - ok = false - } - } - return ok -} - func NewMainApp() *cli.App { app := cli.NewApp() app.EnableBashCompletion = true @@ -187,6 +154,7 @@ func NewMainApp() *cli.App { app.DefaultCommand = CmdWeb.Name globalFlags := appGlobalFlags() + app.Flags = append(app.Flags, cli.VersionFlag) app.Flags = append(app.Flags, globalFlags...) app.HideHelp = true // use our own help action to show helps (with more information like default config) app.Before = PrepareConsoleLoggerLevel(log.INFO) @@ -196,8 +164,5 @@ func NewMainApp() *cli.App { app.Commands = append(app.Commands, subCmdWithConfig...) app.Commands = append(app.Commands, subCmdStandalone...) - if !checkCommandFlags(app) { - panic("some flags are incorrect") // this is a runtime check to help developers - } return app } diff --git a/cmd/web.go b/cmd/web.go index dfe2091d06..b69769ec43 100644 --- a/cmd/web.go +++ b/cmd/web.go @@ -107,13 +107,18 @@ func createPIDFile(pidPath string) { } } -func serveInstall(ctx *cli.Context) error { +func showWebStartupMessage(msg string) { log.Info("Gitea version: %s%s", setting.AppVer, setting.AppBuiltWith) - log.Info("App path: %s", setting.AppPath) - log.Info("Work path: %s", setting.AppWorkPath) - log.Info("Custom path: %s", setting.CustomPath) - log.Info("Config file: %s", setting.CustomConf) - log.Info("Prepare to run install page") + log.Info("* RunMode: %s", setting.RunMode) + log.Info("* AppPath: %s", setting.AppPath) + log.Info("* WorkPath: %s", setting.AppWorkPath) + log.Info("* CustomPath: %s", setting.CustomPath) + log.Info("* ConfigFile: %s", setting.CustomConf) + log.Info("%s", msg) +} + +func serveInstall(ctx *cli.Context) error { + showWebStartupMessage("Prepare to run install page") routers.InitWebInstallPage(graceful.GetManager().HammerContext()) @@ -150,29 +155,24 @@ func serveInstalled(ctx *cli.Context) error { setting.LoadCommonSettings() setting.MustInstalled() - log.Info("Gitea version: %s%s", setting.AppVer, setting.AppBuiltWith) - log.Info("App path: %s", setting.AppPath) - log.Info("Work path: %s", setting.AppWorkPath) - log.Info("Custom path: %s", setting.CustomPath) - log.Info("Config file: %s", setting.CustomConf) - log.Info("Run mode: %s", setting.RunMode) - log.Info("Prepare to run web server") + showWebStartupMessage("Prepare to run web server") if setting.AppWorkPathMismatch { log.Error("WORK_PATH from config %q doesn't match other paths from environment variables or command arguments. "+ - "Only WORK_PATH in config should be set and used. Please remove the other outdated work paths from environment variables and command arguments", setting.CustomConf) + "Only WORK_PATH in config should be set and used. Please make sure the path in config file is correct, "+ + "remove the other outdated work paths from environment variables and command arguments", setting.CustomConf) } rootCfg := setting.CfgProvider if rootCfg.Section("").Key("WORK_PATH").String() == "" { saveCfg, err := rootCfg.PrepareSaving() if err != nil { - log.Error("Unable to prepare saving WORK_PATH=%s to config %q: %v\nYou must set it manually, otherwise there might be bugs when accessing the git repositories.", setting.AppWorkPath, setting.CustomConf, err) + log.Error("Unable to prepare saving WORK_PATH=%s to config %q: %v\nYou should set it manually, otherwise there might be bugs when accessing the git repositories.", setting.AppWorkPath, setting.CustomConf, err) } else { rootCfg.Section("").Key("WORK_PATH").SetValue(setting.AppWorkPath) saveCfg.Section("").Key("WORK_PATH").SetValue(setting.AppWorkPath) if err = saveCfg.Save(); err != nil { - log.Error("Unable to update WORK_PATH=%s to config %q: %v\nYou must set it manually, otherwise there might be bugs when accessing the git repositories.", setting.AppWorkPath, setting.CustomConf, err) + log.Error("Unable to update WORK_PATH=%s to config %q: %v\nYou should set it manually, otherwise there might be bugs when accessing the git repositories.", setting.AppWorkPath, setting.CustomConf, err) } } } From d92b4cd0935fcb7be3fb30253426988aada78d32 Mon Sep 17 00:00:00 2001 From: wxiaoguang Date: Sat, 5 Aug 2023 23:36:45 +0800 Subject: [PATCH 065/200] Fix incorrect CLI exit code and duplicate error message (#26346) Follow the CLI refactoring, and add tests. --- cmd/main.go | 22 +++++++++++- cmd/main_test.go | 79 +++++++++++++++++++++++++++++++++++-------- main.go | 18 ++++------ modules/test/utils.go | 6 ++++ 4 files changed, 98 insertions(+), 27 deletions(-) diff --git a/cmd/main.go b/cmd/main.go index 13f9bba013..feda41e68b 100644 --- a/cmd/main.go +++ b/cmd/main.go @@ -6,6 +6,7 @@ package cmd import ( "fmt" "os" + "strings" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/setting" @@ -117,8 +118,12 @@ func prepareWorkPathAndCustomConf(action cli.ActionFunc) func(ctx *cli.Context) } } -func NewMainApp() *cli.App { +func NewMainApp(version, versionExtra string) *cli.App { app := cli.NewApp() + app.Name = "Gitea" + app.Usage = "A painless self-hosted Git service" + app.Description = `By default, Gitea will start serving using the web-server with no argument, which can alternatively be run by running the subcommand "web".` + app.Version = version + versionExtra app.EnableBashCompletion = true // these sub-commands need to use config file @@ -166,3 +171,18 @@ func NewMainApp() *cli.App { return app } + +func RunMainApp(app *cli.App, args ...string) error { + err := app.Run(args) + if err == nil { + return nil + } + if strings.HasPrefix(err.Error(), "flag provided but not defined:") { + // the cli package should already have output the error message, so just exit + cli.OsExiter(1) + return err + } + _, _ = fmt.Fprintf(app.ErrWriter, "Command error: %v\n", err) + cli.OsExiter(1) + return err +} diff --git a/cmd/main_test.go b/cmd/main_test.go index e9204d09cc..0e32dce564 100644 --- a/cmd/main_test.go +++ b/cmd/main_test.go @@ -5,6 +5,7 @@ package cmd import ( "fmt" + "io" "os" "path/filepath" "strings" @@ -12,6 +13,7 @@ import ( "code.gitea.io/gitea/models/unittest" "code.gitea.io/gitea/modules/setting" + "code.gitea.io/gitea/modules/test" "github.com/stretchr/testify/assert" "github.com/urfave/cli/v2" @@ -27,21 +29,38 @@ func makePathOutput(workPath, customPath, customConf string) string { return fmt.Sprintf("WorkPath=%s\nCustomPath=%s\nCustomConf=%s", workPath, customPath, customConf) } -func newTestApp() *cli.App { - app := NewMainApp() - testCmd := &cli.Command{ - Name: "test-cmd", - Action: func(ctx *cli.Context) error { - _, _ = fmt.Fprint(app.Writer, makePathOutput(setting.AppWorkPath, setting.CustomPath, setting.CustomConf)) - return nil - }, - } +func newTestApp(testCmdAction func(ctx *cli.Context) error) *cli.App { + app := NewMainApp("version", "version-extra") + testCmd := &cli.Command{Name: "test-cmd", Action: testCmdAction} prepareSubcommandWithConfig(testCmd, appGlobalFlags()) app.Commands = append(app.Commands, testCmd) app.DefaultCommand = testCmd.Name return app } +type runResult struct { + Stdout string + Stderr string + ExitCode int +} + +func runTestApp(app *cli.App, args ...string) (runResult, error) { + outBuf := new(strings.Builder) + errBuf := new(strings.Builder) + app.Writer = outBuf + app.ErrWriter = errBuf + exitCode := -1 + defer test.MockVariableValue(&cli.ErrWriter, app.ErrWriter)() + defer test.MockVariableValue(&cli.OsExiter, func(code int) { + if exitCode == -1 { + exitCode = code // save the exit code once and then reset the writer (to simulate the exit) + app.Writer, app.ErrWriter, cli.ErrWriter = io.Discard, io.Discard, io.Discard + } + })() + err := RunMainApp(app, args...) + return runResult{outBuf.String(), errBuf.String(), exitCode}, err +} + func TestCliCmd(t *testing.T) { defaultWorkPath := filepath.Dir(setting.AppPath) defaultCustomPath := filepath.Join(defaultWorkPath, "custom") @@ -92,7 +111,10 @@ func TestCliCmd(t *testing.T) { }, } - app := newTestApp() + app := newTestApp(func(ctx *cli.Context) error { + _, _ = fmt.Fprint(ctx.App.Writer, makePathOutput(setting.AppWorkPath, setting.CustomPath, setting.CustomConf)) + return nil + }) var envBackup []string for _, s := range os.Environ() { if strings.HasPrefix(s, "GITEA_") && strings.Contains(s, "=") { @@ -120,12 +142,39 @@ func TestCliCmd(t *testing.T) { _ = os.Setenv(k, v) } args := strings.Split(c.cmd, " ") // for test only, "split" is good enough - out := new(strings.Builder) - app.Writer = out - err := app.Run(args) + r, err := runTestApp(app, args...) assert.NoError(t, err, c.cmd) assert.NotEmpty(t, c.exp, c.cmd) - outStr := out.String() - assert.Contains(t, outStr, c.exp, c.cmd) + assert.Contains(t, r.Stdout, c.exp, c.cmd) } } + +func TestCliCmdError(t *testing.T) { + app := newTestApp(func(ctx *cli.Context) error { return fmt.Errorf("normal error") }) + r, err := runTestApp(app, "./gitea", "test-cmd") + assert.Error(t, err) + assert.Equal(t, 1, r.ExitCode) + assert.Equal(t, "", r.Stdout) + assert.Equal(t, "Command error: normal error\n", r.Stderr) + + app = newTestApp(func(ctx *cli.Context) error { return cli.Exit("exit error", 2) }) + r, err = runTestApp(app, "./gitea", "test-cmd") + assert.Error(t, err) + assert.Equal(t, 2, r.ExitCode) + assert.Equal(t, "", r.Stdout) + assert.Equal(t, "exit error\n", r.Stderr) + + app = newTestApp(func(ctx *cli.Context) error { return nil }) + r, err = runTestApp(app, "./gitea", "test-cmd", "--no-such") + assert.Error(t, err) + assert.Equal(t, 1, r.ExitCode) + assert.Equal(t, "Incorrect Usage: flag provided but not defined: -no-such\n\n", r.Stdout) + assert.Equal(t, "", r.Stderr) // the cli package's strange behavior, the error message is not in stderr .... + + app = newTestApp(func(ctx *cli.Context) error { return nil }) + r, err = runTestApp(app, "./gitea", "test-cmd") + assert.NoError(t, err) + assert.Equal(t, -1, r.ExitCode) // the cli.OsExiter is not called + assert.Equal(t, "", r.Stdout) + assert.Equal(t, "", r.Stderr) +} diff --git a/main.go b/main.go index 652a71195e..775c729c56 100644 --- a/main.go +++ b/main.go @@ -5,7 +5,6 @@ package main import ( - "fmt" "os" "runtime" "strings" @@ -21,6 +20,8 @@ import ( _ "code.gitea.io/gitea/modules/markup/csv" _ "code.gitea.io/gitea/modules/markup/markdown" _ "code.gitea.io/gitea/modules/markup/orgmode" + + "github.com/urfave/cli/v2" ) // these flags will be set by the build flags @@ -37,17 +38,12 @@ func init() { } func main() { - app := cmd.NewMainApp() - app.Name = "Gitea" - app.Usage = "A painless self-hosted Git service" - app.Description = `By default, Gitea will start serving using the web-server with no argument, which can alternatively be run by running the subcommand "web".` - app.Version = Version + formatBuiltWith() - - err := app.Run(os.Args) - if err != nil { - _, _ = fmt.Fprintf(app.Writer, "\nFailed to run with %s: %v\n", os.Args, err) + cli.OsExiter = func(code int) { + log.GetManager().Close() + os.Exit(code) } - + app := cmd.NewMainApp(Version, formatBuiltWith()) + _ = cmd.RunMainApp(app, os.Args...) // all errors should have been handled by the RunMainApp log.GetManager().Close() } diff --git a/modules/test/utils.go b/modules/test/utils.go index 2917741c45..4a0c2f1b3b 100644 --- a/modules/test/utils.go +++ b/modules/test/utils.go @@ -33,3 +33,9 @@ func RedirectURL(resp http.ResponseWriter) string { func IsNormalPageCompleted(s string) bool { return strings.Contains(s, `
    `) } + +func MockVariableValue[T any](p *T, v T) (reset func()) { + old := *p + *p = v + return func() { *p = old } +} From c1c83dbaec840871c1247f4bc3f875309b0de6bb Mon Sep 17 00:00:00 2001 From: Track3 Date: Sun, 6 Aug 2023 00:28:25 +0800 Subject: [PATCH 066/200] [docs] Add missing backtick in quickstart.zh-cn.md (#26349) Added missing backtick in quickstart.zh-cn.md docs so inline code can render properly. Co-authored-by: Giteabot --- docs/content/usage/actions/quickstart.zh-cn.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/content/usage/actions/quickstart.zh-cn.md b/docs/content/usage/actions/quickstart.zh-cn.md index 510d4a904f..c5b67ce101 100644 --- a/docs/content/usage/actions/quickstart.zh-cn.md +++ b/docs/content/usage/actions/quickstart.zh-cn.md @@ -127,7 +127,7 @@ jobs: 请注意,演示文件中包含一些表情符号。 请确保您的数据库支持它们,特别是在使用MySQL时。 -如果字符集不是`utf8mb4,将出现错误,例如`Error 1366 (HY000): Incorrect string value: '\\xF0\\x9F\\x8E\\x89 T...' for column 'name' at row 1`。 +如果字符集不是`utf8mb4`,将出现错误,例如`Error 1366 (HY000): Incorrect string value: '\\xF0\\x9F\\x8E\\x89 T...' for column 'name' at row 1`。 有关更多信息,请参阅[数据库准备工作](installation/database-preparation.md#mysql)。 或者,您可以从演示文件中删除所有表情符号,然后再尝试一次。 From 8736b134bd044f81de6ad3a3fb562b2e0e4de213 Mon Sep 17 00:00:00 2001 From: delvh Date: Sun, 6 Aug 2023 21:52:34 +0200 Subject: [PATCH 067/200] Display human-readable text instead of cryptic filemodes (#26352) Now, you don't need to be a git expert anymore to know what these numbers mean. ## Before ![grafik](https://github.com/go-gitea/gitea/assets/51889757/9a964bf6-10fd-40a6-aeb2-ac8f437f8c32) ## After ![grafik](https://github.com/go-gitea/gitea/assets/51889757/84573cb9-55b6-4dde-9866-95f71b657554) or when the mode actually changed: ![grafik](https://github.com/go-gitea/gitea/assets/51889757/0f327538-ebdc-40e7-8c99-f9e21b67f638) --- options/locale/locale_en-US.ini | 9 +++++++++ services/gitdiff/gitdiff.go | 17 +++++++++++++++++ templates/repo/diff/box.tmpl | 6 ++++-- 3 files changed, 30 insertions(+), 2 deletions(-) diff --git a/options/locale/locale_en-US.ini b/options/locale/locale_en-US.ini index b2eeab617e..64bc0c7cc1 100644 --- a/options/locale/locale_en-US.ini +++ b/options/locale/locale_en-US.ini @@ -3505,3 +3505,12 @@ variables.update.success = The variable has been edited. type-1.display_name = Individual Project type-2.display_name = Repository Project type-3.display_name = Organization Project + +[git.filemode] +changed_filemode = %[1]s → %[2]s +# Ordered by git filemode value, ascending. E.g. directory has "040000", normal file has "100644", … +directory = Directory +normal_file = Normal file +executable_file = Executable file +symbolic_link = Symbolic link +submodule = Submodule diff --git a/services/gitdiff/gitdiff.go b/services/gitdiff/gitdiff.go index 9e1db6fd43..4cb2b1303d 100644 --- a/services/gitdiff/gitdiff.go +++ b/services/gitdiff/gitdiff.go @@ -427,6 +427,23 @@ func (diffFile *DiffFile) ShouldBeHidden() bool { return diffFile.IsGenerated || diffFile.IsViewed } +func (diffFile *DiffFile) ModeTranslationKey(mode string) string { + switch mode { + case "040000": + return "git.filemode.directory" + case "100644": + return "git.filemode.normal_file" + case "100755": + return "git.filemode.executable_file" + case "120000": + return "git.filemode.symbolic_link" + case "160000": + return "git.filemode.submodule" + default: + return mode + } +} + func getCommitFileLineCount(commit *git.Commit, filePath string) int { blob, err := commit.GetBlobByPath(filePath) if err != nil { diff --git a/templates/repo/diff/box.tmpl b/templates/repo/diff/box.tmpl index c4dd1f658d..324166b03c 100644 --- a/templates/repo/diff/box.tmpl +++ b/templates/repo/diff/box.tmpl @@ -130,9 +130,11 @@ {{$.locale.Tr "repo.diff.vendored"}} {{end}} {{if and $file.Mode $file.OldMode}} - {{$file.OldMode}} → {{$file.Mode}} + {{$old := $.locale.Tr ($file.ModeTranslationKey $file.OldMode)}} + {{$new := $.locale.Tr ($file.ModeTranslationKey $file.Mode)}} + {{$.locale.Tr "git.filemode.changed_filemode" $old $new}} {{else if $file.Mode}} - {{$file.Mode}} + {{$.locale.Tr ($file.ModeTranslationKey $file.Mode)}} {{end}}
    From 049e400327df8be5c904c5570c0e9f57157cd843 Mon Sep 17 00:00:00 2001 From: GiteaBot Date: Mon, 7 Aug 2023 00:27:21 +0000 Subject: [PATCH 068/200] [skip ci] Updated licenses and gitignores --- options/license/HP-1989 | 16 ++++++++++++++++ options/license/Soundex | 7 +++++++ options/license/Texinfo-exception | 4 ++++ 3 files changed, 27 insertions(+) create mode 100644 options/license/HP-1989 create mode 100644 options/license/Soundex create mode 100644 options/license/Texinfo-exception diff --git a/options/license/HP-1989 b/options/license/HP-1989 new file mode 100644 index 0000000000..7422055d95 --- /dev/null +++ b/options/license/HP-1989 @@ -0,0 +1,16 @@ +Copyright (c) 1990- 1993, 1996 Open Software Foundation, Inc. +Copyright (c) 1989 by Hewlett-Packard Company, Palo Alto, Ca. +Digital Equipment Corporation, Maynard, Mass. +Copyright (c) 1998 Microsoft. +To anyone who acknowledges that this file is provided "AS IS" +without any express or implied warranty: permission to use, copy, +modify, and distribute this file for any purpose is hereby +granted without fee, provided that the above copyright notices and +this notice appears in all source code copies, and that none of +the names of Open Software Foundation, Inc., Hewlett-Packard +Company, Microsoft, or Digital Equipment Corporation be used in +advertising or publicity pertaining to distribution of the software +without specific, written prior permission. Neither Open Software +Foundation, Inc., Hewlett-Packard Company, Microsoft, nor Digital +Equipment Corporation makes any representations about the +suitability of this software for any purpose. diff --git a/options/license/Soundex b/options/license/Soundex new file mode 100644 index 0000000000..b745f29db5 --- /dev/null +++ b/options/license/Soundex @@ -0,0 +1,7 @@ +# (c) Copyright 1998-2007 by Mark Mielke # # Freedom to use +these sources for whatever you want, as long as credit # is +given where credit is due, is hereby granted. You may make +modifications # where you see fit but leave this copyright +somewhere visible. As well, try # to initial any changes you +make so that if I like the changes I can # incorporate them +into later versions. # # - Mark Mielke diff --git a/options/license/Texinfo-exception b/options/license/Texinfo-exception new file mode 100644 index 0000000000..931a4070b4 --- /dev/null +++ b/options/license/Texinfo-exception @@ -0,0 +1,4 @@ +As a special exception, when this file is read by TeX when +processing a Texinfo source document, you may use the result without +restriction. This Exception is an additional permission under +section 7 of the GNU General Public License, version 3 ("GPLv3"). From 24fbf4e0592713633144c3fc9a04f64d790f99b0 Mon Sep 17 00:00:00 2001 From: CaiCandong <50507092+CaiCandong@users.noreply.github.com> Date: Mon, 7 Aug 2023 11:43:18 +0800 Subject: [PATCH 069/200] Fix nil pointer dereference error when open link with invalid pull index (#26353) fix #26331 Before: ![image](https://github.com/go-gitea/gitea/assets/50507092/028e6944-84d1-4404-80b6-4a4accdc7d0a) After: ![image](https://github.com/go-gitea/gitea/assets/50507092/b78978f9-e77f-459f-96e1-3a1f36ec8abe) --- routers/web/repo/pull.go | 55 +++++++++++++++++---------------- routers/web/repo/pull_review.go | 4 +-- 2 files changed, 30 insertions(+), 29 deletions(-) diff --git a/routers/web/repo/pull.go b/routers/web/repo/pull.go index 0be8bede74..be4e9711e7 100644 --- a/routers/web/repo/pull.go +++ b/routers/web/repo/pull.go @@ -299,7 +299,7 @@ func ForkPost(ctx *context.Context) { ctx.Redirect(ctxUser.HomeLink() + "/" + url.PathEscape(repo.Name)) } -func checkPullInfo(ctx *context.Context) *issues_model.Issue { +func getPullInfo(ctx *context.Context) (issue *issues_model.Issue, ok bool) { issue, err := issues_model.GetIssueByIndex(ctx, ctx.Repo.Repository.ID, ctx.ParamsInt64(":index")) if err != nil { if issues_model.IsErrIssueNotExist(err) { @@ -307,43 +307,43 @@ func checkPullInfo(ctx *context.Context) *issues_model.Issue { } else { ctx.ServerError("GetIssueByIndex", err) } - return nil + return nil, false } if err = issue.LoadPoster(ctx); err != nil { ctx.ServerError("LoadPoster", err) - return nil + return nil, false } if err := issue.LoadRepo(ctx); err != nil { ctx.ServerError("LoadRepo", err) - return nil + return nil, false } ctx.Data["Title"] = fmt.Sprintf("#%d - %s", issue.Index, issue.Title) ctx.Data["Issue"] = issue if !issue.IsPull { ctx.NotFound("ViewPullCommits", nil) - return nil + return nil, false } if err = issue.LoadPullRequest(ctx); err != nil { ctx.ServerError("LoadPullRequest", err) - return nil + return nil, false } if err = issue.PullRequest.LoadHeadRepo(ctx); err != nil { ctx.ServerError("LoadHeadRepo", err) - return nil + return nil, false } if ctx.IsSigned { // Update issue-user. if err = activities_model.SetIssueReadBy(ctx, issue.ID, ctx.Doer.ID); err != nil { ctx.ServerError("ReadBy", err) - return nil + return nil, false } } - return issue + return issue, true } func setMergeTarget(ctx *context.Context, pull *issues_model.PullRequest) { @@ -361,14 +361,15 @@ func setMergeTarget(ctx *context.Context, pull *issues_model.PullRequest) { // GetPullDiffStats get Pull Requests diff stats func GetPullDiffStats(ctx *context.Context) { - issue := checkPullInfo(ctx) + issue, ok := getPullInfo(ctx) + if !ok { + return + } pull := issue.PullRequest mergeBaseCommitID := GetMergedBaseCommitID(ctx, issue) - if ctx.Written() { - return - } else if mergeBaseCommitID == "" { + if mergeBaseCommitID == "" { ctx.NotFound("PullFiles", nil) return } @@ -702,8 +703,8 @@ type pullCommitList struct { // GetPullCommits get all commits for given pull request func GetPullCommits(ctx *context.Context) { - issue := checkPullInfo(ctx) - if ctx.Written() { + issue, ok := getPullInfo(ctx) + if !ok { return } resp := &pullCommitList{} @@ -735,8 +736,8 @@ func ViewPullCommits(ctx *context.Context) { ctx.Data["PageIsPullList"] = true ctx.Data["PageIsPullCommits"] = true - issue := checkPullInfo(ctx) - if ctx.Written() { + issue, ok := getPullInfo(ctx) + if !ok { return } pull := issue.PullRequest @@ -779,8 +780,8 @@ func viewPullFiles(ctx *context.Context, specifiedStartCommit, specifiedEndCommi ctx.Data["PageIsPullList"] = true ctx.Data["PageIsPullFiles"] = true - issue := checkPullInfo(ctx) - if ctx.Written() { + issue, ok := getPullInfo(ctx) + if !ok { return } pull := issue.PullRequest @@ -1016,8 +1017,8 @@ func ViewPullFilesForAllCommitsOfPr(ctx *context.Context) { // UpdatePullRequest merge PR's baseBranch into headBranch func UpdatePullRequest(ctx *context.Context) { - issue := checkPullInfo(ctx) - if ctx.Written() { + issue, ok := getPullInfo(ctx) + if !ok { return } if issue.IsClosed { @@ -1101,8 +1102,8 @@ func UpdatePullRequest(ctx *context.Context) { // MergePullRequest response for merging pull request func MergePullRequest(ctx *context.Context) { form := web.GetForm(ctx).(*forms.MergePullRequestForm) - issue := checkPullInfo(ctx) - if ctx.Written() { + issue, ok := getPullInfo(ctx) + if !ok { return } @@ -1308,8 +1309,8 @@ func MergePullRequest(ctx *context.Context) { // CancelAutoMergePullRequest cancels a scheduled pr func CancelAutoMergePullRequest(ctx *context.Context) { - issue := checkPullInfo(ctx) - if ctx.Written() { + issue, ok := getPullInfo(ctx) + if !ok { return } @@ -1447,8 +1448,8 @@ func CompareAndPullRequestPost(ctx *context.Context) { // CleanUpPullRequest responses for delete merged branch when PR has been merged func CleanUpPullRequest(ctx *context.Context) { - issue := checkPullInfo(ctx) - if ctx.Written() { + issue, ok := getPullInfo(ctx) + if !ok { return } diff --git a/routers/web/repo/pull_review.go b/routers/web/repo/pull_review.go index c2271750c4..3e433dcf4d 100644 --- a/routers/web/repo/pull_review.go +++ b/routers/web/repo/pull_review.go @@ -259,8 +259,8 @@ type viewedFilesUpdate struct { func UpdateViewedFiles(ctx *context.Context) { // Find corresponding PR - issue := checkPullInfo(ctx) - if ctx.Written() { + issue, ok := getPullInfo(ctx) + if !ok { return } pull := issue.PullRequest From e4b1ea6f15790b3ce918a29404f93353d7143a1c Mon Sep 17 00:00:00 2001 From: wxiaoguang Date: Mon, 7 Aug 2023 18:23:59 +0800 Subject: [PATCH 070/200] Bypass MariaDB performance bug of the "IN" sub-query, fix incorrect IssueIndex (#26279) Close #26277 Fix #26285 --- models/activities/action.go | 32 ++++++++++++++++++++++-------- models/activities/action_test.go | 34 ++++++++++++++++++++++++++++++++ services/issue/issue.go | 2 +- 3 files changed, 59 insertions(+), 9 deletions(-) diff --git a/models/activities/action.go b/models/activities/action.go index 7f22605d0d..432bf8bf3f 100644 --- a/models/activities/action.go +++ b/models/activities/action.go @@ -685,18 +685,34 @@ func NotifyWatchersActions(acts []*Action) error { } // DeleteIssueActions delete all actions related with issueID -func DeleteIssueActions(ctx context.Context, repoID, issueID int64) error { +func DeleteIssueActions(ctx context.Context, repoID, issueID, issueIndex int64) error { // delete actions assigned to this issue - subQuery := builder.Select("`id`"). - From("`comment`"). - Where(builder.Eq{"`issue_id`": issueID}) - if _, err := db.GetEngine(ctx).In("comment_id", subQuery).Delete(&Action{}); err != nil { - return err + e := db.GetEngine(ctx) + + // MariaDB has a performance bug: https://jira.mariadb.org/browse/MDEV-16289 + // so here it uses "DELETE ... WHERE IN" with pre-queried IDs. + var lastCommentID int64 + commentIDs := make([]int64, 0, db.DefaultMaxInSize) + for { + commentIDs = commentIDs[:0] + err := e.Select("`id`").Table(&issues_model.Comment{}). + Where(builder.Eq{"issue_id": issueID}).And("`id` > ?", lastCommentID). + OrderBy("`id`").Limit(db.DefaultMaxInSize). + Find(&commentIDs) + if err != nil { + return err + } else if len(commentIDs) == 0 { + break + } else if _, err = db.GetEngine(ctx).In("comment_id", commentIDs).Delete(&Action{}); err != nil { + return err + } else { + lastCommentID = commentIDs[len(commentIDs)-1] + } } - _, err := db.GetEngine(ctx).Table("action").Where("repo_id = ?", repoID). + _, err := e.Where("repo_id = ?", repoID). In("op_type", ActionCreateIssue, ActionCreatePullRequest). - Where("content LIKE ?", strconv.FormatInt(issueID, 10)+"|%"). + Where("content LIKE ?", strconv.FormatInt(issueIndex, 10)+"|%"). // "IssueIndex|content..." Delete(&Action{}) return err } diff --git a/models/activities/action_test.go b/models/activities/action_test.go index 7044bcc004..9a42740880 100644 --- a/models/activities/action_test.go +++ b/models/activities/action_test.go @@ -4,6 +4,7 @@ package activities_test import ( + "fmt" "path" "testing" @@ -284,3 +285,36 @@ func TestConsistencyUpdateAction(t *testing.T) { assert.NoError(t, db.GetEngine(db.DefaultContext).Where("id = ?", id).Find(&actions)) unittest.CheckConsistencyFor(t, &activities_model.Action{}) } + +func TestDeleteIssueActions(t *testing.T) { + assert.NoError(t, unittest.PrepareTestDatabase()) + + // load an issue + issue := unittest.AssertExistsAndLoadBean(t, &issue_model.Issue{ID: 4}) + assert.NotEqualValues(t, issue.ID, issue.Index) // it needs to use different ID/Index to test the DeleteIssueActions to delete some actions by IssueIndex + + // insert a comment + err := db.Insert(db.DefaultContext, &issue_model.Comment{Type: issue_model.CommentTypeComment, IssueID: issue.ID}) + assert.NoError(t, err) + comment := unittest.AssertExistsAndLoadBean(t, &issue_model.Comment{Type: issue_model.CommentTypeComment, IssueID: issue.ID}) + + // truncate action table and insert some actions + err = db.TruncateBeans(db.DefaultContext, &activities_model.Action{}) + assert.NoError(t, err) + err = db.Insert(db.DefaultContext, &activities_model.Action{ + OpType: activities_model.ActionCommentIssue, + CommentID: comment.ID, + }) + assert.NoError(t, err) + err = db.Insert(db.DefaultContext, &activities_model.Action{ + OpType: activities_model.ActionCreateIssue, + RepoID: issue.RepoID, + Content: fmt.Sprintf("%d|content...", issue.Index), + }) + assert.NoError(t, err) + + // assert that the actions exist, then delete them + unittest.AssertCount(t, &activities_model.Action{}, 2) + assert.NoError(t, activities_model.DeleteIssueActions(db.DefaultContext, issue.RepoID, issue.ID, issue.Index)) + unittest.AssertCount(t, &activities_model.Action{}, 0) +} diff --git a/services/issue/issue.go b/services/issue/issue.go index b6c6a26cbd..9ca4e21b17 100644 --- a/services/issue/issue.go +++ b/services/issue/issue.go @@ -248,7 +248,7 @@ func deleteIssue(ctx context.Context, issue *issues_model.Issue) error { issue.MilestoneID, err) } - if err := activities_model.DeleteIssueActions(ctx, issue.RepoID, issue.ID); err != nil { + if err := activities_model.DeleteIssueActions(ctx, issue.RepoID, issue.ID, issue.Index); err != nil { return err } From 87f70979cfe2ba8662b12b688f020b7732741de0 Mon Sep 17 00:00:00 2001 From: Earl Warren <109468362+earl-warren@users.noreply.github.com> Date: Mon, 7 Aug 2023 15:11:25 +0200 Subject: [PATCH 071/200] Do not highlight `#number` in documents (#26365) - Currently the post processing will transform all issue indexes (such as `#6`) into a clickable link. - This makes sense in an situation like issues or PRs, where referencing to other issues is quite common and only referencing their issue index is an handy and efficient way to do it. - Currently this is also run for documents (which is the user profile and viewing rendered files), but in those situations it's less common to reference issues by their index and instead could mean something else. - This patch disables this post processing for issue index for documents. Matches Github's behavior. - Added unit tests. - Resolves https://codeberg.org/Codeberg/Community/issues/1120 Co-authored-by: Gusted --- modules/markup/html.go | 2 +- modules/markup/html_internal_test.go | 24 +++++++++++++++++++ modules/markup/html_test.go | 36 ++++++++++++++++++++++++++++ 3 files changed, 61 insertions(+), 1 deletion(-) diff --git a/modules/markup/html.go b/modules/markup/html.go index da16bcd3cb..e53ccc6a79 100644 --- a/modules/markup/html.go +++ b/modules/markup/html.go @@ -852,7 +852,7 @@ func fullIssuePatternProcessor(ctx *RenderContext, node *html.Node) { } func issueIndexPatternProcessor(ctx *RenderContext, node *html.Node) { - if ctx.Metas == nil { + if ctx.Metas == nil || ctx.Metas["mode"] == "document" { return } var ( diff --git a/modules/markup/html_internal_test.go b/modules/markup/html_internal_test.go index 00ffe45c28..7b7f6df701 100644 --- a/modules/markup/html_internal_test.go +++ b/modules/markup/html_internal_test.go @@ -262,6 +262,30 @@ func TestRender_IssueIndexPattern5(t *testing.T) { }) } +func TestRender_IssueIndexPattern_Document(t *testing.T) { + setting.AppURL = TestAppURL + metas := map[string]string{ + "format": "https://someurl.com/{user}/{repo}/{index}", + "user": "someUser", + "repo": "someRepo", + "style": IssueNameStyleNumeric, + "mode": "document", + } + + testRenderIssueIndexPattern(t, "#1", "#1", &RenderContext{ + Ctx: git.DefaultContext, + Metas: metas, + }) + testRenderIssueIndexPattern(t, "#1312", "#1312", &RenderContext{ + Ctx: git.DefaultContext, + Metas: metas, + }) + testRenderIssueIndexPattern(t, "!1", "!1", &RenderContext{ + Ctx: git.DefaultContext, + Metas: metas, + }) +} + func testRenderIssueIndexPattern(t *testing.T, input, expected string, ctx *RenderContext) { if ctx.URLPrefix == "" { ctx.URLPrefix = TestAppURL diff --git a/modules/markup/html_test.go b/modules/markup/html_test.go index a8d7ba7948..9156bc6331 100644 --- a/modules/markup/html_test.go +++ b/modules/markup/html_test.go @@ -529,6 +529,42 @@ func Test_ParseClusterFuzz(t *testing.T) { assert.NotContains(t, res.String(), ":gitea:`) + test( + "Some text with 😄 in the middle", + `Some text with 😄 in the middle`) + test("http://localhost:3000/person/repo/issues/4#issuecomment-1234", + `person/repo#4 (comment)`) +} + func TestIssue16020(t *testing.T) { setting.AppURL = TestAppURL From a5d8f95550a7efa17a20a41b4b338616120b6dcb Mon Sep 17 00:00:00 2001 From: delvh Date: Mon, 7 Aug 2023 18:11:33 +0200 Subject: [PATCH 072/200] Add changelog for 1.20.3 (#26373) --- CHANGELOG.md | 35 ++++++++++++++++++++++++++++++++--- 1 file changed, 32 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c6699a6bfa..85ad622f7e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,9 +2,38 @@ This changelog goes through all the changes that have been made in each release without substantial changes to our git log; to see the highlights of what has -been added to each release, please refer to the [blog](https://blog.gitea.io). +been added to each release, please refer to the [blog](https://blog.gitea.com). -## [1.20.2](https://github.com/go-gitea/gitea/releases/tag/1.20.2) - 2023-07-29 +## [1.20.3](https://github.com/go-gitea/gitea/releases/tag/v1.20.3) - 2023-08-07 + +* BREAKING + * Fix the wrong derive path (#26271) (#26318) +* SECURITY + * Fix API leaking Usermail if not logged in (#25097) (#26350) +* ENHANCEMENTS + * Display human-readable text instead of cryptic filemodes (#26352) (#26358) + * Hide `last indexed SHA` when a repo could not be indexed yet (#26340) (#26345) + * Fix the topic validation rule and suport dots (#26286) (#26303) + * Fix due date rendering the wrong date in issue (#26268) (#26274) + * Don't autosize textarea in diff view (#26233) (#26244) + * Fix commit compare style (#26209) (#26226) + * Warn instead of reporting an error when a webhook cannot be found (#26039) (#26211) +* BUGFIXES + * Bypass MariaDB performance bug of the "IN" sub-query, fix incorrect IssueIndex (#26279) (#26368) + * Fix incorrect CLI exit code and duplicate error message (#26346) (#26347) + * Prevent newline errors with Debian packages (#26332) (#26342) + * Fix bug with sqlite load read (#26305) (#26339) + * Make git batch operations use parent context timeout instead of default timeout (#26325) (#26330) + * Support getting changed files when commit ID is `EmptySHA` (#26290) (#26316) + * Clarify the logger's MODE config option (#26267) (#26281) + * Use shared template for webhook icons (#26242) (#26246) + * Fix pull request check list is limited (#26179) (#26245) + * Fix attachment clipboard copy on insecure origin (#26224) (#26231) + * Fix access check for org-level project (#26182) (#26223) +* MISC + * Upgrade x/net to 0.13.0 (#26301) + +## [1.20.2](https://github.com/go-gitea/gitea/releases/tag/v1.20.2) - 2023-07-29 * ENHANCEMENTS * Calculate MAX_WORKERS default value by CPU number (#26177) (#26183) @@ -32,7 +61,7 @@ been added to each release, please refer to the [blog](https://blog.gitea.io). * Fix wrong workflow status when rerun a job in an already finished workflow (#26119) (#26124) * Fix duplicated url prefix on issue context menu (#26066) (#26067) -## [1.20.1](https://github.com/go-gitea/gitea/releases/tag/1.20.1) - 2023-07-22 +## [1.20.1](https://github.com/go-gitea/gitea/releases/tag/v1.20.1) - 2023-07-22 * SECURITY * Disallow dangerous URL schemes (#25960) (#25964) From ab0eb1c47b10a1a65f9db0b609fb5339613d1708 Mon Sep 17 00:00:00 2001 From: cassiozareck <121526696+cassiozareck@users.noreply.github.com> Date: Mon, 7 Aug 2023 16:00:53 -0300 Subject: [PATCH 073/200] Rename code_langauge.go to code_language.go (#26377) --- modules/analyze/{code_langauge.go => code_language.go} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename modules/analyze/{code_langauge.go => code_language.go} (100%) diff --git a/modules/analyze/code_langauge.go b/modules/analyze/code_language.go similarity index 100% rename from modules/analyze/code_langauge.go rename to modules/analyze/code_language.go From f5dbac9d36f1678b928bee04e85fbd045c725698 Mon Sep 17 00:00:00 2001 From: Lunny Xiao Date: Tue, 8 Aug 2023 03:26:40 +0800 Subject: [PATCH 074/200] Use more `IssueList` instead of `[]*Issue` (#26369) --- models/issues/issue.go | 6 +++--- models/issues/issue_project.go | 4 ++-- models/issues/issue_search.go | 2 +- routers/web/user/notification.go | 3 +-- 4 files changed, 7 insertions(+), 8 deletions(-) diff --git a/models/issues/issue.go b/models/issues/issue.go index 38726de85a..f000f4c660 100644 --- a/models/issues/issue.go +++ b/models/issues/issue.go @@ -854,8 +854,8 @@ func (issue *Issue) MovePin(ctx context.Context, newPosition int) error { } // GetPinnedIssues returns the pinned Issues for the given Repo and type -func GetPinnedIssues(ctx context.Context, repoID int64, isPull bool) ([]*Issue, error) { - issues := make([]*Issue, 0) +func GetPinnedIssues(ctx context.Context, repoID int64, isPull bool) (IssueList, error) { + issues := make(IssueList, 0) err := db.GetEngine(ctx). Table("issue"). @@ -868,7 +868,7 @@ func GetPinnedIssues(ctx context.Context, repoID int64, isPull bool) ([]*Issue, return nil, err } - err = IssueList(issues).LoadAttributes(ctx) + err = issues.LoadAttributes(ctx) if err != nil { return nil, err } diff --git a/models/issues/issue_project.go b/models/issues/issue_project.go index 782638d997..ed249527bf 100644 --- a/models/issues/issue_project.go +++ b/models/issues/issue_project.go @@ -53,7 +53,7 @@ func (issue *Issue) projectBoardID(ctx context.Context) int64 { // LoadIssuesFromBoard load issues assigned to this board func LoadIssuesFromBoard(ctx context.Context, b *project_model.Board) (IssueList, error) { - issueList := make([]*Issue, 0, 10) + issueList := make(IssueList, 0, 10) if b.ID != 0 { issues, err := Issues(ctx, &IssuesOptions{ @@ -79,7 +79,7 @@ func LoadIssuesFromBoard(ctx context.Context, b *project_model.Board) (IssueList issueList = append(issueList, issues...) } - if err := IssueList(issueList).LoadComments(ctx); err != nil { + if err := issueList.LoadComments(ctx); err != nil { return nil, err } diff --git a/models/issues/issue_search.go b/models/issues/issue_search.go index f9c1dbb384..281339044b 100644 --- a/models/issues/issue_search.go +++ b/models/issues/issue_search.go @@ -441,7 +441,7 @@ func GetRepoIDsForIssuesOptions(opts *IssuesOptions, user *user_model.User) ([]i } // Issues returns a list of issues by given conditions. -func Issues(ctx context.Context, opts *IssuesOptions) ([]*Issue, error) { +func Issues(ctx context.Context, opts *IssuesOptions) (IssueList, error) { sess := db.GetEngine(ctx). Join("INNER", "repository", "`issue`.repo_id = `repository`.id") applyLimit(sess, opts) diff --git a/routers/web/user/notification.go b/routers/web/user/notification.go index 60ae628445..579287ffac 100644 --- a/routers/web/user/notification.go +++ b/routers/web/user/notification.go @@ -296,8 +296,7 @@ func NotificationSubscriptions(ctx *context.Context) { } ctx.Data["CommitStatus"] = commitStatus - issueList := issues_model.IssueList(issues) - approvalCounts, err := issueList.GetApprovalCounts(ctx) + approvalCounts, err := issues.GetApprovalCounts(ctx) if err != nil { ctx.ServerError("ApprovalCounts", err) return From 3a42743b3afbb56209364f77b887b6b0499062cb Mon Sep 17 00:00:00 2001 From: CaiCandong <50507092+CaiCandong@users.noreply.github.com> Date: Tue, 8 Aug 2023 03:59:17 +0800 Subject: [PATCH 075/200] Fix incorrect sort link with `.profile` repository (#26374) fix #26360 --- templates/explore/repo_search.tmpl | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/templates/explore/repo_search.tmpl b/templates/explore/repo_search.tmpl index 6e150dc7f2..c056662fb8 100644 --- a/templates/explore/repo_search.tmpl +++ b/templates/explore/repo_search.tmpl @@ -19,18 +19,18 @@ {{svg "octicon-triangle-down" 14 "dropdown icon"}}
    From c2b6897e35ccdebc4b49cfc7fb165ee654c8e55d Mon Sep 17 00:00:00 2001 From: Maxim Slipenko Date: Mon, 7 Aug 2023 23:44:04 +0300 Subject: [PATCH 076/200] Fix text truncate (#26354) Fixes: https://github.com/go-gitea/gitea/issues/25597 Before: ![image](https://github.com/go-gitea/gitea/assets/36362599/c8c27bcb-469f-4def-8521-d9e054c16ecb) After: ![image](https://github.com/go-gitea/gitea/assets/36362599/2405b6e8-fc5c-4b13-b66b-007bc11edbc4) Co-authored-by: Giteabot --- web_src/css/base.css | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/web_src/css/base.css b/web_src/css/base.css index 213f3f88f2..d44f949318 100644 --- a/web_src/css/base.css +++ b/web_src/css/base.css @@ -1218,7 +1218,7 @@ img.ui.avatar, } .ui .text.truncate { - overflow: hidden; + overflow-x: clip; text-overflow: ellipsis; white-space: nowrap; display: inline-block; From 0c6ae61229bce9d9ad3d359cee927464968a2dd1 Mon Sep 17 00:00:00 2001 From: KN4CK3R Date: Tue, 8 Aug 2023 02:46:10 +0200 Subject: [PATCH 077/200] Allow package cleanup from admin page (#25307) Until now expired package data gets deleted daily by a cronjob. The admin page shows the size of all packages and the size of unreferenced data. The users (#25035, #20631) expect the deletion of this data if they run the cronjob from the admin page but the job only deletes data older than 24h. This PR adds a new button which deletes all expired data. ![grafik](https://github.com/go-gitea/gitea/assets/1666336/b3e35d73-9496-4fa7-a20c-e5d30b1f6850) --------- Co-authored-by: silverwind --- options/locale/locale_en-US.ini | 1 + routers/web/admin/packages.go | 12 ++++++++++++ routers/web/web.go | 1 + services/cron/tasks_basic.go | 2 +- services/packages/cleanup/cleanup.go | 26 ++++++++++++++++++++++---- templates/admin/packages/list.tmpl | 6 ++++++ tests/integration/api_packages_test.go | 4 ++-- 7 files changed, 45 insertions(+), 7 deletions(-) diff --git a/options/locale/locale_en-US.ini b/options/locale/locale_en-US.ini index 64bc0c7cc1..f946aff10c 100644 --- a/options/locale/locale_en-US.ini +++ b/options/locale/locale_en-US.ini @@ -2833,6 +2833,7 @@ repos.lfs_size = LFS Size packages.package_manage_panel = Package Management packages.total_size = Total Size: %s packages.unreferenced_size = Unreferenced Size: %s +packages.cleanup = Clean up expired data packages.owner = Owner packages.creator = Creator packages.name = Name diff --git a/routers/web/admin/packages.go b/routers/web/admin/packages.go index 8e4b8a373e..8d4c29813e 100644 --- a/routers/web/admin/packages.go +++ b/routers/web/admin/packages.go @@ -6,6 +6,7 @@ package admin import ( "net/http" "net/url" + "time" "code.gitea.io/gitea/models/db" packages_model "code.gitea.io/gitea/models/packages" @@ -14,6 +15,7 @@ import ( "code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/util" packages_service "code.gitea.io/gitea/services/packages" + packages_cleanup_service "code.gitea.io/gitea/services/packages/cleanup" ) const ( @@ -99,3 +101,13 @@ func DeletePackageVersion(ctx *context.Context) { ctx.Flash.Success(ctx.Tr("packages.settings.delete.success")) ctx.JSONRedirect(setting.AppSubURL + "/admin/packages?page=" + url.QueryEscape(ctx.FormString("page")) + "&q=" + url.QueryEscape(ctx.FormString("q")) + "&type=" + url.QueryEscape(ctx.FormString("type"))) } + +func CleanupExpiredData(ctx *context.Context) { + if err := packages_cleanup_service.CleanupExpiredData(ctx, time.Duration(0)); err != nil { + ctx.ServerError("CleanupExpiredData", err) + return + } + + ctx.Flash.Success(ctx.Tr("packages.cleanup.success")) + ctx.Redirect(setting.AppSubURL + "/admin/packages") +} diff --git a/routers/web/web.go b/routers/web/web.go index aa3d830f94..2c2309e827 100644 --- a/routers/web/web.go +++ b/routers/web/web.go @@ -597,6 +597,7 @@ func registerRoutes(m *web.Route) { m.Group("/packages", func() { m.Get("", admin.Packages) m.Post("/delete", admin.DeletePackageVersion) + m.Post("/cleanup", admin.CleanupExpiredData) }, packagesEnabled) m.Group("/hooks", func() { diff --git a/services/cron/tasks_basic.go b/services/cron/tasks_basic.go index 2e6560ec0c..2a213ae515 100644 --- a/services/cron/tasks_basic.go +++ b/services/cron/tasks_basic.go @@ -152,7 +152,7 @@ func registerCleanupPackages() { OlderThan: 24 * time.Hour, }, func(ctx context.Context, _ *user_model.User, config Config) error { realConfig := config.(*OlderThanConfig) - return packages_cleanup_service.Cleanup(ctx, realConfig.OlderThan) + return packages_cleanup_service.CleanupTask(ctx, realConfig.OlderThan) }) } diff --git a/services/packages/cleanup/cleanup.go b/services/packages/cleanup/cleanup.go index 43fbc1ad9b..77bcfb1942 100644 --- a/services/packages/cleanup/cleanup.go +++ b/services/packages/cleanup/cleanup.go @@ -20,9 +20,17 @@ import ( debian_service "code.gitea.io/gitea/services/packages/debian" ) -// Cleanup removes expired package data -func Cleanup(taskCtx context.Context, olderThan time.Duration) error { - ctx, committer, err := db.TxContext(taskCtx) +// Task method to execute cleanup rules and cleanup expired package data +func CleanupTask(ctx context.Context, olderThan time.Duration) error { + if err := ExecuteCleanupRules(ctx); err != nil { + return err + } + + return CleanupExpiredData(ctx, olderThan) +} + +func ExecuteCleanupRules(outerCtx context.Context) error { + ctx, committer, err := db.TxContext(outerCtx) if err != nil { return err } @@ -30,7 +38,7 @@ func Cleanup(taskCtx context.Context, olderThan time.Duration) error { err = packages_model.IterateEnabledCleanupRules(ctx, func(ctx context.Context, pcr *packages_model.PackageCleanupRule) error { select { - case <-taskCtx.Done(): + case <-outerCtx.Done(): return db.ErrCancelledf("While processing package cleanup rules") default: } @@ -122,6 +130,16 @@ func Cleanup(taskCtx context.Context, olderThan time.Duration) error { return err } + return committer.Commit() +} + +func CleanupExpiredData(outerCtx context.Context, olderThan time.Duration) error { + ctx, committer, err := db.TxContext(outerCtx) + if err != nil { + return err + } + defer committer.Close() + if err := container_service.Cleanup(ctx, olderThan); err != nil { return err } diff --git a/templates/admin/packages/list.tmpl b/templates/admin/packages/list.tmpl index 9aa1d933f6..4cf30f58e6 100644 --- a/templates/admin/packages/list.tmpl +++ b/templates/admin/packages/list.tmpl @@ -4,6 +4,12 @@ {{.locale.Tr "admin.packages.package_manage_panel"}} ({{.locale.Tr "admin.total" .TotalCount}}, {{.locale.Tr "admin.packages.total_size" (FileSize .TotalBlobSize)}}, {{.locale.Tr "admin.packages.unreferenced_size" (FileSize .TotalUnreferencedBlobSize)}}) +
    +
    + {{.CsrfTokenHtml}} + +
    +
    diff --git a/tests/integration/api_packages_test.go b/tests/integration/api_packages_test.go index cd981e9c73..e530b2c1ad 100644 --- a/tests/integration/api_packages_test.go +++ b/tests/integration/api_packages_test.go @@ -475,7 +475,7 @@ func TestPackageCleanup(t *testing.T) { _, err = packages_model.GetInternalVersionByNameAndVersion(db.DefaultContext, user.ID, packages_model.TypeContainer, "cleanup-test", container_model.UploadVersion) assert.NoError(t, err) - err = packages_cleanup_service.Cleanup(db.DefaultContext, duration) + err = packages_cleanup_service.CleanupTask(db.DefaultContext, duration) assert.NoError(t, err) pbs, err = packages_model.FindExpiredUnreferencedBlobs(db.DefaultContext, duration) @@ -610,7 +610,7 @@ func TestPackageCleanup(t *testing.T) { pcr, err := packages_model.InsertCleanupRule(db.DefaultContext, c.Rule) assert.NoError(t, err) - err = packages_cleanup_service.Cleanup(db.DefaultContext, duration) + err = packages_cleanup_service.CleanupTask(db.DefaultContext, duration) assert.NoError(t, err) for _, v := range c.Versions { From 69130532239ee7ade82977f456c12826e1adeb1e Mon Sep 17 00:00:00 2001 From: wxiaoguang Date: Tue, 8 Aug 2023 09:22:47 +0800 Subject: [PATCH 078/200] Start using template context function (#26254) Before: * `{{.locale.Tr ...}}` * `{{$.locale.Tr ...}}` * `{{$.root.locale.Tr ...}}` * `{{template "sub" .}}` * `{{template "sub" (dict "locale" $.locale)}}` * `{{template "sub" (dict "root" $)}}` * ..... With context function: only need to `{{ctx.Locale.Tr ...}}` The "ctx" could be considered as a super-global variable for all templates including sub-templates. To avoid potential risks (any bug in the template context function package), this PR only starts using "ctx" in "head.tmpl" and "footer.tmpl" and it has a "DataRaceCheck". If there is anything wrong, the code can be fixed or reverted easily. --- modules/context/context.go | 15 +++++++-- modules/context/context_response.go | 4 +-- modules/context/context_template.go | 49 +++++++++++++++++++++++++++++ modules/templates/helper.go | 2 ++ modules/templates/htmlrenderer.go | 12 ++++--- modules/test/context_tests.go | 4 +-- routers/common/errpage.go | 2 +- routers/install/install.go | 4 +++ routers/web/auth/oauth.go | 2 +- routers/web/swagger_json.go | 2 +- templates/base/footer.tmpl | 4 ++- templates/base/head.tmpl | 13 ++++---- 12 files changed, 91 insertions(+), 22 deletions(-) create mode 100644 modules/context/context_template.go diff --git a/modules/context/context.go b/modules/context/context.go index de0518a1d2..b75ba9ab67 100644 --- a/modules/context/context.go +++ b/modules/context/context.go @@ -5,6 +5,7 @@ package context import ( + "context" "html" "html/template" "io" @@ -31,14 +32,16 @@ import ( // Render represents a template render type Render interface { - TemplateLookup(tmpl string) (templates.TemplateExecutor, error) - HTML(w io.Writer, status int, name string, data any) error + TemplateLookup(tmpl string, templateCtx context.Context) (templates.TemplateExecutor, error) + HTML(w io.Writer, status int, name string, data any, templateCtx context.Context) error } // Context represents context of a request. type Context struct { *Base + TemplateContext TemplateContext + Render Render PageData map[string]any // data used by JavaScript modules in one page, it's `window.config.pageData` @@ -60,6 +63,8 @@ type Context struct { Package *Package } +type TemplateContext map[string]any + func init() { web.RegisterResponseStatusProvider[*Context](func(req *http.Request) web_types.ResponseStatusProvider { return req.Context().Value(WebContextKey).(*Context) @@ -133,8 +138,12 @@ func Contexter() func(next http.Handler) http.Handler { } defer baseCleanUp() + // TODO: "install.go" also shares the same logic, which should be refactored to a general function + ctx.TemplateContext = NewTemplateContext(ctx) + ctx.TemplateContext["Locale"] = ctx.Locale + ctx.Data.MergeFrom(middleware.CommonTemplateContextData()) - ctx.Data["Context"] = &ctx + ctx.Data["Context"] = ctx // TODO: use "ctx" in template and remove this ctx.Data["CurrentURL"] = setting.AppSubURL + req.URL.RequestURI() ctx.Data["Link"] = ctx.Link ctx.Data["locale"] = ctx.Locale diff --git a/modules/context/context_response.go b/modules/context/context_response.go index 9dc6d1fc0e..5729865561 100644 --- a/modules/context/context_response.go +++ b/modules/context/context_response.go @@ -75,7 +75,7 @@ func (ctx *Context) HTML(status int, name base.TplName) { return strconv.FormatInt(time.Since(tmplStartTime).Nanoseconds()/1e6, 10) + "ms" } - err := ctx.Render.HTML(ctx.Resp, status, string(name), ctx.Data) + err := ctx.Render.HTML(ctx.Resp, status, string(name), ctx.Data, ctx.TemplateContext) if err == nil { return } @@ -93,7 +93,7 @@ func (ctx *Context) HTML(status int, name base.TplName) { // RenderToString renders the template content to a string func (ctx *Context) RenderToString(name base.TplName, data map[string]any) (string, error) { var buf strings.Builder - err := ctx.Render.HTML(&buf, http.StatusOK, string(name), data) + err := ctx.Render.HTML(&buf, http.StatusOK, string(name), data, ctx.TemplateContext) return buf.String(), err } diff --git a/modules/context/context_template.go b/modules/context/context_template.go new file mode 100644 index 0000000000..ba90fc170a --- /dev/null +++ b/modules/context/context_template.go @@ -0,0 +1,49 @@ +// Copyright 2023 The Gitea Authors. All rights reserved. +// SPDX-License-Identifier: MIT + +package context + +import ( + "context" + "errors" + "time" + + "code.gitea.io/gitea/modules/log" +) + +var _ context.Context = TemplateContext(nil) + +func NewTemplateContext(ctx context.Context) TemplateContext { + return TemplateContext{"_ctx": ctx} +} + +func (c TemplateContext) parentContext() context.Context { + return c["_ctx"].(context.Context) +} + +func (c TemplateContext) Deadline() (deadline time.Time, ok bool) { + return c.parentContext().Deadline() +} + +func (c TemplateContext) Done() <-chan struct{} { + return c.parentContext().Done() +} + +func (c TemplateContext) Err() error { + return c.parentContext().Err() +} + +func (c TemplateContext) Value(key any) any { + return c.parentContext().Value(key) +} + +// DataRaceCheck checks whether the template context function "ctx()" returns the consistent context +// as the current template's rendering context (request context), to help to find data race issues as early as possible. +// When the code is proven to be correct and stable, this function should be removed. +func (c TemplateContext) DataRaceCheck(dataCtx context.Context) (string, error) { + if c.parentContext() != dataCtx { + log.Error("TemplateContext.DataRaceCheck: parent context mismatch\n%s", log.Stack(2)) + return "", errors.New("parent context mismatch") + } + return "", nil +} diff --git a/modules/templates/helper.go b/modules/templates/helper.go index 2b918f42c0..cfcfbbed38 100644 --- a/modules/templates/helper.go +++ b/modules/templates/helper.go @@ -28,6 +28,8 @@ import ( // NewFuncMap returns functions for injecting to templates func NewFuncMap() template.FuncMap { return map[string]any{ + "ctx": func() any { return nil }, // template context function + "DumpVar": dumpVar, // ----------------------------------------------------------------- diff --git a/modules/templates/htmlrenderer.go b/modules/templates/htmlrenderer.go index d470435b63..5ab46cb13a 100644 --- a/modules/templates/htmlrenderer.go +++ b/modules/templates/htmlrenderer.go @@ -6,6 +6,7 @@ package templates import ( "bufio" "bytes" + "context" "errors" "fmt" "io" @@ -39,27 +40,28 @@ var ( var ErrTemplateNotInitialized = errors.New("template system is not initialized, check your log for errors") -func (h *HTMLRender) HTML(w io.Writer, status int, name string, data any) error { +func (h *HTMLRender) HTML(w io.Writer, status int, name string, data any, ctx context.Context) error { //nolint:revive if respWriter, ok := w.(http.ResponseWriter); ok { if respWriter.Header().Get("Content-Type") == "" { respWriter.Header().Set("Content-Type", "text/html; charset=utf-8") } respWriter.WriteHeader(status) } - t, err := h.TemplateLookup(name) + t, err := h.TemplateLookup(name, ctx) if err != nil { return texttemplate.ExecError{Name: name, Err: err} } return t.Execute(w, data) } -func (h *HTMLRender) TemplateLookup(name string) (TemplateExecutor, error) { +func (h *HTMLRender) TemplateLookup(name string, ctx context.Context) (TemplateExecutor, error) { //nolint:revive tmpls := h.templates.Load() if tmpls == nil { return nil, ErrTemplateNotInitialized } - - return tmpls.Executor(name, NewFuncMap()) + m := NewFuncMap() + m["ctx"] = func() any { return ctx } + return tmpls.Executor(name, m) } func (h *HTMLRender) CompileTemplates() error { diff --git a/modules/test/context_tests.go b/modules/test/context_tests.go index 9e7095e116..92d7f8b22b 100644 --- a/modules/test/context_tests.go +++ b/modules/test/context_tests.go @@ -150,11 +150,11 @@ func LoadGitRepo(t *testing.T, ctx *context.Context) { type mockRender struct{} -func (tr *mockRender) TemplateLookup(tmpl string) (templates.TemplateExecutor, error) { +func (tr *mockRender) TemplateLookup(tmpl string, _ gocontext.Context) (templates.TemplateExecutor, error) { return nil, nil } -func (tr *mockRender) HTML(w io.Writer, status int, _ string, _ any) error { +func (tr *mockRender) HTML(w io.Writer, status int, _ string, _ any, _ gocontext.Context) error { if resp, ok := w.(http.ResponseWriter); ok { resp.WriteHeader(status) } diff --git a/routers/common/errpage.go b/routers/common/errpage.go index 3d82c96deb..9c8ccc3388 100644 --- a/routers/common/errpage.go +++ b/routers/common/errpage.go @@ -48,7 +48,7 @@ func RenderPanicErrorPage(w http.ResponseWriter, req *http.Request, err any) { data["ErrorMsg"] = "PANIC: " + combinedErr } - err = templates.HTMLRenderer().HTML(w, http.StatusInternalServerError, string(tplStatus500), data) + err = templates.HTMLRenderer().HTML(w, http.StatusInternalServerError, string(tplStatus500), data, nil) if err != nil { log.Error("Error occurs again when rendering error page: %v", err) w.WriteHeader(http.StatusInternalServerError) diff --git a/routers/install/install.go b/routers/install/install.go index 6a8f561271..aa9c0f4986 100644 --- a/routers/install/install.go +++ b/routers/install/install.go @@ -68,9 +68,13 @@ func Contexter() func(next http.Handler) http.Handler { } defer baseCleanUp() + ctx.TemplateContext = context.NewTemplateContext(ctx) + ctx.TemplateContext["Locale"] = ctx.Locale + ctx.AppendContextValue(context.WebContextKey, ctx) ctx.Data.MergeFrom(middleware.CommonTemplateContextData()) ctx.Data.MergeFrom(middleware.ContextData{ + "Context": ctx, // TODO: use "ctx" in template and remove this "locale": ctx.Locale, "Title": ctx.Locale.Tr("install.install"), "PageIsInstall": true, diff --git a/routers/web/auth/oauth.go b/routers/web/auth/oauth.go index 3c367b3d27..78dc84472a 100644 --- a/routers/web/auth/oauth.go +++ b/routers/web/auth/oauth.go @@ -578,7 +578,7 @@ func GrantApplicationOAuth(ctx *context.Context) { // OIDCWellKnown generates JSON so OIDC clients know Gitea's capabilities func OIDCWellKnown(ctx *context.Context) { - t, err := ctx.Render.TemplateLookup("user/auth/oidc_wellknown") + t, err := ctx.Render.TemplateLookup("user/auth/oidc_wellknown", nil) if err != nil { ctx.ServerError("unable to find template", err) return diff --git a/routers/web/swagger_json.go b/routers/web/swagger_json.go index 1844b90d95..493c97aa67 100644 --- a/routers/web/swagger_json.go +++ b/routers/web/swagger_json.go @@ -13,7 +13,7 @@ const tplSwaggerV1Json base.TplName = "swagger/v1_json" // SwaggerV1Json render swagger v1 json func SwaggerV1Json(ctx *context.Context) { - t, err := ctx.Render.TemplateLookup(string(tplSwaggerV1Json)) + t, err := ctx.Render.TemplateLookup(string(tplSwaggerV1Json), nil) if err != nil { ctx.ServerError("unable to find template", err) return diff --git a/templates/base/footer.tmpl b/templates/base/footer.tmpl index e3cac806a4..31c669a921 100644 --- a/templates/base/footer.tmpl +++ b/templates/base/footer.tmpl @@ -26,6 +26,8 @@ {{end}} {{end}} -{{template "custom/footer" .}} + + {{template "custom/footer" .}} + {{ctx.DataRaceCheck $.Context}} diff --git a/templates/base/head.tmpl b/templates/base/head.tmpl index 4858d0b7de..8eebaebd70 100644 --- a/templates/base/head.tmpl +++ b/templates/base/head.tmpl @@ -1,5 +1,5 @@ - + {{if .Title}}{{.Title | RenderEmojiPlain}} - {{end}}{{if .Repository.Name}}{{.Repository.Name}} - {{end}}{{AppName}} @@ -28,7 +28,7 @@ {{if .PageIsUserProfile}} - + {{if .ContextUser.Description}} @@ -48,10 +48,10 @@ {{end}} {{end}} - {{if (.Repository.AvatarLink $.Context)}} - + {{if (.Repository.AvatarLink ctx)}} + {{else}} - + {{end}} {{else}} @@ -65,10 +65,11 @@ {{template "custom/header" .}} + {{ctx.DataRaceCheck $.Context}} {{template "custom/body_outer_pre" .}}
    - + {{template "custom/body_inner_pre" .}} From 78b2a1cc3689e1b7555bd874763eea7eb28982f9 Mon Sep 17 00:00:00 2001 From: wxiaoguang Date: Tue, 8 Aug 2023 15:29:35 +0800 Subject: [PATCH 079/200] Remove unnecessary template helper repoAvatar (#26387) And simplify the "repo/icon" code --- modules/templates/helper.go | 1 - modules/templates/util_avatar.go | 11 ----------- templates/explore/repo_list.tmpl | 7 +------ templates/org/team/repositories.tmpl | 7 +------ templates/repo/header.tmpl | 11 +++-------- templates/repo/icon.tmpl | 21 +++++++++++---------- 6 files changed, 16 insertions(+), 42 deletions(-) diff --git a/modules/templates/helper.go b/modules/templates/helper.go index cfcfbbed38..30ca767cae 100644 --- a/modules/templates/helper.go +++ b/modules/templates/helper.go @@ -59,7 +59,6 @@ func NewFuncMap() template.FuncMap { "avatarHTML": AvatarHTML, "avatarByAction": AvatarByAction, "avatarByEmail": AvatarByEmail, - "repoAvatar": RepoAvatar, "EntryIcon": base.EntryIcon, "MigrationIcon": MigrationIcon, "ActionIcon": ActionIcon, diff --git a/modules/templates/util_avatar.go b/modules/templates/util_avatar.go index 9f8f8f87a9..81961041a0 100644 --- a/modules/templates/util_avatar.go +++ b/modules/templates/util_avatar.go @@ -60,17 +60,6 @@ func AvatarByAction(ctx context.Context, action *activities_model.Action, others return Avatar(ctx, action.ActUser, others...) } -// RepoAvatar renders repo avatars. args: repo, size(int), class (string) -func RepoAvatar(repo *repo_model.Repository, others ...any) template.HTML { - size, class := gitea_html.ParseSizeAndClass(avatars.DefaultAvatarPixelSize, avatars.DefaultAvatarClass, others...) - - src := repo.RelAvatarLink() - if src != "" { - return AvatarHTML(src, size, class, repo.FullName()) - } - return template.HTML("") -} - // AvatarByEmail renders avatars by email address. args: email, name, size (int), class (string) func AvatarByEmail(ctx context.Context, email, name string, others ...any) template.HTML { size, class := gitea_html.ParseSizeAndClass(avatars.DefaultAvatarPixelSize, avatars.DefaultAvatarClass, others...) diff --git a/templates/explore/repo_list.tmpl b/templates/explore/repo_list.tmpl index 44f7900327..260f165b73 100644 --- a/templates/explore/repo_list.tmpl +++ b/templates/explore/repo_list.tmpl @@ -2,12 +2,7 @@ {{range .Repos}}
    - {{$avatar := (repoAvatar . 32)}} - {{if $avatar}} - {{$avatar}} - {{else}} - {{template "repo/icon" .}} - {{end}} + {{template "repo/icon" .}}
    diff --git a/templates/org/team/repositories.tmpl b/templates/org/team/repositories.tmpl index 698b0a91ba..ab5f6c6e75 100644 --- a/templates/org/team/repositories.tmpl +++ b/templates/org/team/repositories.tmpl @@ -30,12 +30,7 @@ {{range .Team.Repos}}
    - {{$avatar := (repoAvatar . 32)}} - {{if $avatar}} - {{$avatar}} - {{else}} - {{template "repo/icon" .}} - {{end}} + {{template "repo/icon" .}}
    diff --git a/templates/repo/header.tmpl b/templates/repo/header.tmpl index 865f3ba4a7..984e9f044e 100644 --- a/templates/repo/header.tmpl +++ b/templates/repo/header.tmpl @@ -4,14 +4,9 @@
    - {{$avatar := (repoAvatar . 32 "gt-mr-3")}} - {{if $avatar}} - {{$avatar}} - {{else}} -
    - {{template "repo/icon" .}} -
    - {{end}} +
    + {{template "repo/icon" .}} +
    {{.Owner.Name}}
    /
    {{.Name}} diff --git a/templates/repo/icon.tmpl b/templates/repo/icon.tmpl index a37197d42a..6c63e6eca6 100644 --- a/templates/repo/icon.tmpl +++ b/templates/repo/icon.tmpl @@ -1,15 +1,16 @@
    - {{if $.IsTemplate}} + {{$avatarLink := .RelAvatarLink}} + {{if $avatarLink}} + {{.FullName}} + {{else if $.IsTemplate}} {{svg "octicon-repo-template" 32}} + {{else if $.IsPrivate}} + {{svg "octicon-lock" 32}} + {{else if $.IsMirror}} + {{svg "octicon-mirror" 32}} + {{else if $.IsFork}} + {{svg "octicon-repo-forked" 32}} {{else}} - {{if $.IsPrivate}} - {{svg "octicon-lock" 32}} - {{else if $.IsMirror}} - {{svg "octicon-mirror" 32}} - {{else if $.IsFork}} - {{svg "octicon-repo-forked" 32}} - {{else}} - {{svg "octicon-repo" 32}} - {{end}} + {{svg "octicon-repo" 32}} {{end}}
    From 71d253f42e6f7d73fdaad5039df58893c336a0e6 Mon Sep 17 00:00:00 2001 From: wxiaoguang Date: Tue, 8 Aug 2023 16:29:14 +0800 Subject: [PATCH 080/200] Remove unnecessary template helper DisableGravatar (#26386) And one "AllowedUserVisibilityModes" was missing, add it. Co-authored-by: Giteabot --- modules/templates/helper.go | 5 ----- routers/web/admin/users.go | 3 +++ routers/web/user/setting/profile.go | 4 ++++ templates/admin/user/edit.tmpl | 2 +- templates/user/settings/profile.tmpl | 2 +- 5 files changed, 9 insertions(+), 7 deletions(-) diff --git a/modules/templates/helper.go b/modules/templates/helper.go index 30ca767cae..d9c297411a 100644 --- a/modules/templates/helper.go +++ b/modules/templates/helper.go @@ -5,7 +5,6 @@ package templates import ( - "context" "fmt" "html" "html/template" @@ -13,7 +12,6 @@ import ( "strings" "time" - system_model "code.gitea.io/gitea/models/system" "code.gitea.io/gitea/modules/base" "code.gitea.io/gitea/modules/emoji" "code.gitea.io/gitea/modules/markup" @@ -104,9 +102,6 @@ func NewFuncMap() template.FuncMap { "AssetVersion": func() string { return setting.AssetVersion }, - "DisableGravatar": func(ctx context.Context) bool { - return system_model.GetSettingWithCacheBool(ctx, system_model.KeyPictureDisableGravatar) - }, "DefaultShowFullName": func() bool { return setting.UI.DefaultShowFullName }, diff --git a/routers/web/admin/users.go b/routers/web/admin/users.go index 08a4076418..03c89bdab1 100644 --- a/routers/web/admin/users.go +++ b/routers/web/admin/users.go @@ -13,6 +13,7 @@ import ( "code.gitea.io/gitea/models" "code.gitea.io/gitea/models/auth" "code.gitea.io/gitea/models/db" + system_model "code.gitea.io/gitea/models/system" user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/auth/password" "code.gitea.io/gitea/modules/base" @@ -255,6 +256,7 @@ func EditUser(ctx *context.Context) { ctx.Data["DisableRegularOrgCreation"] = setting.Admin.DisableRegularOrgCreation ctx.Data["DisableMigrations"] = setting.Repository.DisableMigrations ctx.Data["AllowedUserVisibilityModes"] = setting.Service.AllowedUserVisibilityModesSlice.ToVisibleTypeSlice() + ctx.Data["DisableGravatar"] = system_model.GetSettingWithCacheBool(ctx, system_model.KeyPictureDisableGravatar) prepareUserInfo(ctx) if ctx.Written() { @@ -271,6 +273,7 @@ func EditUserPost(ctx *context.Context) { ctx.Data["PageIsAdminUsers"] = true ctx.Data["DisableMigrations"] = setting.Repository.DisableMigrations ctx.Data["AllowedUserVisibilityModes"] = setting.Service.AllowedUserVisibilityModesSlice.ToVisibleTypeSlice() + ctx.Data["DisableGravatar"] = system_model.GetSettingWithCacheBool(ctx, system_model.KeyPictureDisableGravatar) u := prepareUserInfo(ctx) if ctx.Written() { diff --git a/routers/web/user/setting/profile.go b/routers/web/user/setting/profile.go index 47066d5e38..ab7d2e58b3 100644 --- a/routers/web/user/setting/profile.go +++ b/routers/web/user/setting/profile.go @@ -17,6 +17,7 @@ import ( "code.gitea.io/gitea/models/db" "code.gitea.io/gitea/models/organization" repo_model "code.gitea.io/gitea/models/repo" + system_model "code.gitea.io/gitea/models/system" user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/base" "code.gitea.io/gitea/modules/context" @@ -43,6 +44,7 @@ func Profile(ctx *context.Context) { ctx.Data["Title"] = ctx.Tr("settings.profile") ctx.Data["PageIsSettingsProfile"] = true ctx.Data["AllowedUserVisibilityModes"] = setting.Service.AllowedUserVisibilityModesSlice.ToVisibleTypeSlice() + ctx.Data["DisableGravatar"] = system_model.GetSettingWithCacheBool(ctx, system_model.KeyPictureDisableGravatar) ctx.HTML(http.StatusOK, tplSettingsProfile) } @@ -83,6 +85,8 @@ func ProfilePost(ctx *context.Context) { form := web.GetForm(ctx).(*forms.UpdateProfileForm) ctx.Data["Title"] = ctx.Tr("settings") ctx.Data["PageIsSettingsProfile"] = true + ctx.Data["AllowedUserVisibilityModes"] = setting.Service.AllowedUserVisibilityModesSlice.ToVisibleTypeSlice() + ctx.Data["DisableGravatar"] = system_model.GetSettingWithCacheBool(ctx, system_model.KeyPictureDisableGravatar) if ctx.HasError() { ctx.HTML(http.StatusOK, tplSettingsProfile) diff --git a/templates/admin/user/edit.tmpl b/templates/admin/user/edit.tmpl index 96e09156d1..4fea418e6f 100644 --- a/templates/admin/user/edit.tmpl +++ b/templates/admin/user/edit.tmpl @@ -159,7 +159,7 @@
    {{.CsrfTokenHtml}} - {{if not (DisableGravatar $.Context)}} + {{if not .DisableGravatar}}
    diff --git a/templates/user/settings/profile.tmpl b/templates/user/settings/profile.tmpl index e0240e391f..96193a42ef 100644 --- a/templates/user/settings/profile.tmpl +++ b/templates/user/settings/profile.tmpl @@ -99,7 +99,7 @@
    {{.CsrfTokenHtml}} - {{if not (DisableGravatar $.Context)}} + {{if not .DisableGravatar}}
    From 20f47bbca932b1f6a5290fda3391928686ed0c24 Mon Sep 17 00:00:00 2001 From: Earl Warren <109468362+earl-warren@users.noreply.github.com> Date: Tue, 8 Aug 2023 11:04:04 +0200 Subject: [PATCH 081/200] fix generated source URL on rendered files (#26364) - The permalink and 'Reference in New issue' URL of an renderable file (those where you can see the source and a rendered version of it, such as markdown) doesn't contain `?display=source`. This leads the issue that the URL doesn't have any effect, as by default the rendered version is shown and thus not the source. - Add `?display=source` to the permalink URL and to 'Reference in New Issue' if it's renderable file. - Add integration testing. Refs: https://codeberg.org/forgejo/forgejo/pulls/1088 Co-authored-by: Gusted Co-authored-by: Giteabot --- models/fixtures/repo_unit.yml | 12 ++++++++++++ templates/repo/view_file.tmpl | 4 ++-- tests/integration/repo_test.go | 36 ++++++++++++++++++++++++++++++++++ 3 files changed, 50 insertions(+), 2 deletions(-) diff --git a/models/fixtures/repo_unit.yml b/models/fixtures/repo_unit.yml index bb8715a202..c22eb8c2a2 100644 --- a/models/fixtures/repo_unit.yml +++ b/models/fixtures/repo_unit.yml @@ -637,3 +637,15 @@ repo_id: 58 type: 5 created_unix: 946684810 + +- + id: 96 + repo_id: 49 + type: 1 + created_unix: 946684810 + +- + id: 97 + repo_id: 49 + type: 2 + created_unix: 946684810 diff --git a/templates/repo/view_file.tmpl b/templates/repo/view_file.tmpl index 96339c9699..c7d5b276d2 100644 --- a/templates/repo/view_file.tmpl +++ b/templates/repo/view_file.tmpl @@ -116,10 +116,10 @@ {{end}} {{end}} diff --git a/tests/integration/repo_test.go b/tests/integration/repo_test.go index 2fb1a37d31..9ace3ca30c 100644 --- a/tests/integration/repo_test.go +++ b/tests/integration/repo_test.go @@ -408,3 +408,39 @@ func TestMarkDownReadmeImageSubfolder(t *testing.T) { assert.True(t, exists, "Image not found in markdown file") assert.Equal(t, "/user2/repo1/media/branch/sub-home-md-img-check/docs/test-fake-img.jpg", src) } + +func TestGeneratedSourceLink(t *testing.T) { + defer tests.PrepareTestEnv(t)() + + t.Run("Rendered file", func(t *testing.T) { + defer tests.PrintCurrentTest(t)() + req := NewRequest(t, "GET", "/user2/repo1/src/branch/master/README.md?display=source") + resp := MakeRequest(t, req, http.StatusOK) + doc := NewHTMLParser(t, resp.Body) + + dataURL, exists := doc.doc.Find(".copy-line-permalink").Attr("data-url") + assert.True(t, exists) + assert.Equal(t, "/user2/repo1/src/commit/65f1bf27bc3bf70f64657658635e66094edbcb4d/README.md?display=source", dataURL) + + dataURL, exists = doc.doc.Find(".ref-in-new-issue").Attr("data-url-param-body-link") + assert.True(t, exists) + assert.Equal(t, "/user2/repo1/src/commit/65f1bf27bc3bf70f64657658635e66094edbcb4d/README.md?display=source", dataURL) + }) + + t.Run("Non-Rendered file", func(t *testing.T) { + defer tests.PrintCurrentTest(t)() + + session := loginUser(t, "user27") + req := NewRequest(t, "GET", "/user27/repo49/src/branch/master/test/test.txt") + resp := session.MakeRequest(t, req, http.StatusOK) + doc := NewHTMLParser(t, resp.Body) + + dataURL, exists := doc.doc.Find(".copy-line-permalink").Attr("data-url") + assert.True(t, exists) + assert.Equal(t, "/user27/repo49/src/commit/aacbdfe9e1c4b47f60abe81849045fa4e96f1d75/test/test.txt", dataURL) + + dataURL, exists = doc.doc.Find(".ref-in-new-issue").Attr("data-url-param-body-link") + assert.True(t, exists) + assert.Equal(t, "/user27/repo49/src/commit/aacbdfe9e1c4b47f60abe81849045fa4e96f1d75/test/test.txt", dataURL) + }) +} From 4fc4f6e6341cd6115dd7ac6e03888df16c6f718e Mon Sep 17 00:00:00 2001 From: wxiaoguang Date: Tue, 8 Aug 2023 18:44:19 +0800 Subject: [PATCH 082/200] Refactor "editorconfig" (#26391) There are 2 kinds of ".Editorconfig" in code, one is `JSON string` for the web edtior, another is `*editorconfig.Editorconfig` for the file rendering (used by `TabSizeClass`) This PR distinguish them with different names. And by the way, change the default tab size from 8 to 4, I think few people would like to use 8-size tabs nowadays. --- modules/templates/util_misc.go | 23 ++++++----------------- routers/web/repo/editor.go | 4 ++-- templates/repo/editor/edit.tmpl | 2 +- 3 files changed, 9 insertions(+), 20 deletions(-) diff --git a/modules/templates/util_misc.go b/modules/templates/util_misc.go index 9cdabeb3ac..7700a13932 100644 --- a/modules/templates/util_misc.go +++ b/modules/templates/util_misc.go @@ -5,10 +5,10 @@ package templates import ( "context" - "fmt" "html/template" "mime" "path/filepath" + "strconv" "strings" "time" @@ -174,23 +174,12 @@ func FilenameIsImage(filename string) bool { return strings.HasPrefix(mimeType, "image/") } -func TabSizeClass(ec any, filename string) string { - var ( - value *editorconfig.Editorconfig - ok bool - ) +func TabSizeClass(ec *editorconfig.Editorconfig, filename string) string { if ec != nil { - if value, ok = ec.(*editorconfig.Editorconfig); !ok || value == nil { - return "tab-size-8" - } - def, err := value.GetDefinitionForFilename(filename) - if err != nil { - log.Error("tab size class: getting definition for filename: %v", err) - return "tab-size-8" - } - if def.TabWidth > 0 { - return fmt.Sprintf("tab-size-%d", def.TabWidth) + def, err := ec.GetDefinitionForFilename(filename) + if err == nil && def.TabWidth >= 1 && def.TabWidth <= 16 { + return "tab-size-" + strconv.Itoa(def.TabWidth) } } - return "tab-size-8" + return "tab-size-4" } diff --git a/routers/web/repo/editor.go b/routers/web/repo/editor.go index ad2055fd57..b5129b730b 100644 --- a/routers/web/repo/editor.go +++ b/routers/web/repo/editor.go @@ -191,7 +191,7 @@ func editFile(ctx *context.Context, isNewFile bool) { ctx.Data["last_commit"] = ctx.Repo.CommitID ctx.Data["PreviewableExtensions"] = strings.Join(markup.PreviewableExtensions(), ",") ctx.Data["LineWrapExtensions"] = strings.Join(setting.Repository.Editor.LineWrapExtensions, ",") - ctx.Data["Editorconfig"] = GetEditorConfig(ctx, treePath) + ctx.Data["EditorconfigJson"] = GetEditorConfig(ctx, treePath) ctx.HTML(http.StatusOK, tplEditFile) } @@ -242,7 +242,7 @@ func editFilePost(ctx *context.Context, form forms.EditRepoFileForm, isNewFile b ctx.Data["last_commit"] = ctx.Repo.CommitID ctx.Data["PreviewableExtensions"] = strings.Join(markup.PreviewableExtensions(), ",") ctx.Data["LineWrapExtensions"] = strings.Join(setting.Repository.Editor.LineWrapExtensions, ",") - ctx.Data["Editorconfig"] = GetEditorConfig(ctx, form.TreePath) + ctx.Data["EditorconfigJson"] = GetEditorConfig(ctx, form.TreePath) if ctx.HasError() { ctx.HTML(http.StatusOK, tplEditFile) diff --git a/templates/repo/editor/edit.tmpl b/templates/repo/editor/edit.tmpl index cfdb6298e5..988b11911d 100644 --- a/templates/repo/editor/edit.tmpl +++ b/templates/repo/editor/edit.tmpl @@ -15,7 +15,7 @@ {{range $i, $v := .TreeNames}}
    /
    {{if eq $i $l}} - + {{svg "octicon-info"}} {{else}} {{$v}} From daf709286397c30d12a75f5c7bb262486f531143 Mon Sep 17 00:00:00 2001 From: "Panagiotis \"Ivory\" Vasilopoulos" Date: Tue, 8 Aug 2023 15:25:05 +0000 Subject: [PATCH 083/200] Improve multiple strings in en-US locale (#26213) I kept sending pull requests that consisted of one-line changes. It's time to settle this once and for all. (Maybe.) - Explain Gitea behavior and the consequences of each setting better, so that the user does not have to consult the docs. - Do not use different spellings of identical terms interchangeably, e.g. `e-mail` and `email`. - Use more conventional terms to describe the same things, e.g. `Confirm Password` instead of `Re-Type Password`. - Introduces additional clarification for Mirror Settings - Small adjustments in test - This is a cry for help. - Grammar and spelling consistencies for en-US locale (e.g. cancelled -> canceled) - Introduce tooltip improvements. --------- Co-authored-by: delvh Co-authored-by: wxiaoguang Co-authored-by: Giteabot --- options/locale/locale_en-US.ini | 158 ++++++++++++++------------- templates/repo/settings/options.tmpl | 4 +- tests/e2e/example.test.e2e.js | 2 +- 3 files changed, 84 insertions(+), 80 deletions(-) diff --git a/options/locale/locale_en-US.ini b/options/locale/locale_en-US.ini index f946aff10c..7697c2a61c 100644 --- a/options/locale/locale_en-US.ini +++ b/options/locale/locale_en-US.ini @@ -29,7 +29,7 @@ username = Username email = Email Address password = Password access_token = Access Token -re_type = Re-Type Password +re_type = Confirm Password captcha = CAPTCHA twofa = Two-Factor Authentication twofa_scratch = Two-Factor Scratch Code @@ -171,7 +171,7 @@ string.desc = Z - A [error] occurred = An error occurred -report_message = If you are sure this is a Gitea bug, please search for issues on GitHub or open a new issue if necessary. +report_message = If you believe that this is a Gitea bug, please search for issues on GitHub or open a new issue if necessary. missing_csrf = Bad Request: no CSRF token present invalid_csrf = Bad Request: invalid CSRF token not_found = The target couldn't be found. @@ -361,7 +361,7 @@ remember_me = Remember This Device forgot_password_title= Forgot Password forgot_password = Forgot password? sign_up_now = Need an account? Register now. -sign_up_successful = Account was successfully created. +sign_up_successful = Account was successfully created. Welcome! confirmation_mail_sent_prompt = A new confirmation email has been sent to %s. Please check your inbox within the next %s to complete the registration process. must_change_password = Update your password allow_password_change = Require user to change password (recommended) @@ -369,7 +369,7 @@ reset_password_mail_sent_prompt = A confirmation email has been sent to %s%s). If you haven't received a confirmation email or need to resend a new one, please click on the button below. resend_mail = Click here to resend your activation email @@ -379,7 +379,7 @@ reset_password = Account Recovery invalid_code = Your confirmation code is invalid or has expired. invalid_password = Your password does not match the password that was used to create the account. reset_password_helper = Recover Account -reset_password_wrong_user = You are signed in as %s, but the account recovery link is for %s +reset_password_wrong_user = You are signed in as %s, but the account recovery link is meant for %s password_too_short = Password length cannot be less than %d characters. non_local_account = Non-local users cannot update their password through the Gitea web interface. verify = Verify @@ -404,7 +404,7 @@ openid_connect_title = Connect to an existing account openid_connect_desc = The chosen OpenID URI is unknown. Associate it with a new account here. openid_register_title = Create new account openid_register_desc = The chosen OpenID URI is unknown. Associate it with a new account here. -openid_signin_desc = Enter your OpenID URI. For example: https://anne.me, bob.openid.org.cn or gnusocial.net/carry. +openid_signin_desc = Enter your OpenID URI. For example: alice.openid.example.org or https://openid.example.org/alice. disable_forgot_password_mail = Account recovery is disabled because no email is set up. Please contact your site administrator. disable_forgot_password_mail_admin = Account recovery is only available when email is set up. Please set up email to enable account recovery. email_domain_blacklisted = You cannot register with your email address. @@ -414,9 +414,9 @@ authorize_application_created_by = This application was created by %s. authorize_application_description = If you grant the access, it will be able to access and write to all your account information, including private repos and organisations. authorize_title = Authorize "%s" to access your account? authorization_failed = Authorization failed -authorization_failed_desc = The authorization failed because we detected an invalid request. Please contact the maintainer of the app you've tried to authorize. +authorization_failed_desc = The authorization failed because we detected an invalid request. Please contact the maintainer of the app you have tried to authorize. sspi_auth_failed = SSPI authentication failed -password_pwned = The password you chose is on a list of stolen passwords previously exposed in public data breaches. Please try again with a different password. +password_pwned = The password you chose is on a list of stolen passwords previously exposed in public data breaches. Please try again with a different password and consider changing this password elsewhere too. password_pwned_err = Could not complete request to HaveIBeenPwned [mail] @@ -431,7 +431,7 @@ activate_account.text_1 = Hi %[1]s, thanks for registering at %[2]s! activate_account.text_2 = Please click the following link to activate your account within %s: activate_email = Verify your email address -activate_email.title = %s, please verify your e-mail address +activate_email.title = %s, please verify your email address activate_email.text = Please click the following link to verify your email address within %s: register_notify = Welcome to Gitea @@ -497,7 +497,7 @@ UserName = Username RepoName = Repository name Email = Email address Password = Password -Retype = Re-Type Password +Retype = Confirm Password SSHTitle = SSH key name HttpsUrl = HTTPS URL PayloadUrl = Payload URL @@ -624,13 +624,13 @@ delete = Delete Account twofa = Two-Factor Authentication account_link = Linked Accounts organization = Organizations -uid = Uid +uid = UID webauthn = Security Keys public_profile = Public Profile -biography_placeholder = Tell us a little bit about yourself +biography_placeholder = Tell us a little bit about yourself! (You can use Markdown) location_placeholder = Share your approximate location with others -profile_desc = Your email address will be used for notifications and other operations. +profile_desc = Control how your profile is show to other users. Your primary email address will be used for notifications, password recovery and web-based Git operations. password_username_disabled = Non-local users are not allowed to change their username. Please contact your site administrator for more details. full_name = Full Name website = Website @@ -685,7 +685,7 @@ update_user_avatar_success = The user's avatar has been updated. change_password = Update Password old_password = Current Password new_password = New Password -retype_new_password = Re-Type New Password +retype_new_password = Confirm New Password password_incorrect = The current password is incorrect. change_password_success = Your password has been updated. Sign in using your new password from now on. password_change_disabled = Non-local users cannot update their password through the Gitea web interface. @@ -694,7 +694,7 @@ emails = Email Addresses manage_emails = Manage Email Addresses manage_themes = Select default theme manage_openid = Manage OpenID Addresses -email_desc = Your primary email address will be used for notifications and other 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. primary = Primary activated = Activated @@ -721,7 +721,7 @@ add_email_success = The new email address has been added. email_preference_set_success = Email preference has been set successfully. add_openid_success = The new OpenID address has been added. keep_email_private = Hide Email Address -keep_email_private_popup = Your email address will only be visible to you and the administrators +keep_email_private_popup = This will hide your email address from your profile, as well as when you make a pull request or edit a file using the web interface. Pushed commits will not be modified. openid_desc = OpenID lets you delegate authentication to an external provider. manage_ssh_keys = Manage SSH Keys @@ -800,9 +800,9 @@ ssh_disabled = SSH Disabled ssh_signonly = SSH is currently disabled so these keys are only used for commit signature verification. ssh_externally_managed = This SSH key is externally managed for this user manage_social = Manage Associated Social Accounts -social_desc = These social accounts are linked to your Gitea account. Make sure you recognize all of them as they can be used to sign in to your Gitea account. +social_desc = These social accounts can be used to sign in to your account. Make sure you recognize all of them. unbind = Unlink -unbind_success = The social account has been unlinked from your Gitea account. +unbind_success = The social account has been removed successfully. manage_access_token = Manage Access Tokens generate_new_token = Generate New Token @@ -836,8 +836,8 @@ remove_oauth2_application_desc = Removing an OAuth2 application will revoke acce remove_oauth2_application_success = The application has been deleted. create_oauth2_application = Create a new OAuth2 Application create_oauth2_application_button = Create Application -create_oauth2_application_success = You've successfully created a new OAuth2 application. -update_oauth2_application_success = You've successfully updated the OAuth2 application. +create_oauth2_application_success = You have successfully created a new OAuth2 application. +update_oauth2_application_success = You have successfully updated the OAuth2 application. oauth2_application_name = Application Name oauth2_confidential_client = Confidential Client. Select for apps that keep the secret confidential, such as web apps. Do not select for native apps including desktop and mobile apps. oauth2_redirect_uris = Redirect URIs. Please use a new line for every URI. @@ -846,24 +846,24 @@ oauth2_client_id = Client ID oauth2_client_secret = Client Secret oauth2_regenerate_secret = Regenerate Secret oauth2_regenerate_secret_hint = Lost your secret? -oauth2_client_secret_hint = The secret won't be visible if you revisit this page. Please save your secret. +oauth2_client_secret_hint = The secret will not be shown again after you leave or refresh this page. Please ensure that you have saved it. oauth2_application_edit = Edit oauth2_application_create_description = OAuth2 applications gives your third-party application access to user accounts on this instance. -oauth2_application_remove_description = Removing an OAuth2 application will prevent it to access authorized user accounts on this instance. Continue? +oauth2_application_remove_description = Removing an OAuth2 application will prevent it from accessing authorized user accounts on this instance. Continue? authorized_oauth2_applications = Authorized OAuth2 Applications -authorized_oauth2_applications_description = You've granted access to your personal Gitea account to these third party applications. Please revoke access for applications no longer needed. +authorized_oauth2_applications_description = You have granted access to your personal Gitea account to these third party applications. Please revoke access for applications you no longer need. revoke_key = Revoke revoke_oauth2_grant = Revoke Access revoke_oauth2_grant_description = Revoking access for this third party application will prevent this application from accessing your data. Are you sure? -revoke_oauth2_grant_success = You've revoked access successfully. +revoke_oauth2_grant_success = Access revoked successfully. twofa_desc = Two-factor authentication enhances the security of your account. twofa_is_enrolled = Your account is currently enrolled in two-factor authentication. twofa_not_enrolled = Your account is not currently enrolled in two-factor authentication. twofa_disable = Disable Two-Factor Authentication twofa_scratch_token_regenerate = Regenerate Scratch Token -twofa_scratch_token_regenerated = Your scratch token is now %s. Store it in a safe place. +twofa_scratch_token_regenerated = Your scratch token is now %s. Store it in a safe place, it will never be shown again. twofa_enroll = Enroll into Two-Factor Authentication twofa_disable_note = You can disable two-factor authentication if needed. twofa_disable_desc = Disabling two-factor authentication will make your account less secure. Continue? @@ -890,10 +890,10 @@ remove_account_link = Remove Linked Account remove_account_link_desc = Removing a linked account will revoke its access to your Gitea account. Continue? remove_account_link_success = The linked account has been removed. -hooks.desc = Add webhooks which will be triggered for all repositories owned by this user. +hooks.desc = Add webhooks which will be triggered for all repositories that you own. orgs_none = You are not a member of any organizations. -repos_none = You do not own any repositories +repos_none = You do not own any repositories. delete_account = Delete Your Account delete_prompt = This operation will permanently delete your user account. It CANNOT be undone. @@ -912,12 +912,12 @@ visibility = User visibility visibility.public = Public visibility.public_tooltip = Visible to everyone visibility.limited = Limited -visibility.limited_tooltip = Visible to authenticated users only +visibility.limited_tooltip = Visible only to authenticated users visibility.private = Private -visibility.private_tooltip = Visible only to organization members +visibility.private_tooltip = Visible only to members of organizations you have joined [repo] -new_repo_helper = A repository contains all project files, including revision history. Already have it elsewhere? Migrate repository. +new_repo_helper = A repository contains all project files, including revision history. Already hosting one elsewhere? Migrate repository. owner = Owner owner_helper = Some organizations may not show up in the dropdown due to a maximum repository count limit. repo_name = Repository Name @@ -929,7 +929,7 @@ template_helper = Make repository a template template_description = Template repositories let users generate new repositories with the same directory structure, files, and optional settings. visibility = Visibility visibility_description = Only the owner or the organization members if they have rights, will be able to see it. -visibility_helper = Make Repository Private +visibility_helper = Make repository private visibility_helper_forced = Your site administrator forces new repositories to be private. visibility_fork_helper = (Changing this will affect all forks.) clone_helper = Need help cloning? Visit Help. @@ -975,8 +975,8 @@ mirror_interval_invalid = The mirror interval is not valid. mirror_sync_on_commit = Sync when commits are pushed mirror_address = Clone From URL mirror_address_desc = Put any required credentials in the Authorization section. -mirror_address_url_invalid = The provided url is invalid. You must escape all components of the url correctly. -mirror_address_protocol_invalid = The provided url is invalid. Only http(s):// or git:// locations can be mirrored from. +mirror_address_url_invalid = The provided URL is invalid. You must escape all components of the url correctly. +mirror_address_protocol_invalid = The provided URL is invalid. Only http(s):// or git:// locations can be used for mirroring. mirror_lfs = Large File Storage (LFS) mirror_lfs_desc = Activate mirroring of LFS data. mirror_lfs_endpoint = LFS Endpoint @@ -1008,8 +1008,8 @@ transfer.accept = Accept Transfer transfer.accept_desc = Transfer to "%s" transfer.reject = Reject Transfer transfer.reject_desc = Cancel transfer to "%s" -transfer.no_permission_to_accept = You do not have permission to Accept -transfer.no_permission_to_reject = You do not have permission to Reject +transfer.no_permission_to_accept = You do not have permission to accept this transfer. +transfer.no_permission_to_reject = You do not have permission to reject this transfer. desc.private = Private desc.public = Public @@ -1030,8 +1030,8 @@ template.issue_labels = Issue Labels template.one_item = Must select at least one template item template.invalid = Must select a template repository -archive.title = This repo is archived. You can view files and clone it, but cannot push or open issues/pull-requests. -archive.title_date = This repository has been archived on %s. You can view files and clone it, but cannot push or open issues/pull-requests. +archive.title = This repo is archived. You can view files and clone it, but cannot push or open issues or pull requests. +archive.title_date = This repository has been archived on %s. You can view files and clone it, but cannot push or open issues or pull requests. archive.issue.nocomment = This repo is archived. You cannot comment on issues. archive.pull.nocomment = This repo is archived. You cannot comment on pull requests. @@ -1048,7 +1048,7 @@ migrate_options_lfs = Migrate LFS files migrate_options_lfs_endpoint.label = LFS Endpoint migrate_options_lfs_endpoint.description = Migration will attempt to use your Git remote to determine the LFS server. You can also specify a custom endpoint if the repository LFS data is stored somewhere else. migrate_options_lfs_endpoint.description.local = A local server path is supported too. -migrate_options_lfs_endpoint.placeholder = Leave blank to derive from clone URL +migrate_options_lfs_endpoint.placeholder = If left blank, the endpoint will be derived from the clone URL migrate_items = Migration Items migrate_items_wiki = Wiki migrate_items_milestones = Milestones @@ -1424,7 +1424,7 @@ issues.filter_sort.moststars = Most stars issues.filter_sort.feweststars = Fewest stars issues.filter_sort.mostforks = Most forks issues.filter_sort.fewestforks = Fewest forks -issues.keyword_search_unavailable = Currently searching by keyword is not available. Please contact your site administrator. +issues.keyword_search_unavailable = Searching by keyword is currently not available. Please contact your site administrator. issues.action_open = Open issues.action_close = Close issues.action_label = Label @@ -1543,7 +1543,7 @@ issues.tracking_already_started = `You have already started time tracking on %d%% Completed milestones.create = Create Milestone milestones.title = Title @@ -1817,19 +1817,19 @@ milestones.filter_sort.most_complete = Most complete milestones.filter_sort.most_issues = Most issues milestones.filter_sort.least_issues = Least issues -signing.will_sign = This commit will be signed with key "%s" -signing.wont_sign.error = There was an error whilst checking if the commit could be signed -signing.wont_sign.nokey = There is no key available to sign this commit -signing.wont_sign.never = Commits are never signed -signing.wont_sign.always = Commits are always signed -signing.wont_sign.pubkey = The commit will not be signed because you do not have a public key associated with your account -signing.wont_sign.twofa = You must have two factor authentication enabled to have commits signed -signing.wont_sign.parentsigned = The commit will not be signed as the parent commit is not signed -signing.wont_sign.basesigned = The merge will not be signed as the base commit is not signed -signing.wont_sign.headsigned = The merge will not be signed as the head commit is not signed -signing.wont_sign.commitssigned = The merge will not be signed as all the associated commits are not signed -signing.wont_sign.approved = The merge will not be signed as the PR is not approved -signing.wont_sign.not_signed_in = You are not signed in +signing.will_sign = This commit will be signed with key "%s". +signing.wont_sign.error = There was an error whilst checking if the commit could be signed. +signing.wont_sign.nokey = There is no key available to sign this commit. +signing.wont_sign.never = Commits are never signed. +signing.wont_sign.always = Commits are always signed. +signing.wont_sign.pubkey = The commit will not be signed because you do not have a public key associated with your account. +signing.wont_sign.twofa = You must have two factor authentication enabled to have commits signed. +signing.wont_sign.parentsigned = The commit will not be signed as the parent commit is not signed. +signing.wont_sign.basesigned = The merge will not be signed as the base commit is not signed. +signing.wont_sign.headsigned = The merge will not be signed as the head commit is not signed. +signing.wont_sign.commitssigned = The merge will not be signed as all the associated commits are not signed. +signing.wont_sign.approved = The merge will not be signed as the PR is not approved. +signing.wont_sign.not_signed_in = You are not signed in. ext_wiki = Access to External Wiki ext_wiki.desc = Link to an external wiki. @@ -1959,7 +1959,9 @@ settings.mirror_settings.docs.disabled_push_mirror.info = Push mirrors have been settings.mirror_settings.docs.no_new_mirrors = Your repository is mirroring changes to or from another repository. Please keep in mind that you can't create any new mirrors at this time. settings.mirror_settings.docs.can_still_use = Although you can't modify existing mirrors or create new ones, you may still use your existing mirror. settings.mirror_settings.docs.pull_mirror_instructions = To set up a pull mirror, please consult: +settings.mirror_settings.docs.more_information_if_disabled = You can find out more about push and pull mirrors here: settings.mirror_settings.docs.doc_link_title = How do I mirror repositories? +settings.mirror_settings.docs.doc_link_pull_section = the "Pulling from a remote repository" section of the documentation. settings.mirror_settings.docs.pulling_remote_title = Pulling from a remote repository settings.mirror_settings.mirrored_repository = Mirrored repository settings.mirror_settings.direction = Direction @@ -2039,7 +2041,7 @@ settings.transfer.rejected = Repository transfer was rejected. settings.transfer.success = Repository transfer was successful. settings.transfer_abort = Cancel transfer settings.transfer_abort_invalid = You cannot cancel a non existent repository transfer. -settings.transfer_abort_success = The repository transfer to %s was successfully cancelled. +settings.transfer_abort_success = The repository transfer to %s was successfully canceled. settings.transfer_desc = Transfer this repository to a user or to an organization for which you have administrator rights. settings.transfer_form_title = Enter the repository name as confirmation: settings.transfer_in_progress = There is currently an ongoing transfer. Please cancel it if you will like to transfer this repository to another user. @@ -2315,17 +2317,17 @@ settings.matrix.room_id = Room ID settings.matrix.message_type = Message Type settings.archive.button = Archive Repo settings.archive.header = Archive This Repo -settings.archive.text = Archiving the repo will make it entirely read-only. It is hidden from the dashboard, cannot be committed to and no issues or pull-requests can be created. +settings.archive.text = Archiving the repo will make it entirely read-only. It will be hidden from the dashboard. Nobody (not even you!) will be able to make new commits, or open any issues or pull requests. settings.archive.success = The repo was successfully archived. settings.archive.error = An error occurred while trying to archive the repo. See the log for more details. settings.archive.error_ismirror = You cannot archive a mirrored repo. settings.archive.branchsettings_unavailable = Branch settings are not available if the repo is archived. settings.archive.tagsettings_unavailable = Tag settings are not available if the repo is archived. -settings.unarchive.button = Un-Archive Repo -settings.unarchive.header = Un-Archive This Repo -settings.unarchive.text = Un-Archiving the repo will restore its ability to receive commits and pushes, as well as new issues and pull-requests. -settings.unarchive.success = The repo was successfully un-archived. -settings.unarchive.error = An error occurred while trying to un-archive the repo. See the log for more details. +settings.unarchive.button = Unarchive repo +settings.unarchive.header = Unarchive this repo +settings.unarchive.text = Unarchiving the repo will restore its ability to receive commits and pushes, as well as new issues and pull-requests. +settings.unarchive.success = The repo was successfully unarchived. +settings.unarchive.error = An error occurred while trying to unarchive the repo. See the log for more details. settings.update_avatar_success = The repository avatar has been updated. settings.lfs=LFS settings.lfs_filelist=LFS files stored in this repository @@ -2449,7 +2451,7 @@ release.edit_release = Update Release release.delete_release = Delete Release release.delete_tag = Delete Tag release.deletion = Delete Release -release.deletion_desc = Deleting a release only removes it from Gitea. Git tag, repository contents and history remain unchanged. Continue? +release.deletion_desc = Deleting a release only removes it from Gitea. It will not affect the Git tag, the contents of your repository or its history. Continue? release.deletion_success = The release has been deleted. release.deletion_tag_desc = Will delete this tag from repository. Repository contents and history remain unchanged. Continue? release.deletion_tag_success = The tag has been deleted. @@ -2470,7 +2472,7 @@ branch.already_exists = A branch named "%s" already exists. branch.delete_head = Delete branch.delete = Delete Branch "%s" branch.delete_html = Delete Branch -branch.delete_desc = Deleting a branch is permanent. Although the deleted branch may exist for a short time before cleaning up, in most cases it CANNOT be undone. Continue? +branch.delete_desc = Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue? branch.deletion_success = Branch "%s" has been deleted. branch.deletion_failed = Failed to delete branch "%s". branch.delete_branch_has_new_commits = Branch "%s" cannot be deleted because new commits have been added after merging. @@ -2639,7 +2641,7 @@ teams.all_repositories_helper = Team has access to all repositories. Selecting t teams.all_repositories_read_permission_desc = This team grants Read access to all repositories: members can view and clone repositories. teams.all_repositories_write_permission_desc = This team grants Write access to all repositories: members can read from and push to repositories. teams.all_repositories_admin_permission_desc = This team grants Admin access to all repositories: members can read from, push to and add collaborators to repositories. -teams.invite.title = You've been invited to join team %s in organization %s. +teams.invite.title = You have been invited to join team %s in organization %s. teams.invite.by = Invited by %s teams.invite.description = Please click the button below to join the team. @@ -2672,13 +2674,13 @@ dashboard.clean_unbind_oauth = Clean unbound OAuth connections dashboard.clean_unbind_oauth_success = All unbound OAuth connections have been deleted. dashboard.task.started=Started Task: %[1]s dashboard.task.process=Task: %[1]s -dashboard.task.cancelled=Task: %[1]s cancelled: %[3]s +dashboard.task.cancelled=Task: %[1]s canceled: %[3]s dashboard.task.error=Error in Task: %[1]s: %[3]s dashboard.task.finished=Task: %[1]s started by %[2]s has finished dashboard.task.unknown=Unknown task: %[1]s dashboard.cron.started=Started Cron: %[1]s dashboard.cron.process=Cron: %[1]s -dashboard.cron.cancelled=Cron: %[1]s cancelled: %[3]s +dashboard.cron.cancelled=Cron: %[1]s canceled: %[3]s dashboard.cron.error=Error in Cron: %s: %[3]s dashboard.cron.finished=Cron: %[1]s has finished dashboard.delete_inactive_accounts = Delete all unactivated accounts @@ -3376,17 +3378,17 @@ settings.delete.success = The package has been deleted. settings.delete.error = Failed to delete the package. owner.settings.cargo.title = Cargo Registry Index owner.settings.cargo.initialize = Initialize Index -owner.settings.cargo.initialize.description = To use the Cargo registry a special index git repository is needed. Here you can (re)create it with the required config. +owner.settings.cargo.initialize.description = A special index Git repository is needed to use the Cargo registry. Using this option will (re-)create the repository and configure it automatically. owner.settings.cargo.initialize.error = Failed to initialize Cargo index: %v owner.settings.cargo.initialize.success = The Cargo index was successfully created. owner.settings.cargo.rebuild = Rebuild Index -owner.settings.cargo.rebuild.description = If the index is out of sync with the cargo packages stored you can rebuild it here. +owner.settings.cargo.rebuild.description = Rebuilding can be useful if the index is not synchronized with the stored Cargo packages. owner.settings.cargo.rebuild.error = Failed to rebuild Cargo index: %v owner.settings.cargo.rebuild.success = The Cargo index was successfully rebuild. owner.settings.cleanuprules.title = Manage Cleanup Rules owner.settings.cleanuprules.add = Add Cleanup Rule owner.settings.cleanuprules.edit = Edit Cleanup Rule -owner.settings.cleanuprules.none = No cleanup rules available. Read the docs to learn more. +owner.settings.cleanuprules.none = No cleanup rules available. Please consult the documentation. owner.settings.cleanuprules.preview = Cleanup Rule Preview owner.settings.cleanuprules.preview.overview = %d packages are scheduled to be removed. owner.settings.cleanuprules.preview.none = Cleanup rule does not match any packages. @@ -3405,7 +3407,7 @@ owner.settings.cleanuprules.success.update = Cleanup rule has been updated. owner.settings.cleanuprules.success.delete = Cleanup rule has been deleted. owner.settings.chef.title = Chef Registry owner.settings.chef.keypair = Generate key pair -owner.settings.chef.keypair.description = Generate a key pair used to authenticate against the Chef registry. The previous key can not be used afterwards. +owner.settings.chef.keypair.description = A key pair is necessary to authenticate to the Chef registry. If you have generated a key pair before, generating a new key pair will discard the old key pair. [secrets] secrets = Secrets @@ -3432,7 +3434,7 @@ status.waiting = "Waiting" status.running = "Running" status.success = "Success" status.failure = "Failure" -status.cancelled = "Cancelled" +status.cancelled = "Canceled" status.skipped = "Skipped" status.blocked = "Blocked" diff --git a/templates/repo/settings/options.tmpl b/templates/repo/settings/options.tmpl index b247e85fa3..cc7f431535 100644 --- a/templates/repo/settings/options.tmpl +++ b/templates/repo/settings/options.tmpl @@ -83,13 +83,15 @@ {{$.locale.Tr "repo.settings.mirror_settings.docs"}} {{$.locale.Tr "repo.settings.mirror_settings.docs.doc_link_title"}}

    {{$.locale.Tr "repo.settings.mirror_settings.docs.pull_mirror_instructions"}} - {{$.locale.Tr "repo.settings.mirror_settings.docs.doc_link_title"}}
    + {{$.locale.Tr "repo.settings.mirror_settings.docs.doc_link_pull_section"}}
    {{else if $onlyNewPushMirrorsEnabled}} {{$.locale.Tr "repo.settings.mirror_settings.docs.disabled_pull_mirror.instructions"}} + {{$.locale.Tr "repo.settings.mirror_settings.docs.more_information_if_disabled"}} {{$.locale.Tr "repo.settings.mirror_settings.docs.doc_link_title"}}
    {{else if $onlyNewPullMirrorsEnabled}} {{$.locale.Tr "repo.settings.mirror_settings.docs.disabled_push_mirror.instructions"}} {{$.locale.Tr "repo.settings.mirror_settings.docs.disabled_push_mirror.pull_mirror_warning"}} + {{$.locale.Tr "repo.settings.mirror_settings.docs.more_information_if_disabled"}} {{$.locale.Tr "repo.settings.mirror_settings.docs.doc_link_title"}}

    {{$.locale.Tr "repo.settings.mirror_settings.docs.disabled_push_mirror.info"}} {{if $existingPushMirror}} diff --git a/tests/e2e/example.test.e2e.js b/tests/e2e/example.test.e2e.js index b0aa2b7a65..5e45bad24a 100644 --- a/tests/e2e/example.test.e2e.js +++ b/tests/e2e/example.test.e2e.js @@ -24,7 +24,7 @@ test('Test Register Form', async ({page}, workerInfo) => { // Make sure we routed to the home page. Else login failed. await expect(page.url()).toBe(`${workerInfo.project.use.baseURL}/`); await expect(page.locator('.dashboard-navbar span>img.ui.avatar')).toBeVisible(); - await expect(page.locator('.ui.positive.message.flash-success')).toHaveText('Account was successfully created.'); + await expect(page.locator('.ui.positive.message.flash-success')).toHaveText('Account was successfully created. Welcome!'); save_visual(page); }); From e6f8e9318b1984d3e735bff0d2eca4a22906973d Mon Sep 17 00:00:00 2001 From: KN4CK3R Date: Tue, 8 Aug 2023 18:28:24 +0200 Subject: [PATCH 084/200] Use flex classes in package settings (#26314) Regression of #25790 Fixes #26310 --------- Co-authored-by: Giteabot --- templates/org/team/members.tmpl | 28 +++++++++++++--------- templates/package/settings.tmpl | 42 +++++++++++++++++---------------- 2 files changed, 39 insertions(+), 31 deletions(-) diff --git a/templates/org/team/members.tmpl b/templates/org/team/members.tmpl index 4a97763d9a..a73eb7bbd3 100644 --- a/templates/org/team/members.tmpl +++ b/templates/org/team/members.tmpl @@ -53,17 +53,23 @@
    {{if and .Invites $.IsOrganizationOwner}}

    {{$.locale.Tr "org.teams.invite_team_member.list"}}

    -
    - {{range .Invites}} -
    - {{.Email}} - - {{$.CsrfTokenHtml}} - - - -
    - {{end}} +
    +
    + {{range .Invites}} +
    +
    + {{.Email}} +
    +
    +
    + {{$.CsrfTokenHtml}} + + +
    +
    +
    + {{end}} +
    {{end}}
    diff --git a/templates/package/settings.tmpl b/templates/package/settings.tmpl index abcdd7ec1c..af543328f8 100644 --- a/templates/package/settings.tmpl +++ b/templates/package/settings.tmpl @@ -38,28 +38,30 @@

    {{.locale.Tr "repo.settings.danger_zone"}}

    -
    -
    -
    - -
    -
    -
    {{.locale.Tr "packages.settings.delete"}}
    -

    {{.locale.Tr "packages.settings.delete.description"}}

    -
    -