feat: add chunked desktop client release uploads
Deployment Config CI / Deployment Config (push) Successful in 28s
Frontend CI / Frontend (push) Successful in 2m12s
Backend CI / Backend (push) Successful in 14m44s

This commit is contained in:
2026-06-01 01:31:54 +08:00
parent c5da0cf507
commit 76df672133
14 changed files with 1195 additions and 57 deletions
+15 -2
View File
@@ -72,12 +72,25 @@ func (c *aliyunClient) Validate() error {
}
func (c *aliyunClient) PutBytes(ctx context.Context, objectKey string, content []byte, contentType string) error {
return c.PutReader(ctx, objectKey, bytes.NewReader(content), int64(len(content)), contentType)
}
func (c *aliyunClient) PutReader(
ctx context.Context,
objectKey string,
reader io.Reader,
size int64,
contentType string,
) error {
if err := c.Validate(); err != nil {
return err
}
if strings.TrimSpace(objectKey) == "" {
return fmt.Errorf("object key is required")
}
if reader == nil {
return fmt.Errorf("object reader is required")
}
exists, err := c.client.IsBucketExist(c.bucket)
if err != nil {
@@ -113,11 +126,11 @@ func (c *aliyunClient) PutBytes(ctx context.Context, objectKey string, content [
if err != nil {
return err
}
if err := bucket.PutObject(objectKey, bytes.NewReader(content), options...); err != nil {
if err := bucket.PutObject(objectKey, reader, options...); err != nil {
c.logError(ctx, "aliyun put object failed",
zap.String("bucket", c.bucket),
zap.String("object_key", objectKey),
zap.Int("content_size", len(content)),
zap.Int64("content_size", size),
zap.String("object_acl", strings.TrimSpace(c.cfg.ObjectACL)),
zap.String("content_type", contentType),
zap.String("aliyun_error_code", aliyunErrorCode(err)),
@@ -4,6 +4,7 @@ import (
"context"
"errors"
"fmt"
"io"
"strings"
"time"
@@ -27,6 +28,10 @@ type Client interface {
DownloadURL(objectKey string) (string, error)
}
type ReaderClient interface {
PutReader(ctx context.Context, objectKey string, reader io.Reader, size int64, contentType string) error
}
type ManagementClient interface {
Client
List(ctx context.Context, in ListInput) (*ListResult, error)
@@ -106,6 +111,10 @@ func (c disabledClient) PutBytes(context.Context, string, []byte, string) error
return c.Validate()
}
func (c disabledClient) PutReader(context.Context, string, io.Reader, int64, string) error {
return c.Validate()
}
func (c disabledClient) GetBytes(context.Context, string) ([]byte, error) {
return nil, c.Validate()
}
+15 -2
View File
@@ -103,6 +103,16 @@ func (c *minioClient) PutBytes(
objectKey string,
content []byte,
contentType string,
) error {
return c.PutReader(ctx, objectKey, bytes.NewReader(content), int64(len(content)), contentType)
}
func (c *minioClient) PutReader(
ctx context.Context,
objectKey string,
reader io.Reader,
size int64,
contentType string,
) error {
if err := c.Validate(); err != nil {
return err
@@ -110,6 +120,9 @@ func (c *minioClient) PutBytes(
if strings.TrimSpace(objectKey) == "" {
return fmt.Errorf("object key is required")
}
if reader == nil {
return fmt.Errorf("object reader is required")
}
exists, err := c.client.BucketExists(ctx, c.bucket)
if err != nil {
@@ -131,14 +144,14 @@ func (c *minioClient) PutBytes(
}
}
_, err = c.client.PutObject(ctx, c.bucket, objectKey, bytes.NewReader(content), int64(len(content)), minio.PutObjectOptions{
_, err = c.client.PutObject(ctx, c.bucket, objectKey, reader, size, minio.PutObjectOptions{
ContentType: contentType,
})
if err != nil {
c.logError(ctx, "minio put object failed",
zap.String("bucket", c.bucket),
zap.String("object_key", objectKey),
zap.Int("content_size", len(content)),
zap.Int64("content_size", size),
zap.Error(err),
)
return fmt.Errorf("put minio object: %w", err)
@@ -2,6 +2,7 @@ package objectstorage
import (
"context"
"io"
"sync"
)
@@ -31,6 +32,19 @@ func (c *ReloadableClient) PutBytes(ctx context.Context, objectKey string, conte
return c.snapshot().PutBytes(ctx, objectKey, content, contentType)
}
func (c *ReloadableClient) PutReader(ctx context.Context, objectKey string, reader io.Reader, size int64, contentType string) error {
client := c.snapshot()
readerClient, ok := client.(ReaderClient)
if !ok {
content, err := io.ReadAll(reader)
if err != nil {
return err
}
return client.PutBytes(ctx, objectKey, content, contentType)
}
return readerClient.PutReader(ctx, objectKey, reader, size, contentType)
}
func (c *ReloadableClient) GetBytes(ctx context.Context, objectKey string) ([]byte, error) {
return c.snapshot().GetBytes(ctx, objectKey)
}