Merge branch 'main' into zig

This commit is contained in:
techknowlogick 2024-11-23 17:18:45 -05:00 committed by GitHub
commit 88a8e0fa0e
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
9 changed files with 61 additions and 15 deletions

View File

@ -63,3 +63,4 @@ Tim-Niclas Oelschläger <zokki.softwareschmiede@gmail.com> (@zokkis)
Yu Liu <1240335630@qq.com> (@HEREYUA) Yu Liu <1240335630@qq.com> (@HEREYUA)
Kemal Zebari <kemalzebra@gmail.com> (@kemzeb) Kemal Zebari <kemalzebra@gmail.com> (@kemzeb)
Rowan Bohde <rowan.bohde@gmail.com> (@bohde) Rowan Bohde <rowan.bohde@gmail.com> (@bohde)
hiifong <i@hiif.ong> (@hiifong)

View File

@ -1944,6 +1944,13 @@ LEVEL = Info
;; Minio secretAccessKey to connect only available when STORAGE_TYPE is `minio` ;; Minio secretAccessKey to connect only available when STORAGE_TYPE is `minio`
;MINIO_SECRET_ACCESS_KEY = ;MINIO_SECRET_ACCESS_KEY =
;; ;;
;; Preferred IAM Endpoint to override Minio's default IAM Endpoint resolution only available when STORAGE_TYPE is `minio`.
;; If not provided and STORAGE_TYPE is `minio`, will search for and derive endpoint from known environment variables
;; (AWS_CONTAINER_AUTHORIZATION_TOKEN, AWS_CONTAINER_AUTHORIZATION_TOKEN_FILE, AWS_CONTAINER_CREDENTIALS_RELATIVE_URI,
;; AWS_CONTAINER_CREDENTIALS_FULL_URI, AWS_WEB_IDENTITY_TOKEN_FILE, AWS_ROLE_ARN, AWS_ROLE_SESSION_NAME, AWS_REGION),
;; or the DefaultIAMRoleEndpoint if not provided otherwise.
;MINIO_IAM_ENDPOINT =
;;
;; Minio bucket to store the attachments only available when STORAGE_TYPE is `minio` ;; Minio bucket to store the attachments only available when STORAGE_TYPE is `minio`
;MINIO_BUCKET = gitea ;MINIO_BUCKET = gitea
;; ;;
@ -2688,6 +2695,13 @@ LEVEL = Info
;; Minio secretAccessKey to connect only available when STORAGE_TYPE is `minio` ;; Minio secretAccessKey to connect only available when STORAGE_TYPE is `minio`
;MINIO_SECRET_ACCESS_KEY = ;MINIO_SECRET_ACCESS_KEY =
;; ;;
;; Preferred IAM Endpoint to override Minio's default IAM Endpoint resolution only available when STORAGE_TYPE is `minio`.
;; If not provided and STORAGE_TYPE is `minio`, will search for and derive endpoint from known environment variables
;; (AWS_CONTAINER_AUTHORIZATION_TOKEN, AWS_CONTAINER_AUTHORIZATION_TOKEN_FILE, AWS_CONTAINER_CREDENTIALS_RELATIVE_URI,
;; AWS_CONTAINER_CREDENTIALS_FULL_URI, AWS_WEB_IDENTITY_TOKEN_FILE, AWS_ROLE_ARN, AWS_ROLE_SESSION_NAME, AWS_REGION),
;; or the DefaultIAMRoleEndpoint if not provided otherwise.
;MINIO_IAM_ENDPOINT =
;;
;; Minio bucket to store the attachments only available when STORAGE_TYPE is `minio` ;; Minio bucket to store the attachments only available when STORAGE_TYPE is `minio`
;MINIO_BUCKET = gitea ;MINIO_BUCKET = gitea
;; ;;

View File

