From 8218b6484c86eaec6b45e97bbf85a88c2db71568 Mon Sep 17 00:00:00 2001 From: james yang Date: Mon, 13 May 2024 22:05:56 +0800 Subject: [PATCH 01/29] fix: change npm scope registry (#30964) https://docs.npmjs.com/cli/v10/using-npm/scope#associating-a-scope-with-a-registry --- docs/content/usage/packages/npm.en-us.md | 4 ++-- docs/content/usage/packages/npm.zh-cn.md | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/content/usage/packages/npm.en-us.md b/docs/content/usage/packages/npm.en-us.md index 1590b9623a..ccc075b140 100644 --- a/docs/content/usage/packages/npm.en-us.md +++ b/docs/content/usage/packages/npm.en-us.md @@ -30,7 +30,7 @@ The following examples use the `npm` tool with the scope `@test`. To register the package registry you need to configure a new package source. ```shell -npm config set {scope}:registry https://gitea.example.com/api/packages/{owner}/npm/ +npm config set {scope}:registry=https://gitea.example.com/api/packages/{owner}/npm/ npm config set -- '//gitea.example.com/api/packages/{owner}/npm/:_authToken' "{token}" ``` @@ -43,7 +43,7 @@ npm config set -- '//gitea.example.com/api/packages/{owner}/npm/:_authToken' "{t For example: ```shell -npm config set @test:registry https://gitea.example.com/api/packages/testuser/npm/ +npm config set @test:registry=https://gitea.example.com/api/packages/testuser/npm/ npm config set -- '//gitea.example.com/api/packages/testuser/npm/:_authToken' "personal_access_token" ``` diff --git a/docs/content/usage/packages/npm.zh-cn.md b/docs/content/usage/packages/npm.zh-cn.md index d51b8b78a1..772cdc08b2 100644 --- a/docs/content/usage/packages/npm.zh-cn.md +++ b/docs/content/usage/packages/npm.zh-cn.md @@ -30,7 +30,7 @@ menu: 要注册软件包注册表,您需要配置一个新的软件包源。 ```shell -npm config set {scope}:registry https://gitea.example.com/api/packages/{owner}/npm/ +npm config set {scope}:registry=https://gitea.example.com/api/packages/{owner}/npm/ npm config set -- '//gitea.example.com/api/packages/{owner}/npm/:_authToken' "{token}" ``` @@ -43,7 +43,7 @@ npm config set -- '//gitea.example.com/api/packages/{owner}/npm/:_authToken' "{t 例如: ```shell -npm config set @test:registry https://gitea.example.com/api/packages/testuser/npm/ +npm config set @test:registry=https://gitea.example.com/api/packages/testuser/npm/ npm config set -- '//gitea.example.com/api/packages/testuser/npm/:_authToken' "personal_access_token" ``` From ed25676a9ae75c3a5f092dbaa449770fb1e9e70c Mon Sep 17 00:00:00 2001 From: silverwind Date: Mon, 13 May 2024 23:33:51 +0200 Subject: [PATCH 02/29] Restyle release list, fix branch dropdown (#30837) Fixes https://github.com/go-gitea/gitea/issues/30821 and restyles the release list. Desktop: Screenshot 2024-05-02 at 20 46 10 Mobile: Screenshot 2024-05-02 at 20 46 21 --------- Co-authored-by: Giteabot --- templates/repo/release/list.tmpl | 17 ++++--- templates/repo/tag/list.tmpl | 8 ++-- tests/integration/release_test.go | 8 ++-- web_src/css/repo/release-tag.css | 80 ++++++++++++++++++++----------- 4 files changed, 68 insertions(+), 45 deletions(-) diff --git a/templates/repo/release/list.tmpl b/templates/repo/release/list.tmpl index 5a8668fbe1..34548672b5 100644 --- a/templates/repo/release/list.tmpl +++ b/templates/repo/release/list.tmpl @@ -7,18 +7,18 @@
    {{range $idx, $info := .Releases}} {{$release := $info.Release}} -
  • -
    +
  • +
    {{svg "octicon-tag" 16 "tw-mr-1"}}{{$release.TagName}} {{if and $release.Sha1 ($.Permission.CanRead ctx.Consts.RepoUnitTypeCode)}} {{svg "octicon-git-commit" 16 "tw-mr-1"}}{{ShortSha $release.Sha1}} {{template "repo/branch_dropdown" dict "root" $ "release" $release}} {{end}}
    -
    +

    - {{if $.PageIsSingleTag}}{{$release.Title}}{{else}}{{$release.Title}}{{end}} + {{if $.PageIsSingleTag}}{{$release.Title}}{{else}}{{$release.Title}}{{end}} {{template "repo/commit_statuses" dict "Status" $info.CommitStatus "Statuses" $info.CommitStatuses "AdditionalClasses" "tw-flex"}} {{if $release.IsDraft}} {{ctx.Locale.Tr "repo.release.draft"}} @@ -62,22 +62,22 @@

    - + {{ctx.Locale.Tr "repo.release.downloads"}}
    -
  • {{end}} diff --git a/templates/repo/tag/list.tmpl b/templates/repo/tag/list.tmpl index b3ad3a7c47..354808ed2e 100644 --- a/templates/repo/tag/list.tmpl +++ b/templates/repo/tag/list.tmpl @@ -16,12 +16,12 @@ {{range $idx, $release := .Releases}} - -

    + +

    {{if $canReadReleases}} - {{.TagName}} + {{.TagName}} {{else}} - {{.TagName}} + {{.TagName}} {{end}}

    diff --git a/tests/integration/release_test.go b/tests/integration/release_test.go index ce0c440167..40bd798d16 100644 --- a/tests/integration/release_test.go +++ b/tests/integration/release_test.go @@ -142,7 +142,7 @@ func TestViewReleaseListNoLogin(t *testing.T) { rsp := MakeRequest(t, req, http.StatusOK) htmlDoc := NewHTMLParser(t, rsp.Body) - releases := htmlDoc.Find("#release-list li.ui.grid") + releases := htmlDoc.Find("#release-list .release-entry") assert.Equal(t, 5, releases.Length()) links := make([]string, 0, 5) @@ -198,7 +198,7 @@ func TestViewReleaseListLogin(t *testing.T) { rsp := session.MakeRequest(t, req, http.StatusOK) htmlDoc := NewHTMLParser(t, rsp.Body) - releases := htmlDoc.Find("#release-list li.ui.grid") + releases := htmlDoc.Find("#release-list .release-entry") assert.Equal(t, 3, releases.Length()) links := make([]string, 0, 5) @@ -229,12 +229,12 @@ func TestViewTagsList(t *testing.T) { rsp := session.MakeRequest(t, req, http.StatusOK) htmlDoc := NewHTMLParser(t, rsp.Body) - tags := htmlDoc.Find(".tag-list tr") + tags := htmlDoc.Find(".tag-list-row-link") assert.Equal(t, 3, tags.Length()) tagNames := make([]string, 0, 5) tags.Each(func(i int, s *goquery.Selection) { - tagNames = append(tagNames, s.Find(".tag a.tw-flex.tw-items-center").Text()) + tagNames = append(tagNames, s.Text()) }) assert.EqualValues(t, []string{"v1.0", "delete-tag", "v1.1"}, tagNames) diff --git a/web_src/css/repo/release-tag.css b/web_src/css/repo/release-tag.css index a146eda6a9..32027dd886 100644 --- a/web_src/css/repo/release-tag.css +++ b/web_src/css/repo/release-tag.css @@ -1,10 +1,11 @@ -.repository.releases #release-list { - margin-top: 12px; - padding-top: 12px; +#release-list { + display: flex; + flex-direction: column; + gap: var(--page-spacing); padding-left: 0; } -.repository.releases #release-list .release-list-title { +#release-list .release-list-title { font-size: 2rem; font-weight: var(--font-weight-normal); display: flex; @@ -13,58 +14,81 @@ margin: 0; } -.repository.releases #release-list > li .meta { - padding-top: 25px; +#release-list .release-entry { + display: flex; + gap: var(--page-spacing); +} + +#release-list .release-entry .meta { + flex: 0 0 150px; position: relative; text-align: right; display: flex; flex-direction: column; - gap: 1em; + gap: 10px; } -.repository.releases #release-list > li .detail { - padding-bottom: 20px; - border-left: 1px solid var(--color-secondary); +#release-list .release-entry .detail { + flex: 1; + margin: 0; } -.repository.releases #release-list > li .detail .author img { +@media (max-width: 767.98px) { + #release-list .release-entry { + flex-direction: column; + gap: var(--page-spacing); + } + #release-list .release-entry .meta { + margin-left: 6px; + flex-direction: row; + flex-basis: auto; + display: flex; + align-items: center; + } + #release-list .js-branch-tag-selector { + margin-left: auto; + } + #release-list .branch-selector-dropdown .menu { /* open menu to left */ + right: 0; + left: auto; + } +} + +#release-list .release-entry .detail .author img { margin-bottom: 2px; /* the legacy trick to align the avatar vertically, no better solution at the moment */ } -.repository.releases #release-list > li .detail .download .list { +#release-list .release-entry .detail .download .list { padding-left: 0; border: 1px solid var(--color-secondary); border-radius: var(--border-radius); - background: var(--color-light); } -.repository.releases #release-list > li .detail .download .list li { +#release-list .release-entry .detail .download .list li { display: flex; justify-content: space-between; padding: 8px; border-bottom: 1px solid var(--color-secondary); } -.repository.releases #release-list > li .detail .download .list li:last-child { +#release-list .release-entry .detail .download[open] summary { + margin-bottom: 10px; +} + +#release-list .download-icon { + margin-right: .25rem; + color: var(--color-text-light-1); +} + +#release-list .release-entry .detail .download .list li:last-child { border-bottom: none; } -.repository.releases #release-list > li .detail .dot { - width: 10px; - height: 10px; - background-color: var(--color-secondary-dark-3); - position: absolute; - left: -5.5px; - top: 30px; - border-radius: var(--border-radius-circle); - border: 2.5px solid var(--color-body); -} - -.repository.tags #tags-table .tag { +#tags-table .tag-list-row { padding: 8px 12px; } -.repository.tags #tags-table .release-tag-name { +#tags-table .tag-list-row-title { font-size: 18px; font-weight: var(--font-weight-normal); } From 9a577c62e4848a497340cbe8fbfb5d663ccd78a4 Mon Sep 17 00:00:00 2001 From: GiteaBot Date: Tue, 14 May 2024 00:25:02 +0000 Subject: [PATCH 03/29] [skip ci] Updated translations via Crowdin --- options/locale/locale_ja-JP.ini | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/options/locale/locale_ja-JP.ini b/options/locale/locale_ja-JP.ini index e33a1ae173..03a06dab16 100644 --- a/options/locale/locale_ja-JP.ini +++ b/options/locale/locale_ja-JP.ini @@ -164,6 +164,8 @@ search=検索… type_tooltip=検索タイプ fuzzy=あいまい fuzzy_tooltip=検索語におおよそ一致する結果も含めます +exact=完全一致 +exact_tooltip=検索語と完全に一致する結果だけを含めます repo_kind=リポジトリを検索... user_kind=ユーザーを検索... org_kind=組織を検索... @@ -177,6 +179,8 @@ branch_kind=ブランチを検索... commit_kind=コミットを検索... runner_kind=ランナーを検索... no_results=一致する結果が見つかりませんでした +issue_kind=イシューを検索... +pull_kind=プルリクエストを検索... keyword_search_unavailable=キーワード検索は現在利用できません。 サイト管理者にお問い合わせください。 [aria] @@ -883,6 +887,7 @@ repo_and_org_access=リポジトリと組織へのアクセス permissions_public_only=公開のみ permissions_access_all=すべて (公開、プライベート、限定) select_permissions=許可の選択 +permission_not_set=設定なし permission_no_access=アクセス不可 permission_read=読み取り permission_write=読み取りと書き込み @@ -2093,6 +2098,7 @@ settings.advanced_settings=拡張設定 settings.wiki_desc=Wikiを有効にする settings.use_internal_wiki=ビルトインのWikiを使用する settings.default_wiki_branch_name=デフォルトのWikiブランチ名 +settings.default_wiki_everyone_access=サインインユーザーのデフォルトのアクセス権限: settings.failed_to_change_default_wiki_branch=デフォルトのWikiブランチを変更できませんでした。 settings.use_external_wiki=外部のWikiを使用する settings.external_wiki_url=外部WikiのURL @@ -3486,6 +3492,7 @@ npm.install=npm を使用してパッケージをインストールするには npm.install2=または package.json ファイルに追加します: npm.dependencies=依存関係 npm.dependencies.development=開発用依存関係 +npm.dependencies.bundle=バンドルされた依存関係 npm.dependencies.peer=Peer依存関係 npm.dependencies.optional=オプションの依存関係 npm.details.tag=タグ From b1d8f13bd0ecd9c576ebf2ecbd9c7dbeb3f5254f Mon Sep 17 00:00:00 2001 From: KN4CK3R Date: Tue, 14 May 2024 08:48:21 +0200 Subject: [PATCH 04/29] Protected tag is no internal server error (#30962) Fixes #30959 Adds an API test for protected tags. Fix existing tag in combination with fixtures. --- models/fixtures/protected_tag.yml | 24 ++++++++++++++++++++++++ routers/api/v1/repo/release.go | 11 ++++++++--- routers/api/v1/repo/release_tags.go | 6 +++--- routers/api/v1/repo/tag.go | 8 ++++++-- templates/swagger/v1_json.tmpl | 17 +++++++++++++---- tests/integration/api_releases_test.go | 25 +++++++++++++++++++++++++ tests/integration/repo_tag_test.go | 21 ++++----------------- 7 files changed, 83 insertions(+), 29 deletions(-) create mode 100644 models/fixtures/protected_tag.yml diff --git a/models/fixtures/protected_tag.yml b/models/fixtures/protected_tag.yml new file mode 100644 index 0000000000..dbec52c0c2 --- /dev/null +++ b/models/fixtures/protected_tag.yml @@ -0,0 +1,24 @@ +- + id: 1 + repo_id: 4 + name_pattern: /v.+/ + allowlist_user_i_ds: [] + allowlist_team_i_ds: [] + created_unix: 1715596037 + updated_unix: 1715596037 +- + id: 2 + repo_id: 1 + name_pattern: v-* + allowlist_user_i_ds: [] + allowlist_team_i_ds: [] + created_unix: 1715596037 + updated_unix: 1715596037 +- + id: 3 + repo_id: 1 + name_pattern: v-1.1 + allowlist_user_i_ds: [2] + allowlist_team_i_ds: [] + created_unix: 1715596037 + updated_unix: 1715596037 diff --git a/routers/api/v1/repo/release.go b/routers/api/v1/repo/release.go index f0f3c0bbc7..f92fb86f5c 100644 --- a/routers/api/v1/repo/release.go +++ b/routers/api/v1/repo/release.go @@ -215,6 +215,9 @@ func CreateRelease(ctx *context.APIContext) { // "$ref": "#/responses/notFound" // "409": // "$ref": "#/responses/error" + // "422": + // "$ref": "#/responses/validationError" + form := web.GetForm(ctx).(*api.CreateReleaseOption) if ctx.Repo.Repository.IsEmpty { ctx.Error(http.StatusUnprocessableEntity, "RepoIsEmpty", fmt.Errorf("repo is empty")) @@ -246,6 +249,8 @@ func CreateRelease(ctx *context.APIContext) { if err := release_service.CreateRelease(ctx.Repo.GitRepo, rel, nil, ""); err != nil { if repo_model.IsErrReleaseAlreadyExist(err) { ctx.Error(http.StatusConflict, "ReleaseAlreadyExist", err) + } else if models.IsErrProtectedTagName(err) { + ctx.Error(http.StatusUnprocessableEntity, "ProtectedTagName", err) } else { ctx.Error(http.StatusInternalServerError, "CreateRelease", err) } @@ -386,8 +391,8 @@ func DeleteRelease(ctx *context.APIContext) { // "$ref": "#/responses/empty" // "404": // "$ref": "#/responses/notFound" - // "405": - // "$ref": "#/responses/empty" + // "422": + // "$ref": "#/responses/validationError" id := ctx.ParamsInt64(":id") rel, err := repo_model.GetReleaseForRepoByID(ctx, ctx.Repo.Repository.ID, id) @@ -401,7 +406,7 @@ func DeleteRelease(ctx *context.APIContext) { } if err := release_service.DeleteReleaseByID(ctx, ctx.Repo.Repository, rel, ctx.Doer, false); err != nil { if models.IsErrProtectedTagName(err) { - ctx.Error(http.StatusMethodNotAllowed, "delTag", "user not allowed to delete protected tag") + ctx.Error(http.StatusUnprocessableEntity, "delTag", "user not allowed to delete protected tag") return } ctx.Error(http.StatusInternalServerError, "DeleteReleaseByID", err) diff --git a/routers/api/v1/repo/release_tags.go b/routers/api/v1/repo/release_tags.go index fec91164a2..f845fad53b 100644 --- a/routers/api/v1/repo/release_tags.go +++ b/routers/api/v1/repo/release_tags.go @@ -92,8 +92,8 @@ func DeleteReleaseByTag(ctx *context.APIContext) { // "$ref": "#/responses/empty" // "404": // "$ref": "#/responses/notFound" - // "405": - // "$ref": "#/responses/empty" + // "422": + // "$ref": "#/responses/validationError" tag := ctx.Params(":tag") @@ -114,7 +114,7 @@ func DeleteReleaseByTag(ctx *context.APIContext) { if err = releaseservice.DeleteReleaseByID(ctx, ctx.Repo.Repository, release, ctx.Doer, false); err != nil { if models.IsErrProtectedTagName(err) { - ctx.Error(http.StatusMethodNotAllowed, "delTag", "user not allowed to delete protected tag") + ctx.Error(http.StatusUnprocessableEntity, "delTag", "user not allowed to delete protected tag") return } ctx.Error(http.StatusInternalServerError, "DeleteReleaseByID", err) diff --git a/routers/api/v1/repo/tag.go b/routers/api/v1/repo/tag.go index a6908f3615..8577a0e896 100644 --- a/routers/api/v1/repo/tag.go +++ b/routers/api/v1/repo/tag.go @@ -184,6 +184,8 @@ func CreateTag(ctx *context.APIContext) { // "$ref": "#/responses/empty" // "409": // "$ref": "#/responses/conflict" + // "422": + // "$ref": "#/responses/validationError" // "423": // "$ref": "#/responses/repoArchivedError" form := web.GetForm(ctx).(*api.CreateTagOption) @@ -205,7 +207,7 @@ func CreateTag(ctx *context.APIContext) { return } if models.IsErrProtectedTagName(err) { - ctx.Error(http.StatusMethodNotAllowed, "CreateNewTag", "user not allowed to create protected tag") + ctx.Error(http.StatusUnprocessableEntity, "CreateNewTag", "user not allowed to create protected tag") return } @@ -253,6 +255,8 @@ func DeleteTag(ctx *context.APIContext) { // "$ref": "#/responses/empty" // "409": // "$ref": "#/responses/conflict" + // "422": + // "$ref": "#/responses/validationError" // "423": // "$ref": "#/responses/repoArchivedError" tagName := ctx.Params("*") @@ -274,7 +278,7 @@ func DeleteTag(ctx *context.APIContext) { if err = releaseservice.DeleteReleaseByID(ctx, ctx.Repo.Repository, tag, ctx.Doer, true); err != nil { if models.IsErrProtectedTagName(err) { - ctx.Error(http.StatusMethodNotAllowed, "delTag", "user not allowed to delete protected tag") + ctx.Error(http.StatusUnprocessableEntity, "delTag", "user not allowed to delete protected tag") return } ctx.Error(http.StatusInternalServerError, "DeleteReleaseByID", err) diff --git a/templates/swagger/v1_json.tmpl b/templates/swagger/v1_json.tmpl index b1255f1289..9ad0aa2ab6 100644 --- a/templates/swagger/v1_json.tmpl +++ b/templates/swagger/v1_json.tmpl @@ -12831,6 +12831,9 @@ }, "409": { "$ref": "#/responses/error" + }, + "422": { + "$ref": "#/responses/validationError" } } } @@ -12949,8 +12952,8 @@ "404": { "$ref": "#/responses/notFound" }, - "405": { - "$ref": "#/responses/empty" + "422": { + "$ref": "#/responses/validationError" } } } @@ -13035,8 +13038,8 @@ "404": { "$ref": "#/responses/notFound" }, - "405": { - "$ref": "#/responses/empty" + "422": { + "$ref": "#/responses/validationError" } } }, @@ -13886,6 +13889,9 @@ "409": { "$ref": "#/responses/conflict" }, + "422": { + "$ref": "#/responses/validationError" + }, "423": { "$ref": "#/responses/repoArchivedError" } @@ -13979,6 +13985,9 @@ "409": { "$ref": "#/responses/conflict" }, + "422": { + "$ref": "#/responses/validationError" + }, "423": { "$ref": "#/responses/repoArchivedError" } diff --git a/tests/integration/api_releases_test.go b/tests/integration/api_releases_test.go index 73b371b2cb..0b336a90e2 100644 --- a/tests/integration/api_releases_test.go +++ b/tests/integration/api_releases_test.go @@ -154,6 +154,31 @@ func TestAPICreateAndUpdateRelease(t *testing.T) { assert.EqualValues(t, rel.Note, newRelease.Note) } +func TestAPICreateProtectedTagRelease(t *testing.T) { + defer tests.PrepareTestEnv(t)() + + repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 4}) + writer := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 4}) + session := loginUser(t, writer.LowerName) + token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteRepository) + + gitRepo, err := gitrepo.OpenRepository(git.DefaultContext, repo) + assert.NoError(t, err) + defer gitRepo.Close() + + commit, err := gitRepo.GetBranchCommit("master") + assert.NoError(t, err) + + req := NewRequestWithJSON(t, "POST", fmt.Sprintf("/api/v1/repos/%s/%s/releases", repo.OwnerName, repo.Name), &api.CreateReleaseOption{ + TagName: "v0.0.1", + Title: "v0.0.1", + IsDraft: false, + IsPrerelease: false, + Target: commit.ID.String(), + }).AddTokenAuth(token) + MakeRequest(t, req, http.StatusUnprocessableEntity) +} + func TestAPICreateReleaseToDefaultBranch(t *testing.T) { defer tests.PrepareTestEnv(t)() diff --git a/tests/integration/repo_tag_test.go b/tests/integration/repo_tag_test.go index 7e77906473..6d3d85532c 100644 --- a/tests/integration/repo_tag_test.go +++ b/tests/integration/repo_tag_test.go @@ -26,22 +26,10 @@ func TestCreateNewTagProtected(t *testing.T) { repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}) owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID}) - t.Run("API", func(t *testing.T) { + t.Run("Code", func(t *testing.T) { defer tests.PrintCurrentTest(t)() - err := release.CreateNewTag(git.DefaultContext, owner, repo, "master", "v-1", "first tag") - assert.NoError(t, err) - - err = git_model.InsertProtectedTag(db.DefaultContext, &git_model.ProtectedTag{ - RepoID: repo.ID, - NamePattern: "v-*", - }) - assert.NoError(t, err) - err = git_model.InsertProtectedTag(db.DefaultContext, &git_model.ProtectedTag{ - RepoID: repo.ID, - NamePattern: "v-1.1", - AllowlistUserIDs: []int64{repo.OwnerID}, - }) + err := release.CreateNewTag(git.DefaultContext, owner, repo, "master", "t-first", "first tag") assert.NoError(t, err) err = release.CreateNewTag(git.DefaultContext, owner, repo, "master", "v-2", "second tag") @@ -54,13 +42,12 @@ func TestCreateNewTagProtected(t *testing.T) { t.Run("Git", func(t *testing.T) { onGiteaRun(t, func(t *testing.T, u *url.URL) { - username := "user2" - httpContext := NewAPITestContext(t, username, "repo1") + httpContext := NewAPITestContext(t, owner.Name, repo.Name) dstPath := t.TempDir() u.Path = httpContext.GitPath() - u.User = url.UserPassword(username, userPassword) + u.User = url.UserPassword(owner.Name, userPassword) doGitClone(dstPath, u)(t) From f4f4e18b14c3d772e9183e8f1d2b2df45712c496 Mon Sep 17 00:00:00 2001 From: wxiaoguang Date: Tue, 14 May 2024 21:47:03 +0800 Subject: [PATCH 05/29] Filter out duplicate action(activity) items for a repository (#30957) Fix #20986 --- models/activities/action.go | 11 ++++++++++- models/activities/action_test.go | 21 +++++++++++++++++++++ 2 files changed, 31 insertions(+), 1 deletion(-) diff --git a/models/activities/action.go b/models/activities/action.go index 7e2ef4c9ae..d23f2bd986 100644 --- a/models/activities/action.go +++ b/models/activities/action.go @@ -524,7 +524,12 @@ func activityQueryCondition(ctx context.Context, opts GetFeedsOptions) (builder. } if opts.RequestedRepo != nil { - cond = cond.And(builder.Eq{"repo_id": opts.RequestedRepo.ID}) + // repo's actions could have duplicate items, see the comment of NotifyWatchers + // so here we only filter the "original items", aka: user_id == act_user_id + cond = cond.And( + builder.Eq{"`action`.repo_id": opts.RequestedRepo.ID}, + builder.Expr("`action`.user_id = `action`.act_user_id"), + ) } if opts.RequestedTeam != nil { @@ -577,6 +582,10 @@ func DeleteOldActions(ctx context.Context, olderThan time.Duration) (err error) } // NotifyWatchers creates batch of actions for every watcher. +// It could insert duplicate actions for a repository action, like this: +// * Original action: UserID=1 (the real actor), ActUserID=1 +// * Organization action: UserID=100 (the repo's org), ActUserID=1 +// * Watcher action: UserID=20 (a user who is watching a repo), ActUserID=1 func NotifyWatchers(ctx context.Context, actions ...*Action) error { var watchers []*repo_model.Watch var repo *repo_model.Repository diff --git a/models/activities/action_test.go b/models/activities/action_test.go index 5467bd35fb..557415dcda 100644 --- a/models/activities/action_test.go +++ b/models/activities/action_test.go @@ -318,3 +318,24 @@ func TestDeleteIssueActions(t *testing.T) { assert.NoError(t, activities_model.DeleteIssueActions(db.DefaultContext, issue.RepoID, issue.ID, issue.Index)) unittest.AssertCount(t, &activities_model.Action{}, 0) } + +func TestRepoActions(t *testing.T) { + assert.NoError(t, unittest.PrepareTestDatabase()) + repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}) + _ = db.TruncateBeans(db.DefaultContext, &activities_model.Action{}) + for i := 0; i < 3; i++ { + _ = db.Insert(db.DefaultContext, &activities_model.Action{ + UserID: 2 + int64(i), + ActUserID: 2, + RepoID: repo.ID, + OpType: activities_model.ActionCommentIssue, + }) + } + count, _ := db.Count[activities_model.Action](db.DefaultContext, &db.ListOptions{}) + assert.EqualValues(t, 3, count) + actions, _, err := activities_model.GetFeeds(db.DefaultContext, activities_model.GetFeedsOptions{ + RequestedRepo: repo, + }) + assert.NoError(t, err) + assert.Len(t, actions, 1) +} From effb405cae88474c27f5c8322a2627019af1cf64 Mon Sep 17 00:00:00 2001 From: wxiaoguang Date: Tue, 14 May 2024 22:21:38 +0800 Subject: [PATCH 06/29] Always load or generate oauth2 jwt secret (#30942) Fix #30923 --- modules/setting/oauth2.go | 17 ++++++----------- modules/setting/oauth2_test.go | 28 +++++++++++++++++++++++++++- routers/install/install.go | 11 +++++++++++ 3 files changed, 44 insertions(+), 12 deletions(-) diff --git a/modules/setting/oauth2.go b/modules/setting/oauth2.go index e59f54420b..0d3e63e0b4 100644 --- a/modules/setting/oauth2.go +++ b/modules/setting/oauth2.go @@ -126,16 +126,15 @@ func loadOAuth2From(rootCfg ConfigProvider) { OAuth2.Enabled = sec.Key("ENABLE").MustBool(OAuth2.Enabled) } - if !OAuth2.Enabled { - return - } - - jwtSecretBase64 := loadSecret(sec, "JWT_SECRET_URI", "JWT_SECRET") - if !filepath.IsAbs(OAuth2.JWTSigningPrivateKeyFile) { OAuth2.JWTSigningPrivateKeyFile = filepath.Join(AppDataPath, OAuth2.JWTSigningPrivateKeyFile) } + // FIXME: at the moment, no matter oauth2 is enabled or not, it must generate a "oauth2 JWT_SECRET" + // Because this secret is also used as GeneralTokenSigningSecret (as a quick not-that-breaking fix for some legacy problems). + // Including: CSRF token, account validation token, etc ... + // In main branch, the signing token should be refactored (eg: one unique for LFS/OAuth2/etc ...) + jwtSecretBase64 := loadSecret(sec, "JWT_SECRET_URI", "JWT_SECRET") if InstallLock { jwtSecretBytes, err := generate.DecodeJwtSecretBase64(jwtSecretBase64) if err != nil { @@ -157,8 +156,6 @@ func loadOAuth2From(rootCfg ConfigProvider) { } } -// generalSigningSecret is used as container for a []byte value -// instead of an additional mutex, we use CompareAndSwap func to change the value thread save var generalSigningSecret atomic.Pointer[[]byte] func GetGeneralTokenSigningSecret() []byte { @@ -166,11 +163,9 @@ func GetGeneralTokenSigningSecret() []byte { if old == nil || len(*old) == 0 { jwtSecret, _, err := generate.NewJwtSecretWithBase64() if err != nil { - log.Fatal("Unable to generate general JWT secret: %s", err.Error()) + log.Fatal("Unable to generate general JWT secret: %v", err) } if generalSigningSecret.CompareAndSwap(old, &jwtSecret) { - // FIXME: in main branch, the signing token should be refactored (eg: one unique for LFS/OAuth2/etc ...) - LogStartupProblem(1, log.WARN, "OAuth2 is not enabled, unable to use a persistent signing secret, a new one is generated, which is not persistent between restarts and cluster nodes") return jwtSecret } return *generalSigningSecret.Load() diff --git a/modules/setting/oauth2_test.go b/modules/setting/oauth2_test.go index 4403f35892..38ee4d248d 100644 --- a/modules/setting/oauth2_test.go +++ b/modules/setting/oauth2_test.go @@ -4,6 +4,7 @@ package setting import ( + "os" "testing" "code.gitea.io/gitea/modules/generate" @@ -14,7 +15,7 @@ import ( func TestGetGeneralSigningSecret(t *testing.T) { // when there is no general signing secret, it should be generated, and keep the same value - assert.Nil(t, generalSigningSecret.Load()) + generalSigningSecret.Store(nil) s1 := GetGeneralTokenSigningSecret() assert.NotNil(t, s1) s2 := GetGeneralTokenSigningSecret() @@ -33,6 +34,31 @@ JWT_SECRET = BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB assert.EqualValues(t, expected, actual) } +func TestGetGeneralSigningSecretSave(t *testing.T) { + defer test.MockVariableValue(&InstallLock, true)() + + old := GetGeneralTokenSigningSecret() + assert.Len(t, old, 32) + + tmpFile := t.TempDir() + "/app.ini" + _ = os.WriteFile(tmpFile, nil, 0o644) + cfg, _ := NewConfigProviderFromFile(tmpFile) + loadOAuth2From(cfg) + generated := GetGeneralTokenSigningSecret() + assert.Len(t, generated, 32) + assert.NotEqual(t, old, generated) + + generalSigningSecret.Store(nil) + cfg, _ = NewConfigProviderFromFile(tmpFile) + loadOAuth2From(cfg) + again := GetGeneralTokenSigningSecret() + assert.Equal(t, generated, again) + + iniContent, err := os.ReadFile(tmpFile) + assert.NoError(t, err) + assert.Contains(t, string(iniContent), "JWT_SECRET = ") +} + func TestOauth2DefaultApplications(t *testing.T) { cfg, _ := NewConfigProviderFromData(``) loadOAuth2From(cfg) diff --git a/routers/install/install.go b/routers/install/install.go index 9c6a8849b6..fde8b37ed5 100644 --- a/routers/install/install.go +++ b/routers/install/install.go @@ -481,6 +481,17 @@ func SubmitInstall(ctx *context.Context) { cfg.Section("security").Key("INTERNAL_TOKEN").SetValue(internalToken) } + // FIXME: at the moment, no matter oauth2 is enabled or not, it must generate a "oauth2 JWT_SECRET" + // see the "loadOAuth2From" in "setting/oauth2.go" + if !cfg.Section("oauth2").HasKey("JWT_SECRET") && !cfg.Section("oauth2").HasKey("JWT_SECRET_URI") { + _, jwtSecretBase64, err := generate.NewJwtSecretWithBase64() + if err != nil { + ctx.RenderWithErr(ctx.Tr("install.secret_key_failed", err), tplInstall, &form) + return + } + cfg.Section("oauth2").Key("JWT_SECRET").SetValue(jwtSecretBase64) + } + // if there is already a SECRET_KEY, we should not overwrite it, otherwise the encrypted data will not be able to be decrypted if setting.SecretKey == "" { var secretKey string From 5b6f80989fbd0574ca188ab683389ff7659de30d Mon Sep 17 00:00:00 2001 From: Lunny Xiao Date: Wed, 15 May 2024 07:06:12 +0800 Subject: [PATCH 07/29] Remove unnecessary double quotes on language file (#30977) The double quotes and the prefix/suffix space are unnecessary. Co-authored-by: KN4CK3R --- options/locale/locale_en-US.ini | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/options/locale/locale_en-US.ini b/options/locale/locale_en-US.ini index 6a08041a7c..a85b107eee 100644 --- a/options/locale/locale_en-US.ini +++ b/options/locale/locale_en-US.ini @@ -3348,7 +3348,7 @@ mirror_sync_create = synced new reference %[3]s to %[3]s from mirror approve_pull_request = `approved %[3]s#%[2]s` reject_pull_request = `suggested changes for %[3]s#%[2]s` -publish_release = `released "%[4]s" at %[3]s` +publish_release = `released %[4]s at %[3]s` review_dismissed = `dismissed review from %[4]s for %[3]s#%[2]s` review_dismissed_reason = Reason: create_branch = created branch %[3]s in %[4]s From db578431ea5e8dc7347ba3dc10e82a01c5ba3ace Mon Sep 17 00:00:00 2001 From: GiteaBot Date: Wed, 15 May 2024 00:25:44 +0000 Subject: [PATCH 08/29] [skip ci] Updated translations via Crowdin --- options/locale/locale_cs-CZ.ini | 1 - options/locale/locale_de-DE.ini | 1 - options/locale/locale_el-GR.ini | 1 - options/locale/locale_es-ES.ini | 1 - options/locale/locale_fa-IR.ini | 1 - options/locale/locale_fr-FR.ini | 1 - options/locale/locale_it-IT.ini | 1 - options/locale/locale_ja-JP.ini | 1 - options/locale/locale_lv-LV.ini | 114 ++++++++++++++++---------------- options/locale/locale_pt-BR.ini | 1 - options/locale/locale_pt-PT.ini | 1 - options/locale/locale_ru-RU.ini | 1 - options/locale/locale_si-LK.ini | 1 - options/locale/locale_tr-TR.ini | 1 - options/locale/locale_uk-UA.ini | 1 - options/locale/locale_zh-CN.ini | 1 - options/locale/locale_zh-TW.ini | 1 - 17 files changed, 57 insertions(+), 73 deletions(-) diff --git a/options/locale/locale_cs-CZ.ini b/options/locale/locale_cs-CZ.ini index 82d7867168..6314b62f66 100644 --- a/options/locale/locale_cs-CZ.ini +++ b/options/locale/locale_cs-CZ.ini @@ -3320,7 +3320,6 @@ mirror_sync_create=synchronizoval/a novou referenci %[3]s do mirror_sync_delete=synchronizoval/a a smazal/a referenci %[2]s v %[3]s ze zrcadla approve_pull_request=`schválil/a %[3]s#%[2]s` reject_pull_request=`navrhl/a změny pro %[3]s#%[2]s` -publish_release=`vydal/a "%[4]s" v %[3]s` review_dismissed=`zamítl/a posouzení z %[4]s pro %[3]s#%[2]s` review_dismissed_reason=Důvod: create_branch=vytvořil/a větev %[3]s v %[4]s diff --git a/options/locale/locale_de-DE.ini b/options/locale/locale_de-DE.ini index dd2b34a6f4..5bca84ca08 100644 --- a/options/locale/locale_de-DE.ini +++ b/options/locale/locale_de-DE.ini @@ -3329,7 +3329,6 @@ mirror_sync_create=neue Referenz %[3]s bei % mirror_sync_delete=hat die Referenz des Mirrors %[2]s in %[3]s synchronisiert und gelöscht approve_pull_request=`hat %[3]s#%[2]s approved` reject_pull_request=`schlug Änderungen für %[3]s#%[2]s vor` -publish_release=`veröffentlichte Release "%[4]s" in %[3]s` review_dismissed=`verwarf das Review von %[4]s in %[3]s#%[2]s` review_dismissed_reason=Grund: create_branch=legte den Branch %[3]s in %[4]s an diff --git a/options/locale/locale_el-GR.ini b/options/locale/locale_el-GR.ini index 9553ba2f3a..834d1d7d70 100644 --- a/options/locale/locale_el-GR.ini +++ b/options/locale/locale_el-GR.ini @@ -3210,7 +3210,6 @@ mirror_sync_create=συγχρονίστηκε η νέα αναφορά %[3]s από το είδωλο approve_pull_request=`ενέκρινε το %[3]s#%[2]s` reject_pull_request=`πρότεινε αλλαγές για το %[3]s#%[2]s` -publish_release=`έκδωσε τη "%[4]s" στο %[3]s` review_dismissed=`ακύρωσε την εξέταση από %[4]s for %[3]s#%[2]s` review_dismissed_reason=Αιτία: create_branch=δημιούργησε το κλαδο %[3]s στο %[4]s diff --git a/options/locale/locale_es-ES.ini b/options/locale/locale_es-ES.ini index f3e2d93e80..3894e0e85b 100644 --- a/options/locale/locale_es-ES.ini +++ b/options/locale/locale_es-ES.ini @@ -3193,7 +3193,6 @@ mirror_sync_create=sincronizó la nueva referencia %[3]s a < mirror_sync_delete=sincronizada y eliminada referencia %[2]s en %[3]s desde réplica approve_pull_request=`aprobó %[3]s#%[2]s` reject_pull_request=`sugirió cambios para %[3]s#%[2]s` -publish_release=`se lanzó "%[4]s" en %[3]s` review_dismissed=`descartó la revisión de %[4]s para %[3]s#%[2]s` review_dismissed_reason=Motivo: create_branch=creó rama %[3]s en %[4]s diff --git a/options/locale/locale_fa-IR.ini b/options/locale/locale_fa-IR.ini index 25a3361b3f..d720ecf2f8 100644 --- a/options/locale/locale_fa-IR.ini +++ b/options/locale/locale_fa-IR.ini @@ -2508,7 +2508,6 @@ mirror_sync_create=مرجع جدید %[3]s با %[3]s حذف شده و از قرینه همگام شده approve_pull_request=`تأیید %[3]s#%[2]s` reject_pull_request=`تغییرات پیشنهادی برای %[3]s#%[2]s` -publish_release=` "%[4]s" در %[3]s منتشر شد` review_dismissed=`بازبینی از %[4]s برای %[3]s#%[2]s رد شد` review_dismissed_reason=دلیل: create_branch=شاخه %[3]s در %[4]s ایجاد کرد diff --git a/options/locale/locale_fr-FR.ini b/options/locale/locale_fr-FR.ini index b90039c003..556fab28e8 100644 --- a/options/locale/locale_fr-FR.ini +++ b/options/locale/locale_fr-FR.ini @@ -3249,7 +3249,6 @@ mirror_sync_create=a synchronisé la nouvelle référence %[3]s< mirror_sync_delete=a synchronisé puis supprimé la nouvelle référence %[2]s vers %[3]s depuis le miroir approve_pull_request=`a approuvé %[3]s#%[2]s` reject_pull_request=`a suggérés des changements pour %[3]s#%[2]s` -publish_release=`a publié "%[4]s" dans %[3]s` review_dismissed=`a révoqué l’évaluation de %[4]s dans %[3]s#%[2]s` review_dismissed_reason=Raison : create_branch=a créé la branche %[3]s dans %[4]s diff --git a/options/locale/locale_it-IT.ini b/options/locale/locale_it-IT.ini index eceda0faad..0cecc0b7f3 100644 --- a/options/locale/locale_it-IT.ini +++ b/options/locale/locale_it-IT.ini @@ -2707,7 +2707,6 @@ mirror_sync_create=ha sincronizzato un nuovo riferimento %[3]s%[2]s a %[3]s dal mirror approve_pull_request=`ha approvato %[3]s#%[2]s` reject_pull_request=`ha suggerito modifiche per %[3]s#%[2]s` -publish_release=`ha rilasciato "%[4]s" su %[3]s` review_dismissed=`respinta la recensione da %[4]s per %[3]s#%[2]s` review_dismissed_reason=Motivo: create_branch=ha creato il ramo %[3]s in %[4]s diff --git a/options/locale/locale_ja-JP.ini b/options/locale/locale_ja-JP.ini index 03a06dab16..cf9d9bbc51 100644 --- a/options/locale/locale_ja-JP.ini +++ b/options/locale/locale_ja-JP.ini @@ -3344,7 +3344,6 @@ mirror_sync_create=が %[4]s の新しい参照 %[3]s の参照 %[2]s をミラーから反映し、削除しました approve_pull_request=`が %[3]s#%[2]s を承認しました` reject_pull_request=`が %[3]s#%[2]sについて変更を提案しました` -publish_release=`が %[3]s "%[4]s" をリリースしました` review_dismissed=`が %[4]s%[3]s#%[2]s へのレビューを棄却しました` review_dismissed_reason=理由: create_branch=がブランチ %[3]s%[4]s に作成しました diff --git a/options/locale/locale_lv-LV.ini b/options/locale/locale_lv-LV.ini index 3aed4bd6c5..bdfe3f8c9f 100644 --- a/options/locale/locale_lv-LV.ini +++ b/options/locale/locale_lv-LV.ini @@ -111,7 +111,7 @@ preview=Priekšskatītījums loading=Notiek ielāde… error=Kļūda -error404=Lapa, ko vēlaties atvērt, neeksistē vai arī Jums nav tiesības to aplūkot. +error404=Lapa, ko tiek mēģināts atvērt, vai nu nepastāv vai arī nav tiesību to aplūkot. go_back=Atgriezties never=Nekad @@ -133,10 +133,10 @@ concept_user_organization=Organizācija show_timestamps=Rādīt laika zīmogus show_log_seconds=Rādīt sekundes -show_full_screen=Atvērt pilnā logā +show_full_screen=Rādīt pilnekrānā download_logs=Lejupielādēt žurnālus -confirm_delete_selected=Apstiprināt, lai izdzēstu visus atlasītos vienumus? +confirm_delete_selected=Apstiprināt visu atlasīto vienumus dzēšanu? name=Nosaukums value=Vērtība @@ -651,10 +651,11 @@ cancel=Atcelt language=Valoda ui=Motīvs hidden_comment_types=Attēlojot paslēpt šauds komentārus: +hidden_comment_types_description=Komentāru veidi, kas atzīmēti, netiks rādīti problēmu lapā. Piemēram, atzīmējot "Iezīmes" netiks rādīti komentāri "{lietotājs} pievienoja/noņēma {iezīme} iezīmi". hidden_comment_types.ref_tooltip=Komentāri, kad problēmai tiek pievienota atsauce uz citu probēmu, komentāru, … hidden_comment_types.issue_ref_tooltip=Komentāri par lietotāja izmaiņām ar problēmas saistīto atzaru/tagu comment_type_group_reference=Atsauces -comment_type_group_label=Etiķetes +comment_type_group_label=Iezīmes comment_type_group_milestone=Atskaites punktus comment_type_group_assignee=Atbildīgos comment_type_group_title=Nosaukuma izmaiņas @@ -956,8 +957,8 @@ repo_desc_helper=Ievadiet īsu aprakstu (neobligāts) repo_lang=Valoda repo_gitignore_helper=Izvēlieties .gitignore sagatavi. repo_gitignore_helper_desc=Izvēlieties kādi faili netiks glabāti repozitorijā no sagatavēm biežāk lietotājām valodām. Pēc noklusējuma .gitignore iekļauj valodu kompilācijas rīku artifaktus. -issue_labels=Problēmu etiķetes -issue_labels_helper=Izvēlieties problēmu etiķešu kopu. +issue_labels=Problēmu iezīmes +issue_labels_helper=Izvēlieties problēmu iezīmju kopu. license=Licence license_helper=Izvēlieties licences failu. license_helper_desc=Licence nosaka, ko citi var un ko nevar darīt ar šo kodu. Neesat pārliecintāts, kādu izvēlēties šim projektam? Aplūkojiet licences izvēle. @@ -1030,15 +1031,15 @@ desc.internal=Iekšējs desc.archived=Arhivēts desc.sha256=SHA256 -template.items=Sagataves ieraksti +template.items=Sagataves vienumi template.git_content=Git saturs (noklusētais atzars) template.git_hooks=Git āķi template.git_hooks_tooltip=Pēc repozitorija izveidošanas, Jums nav tiesību mainīt Git āķus. Atzīmējiet šo tikai, ja uzticaties sagataves repozitorija saturam. template.webhooks=Tīmekļa āķi template.topics=Tēmas template.avatar=Profila attēls -template.issue_labels=Problēmu etiķetes -template.one_item=Norādiet vismaz vienu sagataves vienību +template.issue_labels=Problēmu iezīmes +template.one_item=Norādiet vismaz vienu sagataves vienumu template.invalid=Norādiet sagataves repozitoriju archive.title=Šis repozitorijs ir arhivēts. Ir iespējams aplūkot tā failus un to konēt, bet nav iespējams iesūtīt izmaiņas, kā arī izveidot jaunas problēmas vai izmaiņu pieprasījumus. @@ -1060,10 +1061,10 @@ migrate_options_lfs_endpoint.label=LFS galapunkts migrate_options_lfs_endpoint.description=Migrācija mēģinās izmantot attālināto URL, lai noteiktu LFS serveri. Var norādīt arī citu galapunktu, ja repozitorija LFS dati ir izvietoti citā vietā. migrate_options_lfs_endpoint.description.local=Iespējams norādīt arī servera ceļu. migrate_options_lfs_endpoint.placeholder=Ja nav norādīts, galamērķis tiks atvasināts no klonēšanas URL -migrate_items=Vienības, ko pārņemt +migrate_items=Vienumi, ko pārņemt migrate_items_wiki=Vikivietni migrate_items_milestones=Atskaites punktus -migrate_items_labels=Etiķetes +migrate_items_labels=Iezīmes migrate_items_issues=Problēmas migrate_items_pullrequests=Izmaiņu pieprasījumus migrate_items_merge_requests=Sapludināšanas pieprasījumi @@ -1078,7 +1079,7 @@ migrate.permission_denied_blocked=Nav iespējams importēt no neatļautām adres migrate.invalid_local_path=Nederīgs lokālais ceļš. Tas neeksistē vai nav direktorija. migrate.invalid_lfs_endpoint=LFS galapunkts nav korekts. migrate.failed=Migrācija neizdevās: %v -migrate.migrate_items_options=Piekļuves pilnvara ir nepieciešams, lai migrētu papildus datus +migrate.migrate_items_options=Piekļuves pilnvara ir nepieciešama, lai pārņemtu papildus datus migrated_from=Migrēts no %[2]s migrated_from_fake=Migrēts no %[1]s migrate.migrate=Migrēt no %s @@ -1097,7 +1098,7 @@ migrate.gitbucket.description=Migrēt datus no GitBucket instancēm. migrate.migrating_git=Migrē git datus migrate.migrating_topics=Migrē tēmas migrate.migrating_milestones=Migrē atskaites punktus -migrate.migrating_labels=Migrē etiķetes +migrate.migrating_labels=Migrē iezīmes migrate.migrating_releases=Migrē laidienus migrate.migrating_issues=Migrācijas problēmas migrate.migrating_pulls=Migrē izmaiņu pieprasījumus @@ -1141,8 +1142,8 @@ pulls=Izmaiņu pieprasījumi project_board=Projekti packages=Pakotnes actions=Darbības -labels=Etiķetes -org_labels_desc=Organizācijas līmeņa etiķetes var tikt izmantotas visiem repozitorijiem šajā organizācijā +labels=Iezīmes +org_labels_desc=Organizācijas līmeņa iezīmes var tikt izmantotas visiem repozitorijiem šajā organizācijā org_labels_desc_manage=pārvaldīt milestones=Atskaites punkti @@ -1334,19 +1335,19 @@ issues.desc=Organizēt kļūdu ziņojumus, uzdevumus un atskaites punktus. issues.filter_assignees=Filtrēt pēc atbildīgajiem issues.filter_milestones=Filtrēt pēc atskaites punkta issues.filter_projects=Filtrēt pēc projekta -issues.filter_labels=Filtrēt pēc etiķetēm +issues.filter_labels=Filtrēt pēc iezīmēm issues.filter_reviewers=Filtrēt pēc recenzentiem issues.new=Jauna problēma issues.new.title_empty=Nosaukums nevar būt tukšs -issues.new.labels=Etiķetes -issues.new.no_label=Nav etiķešu -issues.new.clear_labels=Noņemt etiķetes +issues.new.labels=Iezīmes +issues.new.no_label=Nav iezīmju +issues.new.clear_labels=Noņemt iezīmes issues.new.projects=Projekti issues.new.clear_projects=Notīrīt projektus issues.new.no_projects=Nav projektu issues.new.open_projects=Aktīvie projekti issues.new.closed_projects=Pabeigtie projekti -issues.new.no_items=Nav neviena ieraksta +issues.new.no_items=Nav vienumu issues.new.milestone=Atskaites punkts issues.new.no_milestone=Nav atskaites punktu issues.new.clear_milestone=Notīrīt atskaites punktus @@ -1365,20 +1366,20 @@ issues.choose.invalid_templates=%v ķļūdaina sagatave(s) atrastas issues.choose.invalid_config=Problēmu konfigurācija satur kļūdas: issues.no_ref=Nav norādīts atzars/tags issues.create=Pieteikt problēmu -issues.new_label=Jauna etiķete -issues.new_label_placeholder=Etiķetes nosaukums +issues.new_label=Jauna iezīme +issues.new_label_placeholder=Iezīmes nosaukums issues.new_label_desc_placeholder=Apraksts -issues.create_label=Izveidot etiķeti -issues.label_templates.title=Ielādēt sākotnēji noteiktu etiķešu kopu -issues.label_templates.info=Nav izveidota neviena etiķete. Jūs varat noklikšķināt uz "Jauna etiķete" augstāk, lai to izveidotu vai izmantot zemāk piedāvātās etiķetes: -issues.label_templates.helper=Izvēlieties etiķešu kopu -issues.label_templates.use=Izmantot etiķešu kopu -issues.label_templates.fail_to_load_file=Neizdevās ielādēt etiķetes sagataves failu "%s": %v -issues.add_label=pievienoja %s etiķeti %s -issues.add_labels=pievienoja %s etiķetes %s -issues.remove_label=noņēma %s etiķeti %s -issues.remove_labels=noņēma %s etiķetes %s -issues.add_remove_labels=pievienoja %s un noņēma %s etiķetes %s +issues.create_label=Izveidot iezīmi +issues.label_templates.title=Ielādēt sākotnēji noteiktu iezīmju kopu +issues.label_templates.info=Nav izveidota neviena iezīme. Nospiediet uz pogas "Jauna iezīme", lai to izveidotu vai izmantojiet zemāk piedāvātās iezīmju kopas: +issues.label_templates.helper=Izvēlieties iezīmju kopu +issues.label_templates.use=Izmantot iezīmju kopu +issues.label_templates.fail_to_load_file=Neizdevās ielādēt iezīmju sagataves failu "%s": %v +issues.add_label=pievienoja %s iezīmi %s +issues.add_labels=pievienoja %s iezīmes %s +issues.remove_label=noņēma %s iezīmi %s +issues.remove_labels=noņēma %s iezīmes %s +issues.add_remove_labels=pievienoja %s un noņēma %s iezīmes %s issues.add_milestone_at=`pievienoja atskaites punktu %s %s` issues.add_project_at=`pievienoja šo problēmu %s projektam %s` issues.change_milestone_at=`nomainīja atskaites punktu no %s uz %s %s` @@ -1396,9 +1397,9 @@ issues.change_ref_at=`nomainīta atsauce no %s uz %s< issues.remove_ref_at=`noņēma atsauci no %s %s` issues.add_ref_at=`pievienoja atsauci uz %s %s` issues.delete_branch_at=`izdzēsa atzaru %s %s` -issues.filter_label=Etiķete -issues.filter_label_exclude=`Izmantojiet alt + peles klikšķis vai enter, lai neiekļautu etiķeti` -issues.filter_label_no_select=Visas etiķetes +issues.filter_label=Iezīme +issues.filter_label_exclude=`Izmantojiet alt + peles klikšķis vai enter, lai neiekļautu iezīmes` +issues.filter_label_no_select=Visas iezīmes issues.filter_label_select_no_label=Nav etiķetes issues.filter_milestone=Atskaites punkts issues.filter_milestone_all=Visi atskaites punkti @@ -1435,13 +1436,13 @@ issues.filter_sort.mostforks=Visvairāk atdalītie issues.filter_sort.fewestforks=Vismazāk atdalītie issues.action_open=Atvērt issues.action_close=Aizvērt -issues.action_label=Etiķete +issues.action_label=Iezīme issues.action_milestone=Atskaites punkts issues.action_milestone_no_select=Nav atskaites punkta issues.action_assignee=Atbildīgais issues.action_assignee_no_select=Nav atbildīgā issues.action_check=Atzīmēt/Notīrīt -issues.action_check_all=Atzīmēt/Notīrīt visus ierakstus +issues.action_check_all=Atzīmēt/notīrīt visus vienumus issues.opened_by=%[3]s atvēra %[1]s pulls.merged_by=%[3]s sapludināja %[1]s pulls.merged_by_fake=%[2]s sapludināja %[1]s @@ -1502,23 +1503,23 @@ issues.sign_in_require_desc=Nepieciešams pieteikties, lai piev issues.edit=Labot issues.cancel=Atcelt issues.save=Saglabāt -issues.label_title=Etiķetes nosaukums -issues.label_description=Etiķetes apraksts -issues.label_color=Etiķetes krāsa -issues.label_exclusive=Ekskluzīvs +issues.label_title=Nosaukums +issues.label_description=Apraksts +issues.label_color=Krāsa +issues.label_exclusive=Sevišķa issues.label_archive=Arhīvēt etiķeti issues.label_archived_filter=Rādīt arhivētās etiķetes issues.label_archive_tooltip=Arhivētās etiķetes pēc noklusējuma netiek iekļautas ieteikumos, kad meklē pēc nosaukuma. -issues.label_exclusive_desc=Nosauciet etiķeti grupa/nosaukums, lai grupētu etiķētes un varētu norādīt tās kā ekskluzīvas ar citām grupa/ etiķetēm. -issues.label_exclusive_warning=Jebkura konfliktējoša ekskluzīvas grupas etiķete tiks noņemta, labojot pieteikumu vai izmaiņu pietikumu etiķetes. -issues.label_count=%d etiķetes +issues.label_exclusive_desc=Nosauciet iezīmi grupa/nosaukums, lai tās grupētu un varētu padarīt kā savstarpēji sevišķas ar citām grupa/ iezīmēm. +issues.label_exclusive_warning=Jebkura konfliktējoša savstarpēji sevišķas grupas iezīme tiks noņemta, labojot problēmas vai izmaiņu pietikuma iezīmes. +issues.label_count=%d iezīmes issues.label_open_issues=%d atvērtas problēmas issues.label_edit=Labot issues.label_delete=Dzēst -issues.label_modify=Labot etiķeti +issues.label_modify=Labot iezīmi issues.label_deletion=Dzēst etiķeti -issues.label_deletion_desc=Dzēšot etiķeti, tā tiks noņemta no visām problēmām un izmaiņu pieprasījumiem. Vai turpināt? -issues.label_deletion_success=Etiķete tika izdzēsta. +issues.label_deletion_desc=Dzēšot iezīmi, tā tiks noņemta no visām problēmām un izmaiņu pieprasījumiem. Vai turpināt? +issues.label_deletion_success=Iezīme tika izdzēsta. issues.label.filter_sort.alphabetically=Alfabētiski issues.label.filter_sort.reverse_alphabetically=Pretēji alfabētiski issues.label.filter_sort.by_size=Mazākais izmērs @@ -1676,7 +1677,7 @@ pulls.allow_edits_from_maintainers_err=Atjaunošana neizdevās pulls.compare_changes_desc=Izvēlieties atzaru, kurā sapludināt izmaiņas un atzaru, no kura tās saņemt. pulls.has_viewed_file=Skatīts pulls.has_changed_since_last_review=Mainīts kopš pēdējās recenzijas -pulls.viewed_files_label=%[1]d no %[2]d failiem apskatīts +pulls.viewed_files_label=apskatīts %[1]d no %[2]d failiem pulls.expand_files=Izvērst visus failus pulls.collapse_files=Savērst visus failus pulls.compare_base=pamata @@ -1886,7 +1887,7 @@ wiki.page_name_desc=Ievadiet vikivietnes lapas nosaukumu. Speciālie nosaukumi i wiki.original_git_entry_tooltip=Attēlot oriģinālo Git faila nosaukumu. activity=Aktivitāte -activity.period.filter_label=Laika periods: +activity.period.filter_label=Laika posms: activity.period.daily=1 diena activity.period.halfweekly=3 dienas activity.period.weekly=1 nedēļa @@ -2171,8 +2172,8 @@ settings.event_issues=Problēmas settings.event_issues_desc=Problēma atvērta, aizvērta, atkārtoti atvērta vai mainīta. settings.event_issue_assign=Problēmas atbildīgie settings.event_issue_assign_desc=Problēmai piešķirti vai noņemti atbildīgie. -settings.event_issue_label=Problēmu etiķetes -settings.event_issue_label_desc=Problēmai pievienotas vai noņemtas etiķetes. +settings.event_issue_label=Problēmu iezīmes +settings.event_issue_label_desc=Problēmai pievienotas vai noņemtas iezīmes. settings.event_issue_milestone=Problēmas atskaites punkts settings.event_issue_milestone_desc=Problēmai pievienots vai noņemts atskaites punkts. settings.event_issue_comment=Problēmas komentārs @@ -2182,8 +2183,8 @@ settings.event_pull_request=Izmaiņu pieprasījums settings.event_pull_request_desc=Izmaiņu pieprasījums atvērts, aizvērts, atkārtoti atvērts vai mainīts. settings.event_pull_request_assign=Izmaiņu pieprasījuma atbildīgie settings.event_pull_request_assign_desc=Izmaiņu pieprasījumam piešķirti vai noņemti atbildīgie. -settings.event_pull_request_label=Izmaiņu pieprasījuma etiķetes -settings.event_pull_request_label_desc=Izmaiņu pieprasījumam pievienotas vai noņemtas etiķetes. +settings.event_pull_request_label=Izmaiņu pieprasījuma iezīmes +settings.event_pull_request_label_desc=Izmaiņu pieprasījumam tika pievienotas vai noņemtas iezīmes. settings.event_pull_request_milestone=Izmaiņu pieprasījuma atskaites punkts settings.event_pull_request_milestone_desc=Izmaiņu pieprasījumam pievienots vai noņemts atskaites punkts. settings.event_pull_request_comment=Izmaiņu pieprasījuma komentārs @@ -2598,7 +2599,7 @@ settings.delete_org_title=Dzēst organizāciju settings.delete_org_desc=Organizācija tiks dzēsta neatgriezeniski. Vai turpināt? settings.hooks_desc=Pievienot tīmekļa āķus, kas nostrādās visiem repozitorijiem šajā organizācijā. -settings.labels_desc=Pievienojiet etiķetes, kas var tikt izmantotas visos šīs organizācijas repozitorijos. +settings.labels_desc=Pievienojiet iezīmes, kas var tikt izmantotas visos šīs organizācijas repozitorijos. members.membership_visibility=Dalībnieka redzamība: members.public=Redzams @@ -3217,7 +3218,6 @@ mirror_sync_create=ar spoguli sinhronizēta jauna atsauce %[3]s< mirror_sync_delete=ar spoguli sinhronizēta un izdzēsta atsauce %[2]s repozitorijam %[3]s approve_pull_request=`apstiprināja izmaiņu pieprasījumu %[3]s#%[2]s` reject_pull_request=`ieteica izmaiņas izmaiņu pieprasījumam %[3]s#%[2]s` -publish_release=`izveidoja versiju "%[4]s" repozitorijā %[3]s` review_dismissed=`noraidīja lietotāja %[4]s recenziju izmaiņu pieprasījumam %[3]s#%[2]s` review_dismissed_reason=Iemesls: create_branch=izveidoja atzaru %[3]s repozitorijā %[4]s @@ -3337,7 +3337,7 @@ container.pull=Atgādājiet šo attēlu no komandrindas: container.digest=Īssavilkums: container.multi_arch=OS / arhitektūra container.layers=Attēla slāņi -container.labels=Etiķetes +container.labels=Iezīmes container.labels.key=Atslēga container.labels.value=Vērtība cran.registry=Iestaties šo reģistru savā Rprofile.site failā: diff --git a/options/locale/locale_pt-BR.ini b/options/locale/locale_pt-BR.ini index 2e23cde801..4799727d98 100644 --- a/options/locale/locale_pt-BR.ini +++ b/options/locale/locale_pt-BR.ini @@ -3153,7 +3153,6 @@ mirror_sync_create=sincronizou a nova referência %[3]s para mirror_sync_delete=referência excluída e sincronizada %[2]s em %[3]s do espelhamento approve_pull_request=`aprovou %[3]s#%[2]s` reject_pull_request=`sugeriu modificações para %[3]s#%[2]s` -publish_release=`lançou a versão "%[4]s" em %[3]s` review_dismissed=`descartou a revisão de %[4]s para %[3]s#%[2]s` review_dismissed_reason=Motivo: create_branch=criou o branch %[3]s em %[4]s diff --git a/options/locale/locale_pt-PT.ini b/options/locale/locale_pt-PT.ini index 642d8915cf..f4c77e4981 100644 --- a/options/locale/locale_pt-PT.ini +++ b/options/locale/locale_pt-PT.ini @@ -3348,7 +3348,6 @@ mirror_sync_create=sincronizou a nova referência %[3]s para mirror_sync_delete=sincronizou e eliminou a referência %[2]s em %[3]s da réplica approve_pull_request=`aprovou %[3]s#%[2]s` reject_pull_request=`sugeriu modificações para %[3]s#%[2]s` -publish_release=`lançou "%[4]s" em %[3]s` review_dismissed=`descartou a revisão de %[4]s para %[3]s#%[2]s` review_dismissed_reason=Motivo: create_branch=criou o ramo %[3]s em %[4]s diff --git a/options/locale/locale_ru-RU.ini b/options/locale/locale_ru-RU.ini index df6df4cf95..81b88dbd45 100644 --- a/options/locale/locale_ru-RU.ini +++ b/options/locale/locale_ru-RU.ini @@ -3147,7 +3147,6 @@ mirror_sync_create=синхронизировал(а) новую ссылку %[2]s на %[3]s из зеркала approve_pull_request=`утвердил(а) задачу %[3]s#%[2]s` reject_pull_request=`предложил(а) изменения для %[3]s#%[2]s` -publish_release=`выпустил(а) "%[4]s" в %[3]s` review_dismissed=`отклонил(а) отзыв от %[4]s для %[3]s#%[2]s` review_dismissed_reason=Причина: create_branch=создал(а) ветку %[3]s в %[4]s diff --git a/options/locale/locale_si-LK.ini b/options/locale/locale_si-LK.ini index 15bbcfebb2..cb437e5530 100644 --- a/options/locale/locale_si-LK.ini +++ b/options/locale/locale_si-LK.ini @@ -2465,7 +2465,6 @@ mirror_sync_create=සමමුහුර්ත නව යොමු %[3]s කැඩපතෙන් approve_pull_request=`අනුමත %[3]s #%[2]s ගේ` reject_pull_request=%[3]s #%[2]sසඳහා යෝජිත වෙනස්කම් -publish_release=`නිදහස් "%[4]s" හි %[3]s` review_dismissed_reason=හේතුව: create_branch=නිර්මාණය කරන ලද ශාඛාව %[3]s %[4]s watched_repo=%[2]sනැරඹීමට පටන් ගත්තා diff --git a/options/locale/locale_tr-TR.ini b/options/locale/locale_tr-TR.ini index be89113f0d..7b57e416f7 100644 --- a/options/locale/locale_tr-TR.ini +++ b/options/locale/locale_tr-TR.ini @@ -3344,7 +3344,6 @@ mirror_sync_create=%[3]s yeni referansını, %[3]s adresindeki %[2]s referansını eşitledi ve sildi approve_pull_request=`%[3]s#%[2]s değişiklik isteğini onayladı` reject_pull_request=`%[3]s#%[2]s için değişiklikler önerdi` -publish_release=`%[3]s deposu için "%[4]s" sürümü yayınlandı` review_dismissed=`%[3]s#%[2]s için %[4]s yorumunu reddetti` review_dismissed_reason=Sebep: create_branch=%[4]s deposunda %[3]s dalını oluşturdu diff --git a/options/locale/locale_uk-UA.ini b/options/locale/locale_uk-UA.ini index 3e38973e02..ddd884e113 100644 --- a/options/locale/locale_uk-UA.ini +++ b/options/locale/locale_uk-UA.ini @@ -2517,7 +2517,6 @@ mirror_sync_create=синхронізував нове посилання %[2]s на %[3]s із дзеркала approve_pull_request=`схвалив %[3]s#%[2]s` reject_pull_request=`запропонував зміни до %[3]s#%[2]s` -publish_release=`опублікував випуск "%[4]s" з %[3]s` review_dismissed=`відхилив відгук від %[4]s для %[3]s#%[2]s` review_dismissed_reason=Причина: create_branch=створив гілку %[3]s в %[4]s diff --git a/options/locale/locale_zh-CN.ini b/options/locale/locale_zh-CN.ini index c98af46d45..10abf90ed7 100644 --- a/options/locale/locale_zh-CN.ini +++ b/options/locale/locale_zh-CN.ini @@ -3347,7 +3347,6 @@ mirror_sync_create=从镜像同步了引用 %[3]s 至仓库 mirror_sync_delete=从镜像同步并从 %[3]s 删除了引用 %[2]s approve_pull_request=`批准了 %[3]s#%[2]s` reject_pull_request=`建议变更 %[3]s#%[2]s` -publish_release=`在 %[3]s 发布了 "%[4]s" ` review_dismissed=`取消了 %[4]s%[3]s#%[2]s 的变更请求` review_dismissed_reason=原因: create_branch=于 %[4]s 创建了分支 %[3]s diff --git a/options/locale/locale_zh-TW.ini b/options/locale/locale_zh-TW.ini index 7823426990..50c0276567 100644 --- a/options/locale/locale_zh-TW.ini +++ b/options/locale/locale_zh-TW.ini @@ -2932,7 +2932,6 @@ mirror_sync_create=從鏡像同步了新參考 %[3]s%[3]s 刪除了參考 %[2]s approve_pull_request=`核可了 %[3]s#%[2]s` reject_pull_request=`提出了修改建議 %[3]s#%[2]s` -publish_release=`發布了 %[3]s "%[4]s" ` review_dismissed=`取消了 %[4]s%[3]s#%[2]s 的審核` review_dismissed_reason=原因: create_branch=在 %[4]s 中建立了分支 %[3]s From d0d6aad85f4d1e2a6d2a6524fe13eccecfd350af Mon Sep 17 00:00:00 2001 From: dicarne Date: Wed, 15 May 2024 21:56:17 +0800 Subject: [PATCH 09/29] Supports forced use of S3 virtual-hosted style (#30969) Add a configuration item to enable S3 virtual-hosted style (V2) to solve the problem caused by some S3 service providers not supporting path style (V1). --- cmd/migrate_storage.go | 6 ++++++ custom/conf/app.example.ini | 6 ++++++ .../config-cheat-sheet.en-us.md | 8 ++++++++ .../config-cheat-sheet.zh-cn.md | 8 ++++++++ modules/setting/storage.go | 2 ++ modules/storage/minio.go | 20 +++++++++++++++---- 6 files changed, 46 insertions(+), 4 deletions(-) diff --git a/cmd/migrate_storage.go b/cmd/migrate_storage.go index 357416fc33..7d1ef052ff 100644 --- a/cmd/migrate_storage.go +++ b/cmd/migrate_storage.go @@ -91,6 +91,11 @@ var CmdMigrateStorage = &cli.Command{ Value: "", Usage: "Minio checksum algorithm (default/md5)", }, + &cli.StringFlag{ + Name: "minio-bucket-lookup-type", + Value: "", + Usage: "Minio bucket lookup type", + }, }, } @@ -220,6 +225,7 @@ func runMigrateStorage(ctx *cli.Context) error { UseSSL: ctx.Bool("minio-use-ssl"), InsecureSkipVerify: ctx.Bool("minio-insecure-skip-verify"), ChecksumAlgorithm: ctx.String("minio-checksum-algorithm"), + BucketLookUpType: ctx.String("minio-bucket-lookup-type"), }, }) default: diff --git a/custom/conf/app.example.ini b/custom/conf/app.example.ini index 577479e39f..4df843b8ce 100644 --- a/custom/conf/app.example.ini +++ b/custom/conf/app.example.ini @@ -1895,6 +1895,9 @@ LEVEL = Info ;; ;; Minio checksum algorithm: default (for MinIO or AWS S3) or md5 (for Cloudflare or Backblaze) ;MINIO_CHECKSUM_ALGORITHM = default +;; +;; Minio bucket lookup method defaults to auto mode; set it to `dns` for virtual host style or `path` for path style, only available when STORAGE_TYPE is `minio` +;MINIO_BUCKET_LOOKUP_TYPE = auto ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; @@ -2576,6 +2579,9 @@ LEVEL = Info ;; ;; Minio skip SSL verification available when STORAGE_TYPE is `minio` ;MINIO_INSECURE_SKIP_VERIFY = false +;; +;; Minio bucket lookup method defaults to auto mode; set it to `dns` for virtual host style or `path` for path style, only available when STORAGE_TYPE is `minio` +;MINIO_BUCKET_LOOKUP_TYPE = auto ;[proxy] ;; Enable the proxy, all requests to external via HTTP will be affected diff --git a/docs/content/administration/config-cheat-sheet.en-us.md b/docs/content/administration/config-cheat-sheet.en-us.md index 07712c1110..6c429bb652 100644 --- a/docs/content/administration/config-cheat-sheet.en-us.md +++ b/docs/content/administration/config-cheat-sheet.en-us.md @@ -851,6 +851,7 @@ Default templates for project boards: - `MINIO_USE_SSL`: **false**: Minio enabled ssl only available when STORAGE_TYPE is `minio` - `MINIO_INSECURE_SKIP_VERIFY`: **false**: Minio skip SSL verification available when STORAGE_TYPE is `minio` - `MINIO_CHECKSUM_ALGORITHM`: **default**: Minio checksum algorithm: `default` (for MinIO or AWS S3) or `md5` (for Cloudflare or Backblaze) +- `MINIO_BUCKET_LOOKUP_TYPE`: **auto**: Minio bucket lookup method defaults to auto mode; set it to `dns` for virtual host style or `path` for path style, only available when STORAGE_TYPE is `minio` ## Log (`log`) @@ -1272,6 +1273,7 @@ is `data/lfs` and the default of `MINIO_BASE_PATH` is `lfs/`. - `MINIO_BASE_PATH`: **lfs/**: Minio base path on the bucket only available when `STORAGE_TYPE` is `minio` - `MINIO_USE_SSL`: **false**: Minio enabled ssl only available when `STORAGE_TYPE` is `minio` - `MINIO_INSECURE_SKIP_VERIFY`: **false**: Minio skip SSL verification available when STORAGE_TYPE is `minio` +- `MINIO_BUCKET_LOOKUP_TYPE`: **auto**: Minio bucket lookup method defaults to auto mode; set it to `dns` for virtual host style or `path` for path style, only available when STORAGE_TYPE is `minio` ## Storage (`storage`) @@ -1286,6 +1288,7 @@ Default storage configuration for attachments, lfs, avatars, repo-avatars, repo- - `MINIO_LOCATION`: **us-east-1**: Minio location to create bucket only available when `STORAGE_TYPE` is `minio` - `MINIO_USE_SSL`: **false**: Minio enabled ssl only available when `STORAGE_TYPE` is `minio` - `MINIO_INSECURE_SKIP_VERIFY`: **false**: Minio skip SSL verification available when STORAGE_TYPE is `minio` +- `MINIO_BUCKET_LOOKUP_TYPE`: **auto**: Minio bucket lookup method defaults to auto mode; set it to `dns` for virtual host style or `path` for path style, only available when STORAGE_TYPE is `minio` The recommended storage configuration for minio like below: @@ -1307,6 +1310,8 @@ MINIO_USE_SSL = false ; Minio skip SSL verification available when STORAGE_TYPE is `minio` MINIO_INSECURE_SKIP_VERIFY = false SERVE_DIRECT = true +; Minio bucket lookup method defaults to auto mode; set it to `dns` for virtual host style or `path` for path style, only available when STORAGE_TYPE is `minio` +MINIO_BUCKET_LOOKUP_TYPE = auto ``` Defaultly every storage has their default base path like below @@ -1353,6 +1358,8 @@ MINIO_LOCATION = us-east-1 MINIO_USE_SSL = false ; Minio skip SSL verification available when STORAGE_TYPE is `minio` MINIO_INSECURE_SKIP_VERIFY = false +; Minio bucket lookup method defaults to auto mode; set it to `dns` for virtual host style or `path` for path style, only available when STORAGE_TYPE is `minio` +MINIO_BUCKET_LOOKUP_TYPE = auto ``` ## Repository Archive Storage (`storage.repo-archive`) @@ -1372,6 +1379,7 @@ is `data/repo-archive` and the default of `MINIO_BASE_PATH` is `repo-archive/`. - `MINIO_BASE_PATH`: **repo-archive/**: Minio base path on the bucket only available when `STORAGE_TYPE` is `minio` - `MINIO_USE_SSL`: **false**: Minio enabled ssl only available when `STORAGE_TYPE` is `minio` - `MINIO_INSECURE_SKIP_VERIFY`: **false**: Minio skip SSL verification available when STORAGE_TYPE is `minio` +- `MINIO_BUCKET_LOOKUP_TYPE`: **auto**: Minio bucket lookup method defaults to auto mode; set it to `dns` for virtual host style or `path` for path style, only available when STORAGE_TYPE is `minio` ## Repository Archives (`repo-archive`) diff --git a/docs/content/administration/config-cheat-sheet.zh-cn.md b/docs/content/administration/config-cheat-sheet.zh-cn.md index 3bb31d3d71..3c6ac8c00a 100644 --- a/docs/content/administration/config-cheat-sheet.zh-cn.md +++ b/docs/content/administration/config-cheat-sheet.zh-cn.md @@ -796,6 +796,7 @@ Gitea 创建以下非唯一队列: - `MINIO_USE_SSL`: **false**: Minio 启用 SSL,仅当 STORAGE_TYPE 为 `minio` 时可用。 - `MINIO_INSECURE_SKIP_VERIFY`: **false**: Minio 跳过 SSL 验证,仅当 STORAGE_TYPE 为 `minio` 时可用。 - `MINIO_CHECKSUM_ALGORITHM`: **default**: Minio 校验算法:`default`(适用于 MinIO 或 AWS S3)或 `md5`(适用于 Cloudflare 或 Backblaze) +- `MINIO_BUCKET_LOOKUP_TYPE`: **auto**: Minio的bucket查找方式默认为`auto`模式,可将其设置为`dns`(虚拟托管样式)或`path`(路径样式),仅当`STORAGE_TYPE`为`minio`时可用。 ## 日志 (`log`) @@ -1201,6 +1202,7 @@ ALLOW_DATA_URI_IMAGES = true - `MINIO_BASE_PATH`:**lfs/**:桶上的 Minio 基本路径,仅在 `STORAGE_TYPE` 为 `minio` 时可用。 - `MINIO_USE_SSL`:**false**:Minio 启用 ssl,仅在 `STORAGE_TYPE` 为 `minio` 时可用。 - `MINIO_INSECURE_SKIP_VERIFY`:**false**:Minio 跳过 SSL 验证,仅在 `STORAGE_TYPE` 为 `minio` 时可用。 +- `MINIO_BUCKET_LOOKUP_TYPE`: **auto**: Minio的bucket查找方式默认为`auto`模式,可将其设置为`dns`(虚拟托管样式)或`path`(路径样式),仅当`STORAGE_TYPE`为`minio`时可用。 ## 存储 (`storage`) @@ -1215,6 +1217,7 @@ ALLOW_DATA_URI_IMAGES = true - `MINIO_LOCATION`:**us-east-1**:创建桶的 Minio 位置,仅在 `STORAGE_TYPE` 为 `minio` 时可用。 - `MINIO_USE_SSL`:**false**:Minio 启用 ssl,仅在 `STORAGE_TYPE` 为 `minio` 时可用。 - `MINIO_INSECURE_SKIP_VERIFY`:**false**:Minio 跳过 SSL 验证,仅在 `STORAGE_TYPE` 为 `minio` 时可用。 +- `MINIO_BUCKET_LOOKUP_TYPE`: **auto**: Minio的bucket查找方式默认为`auto`模式,可将其设置为`dns`(虚拟托管样式)或`path`(路径样式),仅当`STORAGE_TYPE`为`minio`时可用。 建议的 minio 存储配置如下: @@ -1236,6 +1239,8 @@ MINIO_USE_SSL = false ; Minio skip SSL verification available when STORAGE_TYPE is `minio` MINIO_INSECURE_SKIP_VERIFY = false SERVE_DIRECT = true +; Minio bucket lookup method defaults to auto mode; set it to `dns` for virtual host style or `path` for path style, only available when STORAGE_TYPE is `minio` +MINIO_BUCKET_LOOKUP_TYPE = auto ``` 默认情况下,每个存储都有其默认的基本路径,如下所示: @@ -1282,6 +1287,8 @@ MINIO_LOCATION = us-east-1 MINIO_USE_SSL = false ; Minio skip SSL verification available when STORAGE_TYPE is `minio` MINIO_INSECURE_SKIP_VERIFY = false +; Minio bucket lookup method defaults to auto mode; set it to `dns` for virtual host style or `path` for path style, only available when STORAGE_TYPE is `minio` +MINIO_BUCKET_LOOKUP_TYPE = auto ``` ### 存储库归档存储 (`storage.repo-archive`) @@ -1299,6 +1306,7 @@ MINIO_INSECURE_SKIP_VERIFY = false - `MINIO_BASE_PATH`: **repo-archive/**:存储桶上的Minio基本路径,仅在`STORAGE_TYPE`为`minio`时可用。 - `MINIO_USE_SSL`: **false**:启用Minio的SSL,仅在`STORAGE_TYPE`为`minio`时可用。 - `MINIO_INSECURE_SKIP_VERIFY`: **false**:跳过Minio的SSL验证,仅在`STORAGE_TYPE`为`minio`时可用。 +- `MINIO_BUCKET_LOOKUP_TYPE`: **auto**: Minio的bucket查找方式默认为`auto`模式,可将其设置为`dns`(虚拟托管样式)或`path`(路径样式),仅当`STORAGE_TYPE`为`minio`时可用。 ### 存储库归档 (`repo-archive`) diff --git a/modules/setting/storage.go b/modules/setting/storage.go index 0bd52acc0f..d80a61a45e 100644 --- a/modules/setting/storage.go +++ b/modules/setting/storage.go @@ -47,6 +47,7 @@ type MinioStorageConfig struct { InsecureSkipVerify bool `ini:"MINIO_INSECURE_SKIP_VERIFY"` ChecksumAlgorithm string `ini:"MINIO_CHECKSUM_ALGORITHM" json:",omitempty"` ServeDirect bool `ini:"SERVE_DIRECT"` + BucketLookUpType string `ini:"MINIO_BUCKET_LOOKUP_TYPE" json:",omitempty"` } // Storage represents configuration of storages @@ -82,6 +83,7 @@ func getDefaultStorageSection(rootCfg ConfigProvider) ConfigSection { storageSec.Key("MINIO_USE_SSL").MustBool(false) storageSec.Key("MINIO_INSECURE_SKIP_VERIFY").MustBool(false) storageSec.Key("MINIO_CHECKSUM_ALGORITHM").MustString("default") + storageSec.Key("MINIO_BUCKET_LOOKUP_TYPE").MustString("auto") return storageSec } diff --git a/modules/storage/minio.go b/modules/storage/minio.go index b58ab67dc7..986332dfed 100644 --- a/modules/storage/minio.go +++ b/modules/storage/minio.go @@ -85,11 +85,23 @@ func NewMinioStorage(ctx context.Context, cfg *setting.Storage) (ObjectStorage, log.Info("Creating Minio storage at %s:%s with base path %s", config.Endpoint, config.Bucket, config.BasePath) + var lookup minio.BucketLookupType + if config.BucketLookUpType == "auto" || config.BucketLookUpType == "" { + lookup = minio.BucketLookupAuto + } else if config.BucketLookUpType == "dns" { + lookup = minio.BucketLookupDNS + } else if config.BucketLookUpType == "path" { + lookup = minio.BucketLookupPath + } else { + return nil, fmt.Errorf("invalid minio bucket lookup type: %s", config.BucketLookUpType) + } + minioClient, err := minio.New(config.Endpoint, &minio.Options{ - Creds: credentials.NewStaticV4(config.AccessKeyID, config.SecretAccessKey, ""), - Secure: config.UseSSL, - Transport: &http.Transport{TLSClientConfig: &tls.Config{InsecureSkipVerify: config.InsecureSkipVerify}}, - Region: config.Location, + Creds: credentials.NewStaticV4(config.AccessKeyID, config.SecretAccessKey, ""), + Secure: config.UseSSL, + Transport: &http.Transport{TLSClientConfig: &tls.Config{InsecureSkipVerify: config.InsecureSkipVerify}}, + Region: config.Location, + BucketLookup: lookup, }) if err != nil { return nil, convertMinioErr(err) From fc89363832c87678d9e35e865b49c63c7ad498f2 Mon Sep 17 00:00:00 2001 From: Zettat123 Date: Wed, 15 May 2024 22:25:47 +0800 Subject: [PATCH 10/29] Check if the release is converted from the tag when updating the release (#30984) Call `notify_service.NewRelease` when a release is created from an existing tag. --- services/release/release.go | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/services/release/release.go b/services/release/release.go index ba5fd1dd98..399fdc79c0 100644 --- a/services/release/release.go +++ b/services/release/release.go @@ -204,7 +204,7 @@ func UpdateRelease(ctx context.Context, doer *user_model.User, gitRepo *git.Repo if rel.ID == 0 { return errors.New("UpdateRelease only accepts an exist release") } - isCreated, err := createTag(gitRepo.Ctx, gitRepo, rel, "") + isTagCreated, err := createTag(gitRepo.Ctx, gitRepo, rel, "") if err != nil { return err } @@ -216,6 +216,12 @@ func UpdateRelease(ctx context.Context, doer *user_model.User, gitRepo *git.Repo } defer committer.Close() + oldRelease, err := repo_model.GetReleaseByID(ctx, rel.ID) + if err != nil { + return err + } + isConvertedFromTag := oldRelease.IsTag && !rel.IsTag + if err = repo_model.UpdateRelease(ctx, rel); err != nil { return err } @@ -292,7 +298,7 @@ func UpdateRelease(ctx context.Context, doer *user_model.User, gitRepo *git.Repo } if !rel.IsDraft { - if !isCreated { + if !isTagCreated && !isConvertedFromTag { notify_service.UpdateRelease(gitRepo.Ctx, doer, rel) return nil } From ea8e4baacc5c58e45e68291334c3d2c42e9d6737 Mon Sep 17 00:00:00 2001 From: silverwind Date: Wed, 15 May 2024 16:54:34 +0200 Subject: [PATCH 11/29] Put web editor into a segment (#30966) Implement https://github.com/go-gitea/gitea/pull/30707#issuecomment-2084126206 Diff without whitespace: https://github.com/go-gitea/gitea/pull/30966/files?diff=unified&w=1 Might as well backport. --- templates/repo/editor/edit.tmpl | 42 ++++++++++++++++++--------------- 1 file changed, 23 insertions(+), 19 deletions(-) diff --git a/templates/repo/editor/edit.tmpl b/templates/repo/editor/edit.tmpl index ae3f12669c..e990177d8a 100644 --- a/templates/repo/editor/edit.tmpl +++ b/templates/repo/editor/edit.tmpl @@ -26,26 +26,30 @@
    -