Skip to content

Commit 3a06285

Browse files
authored
Merge branch 'main' into bugfix/Fix-the-incorrect-route-path
2 parents cd2c593 + 8ecdc93 commit 3a06285

File tree

18 files changed

+467
-301
lines changed

18 files changed

+467
-301
lines changed

.github/actionlint.yaml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
self-hosted-runner:
2+
labels:
3+
- actuated-4cpu-8gb
4+
- actuated-4cpu-16gb

.github/labeler.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,9 @@ kind/build:
1919

2020
theme/package-registry:
2121
- "modules/packages/**"
22+
- "services/packages/**"
23+
- "routers/api/packages/**"
24+
- "routers/web/shared/packages/**"
2225

2326
kind/cli:
2427
- "cmd/**"

.github/workflows/release-nightly.yml

Lines changed: 43 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,13 @@ on:
44
push:
55
branches: [ main, release/v* ]
66

7+
concurrency:
8+
group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}
9+
cancel-in-progress: true
10+
711
jobs:
812
nightly-binary:
9-
runs-on: ubuntu-latest
13+
runs-on: actuated-4cpu-8gb
1014
steps:
1115
- uses: actions/checkout@v3
1216
# fetch all commits instead of only the last as some branches are long lived and could have many between versions
@@ -51,13 +55,17 @@ jobs:
5155
AWS_REGION: ${{ secrets.AWS_REGION }}
5256
SOURCE_DIR: dist/release
5357
DEST_DIR: gitea/${{ steps.clean_name.outputs.branch }}
54-
nightly-docker:
55-
runs-on: ubuntu-latest
58+
nightly-docker-rootful:
59+
runs-on: actuated-4cpu-16gb
5660
steps:
5761
- uses: actions/checkout@v3
5862
# fetch all commits instead of only the last as some branches are long lived and could have many between versions
5963
# fetch all tags to ensure that "git describe" reports expected Gitea version, eg. v1.21.0-dev-1-g1234567
6064
- run: git fetch --unshallow --quiet --tags --force
65+
- uses: actions/setup-go@v4
66+
with:
67+
go-version: "~1.21"
68+
check-latest: true
6169
- uses: docker/setup-qemu-action@v2
6270
- uses: docker/setup-buildx-action@v2
6371
- name: Get cleaned branch name
@@ -75,13 +83,45 @@ jobs:
7583
with:
7684
username: ${{ secrets.DOCKERHUB_USERNAME }}
7785
password: ${{ secrets.DOCKERHUB_TOKEN }}
86+
- name: fetch go modules
87+
run: make vendor
7888
- name: build rootful docker image
7989
uses: docker/build-push-action@v4
8090
with:
8191
context: .
8292
platforms: linux/amd64,linux/arm64
8393
push: true
8494
tags: gitea/gitea:${{ steps.clean_name.outputs.branch }}
95+
nightly-docker-rootless:
96+
runs-on: actuated-4cpu-8gb
97+
steps:
98+
- uses: actions/checkout@v3
99+
# fetch all commits instead of only the last as some branches are long lived and could have many between versions
100+
# fetch all tags to ensure that "git describe" reports expected Gitea version, eg. v1.21.0-dev-1-g1234567
101+
- run: git fetch --unshallow --quiet --tags --force
102+
- uses: actions/setup-go@v4
103+
with:
104+
go-version: "~1.21"
105+
check-latest: true
106+
- uses: docker/setup-qemu-action@v2
107+
- uses: docker/setup-buildx-action@v2
108+
- name: Get cleaned branch name
109+
id: clean_name
110+
run: |
111+
# if main then say nightly otherwise cleanup name
112+
if [ "${{ github.ref }}" = "refs/heads/main" ]; then
113+
echo "branch=nightly" >> "$GITHUB_OUTPUT"
114+
exit 0
115+
fi
116+
REF_NAME=$(echo "${{ github.ref }}" | sed -e 's/refs\/heads\///' -e 's/refs\/tags\///' -e 's/release\/v//')
117+
echo "branch=${REF_NAME}-nightly" >> "$GITHUB_OUTPUT"
118+
- name: Login to Docker Hub
119+
uses: docker/login-action@v2
120+
with:
121+
username: ${{ secrets.DOCKERHUB_USERNAME }}
122+
password: ${{ secrets.DOCKERHUB_TOKEN }}
123+
- name: fetch go modules
124+
run: make vendor
85125
- name: build rootless docker image
86126
uses: docker/build-push-action@v4
87127
with:

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,7 @@ cpu.out
9595
/.go-licenses
9696

9797
# Snapcraft
98+
/gitea_a*.txt
9899
snap/.snapcraft/
99100
parts/
100101
stage/

models/actions/runner.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -189,6 +189,12 @@ func (opts FindRunnerOptions) toOrder() string {
189189
return "last_online ASC"
190190
case "alphabetically":
191191
return "name ASC"
192+
case "reversealphabetically":
193+
return "name DESC"
194+
case "newest":
195+
return "id DESC"
196+
case "oldest":
197+
return "id ASC"
192198
}
193199
return "last_online DESC"
194200
}