@ -43,6 +43,7 @@ type MinioStorageConfig struct {
Endpoint string `ini:"MINIO_ENDPOINT" json:",omitempty"` Endpoint string `ini:"MINIO_ENDPOINT" json:",omitempty"`
AccessKeyID string `ini:"MINIO_ACCESS_KEY_ID" json:",omitempty"` AccessKeyID string `ini:"MINIO_ACCESS_KEY_ID" json:",omitempty"`
SecretAccessKey string `ini:"MINIO_SECRET_ACCESS_KEY" json:",omitempty"` SecretAccessKey string `ini:"MINIO_SECRET_ACCESS_KEY" json:",omitempty"`
IamEndpoint string `ini:"MINIO_IAM_ENDPOINT" json:",omitempty"`
Bucket string `ini:"MINIO_BUCKET" json:",omitempty"` Bucket string `ini:"MINIO_BUCKET" json:",omitempty"`
Location string `ini:"MINIO_LOCATION" json:",omitempty"` Location string `ini:"MINIO_LOCATION" json:",omitempty"`
BasePath string `ini:"MINIO_BASE_PATH" json:",omitempty"` BasePath string `ini:"MINIO_BASE_PATH" json:",omitempty"`

View File

@ -470,6 +470,19 @@ MINIO_BASE_PATH = /prefix
cfg, err = NewConfigProviderFromData(` cfg, err = NewConfigProviderFromData(`
[storage] [storage]
STORAGE_TYPE = minio STORAGE_TYPE = minio
MINIO_IAM_ENDPOINT = 127.0.0.1
MINIO_USE_SSL = true
MINIO_BASE_PATH = /prefix
`)
assert.NoError(t, err)
assert.NoError(t, loadRepoArchiveFrom(cfg))
assert.EqualValues(t, "127.0.0.1", RepoArchive.Storage.MinioConfig.IamEndpoint)
assert.EqualValues(t, true, RepoArchive.Storage.MinioConfig.UseSSL)
assert.EqualValues(t, "/prefix/repo-archive/", RepoArchive.Storage.MinioConfig.BasePath)
cfg, err = NewConfigProviderFromData(`
[storage]
STORAGE_TYPE = minio
MINIO_ACCESS_KEY_ID = my_access_key MINIO_ACCESS_KEY_ID = my_access_key
MINIO_SECRET_ACCESS_KEY = my_secret_key MINIO_SECRET_ACCESS_KEY = my_secret_key
MINIO_USE_SSL = true MINIO_USE_SSL = true

View File

@ -97,7 +97,7 @@ func NewMinioStorage(ctx context.Context, cfg *setting.Storage) (ObjectStorage,
} }
minioClient, err := minio.New(config.Endpoint, &minio.Options{ minioClient, err := minio.New(config.Endpoint, &minio.Options{
Creds: buildMinioCredentials(config, credentials.DefaultIAMRoleEndpoint), Creds: buildMinioCredentials(config),
Secure: config.UseSSL, Secure: config.UseSSL,
Transport: &http.Transport{TLSClientConfig: &tls.Config{InsecureSkipVerify: config.InsecureSkipVerify}}, Transport: &http.Transport{TLSClientConfig: &tls.Config{InsecureSkipVerify: config.InsecureSkipVerify}},
Region: config.Location, Region: config.Location,
@ -164,7 +164,7 @@ func (m *MinioStorage) buildMinioDirPrefix(p string) string {
return p return p
} }
func buildMinioCredentials(config setting.MinioStorageConfig, iamEndpoint string) *credentials.Credentials { func buildMinioCredentials(config setting.MinioStorageConfig) *credentials.Credentials {
// If static credentials are provided, use those // If static credentials are provided, use those
if config.AccessKeyID != "" { if config.AccessKeyID != "" {
return credentials.NewStaticV4(config.AccessKeyID, config.SecretAccessKey, "") return credentials.NewStaticV4(config.AccessKeyID, config.SecretAccessKey, "")
@ -184,7 +184,9 @@ func buildMinioCredentials(config setting.MinioStorageConfig, iamEndpoint string
&credentials.FileAWSCredentials{}, &credentials.FileAWSCredentials{},
// read IAM role from EC2 metadata endpoint if available // read IAM role from EC2 metadata endpoint if available
&credentials.IAM{ &credentials.IAM{
Endpoint: iamEndpoint, // passing in an empty Endpoint lets the IAM Provider
// decide which endpoint to resolve internally
Endpoint: config.IamEndpoint,
Client: &http.Client{ Client: &http.Client{
Transport: http.DefaultTransport, Transport: http.DefaultTransport,
}, },

View File

@ -107,8 +107,9 @@ func TestMinioCredentials(t *testing.T) {
cfg := setting.MinioStorageConfig{ cfg := setting.MinioStorageConfig{
AccessKeyID: ExpectedAccessKey, AccessKeyID: ExpectedAccessKey,
SecretAccessKey: ExpectedSecretAccessKey, SecretAccessKey: ExpectedSecretAccessKey,
IamEndpoint: FakeEndpoint,
} }
creds := buildMinioCredentials(cfg, FakeEndpoint) creds := buildMinioCredentials(cfg)
v, err := creds.Get() v, err := creds.Get()
assert.NoError(t, err) assert.NoError(t, err)
@ -117,13 +118,15 @@ func TestMinioCredentials(t *testing.T) {
}) })
t.Run("Chain", func(t *testing.T) { t.Run("Chain", func(t *testing.T) {
cfg := setting.MinioStorageConfig{} cfg := setting.MinioStorageConfig{
IamEndpoint: FakeEndpoint,
}
t.Run("EnvMinio", func(t *testing.T) { t.Run("EnvMinio", func(t *testing.T) {
t.Setenv("MINIO_ACCESS_KEY", ExpectedAccessKey+"Minio") t.Setenv("MINIO_ACCESS_KEY", ExpectedAccessKey+"Minio")
t.Setenv("MINIO_SECRET_KEY", ExpectedSecretAccessKey+"Minio") t.Setenv("MINIO_SECRET_KEY", ExpectedSecretAccessKey+"Minio")
creds := buildMinioCredentials(cfg, FakeEndpoint) creds := buildMinioCredentials(cfg)
v, err := creds.Get() v, err := creds.Get()
assert.NoError(t, err) assert.NoError(t, err)
@ -135,7 +138,7 @@ func TestMinioCredentials(t *testing.T) {
t.Setenv("AWS_ACCESS_KEY", ExpectedAccessKey+"AWS") t.Setenv("AWS_ACCESS_KEY", ExpectedAccessKey+"AWS")
t.Setenv("AWS_SECRET_KEY", ExpectedSecretAccessKey+"AWS") t.Setenv("AWS_SECRET_KEY", ExpectedSecretAccessKey+"AWS")
creds := buildMinioCredentials(cfg, FakeEndpoint) creds := buildMinioCredentials(cfg)
v, err := creds.Get() v, err := creds.Get()
assert.NoError(t, err) assert.NoError(t, err)
@ -144,11 +147,11 @@ func TestMinioCredentials(t *testing.T) {
}) })
t.Run("FileMinio", func(t *testing.T) { t.Run("FileMinio", func(t *testing.T) {
t.Setenv("MINIO_SHARED_CREDENTIALS_FILE", "testdata/minio.json")
// prevent loading any actual credentials files from the user // prevent loading any actual credentials files from the user
t.Setenv("MINIO_SHARED_CREDENTIALS_FILE", "testdata/minio.json")
t.Setenv("AWS_SHARED_CREDENTIALS_FILE", "testdata/fake") t.Setenv("AWS_SHARED_CREDENTIALS_FILE", "testdata/fake")
creds := buildMinioCredentials(cfg, FakeEndpoint) creds := buildMinioCredentials(cfg)
v, err := creds.Get() v, err := creds.Get()
assert.NoError(t, err) assert.NoError(t, err)
@ -161,7 +164,7 @@ func TestMinioCredentials(t *testing.T) {
t.Setenv("MINIO_SHARED_CREDENTIALS_FILE", "testdata/fake.json") t.Setenv("MINIO_SHARED_CREDENTIALS_FILE", "testdata/fake.json")
t.Setenv("AWS_SHARED_CREDENTIALS_FILE", "testdata/aws_credentials") t.Setenv("AWS_SHARED_CREDENTIALS_FILE", "testdata/aws_credentials")
creds := buildMinioCredentials(cfg, FakeEndpoint) creds := buildMinioCredentials(cfg)
v, err := creds.Get() v, err := creds.Get()
assert.NoError(t, err) assert.NoError(t, err)
@ -187,7 +190,9 @@ func TestMinioCredentials(t *testing.T) {
defer server.Close() defer server.Close()
// Use the provided EC2 Instance Metadata server // Use the provided EC2 Instance Metadata server
creds := buildMinioCredentials(cfg, server.URL) creds := buildMinioCredentials(setting.MinioStorageConfig{
IamEndpoint: server.URL,
})
v, err := creds.Get() v, err := creds.Get()
assert.NoError(t, err) assert.NoError(t, err)

View File

@ -352,6 +352,9 @@ func Action(ctx *context.Context) {
ctx.Data["IsStaringRepo"] = repo_model.IsStaring(ctx, ctx.Doer.ID, ctx.Repo.Repository.ID) ctx.Data["IsStaringRepo"] = repo_model.IsStaring(ctx, ctx.Doer.ID, ctx.Repo.Repository.ID)
} }
// see the `hx-trigger="refreshUserCards ..."` comments in tmpl
ctx.RespHeader().Add("hx-trigger", "refreshUserCards")
switch ctx.PathParam(":action") { switch ctx.PathParam(":action") {
case "watch", "unwatch", "star", "unstar": case "watch", "unwatch", "star", "unstar":
// we have to reload the repository because NumStars or NumWatching (used in the templates) has just changed // we have to reload the repository because NumStars or NumWatching (used in the templates) has just changed

View File

@ -1123,8 +1123,6 @@ func RenderUserCards(ctx *context.Context, total int, getter func(opts db.ListOp
func Watchers(ctx *context.Context) { func Watchers(ctx *context.Context) {
ctx.Data["Title"] = ctx.Tr("repo.watchers") ctx.Data["Title"] = ctx.Tr("repo.watchers")
ctx.Data["CardsTitle"] = ctx.Tr("repo.watchers") ctx.Data["CardsTitle"] = ctx.Tr("repo.watchers")
ctx.Data["PageIsWatchers"] = true
RenderUserCards(ctx, ctx.Repo.Repository.NumWatches, func(opts db.ListOptions) ([]*user_model.User, error) { RenderUserCards(ctx, ctx.Repo.Repository.NumWatches, func(opts db.ListOptions) ([]*user_model.User, error) {
return repo_model.GetRepoWatchers(ctx, ctx.Repo.Repository.ID, opts) return repo_model.GetRepoWatchers(ctx, ctx.Repo.Repository.ID, opts)
}, tplWatchers) }, tplWatchers)
@ -1134,7 +1132,6 @@ func Watchers(ctx *context.Context) {
func Stars(ctx *context.Context) { func Stars(ctx *context.Context) {
ctx.Data["Title"] = ctx.Tr("repo.stargazers") ctx.Data["Title"] = ctx.Tr("repo.stargazers")
ctx.Data["CardsTitle"] = ctx.Tr("repo.stargazers") ctx.Data["CardsTitle"] = ctx.Tr("repo.stargazers")
ctx.Data["PageIsStargazers"] = true
RenderUserCards(ctx, ctx.Repo.Repository.NumStars, func(opts db.ListOptions) ([]*user_model.User, error) { RenderUserCards(ctx, ctx.Repo.Repository.NumStars, func(opts db.ListOptions) ([]*user_model.User, error) {
return repo_model.GetStargazers(ctx, ctx.Repo.Repository, opts) return repo_model.GetStargazers(ctx, ctx.Repo.Repository, opts)
}, tplWatchers) }, tplWatchers)

View File

@ -1,4 +1,14 @@
<div class="user-cards"> <!-- Refresh the content if a htmx response contains "HX-Trigger" header.
This usually happens when a user stays on the watchers/stargazers page
when they watched/unwatched/starred/unstarred and the list should be refreshed.
To test go to the watchers page and click the watch button. The user cards should reload.
At the moment, no JS initialization would re-trigger (fortunately there is no JS for this page).
-->
<div class="no-loading-indicator tw-hidden"></div>
<div class="user-cards"
hx-trigger="refreshUserCards from:body" hx-indicator=".no-loading-indicator"
hx-get="{{$.CurrentURL}}" hx-swap="outerHTML" hx-select=".user-cards"
>
{{if .CardsTitle}} {{if .CardsTitle}}
<h2 class="ui dividing header"> <h2 class="ui dividing header">
{{.CardsTitle}} {{.CardsTitle}}