modules/storage/minio.go

Lines changed: 36 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,11 @@ func convertMinioErr(err error) error {
7171
return err
7272
}
7373

74+
var getBucketVersioning = func(ctx context.Context, minioClient *minio.Client, bucket string) error {
75+
_, err := minioClient.GetBucketVersioning(ctx, bucket)
76+
return err
77+
}
78+
7479
// NewMinioStorage returns a minio storage
7580
func NewMinioStorage(ctx context.Context, cfg *setting.Storage) (ObjectStorage, error) {
7681
config := cfg.MinioConfig
@@ -90,6 +95,23 @@ func NewMinioStorage(ctx context.Context, cfg *setting.Storage) (ObjectStorage,
9095
return nil, convertMinioErr(err)
9196
}
9297

98+
// The GetBucketVersioning is only used for checking whether the Object Storage parameters are generally good. It doesn't need to succeed.
99+
// The assumption is that if the API returns the HTTP code 400, then the parameters could be incorrect.
100+
// Otherwise even if the request itself fails (403, 404, etc), the code should still continue because the parameters seem "good" enough.
101+
// Keep in mind that GetBucketVersioning requires "owner" to really succeed, so it can't be used to check the existence.
102+
// Not using "BucketExists (HeadBucket)" because it doesn't include detailed failure reasons.
103+
err = getBucketVersioning(ctx, minioClient, config.Bucket)
104+
if err != nil {
105+
errResp, ok := err.(minio.ErrorResponse)
106+
if !ok {
107+
return nil, err
108+
}
109+
if errResp.StatusCode == http.StatusBadRequest {
110+
log.Error("S3 storage connection failure at %s:%s with base path %s and region: %s", config.Endpoint, config.Bucket, config.Location, errResp.Message)
111+
return nil, err
112+
}
113+
}
114+
93115
// Check to see if we already own this bucket
94116
exists, err := minioClient.BucketExists(ctx, config.Bucket)
95117
if err != nil {
@@ -114,9 +136,18 @@ func NewMinioStorage(ctx context.Context, cfg *setting.Storage) (ObjectStorage,
114136
}
115137

116138
func (m *MinioStorage) buildMinioPath(p string) string {
117-
p = util.PathJoinRelX(m.basePath, p)
139+
p = strings.TrimPrefix(util.PathJoinRelX(m.basePath, p), "/") // object store doesn't use slash for root path
118140
if p == "." {
119-
p = "" // minio doesn't use dot as relative path
141+
p = "" // object store doesn't use dot as relative path
142+
}
143+
return p
144+
}
145+
146+
func (m *MinioStorage) buildMinioDirPrefix(p string) string {
147+
// ending slash is required for avoiding matching like "foo/" and "foobar/" with prefix "foo"
148+
p = m.buildMinioPath(p) + "/"
149+
if p == "/" {
150+
p = "" // object store doesn't use slash for root path
120151
}
121152
return p
122153
}
@@ -215,20 +246,11 @@ func (m *MinioStorage) URL(path, name string) (*url.URL, error) {
215246
// IterateObjects iterates across the objects in the miniostorage
216247
func (m *MinioStorage) IterateObjects(dirName string, fn func(path string, obj Object) error) error {
217248
opts := minio.GetObjectOptions{}
218-
lobjectCtx, cancel := context.WithCancel(m.ctx)
219-
defer cancel()
220-
221-
basePath := m.basePath
222-
if dirName != "" {
223-
// ending slash is required for avoiding matching like "foo/" and "foobar/" with prefix "foo"
224-
basePath = m.buildMinioPath(dirName) + "/"
225-
}
226-
227-
for mObjInfo := range m.client.ListObjects(lobjectCtx, m.bucket, minio.ListObjectsOptions{
228-
Prefix: basePath,
249+
for mObjInfo := range m.client.ListObjects(m.ctx, m.bucket, minio.ListObjectsOptions{
250+
Prefix: m.buildMinioDirPrefix(dirName),
229251
Recursive: true,
230252
}) {
231-
object, err := m.client.GetObject(lobjectCtx, m.bucket, mObjInfo.Key, opts)
253+
object, err := m.client.GetObject(m.ctx, m.bucket, mObjInfo.Key, opts)
232254
if err != nil {
233255
return convertMinioErr(err)
234256
}

modules/storage/minio_test.go

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,15 @@
44
package storage
55

66
import (
7+
"context"
8+
"net/http"
79
"os"
810
"testing"
911

1012
"code.gitea.io/gitea/modules/setting"
13+
14+
"github.com/minio/minio-go/v7"
15+
"github.com/stretchr/testify/assert"
1116
)
1217

1318
func TestMinioStorageIterator(t *testing.T) {
@@ -25,3 +30,65 @@ func TestMinioStorageIterator(t *testing.T) {
2530
},
2631
})
2732
}
33+
34+
func TestMinioStoragePath(t *testing.T) {
35+
m := &MinioStorage{basePath: ""}
36+
assert.Equal(t, "", m.buildMinioPath("/"))
37+
assert.Equal(t, "", m.buildMinioPath("."))
38+
assert.Equal(t, "a", m.buildMinioPath("/a"))
39+
assert.Equal(t, "a/b", m.buildMinioPath("/a/b/"))
40+
assert.Equal(t, "", m.buildMinioDirPrefix(""))
41+
assert.Equal(t, "a/", m.buildMinioDirPrefix("/a/"))
42+
43+
m = &MinioStorage{basePath: "/"}
44+
assert.Equal(t, "", m.buildMinioPath("/"))
45+
assert.Equal(t, "", m.buildMinioPath("."))
46+
assert.Equal(t, "a", m.buildMinioPath("/a"))
47+
assert.Equal(t, "a/b", m.buildMinioPath("/a/b/"))
48+
assert.Equal(t, "", m.buildMinioDirPrefix(""))
49+
assert.Equal(t, "a/", m.buildMinioDirPrefix("/a/"))
50+
51+
m = &MinioStorage{basePath: "/base"}
52+
assert.Equal(t, "base", m.buildMinioPath("/"))
53+
assert.Equal(t, "base", m.buildMinioPath("."))
54+
assert.Equal(t, "base/a", m.buildMinioPath("/a"))
55+
assert.Equal(t, "base/a/b", m.buildMinioPath("/a/b/"))
56+
assert.Equal(t, "base/", m.buildMinioDirPrefix(""))
57+
assert.Equal(t, "base/a/", m.buildMinioDirPrefix("/a/"))
58+
59+
m = &MinioStorage{basePath: "/base/"}
60+
assert.Equal(t, "base", m.buildMinioPath("/"))
61+
assert.Equal(t, "base", m.buildMinioPath("."))
62+
assert.Equal(t, "base/a", m.buildMinioPath("/a"))
63+
assert.Equal(t, "base/a/b", m.buildMinioPath("/a/b/"))
64+
assert.Equal(t, "base/", m.buildMinioDirPrefix(""))
65+
assert.Equal(t, "base/a/", m.buildMinioDirPrefix("/a/"))
66+
}
67+
68+
func TestS3StorageBadRequest(t *testing.T) {
69+
if os.Getenv("CI") == "" {
70+
t.Skip("S3Storage not present outside of CI")
71+
return
72+
}
73+
cfg := &setting.Storage{
74+
MinioConfig: setting.MinioStorageConfig{
75+
Endpoint: "minio:9000",
76+
AccessKeyID: "123456",
77+
SecretAccessKey: "12345678",
78+
Bucket: "bucket",
79+
Location: "us-east-1",
80+
},
81+
}
82+
message := "ERROR"
83+
old := getBucketVersioning
84+
defer func() { getBucketVersioning = old }()
85+
getBucketVersioning = func(ctx context.Context, minioClient *minio.Client, bucket string) error {
86+
return minio.ErrorResponse{
87+
StatusCode: http.StatusBadRequest,
88+
Code: "FixtureError",
89+
Message: message,
90+
}
91+
}
92+
_, err := NewStorage(setting.MinioStorageType, cfg)
93+
assert.ErrorContains(t, err, message)
94+
}

options/locale/locale_ja-JP.ini

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3443,10 +3443,32 @@ runs.commit=コミット
34433443
runs.invalid_workflow_helper=ワークフロー設定ファイルは無効です。あなたの設定ファイルを確認してください: %s
34443444
runs.no_matching_runner_helper=一致するランナーがありません: %s
34453445
runs.status=ステータス
3446+
runs.status_no_select=すべてのステータス
3447+
runs.no_results=一致する結果はありません。
3448+
runs.no_runs=ワークフローはまだ実行されていません。
34463449

3450+
workflow.disable=ワークフローを無効にする
3451+
workflow.disable_success=ワークフロー '%s' が無効になりました。
3452+
workflow.enable=ワークフローを有効にする
3453+
workflow.enable_success=ワークフロー '%s' が有効になりました。
34473454

34483455
need_approval_desc=フォークプルリクエストのワークフローを実行するには承認が必要です。
34493456

3457+
variables=変数
3458+
variables.management=変数の管理
3459+
variables.creation=変数の追加
3460+
variables.none=変数はまだありません。
3461+
variables.deletion=変数を削除
3462+
variables.deletion.description=変数の削除は恒久的で元に戻すことはできません。 続行しますか?
3463+
variables.description=変数は特定のActionsに渡されます。 それ以外で読み出されることはありません。
3464+
variables.id_not_exist=idが%dの変数は存在しません。
3465+
variables.edit=変数の編集
3466+
variables.deletion.failed=変数を削除できませんでした。
3467+
variables.deletion.success=変数を削除しました。
3468+
variables.creation.failed=変数を追加できませんでした。
3469+
variables.creation.success=変数 "%s" を追加しました。
3470+
variables.update.failed=変数を更新できませんでした。
3471+
variables.update.success=変数を更新しました。
34503472

34513473
[projects]
34523474
type-1.display_name=個人プロジェクト

0 commit comments

Comments
 (0)