-
Notifications
You must be signed in to change notification settings - Fork 6
Sync with Upstream Latest #78
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: next
Are you sure you want to change the base?
Conversation
Signed-off-by: wang yan <[email protected]> Co-authored-by: wang yan <[email protected]>
for LDAP test, the default port changed from 443 to 9443, the original hostname contains IP:PORT, but the webhook event just contains the IP, need remove port before validation. fix issue related to CI pass checks Signed-off-by: stonezdj <[email protected]>
Signed-off-by: stonezdj <[email protected]>
…n /src (#22304) chore(deps): bump github.com/stretchr/testify in /src Bumps [github.com/stretchr/testify](https://github.com/stretchr/testify) from 1.10.0 to 1.11.1. - [Release notes](https://github.com/stretchr/testify/releases) - [Commits](stretchr/testify@v1.10.0...v1.11.1) --- updated-dependencies: - dependency-name: github.com/stretchr/testify dependency-version: 1.11.1 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <[email protected]> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
…/src (#22306) chore(deps): bump github.com/aws/aws-sdk-go in /src Bumps [github.com/aws/aws-sdk-go](https://github.com/aws/aws-sdk-go) from 1.55.6 to 1.55.8. - [Release notes](https://github.com/aws/aws-sdk-go/releases) - [Changelog](https://github.com/aws/aws-sdk-go/blob/main/CHANGELOG_PENDING.md) - [Commits](aws/aws-sdk-go@v1.55.6...v1.55.8) --- updated-dependencies: - dependency-name: github.com/aws/aws-sdk-go dependency-version: 1.55.8 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <[email protected]> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
… /src (#22305) chore(deps): bump github.com/go-ldap/ldap/v3 in /src Bumps [github.com/go-ldap/ldap/v3](https://github.com/go-ldap/ldap) from 3.4.10 to 3.4.11. - [Release notes](https://github.com/go-ldap/ldap/releases) - [Commits](go-ldap/ldap@v3.4.10...v3.4.11) --- updated-dependencies: - dependency-name: github.com/go-ldap/ldap/v3 dependency-version: 3.4.11 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <[email protected]> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: miner <[email protected]>
… 5.0.0 (#22324) chore(deps): bump aws-actions/configure-aws-credentials Bumps [aws-actions/configure-aws-credentials](https://github.com/aws-actions/configure-aws-credentials) from 4.2.1 to 5.0.0. - [Release notes](https://github.com/aws-actions/configure-aws-credentials/releases) - [Changelog](https://github.com/aws-actions/configure-aws-credentials/blob/main/CHANGELOG.md) - [Commits](aws-actions/configure-aws-credentials@v4.2.1...v5.0.0) --- updated-dependencies: - dependency-name: aws-actions/configure-aws-credentials dependency-version: 5.0.0 dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] <[email protected]> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: miner <[email protected]>
Bumps [actions/setup-node](https://github.com/actions/setup-node) from 4 to 5. - [Release notes](https://github.com/actions/setup-node/releases) - [Commits](actions/setup-node@v4...v5) --- updated-dependencies: - dependency-name: actions/setup-node dependency-version: '5' dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] <[email protected]> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: miner <[email protected]>
Bumps [actions/stale](https://github.com/actions/stale) from 9.1.0 to 10.0.0. - [Release notes](https://github.com/actions/stale/releases) - [Changelog](https://github.com/actions/stale/blob/main/CHANGELOG.md) - [Commits](actions/stale@v9.1.0...v10.0.0) --- updated-dependencies: - dependency-name: actions/stale dependency-version: 10.0.0 dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] <[email protected]> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Wang Yan <[email protected]> Co-authored-by: miner <[email protected]>
…2338) Bumps [golang.org/x/text](https://github.com/golang/text) from 0.27.0 to 0.29.0. - [Release notes](https://github.com/golang/text/releases) - [Commits](golang/text@v0.27.0...v0.29.0) --- updated-dependencies: - dependency-name: golang.org/x/text dependency-version: 0.29.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <[email protected]> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
… to 1.1.31 in /src (#22337) chore(deps): bump github.com/volcengine/volcengine-go-sdk in /src Bumps [github.com/volcengine/volcengine-go-sdk](https://github.com/volcengine/volcengine-go-sdk) from 1.1.29 to 1.1.31. - [Release notes](https://github.com/volcengine/volcengine-go-sdk/releases) - [Commits](volcengine/volcengine-go-sdk@v1.1.29...v1.1.31) --- updated-dependencies: - dependency-name: github.com/volcengine/volcengine-go-sdk dependency-version: 1.1.31 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <[email protected]> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Signed-off-by: stonezdj <[email protected]>
… to 1.1.34 in /src (#22356) chore(deps): bump github.com/volcengine/volcengine-go-sdk in /src Bumps [github.com/volcengine/volcengine-go-sdk](https://github.com/volcengine/volcengine-go-sdk) from 1.1.32 to 1.1.34. - [Release notes](https://github.com/volcengine/volcengine-go-sdk/releases) - [Commits](volcengine/volcengine-go-sdk@v1.1.32...v1.1.34) --- updated-dependencies: - dependency-name: github.com/volcengine/volcengine-go-sdk dependency-version: 1.1.34 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <[email protected]> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
…2360) Bumps [golang.org/x/time](https://github.com/golang/time) from 0.12.0 to 0.13.0. - [Commits](golang/time@v0.12.0...v0.13.0) --- updated-dependencies: - dependency-name: golang.org/x/time dependency-version: 0.13.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <[email protected]> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: miner <[email protected]>
) Bumps [k8s.io/client-go](https://github.com/kubernetes/client-go) from 0.33.3 to 0.34.1. - [Changelog](https://github.com/kubernetes/client-go/blob/master/CHANGELOG.md) - [Commits](kubernetes/client-go@v0.33.3...v0.34.1) --- updated-dependencies: - dependency-name: k8s.io/client-go dependency-version: 0.34.1 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <[email protected]> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
… 4.19.0 in /src (#22358) chore(deps): bump github.com/golang-migrate/migrate/v4 in /src Bumps [github.com/golang-migrate/migrate/v4](https://github.com/golang-migrate/migrate) from 4.18.1 to 4.19.0. - [Release notes](https://github.com/golang-migrate/migrate/releases) - [Changelog](https://github.com/golang-migrate/migrate/blob/master/.goreleaser.yml) - [Commits](golang-migrate/migrate@v4.18.1...v4.19.0) --- updated-dependencies: - dependency-name: github.com/golang-migrate/migrate/v4 dependency-version: 4.19.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <[email protected]> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
…in /src (#22357) chore(deps): bump github.com/coreos/go-oidc/v3 in /src Bumps [github.com/coreos/go-oidc/v3](https://github.com/coreos/go-oidc) from 3.12.0 to 3.15.0. - [Release notes](https://github.com/coreos/go-oidc/releases) - [Commits](coreos/go-oidc@v3.12.0...v3.15.0) --- updated-dependencies: - dependency-name: github.com/coreos/go-oidc/v3 dependency-version: 3.15.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <[email protected]> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: miner <[email protected]>
…com/gorilla/mux/otelmux from 0.59.0 to 0.63.0 in /src (#22379) chore(deps): bump go.opentelemetry.io/contrib/instrumentation/github.com/gorilla/mux/otelmux Bumps [go.opentelemetry.io/contrib/instrumentation/github.com/gorilla/mux/otelmux](https://github.com/open-telemetry/opentelemetry-go-contrib) from 0.59.0 to 0.63.0. - [Release notes](https://github.com/open-telemetry/opentelemetry-go-contrib/releases) - [Changelog](https://github.com/open-telemetry/opentelemetry-go-contrib/blob/main/CHANGELOG.md) - [Commits](open-telemetry/opentelemetry-go-contrib@zpages/v0.59.0...zpages/v0.63.0) --- updated-dependencies: - dependency-name: go.opentelemetry.io/contrib/instrumentation/github.com/gorilla/mux/otelmux dependency-version: 0.63.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <[email protected]> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
remove outdated badges, useless badges, clarify badges Signed-off-by: Vadim Bauer <[email protected]>
* add tag deletion option for gc As proposed in the GC performance enhancement, Harbor will provide an option in the garbage collection job to determine whether tag files should be removed from the backend storage. By default, this option will be enabled (true) to align with the previous behavior. For performance considerations, users can disable tag deletion by unchecking this option. Proposal: goharbor/community#265 Signed-off-by: wang yan <[email protected]> * resolve comments Signed-off-by: wang yan <[email protected]> * fix ut Signed-off-by: wang yan <[email protected]> --------- Signed-off-by: wang yan <[email protected]> Co-authored-by: wang yan <[email protected]>
fixes #21406 The changes are target to fix the system robot to create a project level robots. It should not to get the creator robot with the createe robot's project id, and updates the code get the creator robot from the security context. Signed-off-by: wang yan <[email protected]> Co-authored-by: wang yan <[email protected]>
limit the proxy connection to upstream registry Signed-off-by: stonezdj <[email protected]>
Signed-off-by: stonezdj <[email protected]>
Signed-off-by: Peter Dave Hello <[email protected]>
Fixes #22257 Add support for SKIP_LOG_AUDIT_DATABASE env to control audit log database storage during Harbor initialization. Signed-off-by: wang yan <[email protected]> Co-authored-by: wang yan <[email protected]>
Signed-off-by: Peter Dave Hello <[email protected]>
give the value of skip_audit_log_database bases on the real usage. 1. If audit logs exist in the system (either in audit_log or audit_log_ext tables), set skip_audit_log_database to false 2. If no audit logs exist but the tables show evidence of previous usage set skip_audit_log_database to false Signed-off-by: wang yan <[email protected]> Co-authored-by: wang yan <[email protected]>
Signed-off-by: rocksload <[email protected]>
Signed-off-by: rustversion <[email protected]>
simplify the sql to set the value of skip_audit_log_database, any evidence of previous usage of db to record the audit, set it to false. Signed-off-by: wang yan <[email protected]> Co-authored-by: wang yan <[email protected]>
Signed-off-by: Daniel Jiang <[email protected]>
) Bumps [golang.org/x/net](https://github.com/golang/net) from 0.41.0 to 0.46.0. - [Commits](golang/net@v0.41.0...v0.46.0) --- updated-dependencies: - dependency-name: golang.org/x/net dependency-version: 0.46.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <[email protected]> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Wang Yan <[email protected]>
legacy switch from decodeFilters Signed-off-by: Anurag Ojha <[email protected]>
… to 1.1.44 in /src (#22519) chore(deps): bump github.com/volcengine/volcengine-go-sdk in /src Bumps [github.com/volcengine/volcengine-go-sdk](https://github.com/volcengine/volcengine-go-sdk) from 1.1.34 to 1.1.44. - [Release notes](https://github.com/volcengine/volcengine-go-sdk/releases) - [Commits](volcengine/volcengine-go-sdk@v1.1.34...v1.1.44) --- updated-dependencies: - dependency-name: github.com/volcengine/volcengine-go-sdk dependency-version: 1.1.44 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <[email protected]> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Bumps [actions/upload-artifact](https://github.com/actions/upload-artifact) from 4 to 5. - [Release notes](https://github.com/actions/upload-artifact/releases) - [Commits](actions/upload-artifact@v4...v5) --- updated-dependencies: - dependency-name: actions/upload-artifact dependency-version: '5' dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] <[email protected]> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
fixes #22488 update the permission check of the user api to fix the issue that robot cannot operation this api. the permission checking compares the /system/users with /users, which results in the forbidden error. Update the checking to the correct permission path. Signed-off-by: wang yan <[email protected]> Co-authored-by: wang yan <[email protected]>
Signed-off-by: Orlix <[email protected]>
Signed-off-by: geogrego <[email protected]>
Signed-off-by: Anurag Ojha <[email protected]>
Signed-off-by: chlins <[email protected]>
Signed-off-by: dulanting <[email protected]>
Added test case Signed-off-by: Anurag Ojha <[email protected]>
|
Note Other AI code review bot(s) detectedCodeRabbit has detected other AI code review bot(s) in this pull request and will avoid duplicating their findings in the review comments. This may lead to a less comprehensive review. 📝 WalkthroughWalkthroughBumps VERSION to v2.15.0; adds upstream connection limiting via Redis, GC delete-tag option end-to-end, config-store driver Get plumbing, CI/workflow updates, DB migration to init skip_audit_log_database, UI/i18n additions, dependency upgrades, tests, and multiple small refactors. Changes
Sequence Diagram(s)sequenceDiagram
autonumber
participant Client
participant Middleware as Repoxy Middleware
participant Redis
participant Backend
Note over Middleware,Redis: Acquire slot per artifact/project (Redis Lua)
Client->>Middleware: Request (blob/manifest) with artifact info
Middleware->>Middleware: key := upstreamRegistryConnectionKey(artifact)
Middleware->>Redis: EVAL increaseWithLimit(key, limit)
alt Redis returns 1 (acquired)
Redis-->>Middleware: 1
Middleware->>Backend: Proxy request (may rewrite tag→digest)
Backend-->>Middleware: response
Middleware->>Redis: EVAL decrease(key) (deferred)
Middleware-->>Client: proxied response
else Redis returns 0 (limit exceeded)
Redis-->>Middleware: 0
Middleware-->>Client: 429 Too Many Requests
end
sequenceDiagram
autonumber
participant UI
participant API as Server Handler
participant Controller
participant JobService
Note over UI,JobService: delete_tag flows through GC
UI->>API: schedule GC { delete_tag: true/false, ... }
API->>Controller: create/start GC policy (includes DeleteTag)
Controller->>JobService: enqueue GC task (task.DeleteTag set)
JobService->>JobService: sweep: if task.DeleteTag then attempt v2DeleteManifest else skip v2 path
JobService-->>Controller: task result/status
Controller-->>API: return job response
API-->>UI: show result
Estimated code review effort🎯 4 (Complex) | ⏱️ ~75 minutes Areas needing extra attention:
Possibly related PRs
Pre-merge checks and finishing touches❌ Failed checks (1 warning, 1 inconclusive)
✅ Passed checks (1 passed)
✨ Finishing touches🧪 Generate unit tests (beta)
📜 Recent review detailsConfiguration used: CodeRabbit UI Review profile: CHILL Plan: Pro 📒 Files selected for processing (2)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
🔇 Additional comments (5)
Tip 📝 Customizable high-level summaries are now available in beta!You can now customize how CodeRabbit generates the high-level summary in your pull requests — including its content, structure, tone, and formatting.
Example instruction:
Note: This feature is currently in beta for Pro-tier users, and pricing will be announced later. Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
This PR introduces several enhancements and bug fixes to the Harbor project, including:
- Addition of upstream registry connection limiting for proxy cache projects
- Addition of a
delete_tagparameter for garbage collection - Removal of obsolete test cases (Google GCR and P2P Preheat by Event tests)
- Refactoring to use
strings.CutPrefixinstead ofstrings.HasPrefix+strings.TrimPrefix - Performance optimizations using
strings.Builderfor string concatenation - Updates to translations across multiple languages
- Dependency updates and CI/CD improvements
Reviewed Changes
Copilot reviewed 75 out of 77 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
| src/server/middleware/repoproxy/proxy.go | Adds connection limiting logic for upstream registry access |
| src/pkg/proxy/connection/limit.go | New connection limiter implementation using Redis |
| src/portal/src/app/base/project/project.ts | Adds max_upstream_conn metadata field |
| src/jobservice/job/impl/gc/garbage_collection.go | Adds delete_tag parameter for GC operations |
| tests/resources/TestCaseBody.robot | Adds webhook verification fix for harbor_hostname |
| src/pkg/task/dao/execution.go | Performance optimization using strings.Builder |
| src/pkg/config/store/store.go | Adds GetFromDriver method |
| src/core/main.go | Initializes skip_audit_log_database from ENV |
| Multiple language JSON files | Translation updates |
Comments suppressed due to low confidence (1)
src/portal/src/app/base/project/project-config/project-policy-config/project-policy-config.component.ts:1
- The new
validateMaxUpstreamConnections()method lacks test coverage. Consider adding unit tests similar to those that exist forvalidateBandwidth()to ensure proper validation logic.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| this.validateMaxUpstreamConnections(); | ||
| if (this.bandwidthError) { | ||
| this.inlineAlert.showInlineError(this.maxUpstreamConnError); | ||
| return; | ||
| } |
Copilot
AI
Nov 6, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The condition on line 369 checks this.bandwidthError but then displays this.maxUpstreamConnError on line 370. This should check this.maxUpstreamConnError instead of this.bandwidthError.
| this.translateService | ||
| .get('PROJECT.PROXY_CACHE_MAX_UPSTREAM_CONN_INPUT_TIP') | ||
| .subscribe((res: string) => { | ||
| this.bandwidthError = res; | ||
| }); |
Copilot
AI
Nov 6, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In the validateBandwidth() method, the error message is being fetched with the translation key 'PROJECT.PROXY_CACHE_MAX_UPSTREAM_CONN_INPUT_TIP' but should use 'PROJECT.SPEED_LIMIT_TIP' instead. This appears to be a copy-paste error from the validateMaxUpstreamConnections method.
| } | ||
| cnt, err := strconv.ParseInt(countVal, 10, 32) | ||
| if err != nil { | ||
| log.Warningf("failed th parse the max_upstream_conn, val:%s error %v", countVal, err) |
Copilot
AI
Nov 6, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Corrected spelling of 'th' to 'to'.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@copilot open a new pull request to apply changes based on this feedback
| return err | ||
| } | ||
| } else { | ||
| log.Debugf("key SkipAuditLogDatabase aleady exist in the db with value %v", val) |
Copilot
AI
Nov 6, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Corrected spelling of 'aleady' to 'already'.
| log.Debugf("key SkipAuditLogDatabase aleady exist in the db with value %v", val) | |
| log.Debugf("key SkipAuditLogDatabase already exist in the db with value %v", val) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 24
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
src/server/v2.0/handler/user.go (1)
333-337: Fix error propagation in UpdateUserPasswordIf
UpdatePasswordfails, the code logs and returns the staleerr(likelynil), so the API reports success even though the update failed. Use the fresh error instead.- err2 := u.ctl.UpdatePassword(ctx, uid, params.Password.NewPassword) - if err2 != nil { - log.G(ctx).Errorf("Failed to update password, error: %v", err) - return u.SendError(ctx, err) - } + err2 := u.ctl.UpdatePassword(ctx, uid, params.Password.NewPassword) + if err2 != nil { + log.G(ctx).Errorf("Failed to update password, error: %v", err2) + return u.SendError(ctx, err2) + }
🧹 Nitpick comments (12)
tests/resources/TestCaseBody.robot (1)
19-19: Consider making the port configurable.The
Remove Portkeyword hardcodes the port:9443on line 26. If the port changes or varies across environments, this keyword will need modification. Consider accepting the port as an optional parameter with:9443as a default, or extracting it to a variable.Additionally, the keyword name "Remove Port" suggests it removes any port, but it specifically targets
:9443. A more descriptive name like "Remove Harbor Port" or "Remove Default Port" would clarify its specific behavior.Example refactor to accept port as parameter:
Remove Port - [Arguments] ${address} - ${result}= Replace String ${address} :9443 ${EMPTY} + [Arguments] ${address} ${port}=:9443 + ${result}= Replace String ${address} ${port} ${EMPTY} [Return] ${result}Also applies to: 24-27
src/core/main.go (1)
366-395: Fix typos in log messages.The function logic is correct and handles the coordination between environment variables and database configuration appropriately. However, there are two minor typos in the log messages:
Apply this diff to fix the typos:
- log.Debugf("key SkipAuditLogDatabase do not exist in the db, will initialize as %v", skipAuditEnv) + log.Debugf("key SkipAuditLogDatabase does not exist in the db, will initialize as %v", skipAuditEnv)- log.Debugf("key SkipAuditLogDatabase aleady exist in the db with value %v", val) + log.Debugf("key SkipAuditLogDatabase already exists in the db with value %v", val)src/pkg/reg/adapter/tencentcr/artifact_registry_test.go (2)
6-7: Consider grouping and ordering imports alphabetically.While the current import structure is functional, Go convention prefers grouping standard library imports together and ordering them alphabetically. Consider reordering to:
fmt,reflect,strings,testing.
220-227: Refactor fragile test name string comparison.The hardcoded string check
if tt.name == "valid repository format should not error"creates tight coupling between the test name and its logic. If the test name is renamed, the mock setup breaks silently.Consider setting up the mock based on the test expectations instead:
for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { a := &mockAdapter{} - if tt.name == "valid repository format should not error" { + if !tt.wantErr { a.deleteImageFunc = func(namespace, repo, reference string) error { - if namespace != "demo" || repo != "app" || reference != "v1.0" { + expectedNamespace, expectedRepo := strings.Split(tt.args.repository, "/")[0], strings.Split(tt.args.repository, "/")[1] + if namespace != expectedNamespace || repo != expectedRepo || reference != tt.args.reference { t.Errorf("unexpected args: %s/%s:%s", namespace, repo, reference) } return nil } }src/pkg/cached/manager.go (1)
88-94: Consider eliminatingfmt.Sprintffor further optimization.While the
strings.Builderrefactor is correct, wrappingfmt.SprintfinsideWriteStringstill allocates temporary strings. For maximum performance, consider writing separators and values directly.Example refactor for lines 88-94:
if i%2 == 0 { key, match := keysAndValues[i].(string) if !match { return "", errors.Errorf("key must be string, invalid key type: %#v", keysAndValues[i]) } - s.WriteString(fmt.Sprintf(":%s", key)) + s.WriteByte(':') + s.WriteString(key) } else { switch keysAndValues[i].(type) { case int, int16, int32, int64: - s.WriteString(fmt.Sprintf(":%d", keysAndValues[i])) + s.WriteByte(':') + s.WriteString(strconv.FormatInt(reflect.ValueOf(keysAndValues[i]).Int(), 10)) case string: - s.WriteString(fmt.Sprintf(":%s", keysAndValues[i])) + s.WriteByte(':') + s.WriteString(keysAndValues[i].(string)) default: return "", errors.Errorf("unsupported value type: %#v", keysAndValues[i]) } }You'll need to add imports for
reflectandstrconvif pursuing this optimization.src/server/v2.0/handler/project_metadata_test.go (1)
24-76: Comprehensive validation test coverage for max_upstream_conn.The table-driven tests thoroughly cover the validation logic for
ProMetaMaxUpstreamConn:
- Invalid numeric parsing
- Boundary values (0 and -1 for unlimited)
- Normal positive values
- Error conditions (unsupported keys, empty map)
The test structure follows Go best practices and provides clear documentation of expected behavior.
Consider adding edge cases for completeness:
- Large positive values (e.g.,
MaxInt32)- Negative values other than -1 (should these be rejected?)
{ name: "max upstream conn maximum value", metas: map[string]string{proModels.ProMetaMaxUpstreamConn: "2147483647"}, expectErr: false, }, { name: "max upstream conn negative value other than -1", metas: map[string]string{proModels.ProMetaMaxUpstreamConn: "-5"}, expectErr: true, // or false, depending on requirements },src/server/v2.0/handler/project_metadata.go (1)
164-169: Consider consolidating duplicate validation logic.The validation for
ProMetaMaxUpstreamConnis identical toProMetaProxySpeed(lines 158-163). Both parse a 32-bit integer and return the same error message format.Apply this diff to combine the cases:
case proModels.ProMetaSeverity: severity := vuln.ParseSeverityVersion3(strings.ToLower(value)) if severity == vuln.Unknown { return nil, errors.New(nil).WithCode(errors.BadRequestCode).WithMessagef("invalid value: %s", value) } metas[proModels.ProMetaSeverity] = strings.ToLower(severity.String()) - case proModels.ProMetaProxySpeed: + case proModels.ProMetaProxySpeed, proModels.ProMetaMaxUpstreamConn: v, err := strconv.ParseInt(value, 10, 32) if err != nil { return nil, errors.New(nil).WithCode(errors.BadRequestCode).WithMessagef("invalid value: %s", value) } - metas[proModels.ProMetaProxySpeed] = strconv.FormatInt(v, 10) - case proModels.ProMetaMaxUpstreamConn: - v, err := strconv.ParseInt(value, 10, 32) - if err != nil { - return nil, errors.New(nil).WithCode(errors.BadRequestCode).WithMessagef("invalid value: %s", value) - } - metas[proModels.ProMetaMaxUpstreamConn] = strconv.FormatInt(v, 10) + metas[key] = strconv.FormatInt(v, 10) default: return nil, errors.New(nil).WithCode(errors.BadRequestCode).WithMessagef("invalid key: %s", key) }api/v2.0/swagger.yaml (1)
7324-7327: Tighten schema and docs for max_upstream_conn
- Add input validation and clearer wording; include an example. Also document the default and semantics of "0" vs "-1".
Proposed tweak:
max_upstream_conn: - type: string - description: 'The max connection per artifact to the upstream registry in current proxy cache project, if it is -1, no limit to upstream registry connections' - x-nullable: true + type: string + description: 'Maximum upstream registry connections per artifact for this proxy cache project. Use -1 for unlimited.' + x-nullable: true + pattern: '^(-1|[0-9]+)$' + example: "8"Please confirm:
- What is the backend default when omitted or unparsable (e.g., "0")?
- Does "0" have a special meaning (disable/blocked) or is it just a valid value?
src/portal/src/app/base/project/project-config/project-policy-config/project-policy-config.component.ts (1)
61-75: Coerce max_upstream_conn to number when initializing policyBackend project.metadata values are typically strings; assigning them directly risks type mismatches and UI validation glitches. Parse to number with a safe fallback.
- MaxUpstreamConn?: number | null; + MaxUpstreamConn?: number | null; @@ - this.MaxUpstreamConn = -1; + this.MaxUpstreamConn = -1; @@ - this.MaxUpstreamConn = pro.metadata.max_upstream_conn - ? pro.metadata.max_upstream_conn - : -1; + const muc = (pro && pro.metadata && (pro.metadata as any).max_upstream_conn) ?? -1; + const parsed = Number.parseInt(muc as any, 10); + this.MaxUpstreamConn = Number.isFinite(parsed) ? parsed : -1;Also applies to: 93-96
src/portal/src/app/base/left-side-nav/projects/create-project/create-project.component.ts (2)
445-454: Also gate form validity on maxUpstreamConnErrorPrevents enabling submit when upstream-connection value is invalid.
return ( this.currentForm && this.currentForm.valid && !this.isSubmitOnGoing && this.isNameValid && !this.checkOnGoing && - !this.bandwidthError + !this.bandwidthError && + !this.maxUpstreamConnError );
442-443: Reset upstream-connection error on dialog openClear stale error when starting a new project.
this.speedLimit = -1; - this.project.metadata.max_upstream_conn = -1; + this.project.metadata.max_upstream_conn = -1; + this.maxUpstreamConnError = null;src/jobservice/job/impl/gc/garbage_collection.go (1)
343-372: Readonly handling: consider graceful termination with explicit statusCurrent behavior returns readonly.Err to the worker, causing the whole GC to error out. If that’s intended, fine. Alternatively, you could treat readonly as a controlled abort (recording a distinct status and exiting without marking failures), to avoid noisy job failures when admins toggle read‑only.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (1)
src/go.sumis excluded by!**/*.sum
📒 Files selected for processing (75)
.github/dependabot.yml(1 hunks).github/release.yml(1 hunks).github/workflows/CI.yml(10 hunks).github/workflows/build-package.yml(1 hunks).github/workflows/conformance_test.yml(1 hunks).github/workflows/housekeeping-stale-issues-prs.yaml(1 hunks).github/workflows/pass-CI.yml(2 hunks).github/workflows/publish_release.yml(2 hunks)README.md(1 hunks)VERSION(1 hunks)api/v2.0/swagger.yaml(1 hunks)make/migrations/postgresql/0180_2.15.0_schema.up.sql(1 hunks)src/common/api/base.go(2 hunks)src/common/secret/request.go(1 hunks)src/controller/gc/controller.go(3 hunks)src/controller/gc/controller_test.go(2 hunks)src/controller/gc/model.go(2 hunks)src/controller/registry/controller.go(1 hunks)src/core/main.go(3 hunks)src/go.mod(7 hunks)src/jobservice/job/impl/gc/garbage_collection.go(4 hunks)src/jobservice/job/impl/gc/garbage_collection_test.go(3 hunks)src/jobservice/migration/manager_test.go(2 hunks)src/lib/config/config.go(1 hunks)src/lib/q/builder.go(1 hunks)src/pkg/cached/manager.go(3 hunks)src/pkg/config/db/cache.go(1 hunks)src/pkg/config/db/dao/dao.go(3 hunks)src/pkg/config/db/db.go(2 hunks)src/pkg/config/inmemory/manager.go(2 hunks)src/pkg/config/manager.go(1 hunks)src/pkg/config/manager_test.go(1 hunks)src/pkg/config/rest/rest.go(1 hunks)src/pkg/config/store/driver.go(1 hunks)src/pkg/config/store/store.go(1 hunks)src/pkg/config/store/store_test.go(1 hunks)src/pkg/p2p/preheat/models/policy/policy.go(0 hunks)src/pkg/project/models/pro_meta.go(1 hunks)src/pkg/project/models/project.go(2 hunks)src/pkg/proxy/connection/limit.go(1 hunks)src/pkg/proxy/connection/limit_test.go(1 hunks)src/pkg/quota/dao/util.go(1 hunks)src/pkg/reg/adapter/tencentcr/artifact_registry_test.go(3 hunks)src/pkg/task/dao/execution.go(4 hunks)src/portal/src/app/base/left-side-nav/clearing-job/gc-page/gc/gc.component.html(1 hunks)src/portal/src/app/base/left-side-nav/clearing-job/gc-page/gc/gc.component.ts(7 hunks)src/portal/src/app/base/left-side-nav/projects/create-project/create-project.component.html(1 hunks)src/portal/src/app/base/left-side-nav/projects/create-project/create-project.component.ts(5 hunks)src/portal/src/app/base/project/project-config/project-policy-config/project-policy-config.component.html(1 hunks)src/portal/src/app/base/project/project-config/project-policy-config/project-policy-config.component.ts(5 hunks)src/portal/src/app/base/project/project-config/project-policy-config/project.ts(1 hunks)src/portal/src/app/base/project/project.ts(1 hunks)src/portal/src/i18n/lang/de-de-lang.json(2 hunks)src/portal/src/i18n/lang/en-us-lang.json(2 hunks)src/portal/src/i18n/lang/es-es-lang.json(2 hunks)src/portal/src/i18n/lang/fr-fr-lang.json(2 hunks)src/portal/src/i18n/lang/ko-kr-lang.json(2 hunks)src/portal/src/i18n/lang/pt-br-lang.json(2 hunks)src/portal/src/i18n/lang/ru-ru-lang.json(2 hunks)src/portal/src/i18n/lang/tr-tr-lang.json(2 hunks)src/portal/src/i18n/lang/zh-cn-lang.json(2 hunks)src/server/middleware/repoproxy/proxy.go(5 hunks)src/server/middleware/util/util.go(1 hunks)src/server/v2.0/handler/gc.go(2 hunks)src/server/v2.0/handler/project.go(3 hunks)src/server/v2.0/handler/project_metadata.go(1 hunks)src/server/v2.0/handler/project_metadata_test.go(1 hunks)src/server/v2.0/handler/robot.go(1 hunks)src/server/v2.0/handler/user.go(5 hunks)src/server/v2.0/handler/user_test.go(2 hunks)src/testing/lib/config/manager.go(1 hunks)tests/ci/ut_install.sh(1 hunks)tests/resources/TestCaseBody.robot(2 hunks)tests/robot-cases/Group1-Nightly/P2P_Preheat.robot(0 hunks)tests/robot-cases/Group1-Nightly/Replication.robot(0 hunks)
💤 Files with no reviewable changes (3)
- tests/robot-cases/Group1-Nightly/P2P_Preheat.robot
- tests/robot-cases/Group1-Nightly/Replication.robot
- src/pkg/p2p/preheat/models/policy/policy.go
🧰 Additional context used
🧬 Code graph analysis (19)
src/lib/config/config.go (1)
src/jobservice/job/impl/context.go (1)
Context(42-55)
src/testing/lib/config/manager.go (1)
src/lib/config/config.go (1)
Manager(46-57)
src/server/v2.0/handler/project_metadata.go (2)
src/pkg/project/models/pro_meta.go (1)
ProMetaMaxUpstreamConn(28-28)src/lib/errors/const.go (1)
BadRequestCode(25-25)
src/pkg/project/models/project.go (1)
src/pkg/project/models/pro_meta.go (1)
ProMetaMaxUpstreamConn(28-28)
src/server/v2.0/handler/robot.go (2)
src/controller/robot/model.go (1)
Robot(40-47)src/lib/errors/const.go (1)
DENIED(39-39)
src/pkg/config/db/dao/dao.go (3)
src/lib/q/query.go (2)
Query(23-34)MustClone(54-71)src/lib/config/models/model.go (1)
ConfigEntry(60-64)src/lib/orm/query.go (1)
QuerySetter(75-109)
src/pkg/config/rest/rest.go (1)
src/pkg/config/store/driver.go (1)
Driver(21-28)
src/pkg/proxy/connection/limit_test.go (1)
src/pkg/proxy/connection/limit.go (1)
Limiter(31-31)
src/pkg/config/inmemory/manager.go (2)
src/pkg/config/rest/rest.go (1)
Driver(27-30)src/pkg/config/store/driver.go (1)
Driver(21-28)
src/pkg/config/manager_test.go (2)
src/pkg/config/manager.go (1)
CfgManager(35-37)src/pkg/config/store/store.go (1)
NewConfigStore(39-41)
src/core/main.go (4)
src/lib/log/logger.go (3)
Errorf(333-335)Warningf(323-325)Debugf(303-305)src/lib/config/config.go (1)
GetCfgManager(116-118)src/common/const.go (1)
SkipAuditLogDatabase(219-219)src/lib/config/userconfig.go (1)
SkipAuditLogDatabase(252-254)
src/server/v2.0/handler/project.go (3)
src/pkg/project/models/project.go (1)
Project(43-57)src/server/v2.0/handler/model/project.go (1)
Project(30-32)src/lib/errors/const.go (1)
BadRequestError(75-77)
src/server/middleware/repoproxy/proxy.go (4)
src/lib/redis/client.go (1)
GetHarborClient(64-89)src/lib/errors/errors.go (1)
NewErrs(130-132)src/lib/log/logger.go (2)
Debugf(303-305)Infof(313-315)src/pkg/proxy/connection/limit.go (1)
Limiter(31-31)
src/jobservice/job/impl/gc/garbage_collection.go (2)
src/lib/retry/retry.go (3)
Retry(104-166)Abort(49-51)Callback(87-91)src/pkg/registry/interceptor/readonly/interceptor.go (1)
Err(31-31)
src/pkg/config/store/store_test.go (1)
src/pkg/config/store/store.go (1)
ConfigStore(33-36)
src/server/v2.0/handler/project_metadata_test.go (1)
src/pkg/project/models/pro_meta.go (1)
ProMetaMaxUpstreamConn(28-28)
src/server/v2.0/handler/user.go (3)
src/common/rbac/const.go (4)
ActionUpdate(31-31)ResourceUser(70-70)ActionRead(30-30)ActionDelete(32-32)src/common/const.go (1)
DBAuth(23-23)src/lib/errors/const.go (1)
ForbiddenError(80-82)
src/pkg/config/db/db.go (1)
src/lib/q/query.go (1)
KeyWords(20-20)
src/pkg/reg/adapter/tencentcr/artifact_registry_test.go (1)
src/pkg/reg/model/policy.go (1)
FilterTypeName(22-22)
🪛 actionlint (1.7.8)
.github/workflows/build-package.yml
16-16: label "oracle-vm-24cpu-96gb-x86-64" is unknown. available labels are "windows-latest", "windows-latest-8-cores", "windows-2025", "windows-2022", "windows-11-arm", "ubuntu-latest", "ubuntu-latest-4-cores", "ubuntu-latest-8-cores", "ubuntu-latest-16-cores", "ubuntu-24.04", "ubuntu-24.04-arm", "ubuntu-22.04", "ubuntu-22.04-arm", "macos-latest", "macos-latest-xl", "macos-latest-xlarge", "macos-latest-large", "macos-26-xlarge", "macos-26", "macos-15-intel", "macos-15-xlarge", "macos-15-large", "macos-15", "macos-14-xl", "macos-14-xlarge", "macos-14-large", "macos-14", "macos-13-xl", "macos-13-xlarge", "macos-13-large", "macos-13", "self-hosted", "x64", "arm", "arm64", "linux", "macos", "windows". if it is a custom label for self-hosted runner, set list of labels in actionlint.yaml config file
(runner-label)
.github/workflows/publish_release.yml
10-10: label "oracle-vm-24cpu-96gb-x86-64" is unknown. available labels are "windows-latest", "windows-latest-8-cores", "windows-2025", "windows-2022", "windows-11-arm", "ubuntu-latest", "ubuntu-latest-4-cores", "ubuntu-latest-8-cores", "ubuntu-latest-16-cores", "ubuntu-24.04", "ubuntu-24.04-arm", "ubuntu-22.04", "ubuntu-22.04-arm", "macos-latest", "macos-latest-xl", "macos-latest-xlarge", "macos-latest-large", "macos-26-xlarge", "macos-26", "macos-15-intel", "macos-15-xlarge", "macos-15-large", "macos-15", "macos-14-xl", "macos-14-xlarge", "macos-14-large", "macos-14", "macos-13-xl", "macos-13-xlarge", "macos-13-large", "macos-13", "self-hosted", "x64", "arm", "arm64", "linux", "macos", "windows". if it is a custom label for self-hosted runner, set list of labels in actionlint.yaml config file
(runner-label)
.github/workflows/CI.yml
50-50: label "oracle-vm-24cpu-96gb-x86-64" is unknown. available labels are "windows-latest", "windows-latest-8-cores", "windows-2025", "windows-2022", "windows-11-arm", "ubuntu-latest", "ubuntu-latest-4-cores", "ubuntu-latest-8-cores", "ubuntu-latest-16-cores", "ubuntu-24.04", "ubuntu-24.04-arm", "ubuntu-22.04", "ubuntu-22.04-arm", "macos-latest", "macos-latest-xl", "macos-latest-xlarge", "macos-latest-large", "macos-26-xlarge", "macos-26", "macos-15-intel", "macos-15-xlarge", "macos-15-large", "macos-15", "macos-14-xl", "macos-14-xlarge", "macos-14-large", "macos-14", "macos-13-xl", "macos-13-xlarge", "macos-13-large", "macos-13", "self-hosted", "x64", "arm", "arm64", "linux", "macos", "windows". if it is a custom label for self-hosted runner, set list of labels in actionlint.yaml config file
(runner-label)
111-111: label "oracle-vm-24cpu-96gb-x86-64" is unknown. available labels are "windows-latest", "windows-latest-8-cores", "windows-2025", "windows-2022", "windows-11-arm", "ubuntu-latest", "ubuntu-latest-4-cores", "ubuntu-latest-8-cores", "ubuntu-latest-16-cores", "ubuntu-24.04", "ubuntu-24.04-arm", "ubuntu-22.04", "ubuntu-22.04-arm", "macos-latest", "macos-latest-xl", "macos-latest-xlarge", "macos-latest-large", "macos-26-xlarge", "macos-26", "macos-15-intel", "macos-15-xlarge", "macos-15-large", "macos-15", "macos-14-xl", "macos-14-xlarge", "macos-14-large", "macos-14", "macos-13-xl", "macos-13-xlarge", "macos-13-large", "macos-13", "self-hosted", "x64", "arm", "arm64", "linux", "macos", "windows". if it is a custom label for self-hosted runner, set list of labels in actionlint.yaml config file
(runner-label)
171-171: label "oracle-vm-24cpu-96gb-x86-64" is unknown. available labels are "windows-latest", "windows-latest-8-cores", "windows-2025", "windows-2022", "windows-11-arm", "ubuntu-latest", "ubuntu-latest-4-cores", "ubuntu-latest-8-cores", "ubuntu-latest-16-cores", "ubuntu-24.04", "ubuntu-24.04-arm", "ubuntu-22.04", "ubuntu-22.04-arm", "macos-latest", "macos-latest-xl", "macos-latest-xlarge", "macos-latest-large", "macos-26-xlarge", "macos-26", "macos-15-intel", "macos-15-xlarge", "macos-15-large", "macos-15", "macos-14-xl", "macos-14-xlarge", "macos-14-large", "macos-14", "macos-13-xl", "macos-13-xlarge", "macos-13-large", "macos-13", "self-hosted", "x64", "arm", "arm64", "linux", "macos", "windows". if it is a custom label for self-hosted runner, set list of labels in actionlint.yaml config file
(runner-label)
231-231: label "oracle-vm-24cpu-96gb-x86-64" is unknown. available labels are "windows-latest", "windows-latest-8-cores", "windows-2025", "windows-2022", "windows-11-arm", "ubuntu-latest", "ubuntu-latest-4-cores", "ubuntu-latest-8-cores", "ubuntu-latest-16-cores", "ubuntu-24.04", "ubuntu-24.04-arm", "ubuntu-22.04", "ubuntu-22.04-arm", "macos-latest", "macos-latest-xl", "macos-latest-xlarge", "macos-latest-large", "macos-26-xlarge", "macos-26", "macos-15-intel", "macos-15-xlarge", "macos-15-large", "macos-15", "macos-14-xl", "macos-14-xlarge", "macos-14-large", "macos-14", "macos-13-xl", "macos-13-xlarge", "macos-13-large", "macos-13", "self-hosted", "x64", "arm", "arm64", "linux", "macos", "windows". if it is a custom label for self-hosted runner, set list of labels in actionlint.yaml config file
(runner-label)
289-289: label "oracle-vm-24cpu-96gb-x86-64" is unknown. available labels are "windows-latest", "windows-latest-8-cores", "windows-2025", "windows-2022", "windows-11-arm", "ubuntu-latest", "ubuntu-latest-4-cores", "ubuntu-latest-8-cores", "ubuntu-latest-16-cores", "ubuntu-24.04", "ubuntu-24.04-arm", "ubuntu-22.04", "ubuntu-22.04-arm", "macos-latest", "macos-latest-xl", "macos-latest-xlarge", "macos-latest-large", "macos-26-xlarge", "macos-26", "macos-15-intel", "macos-15-xlarge", "macos-15-large", "macos-15", "macos-14-xl", "macos-14-xlarge", "macos-14-large", "macos-14", "macos-13-xl", "macos-13-xlarge", "macos-13-large", "macos-13", "self-hosted", "x64", "arm", "arm64", "linux", "macos", "windows". if it is a custom label for self-hosted runner, set list of labels in actionlint.yaml config file
(runner-label)
341-341: label "oracle-vm-24cpu-96gb-x86-64" is unknown. available labels are "windows-latest", "windows-latest-8-cores", "windows-2025", "windows-2022", "windows-11-arm", "ubuntu-latest", "ubuntu-latest-4-cores", "ubuntu-latest-8-cores", "ubuntu-latest-16-cores", "ubuntu-24.04", "ubuntu-24.04-arm", "ubuntu-22.04", "ubuntu-22.04-arm", "macos-latest", "macos-latest-xl", "macos-latest-xlarge", "macos-latest-large", "macos-26-xlarge", "macos-26", "macos-15-intel", "macos-15-xlarge", "macos-15-large", "macos-15", "macos-14-xl", "macos-14-xlarge", "macos-14-large", "macos-14", "macos-13-xl", "macos-13-xlarge", "macos-13-large", "macos-13", "self-hosted", "x64", "arm", "arm64", "linux", "macos", "windows". if it is a custom label for self-hosted runner, set list of labels in actionlint.yaml config file
(runner-label)
.github/workflows/conformance_test.yml
18-18: label "oracle-vm-24cpu-96gb-x86-64" is unknown. available labels are "windows-latest", "windows-latest-8-cores", "windows-2025", "windows-2022", "windows-11-arm", "ubuntu-latest", "ubuntu-latest-4-cores", "ubuntu-latest-8-cores", "ubuntu-latest-16-cores", "ubuntu-24.04", "ubuntu-24.04-arm", "ubuntu-22.04", "ubuntu-22.04-arm", "macos-latest", "macos-latest-xl", "macos-latest-xlarge", "macos-latest-large", "macos-26-xlarge", "macos-26", "macos-15-intel", "macos-15-xlarge", "macos-15-large", "macos-15", "macos-14-xl", "macos-14-xlarge", "macos-14-large", "macos-14", "macos-13-xl", "macos-13-xlarge", "macos-13-large", "macos-13", "self-hosted", "x64", "arm", "arm64", "linux", "macos", "windows". if it is a custom label for self-hosted runner, set list of labels in actionlint.yaml config file
(runner-label)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
- GitHub Check: cubic · AI code reviewer
- GitHub Check: CodeQL analysis (go)
🔇 Additional comments (64)
.github/dependabot.yml (1)
21-36: Multi-branch dependency management configuration looks good.The changes introduce separate Dependabot configurations for the
mainandrelease-2.14.0branches, enabling independent dependency updates on each. The labels (branch/mainandbranch/release-2.14.0) provide clear tracking for which branch each update targets. This is a standard and appropriate pattern for managing dependencies across multiple release branches.You may want to confirm that both Dependabot entries execute independently without conflicts. Verify this by monitoring the pull requests created for each branch over the next Dependabot run cycle.
.github/workflows/pass-CI.yml (1)
5-5: Good maintenance documentation for path synchronization.The comments documenting that paths should be kept in sync with
CI.ymlare helpful for preventing drift between workflow configurations. This is a solid maintainability improvement, especially for distributed configuration that's prone to becoming out-of-sync during future updates.To ensure accuracy, please verify that the path configuration in this file (lines 6–14 and 18–27) matches the inverse of the
paths-ignorerules inCI.yml. If they're now out of sync as part of this upstream sync, consider updating both files to maintain consistency.Also applies to: 17-17
tests/ci/ut_install.sh (1)
7-7: Verify downstream Go commands see the environment variable.Removing
sudofromgo env -w GO111MODULE=autoaligns with the subsequentgo installcommands on lines 14-16, which also run without elevated privileges. This ensures the environment variable is set in the user context where Go commands execute, rather than in the root environment.However, please verify that:
- The GO111MODULE setting is correctly propagated to the downstream
go installand other Go commands- The CI environment preserves this user-level environment variable across command invocations
- Any
makecommands that might depend on this variable (e.g., line 26'ssudo make go_check) can access it appropriatelysrc/common/secret/request.go (1)
34-36: LGTM! Clean modernization to usestrings.CutPrefix.This refactor simplifies the header parsing logic by replacing the previous
strings.HasPrefix+strings.TrimPrefixpattern with a singlestrings.CutPrefixcall. This is more idiomatic in modern Go (1.20+) and slightly more efficient since it performs the check and extraction in one pass.src/server/middleware/util/util.go (1)
44-50: Nice idiomatic improvement usingstrings.CutPrefix.Replacing
HasPrefix+TrimPrefixwith the atomicCutPrefixoperation is cleaner, more efficient, and follows modern Go idioms. The variable nameafterclearly conveys intent, and the logic remains correct. Verified that your project's Go version (1.24.6) fully supportsstrings.CutPrefix(available since Go 1.20).src/pkg/quota/dao/util.go (1)
114-115: LGTM! Clean refactor tostrings.CutPrefix.The replacement of the
strings.HasPrefix+ manual trimming pattern withstrings.CutPrefixis a good improvement. This approach is more idiomatic, more efficient (single string scan instead of two), and makes the intent clearer by combining the check and extraction in one operation..github/workflows/housekeeping-stale-issues-prs.yaml (1)
10-10: No action required—actions/[email protected]is fully compatible with this workflow.The breaking changes in v10.0.0 (Node.js 24 runtime and runner v2.327.1+ requirement) are automatically satisfied since this workflow uses
ubuntu-latest, which is a GitHub-hosted runner maintained by GitHub with automatic updates. All configuration parameters remain compatible between v9.1.0 and v10.0.0.tests/resources/TestCaseBody.robot (1)
587-588: LGTM!The usage of
Remove Portcorrectly sanitizes the IP address before using it asharbor_hostnamein the webhook payload. The temporary variable${cleaned_ip}appropriately stores the cleaned value, and the conditional logic based onpayload_formatis correct.src/core/main.go (2)
25-25: LGTM! Imports are appropriate for the new functionality.The
strconvimport is used for parsing the boolean environment variable, and thecommonimport provides theSkipAuditLogDatabaseconstant.Also applies to: 32-32
227-230: LGTM! Appropriate placement and error handling for initialization.The call to
initSkipAuditDBbyEnvis correctly positioned after the admin password update and before API initialization. Logging the error without halting startup is reasonable for this initialization step.make/migrations/postgresql/0180_2.15.0_schema.up.sql (1)
1-17: LGTM! Migration logic correctly preserves existing behavior.The migration is idempotent and intelligently handles backward compatibility:
- For existing deployments with audit log usage (sequences > 1), it sets the flag to
'false'to preserve the current behavior of writing audit logs to the database.- For new deployments with no prior usage, it defers to the environment variable control implemented in the Go initialization code.
- The early return when the key already exists ensures the migration can be safely re-run.
This approach provides a smooth upgrade path while allowing new deployments to opt out of database audit logging via environment variables.
src/jobservice/migration/manager_test.go (2)
144-145: Comment accurately reflects the method behavior.The updated comment correctly describes that
TearDownTestruns after each test case, which properly pairs withSetupTestfor complete test isolation.
61-62: Verified: Correct testify lifecycle method usage with no other issues in codebase.The rename from
SetupTestSuitetoSetupTestis correct.SetupTestSuiteis not a recognized testify lifecycle method, so this change ensures the setup code actually runs before each test case. The fix provides proper test isolation—each test receives fresh mock Redis data, paired withTearDownTestfor cleanup. Verification confirms no other occurrences of the incorrectSetupTestSuiteorTearDownTestSuitepatterns exist in the codebase.src/controller/registry/controller.go (1)
217-222: Go version requirement verified; no issues found.The code change is correct. go.mod specifies
go 1.24.6, which fully supportsstrings.SplitSeqintroduced in Go 1.24. The iterator pattern at line 217 is consistent across the codebase (15+ files use the same pattern identically), confirming this is a deliberate, codebase-wide modernization. No compatibility issues exist.src/pkg/reg/adapter/tencentcr/artifact_registry_test.go (2)
27-58: Excellent test coverage for filterToPatterns.The new test cases comprehensively cover different scenarios: multiple filters with both name and tag types, single name filter, and empty filters. This provides good confidence in the parsing logic.
166-186: Verify intentional error message divergence between mock and production.The core parsing and delegation logic is aligned, but the mock's error message differs from production. Production:
"tcr only support repo in format <namespace>/<name>, but got: %s"vs. mock:"invalid repository format: %s". Additionally, production includes alog.Warningf()call before callingdeleteImage(), which the mock omits. Confirm this divergence is intentional or align the implementations.src/go.mod (3)
22-22: Verify the go-asn1-ber pseudo-version is intentional.Line 22 specifies a very specific pseudo-version:
v1.5.8-0.20250403174932-29230038a667. This appears to be a commit-specific pin rather than a stable release. Confirm whether this is an intentional version pin (e.g., for a bug fix or security patch ahead of an upstream release) or if this should reference a stable release tag instead.
60-60: Verify OpenTelemetry package version alignment.The OpenTelemetry instrumentation package
go.opentelemetry.io/contrib/instrumentation/github.com/gorilla/mux/otelmuxis pinned to v0.63.0 (line 60), while core OTel packages have been updated to v1.38.0 (lines 62, 65, 66, and indirect 175). Verify that this version combination is compatible and tested. If the instrumentation package has a corresponding v0.63.0 release that works with OTel v1.38.0, ensure the version pairs are aligned and that no compatibility issues arise at runtime.Also applies to: 62-62, 65-65, 66-66, 175-175
59-59: Verify volcengine-go-sdk changelog for breaking changes.The volcengine-go-sdk has been updated from v1.1.29 to v1.1.44, a jump of 15 patch versions. Review the upstream changelog for any potential breaking changes, behavior modifications, or deprecations that could affect Harbor's Volcano engine integration.
VERSION (1)
1-1: LGTM - Version bump to v2.15.0.The version bump aligns with the PR objective of syncing with upstream.
.github/release.yml (1)
34-37: LGTM - Good addition of bump-version category.Adding a dedicated changelog category for version bumps improves release note organization and clarity.
src/common/api/base.go (2)
24-24: LGTM - Required import for strings.Builder.The strings package import supports the refactoring in the Validate function.
102-106: LGTM - Efficient string concatenation using strings.Builder.The refactoring from repeated string concatenation to strings.Builder improves performance when assembling validation error messages, especially when multiple validation errors exist.
.github/workflows/build-package.yml (2)
16-16: Coordinated infrastructure update to Oracle VM runner.The migration to a self-hosted Oracle VM runner is consistent across multiple workflow files in this PR. The static analysis warning about the unknown runner label is expected for custom self-hosted runners.
To suppress the static analysis warning, ensure an
actionlint.yamlconfig file exists at the repository root with the custom runner label defined:self-hosted-runner: labels: - oracle-vm-24cpu-96gb-x86-64
19-19: LGTM - AWS credentials action upgrade.Upgrading to v5.0.0 of the AWS credentials action aligns with the coordinated tooling updates across workflow files.
.github/workflows/publish_release.yml (1)
10-10: LGTM - Consistent infrastructure and tooling updates.The runner migration and AWS action upgrade are consistent with the coordinated changes across all workflow files in this PR.
Also applies to: 23-23
.github/workflows/conformance_test.yml (1)
18-18: LGTM - Infrastructure alignment complete.The runner and action updates complete the coordinated infrastructure migration across all CI workflows.
Also applies to: 21-21
src/pkg/task/dao/execution.go (1)
415-450: LGTM - Efficient SQL construction with strings.Builder.The refactoring to use
strings.Builderfor constructing the SQL WHERE clause is more efficient than repeated string concatenation, especially when processing multiplejsonbStrusentries in the loop.src/pkg/cached/manager.go (1)
78-79: LGTM: Efficient string building initialization.The refactor from string concatenation to
strings.Builderreduces memory allocations and improves performance, especially when building cache keys with multiple segments.src/lib/q/builder.go (1)
88-90: LGTM: Efficient prefix handling withstrings.CutPrefix.The replacement of
strings.HasPrefix+strings.TrimPrefixwithstrings.CutPrefixis more efficient (single pass instead of two) and cleaner. This is a good modernization that maintains identical behavior.src/lib/config/config.go (1)
51-51: LGTM: Interface extension for driver-level config retrieval.The new
GetItemFromDrivermethod extends the Manager interface to support direct driver-level retrieval of configuration items. Based on the PR context, implementations are provided insrc/pkg/config/manager.goand corresponding mocks/tests are updated.README.md (1)
2-10: LGTM: Badge updates reflect infrastructure changes.The badge updates align with the CI/infrastructure modernization mentioned in the PR summary. The links and labels are appropriate.
src/pkg/config/db/dao/dao.go (2)
34-35: LGTM: Query-based config retrieval added to DAO.The new
GetConfigItemmethod provides flexible, query-based retrieval of configuration entries, complementing the existingGetConfigEntriesmethod.
92-104: LGTM: Clean implementation with defensive query cloning.The implementation correctly:
- Clones the query to prevent mutation
- Uses the ORM QuerySetter for flexible filtering
- Handles errors appropriately
- Returns results in the expected format
src/server/v2.0/handler/user_test.go (2)
65-66: LGTM: Proper suite setup initialization.Adding the call to
uts.Suite.SetupSuite()ensures the parent test suite is properly initialized, following best practices for testify suites.
79-87: LGTM: Username mocks support authorization testing.The mock
GetUsernamecalls provide the necessary context for testing username-based authorization checks introduced in the handler. The values align with the test scenarios:
- "testuser" for the unauthorized case (user ID 2)
- "admin" for the authorized case (user ID 1)
src/testing/lib/config/manager.go (1)
79-107: LGTM: Auto-generated mock for the new interface method.The mock implementation for
GetItemFromDriverfollows standard mockery patterns and correctly supports the new interface method. As this is auto-generated code, it's consistent with the tooling conventions.src/pkg/config/db/db.go (2)
89-90: LGTM: Method signature aligns with driver interface.The new
Getmethod provides driver-level retrieval of config items by key, implementing the expected signature for the config store driver interface.
91-102: Verify: Raw encrypted data returned without decryption.Unlike the
Loadmethod (lines 36-61), thisGetimplementation returns raw database values without:
- Decrypting password fields
- Checking metadata scope restrictions
- Filtering system-scope settings
This appears intentional for driver-level access based on the method name, but please confirm that returning encrypted passwords and system settings is the expected behavior for this interface.
If raw access is unintentional, consider applying the same transformations as
Load:func (d *Database) Get(ctx context.Context, key string) (map[string]any, error) { resultMap := map[string]any{} configEntries, err := d.cfgDAO.GetConfigItem(ctx, q.New(q.KeyWords{"k": key})) if err != nil { log.Debugf("get config db error: %v", err) return resultMap, err } // convert to map if there's any record for _, item := range configEntries { + itemMetadata, ok := metadata.Instance().GetByName(item.Key) + if !ok { + log.Debugf("failed to get metadata, key:%v, skip item", item.Key) + continue + } + // Decrypt passwords if needed + if _, ok := itemMetadata.ItemType.(*metadata.PasswordType); ok { + if decryptPassword, err := encrypt.Instance().Decrypt(item.Value); err == nil { + item.Value = decryptPassword + } else { + log.Errorf("decrypt password failed, key: %s, error %v", item.Key, err) + } + } resultMap[item.Key] = item.Value } return resultMap, nil }.github/workflows/CI.yml (3)
18-30: Path-ignore patterns correctly re-include test resources.The negation patterns (
!tests/resources/**,!tests/robot-cases/**) ensure that changes to test resources and robot test cases trigger CI runs, even though the parenttests/**directory is ignored. This is the correct approach for selectively including critical test paths.Also applies to: 32-42
50-50: ****The original comment assumes actionlint is flagging
oracle-vm-24cpu-96gb-x86-64as an unknown runner label and recommends configuring actionlint.yaml. However, actionlint is not configured or used anywhere in this repository. There are no actionlint configuration files, no actionlint action references in workflows, and no actionlint invocations. The suggested fix to create actionlint.yaml would not address any actual issue since the linting tool is not running.Likely an incorrect or invalid review comment.
54-54: Verify GitHub Actions v5 migration compatibility and configuration changes.Web search confirms breaking changes across the upgraded actions:
- setup-node@v5: Automatic package-manager caching now enabled by default (disable with
package-manager-cache: falseif it conflicts).- codecov-action@v5: Migrated to Codecov Wrapper with input changes—inputs renamed (
file→files,plugin→plugins) and tokenless-upload behavior modified. Verify all codecov inputs match v5 expectations.- actions/upload-artifact@v5: Enforces immutable archives and disallows multiple uploads to the same artifact name. Confirm your workflow doesn't depend on these v4 behaviors.
- checkout@v5, setup-go@v5: Runtime upgraded to Node 24; verify your runners meet v2.327.1+ requirement.
Review the migration notes for each action and test the workflow in a non-production environment to confirm no breaking changes affect your CI pipeline.
src/portal/src/app/base/project/project-config/project-policy-config/project.ts (1)
39-39: New proxy-cache metadata field aligns with existing patterns.The
max_upstream_connfield follows the same optional nullable pattern asproxy_speed_kb(line 38), which is appropriate for proxy-cache configuration. The AI summary indicates this field is initialized to-1in the constructor of a related component, representing unlimited connections.src/portal/src/app/base/project/project.ts (2)
39-39: Consistent proxy-cache connection limit metadata.The required
max_upstream_connfield complements the optional version inproject-policy-config/project.ts. The required type here ensures all Project instances have a default value, while the policy config version allows optional overrides.
44-44: Default value follows unlimited connection convention.Initializing
max_upstream_connto-1follows the same pattern asproxy_speed_kb(line 49) and conventionally represents unlimited connections. This is consistent with the PR's upstream connection limiting feature for proxy-cache projects.src/controller/gc/controller_test.go (2)
42-46: Test coverage for tag deletion GC feature.The addition of
DeleteTag: trueprovides test coverage for the new garbage collection feature that removes tag files from backend storage, as mentioned in the PR summary. This complements the existingDeleteUntaggedfunctionality.
151-156: Consistent test coverage across GC operations.The
DeleteTagflag is consistently tested in bothStartandCreateSchedulescenarios, ensuring comprehensive coverage of the new tag file deletion feature across different GC execution paths.src/portal/src/i18n/lang/ko-kr-lang.json (1)
274-274: Korean translation for NO_PROJECT is appropriate.The translation "프로젝트를 찾을 수 없습니다" correctly conveys "No project found" in Korean.
src/portal/src/i18n/lang/es-es-lang.json (1)
275-275: Spanish translation for NO_PROJECT is correct.The translation "No pudimos encontrar ningún proyecto" appropriately conveys "We couldn't find any project" in Spanish.
src/pkg/config/inmemory/manager.go (1)
58-61: No issues found with theGet()stub implementation.The in-memory driver is exclusively test infrastructure (explicitly registered in
src/pkg/config/inmemory/manager.go:30and documented as "for unit testing"). Production code uses the DB-based driver. TheGet()method stub returningErrUnsupportedis appropriate and prevents silent failures in the unlikely event the method is called during testing. No production code paths are affected.src/pkg/config/manager.go (1)
183-186: LGTM! Clean delegation pattern.The new method properly delegates to the store layer, maintaining separation of concerns. The implementation is consistent with other methods in this file.
src/portal/src/app/base/left-side-nav/clearing-job/gc-page/gc/gc.component.html (1)
116-133: LGTM! Consistent UI pattern.The new delete tag toggle follows the same structure and styling as the existing delete untagged toggle, maintaining UI consistency.
src/pkg/project/models/pro_meta.go (1)
28-28: LGTM! Constant follows established patterns.The new constant is properly named and positioned within the existing const block, maintaining consistency with other project metadata keys.
src/pkg/config/db/cache.go (1)
64-67: LGTM! Clean delegation to driver layer.The new Get method appropriately delegates to the underlying driver, maintaining the cache's role as a transparent wrapper.
src/server/v2.0/handler/gc.go (2)
103-105: LGTM! Consistent parameter handling.The
delete_tagparameter extraction follows the established pattern used fordelete_untaggedanddry_run, maintaining consistency in the GC scheduling flow.
130-132: LGTM! Consistent parameter handling.The
delete_tagparameter extraction in the scheduled GC branch mirrors the manual GC implementation, ensuring consistent behavior across execution modes.src/portal/src/app/base/project/project-config/project-policy-config/project-policy-config.component.html (1)
95-123: LGTM! Well-structured UI control.The new connection limit input follows the established pattern used for the bandwidth control, including proper error handling, translation support, and disable state management.
src/pkg/config/store/store.go (1)
54-64: LGTM! Proper error handling.The new method includes appropriate validation of the driver before delegation and handles errors correctly. The implementation is consistent with existing methods like
LoadandSave.src/portal/src/i18n/lang/zh-cn-lang.json (1)
1353-1353: Chinese translation for DELETE_TAG is correctly localized.The translation "允许垃圾回收移除后端存储中的Tag文件" properly conveys the intent of the garbage collection feature to delete tag files from backend storage.
src/server/v2.0/handler/robot.go (2)
88-94: LGTM! Robust security validation for robot creation.The added nil-check prevents potential null pointer exceptions, and the permission scope validation correctly ensures that a robot can only create other robots with equal or more restrictive permissions. The error messages are clear and include helpful debugging information.
446-483: LGTM! Correct implementation of permission subset validation.The function properly validates that robot permissions form a subset of the creator's permissions. The wildcard namespace handling and access-level validation logic are both correct.
src/portal/src/i18n/lang/en-us-lang.json (2)
274-277: LGTM! Clear and helpful translation strings.The new translation keys for proxy cache connection limits are well-written and provide good user guidance.
1357-1357: LGTM! Clear translation for GC tag deletion feature.The translation accurately describes the garbage collection tag deletion functionality.
src/jobservice/job/impl/gc/garbage_collection.go (1)
134-139: Parameter parse and logging for delete_tag look goodDefault true, boolean assertion guarded, and included in the parameter log. LGTM.
Also applies to: 169-171
| k8s.io/api v0.34.1 | ||
| k8s.io/apimachinery v0.34.1 | ||
| k8s.io/client-go v0.34.1 | ||
| sigs.k8s.io/yaml v1.6.0 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧩 Analysis chain
Verify Kubernetes client compatibility with v0.34.1.
The Kubernetes packages have been updated from v0.33.x to v0.34.1, which is a minor version bump that may introduce breaking changes or API deprecations. Ensure that Harbor's Kubernetes integration code (RBAC, policy engine, admission webhooks, etc.) is fully compatible with the new version.
🏁 Script executed:
#!/bin/bash
# Search for Kubernetes client usage patterns in the codebase to identify potential compatibility issues
rg -n --type=go -C2 'k8s\.io/(api|client-go|apimachinery)' src/ | head -100Length of output: 1674
---
🌐 Web query:
```web
Kubernetes v0.34.1 release notes breaking changes
```
💡 Result:
Do you mean Kubernetes core (kubernetes/kubernetes) or a specific project (e.g., ingress-nginx, client libraries, minikube, helm)? For example, ingress-nginx has a controller release v0.34.1 — I can fetch its breaking changes if that’s the one. Which project should I look up?
---
🌐 Web query:
```web
Kubernetes authentication v1beta1 API deprecations v0.34
```
💡 Result:
Short answer: authentication.k8s.io/v1beta1 (TokenReview and related types) was deprecated and removed — migrate to authentication.k8s.io/v1. See Kubernetes deprecation guide and authentication docs. [1][2]
Details & action items:
- What changed: authentication.k8s.io/v1beta1 TokenReview is no longer served (removed as of Kubernetes v1.22). Use authentication.k8s.io/v1 instead. [1]
- Migration notes: v1 has the same TokenReview shape; update clients/controllers/webhooks to call authentication.k8s.io/v1. To have the API server send v1 TokenReview to webhooks, start kube-apiserver with --authentication-token-webhook-version=v1. [2]
Sources:
- Kubernetes Deprecated API Migration Guide (TokenReview removal v1.22). [1]
- Kubernetes Authentication docs (TokenReview examples and --authentication-token-webhook-version flag). [2]
---
</parameter>
</invoke>
---
🏁 Script executed:
```shell
#!/bin/bash
# Check if Harbor code already uses authentication v1 API
rg -n --type=go 'k8s\.io/api/authentication/v1' src/
```
Length of output: 320
---
🌐 Web query:
```web
k8s.io/api client library version numbering scheme
```
💡 Result:
Short answer — there are two related but different versioning schemes to be aware of:
- k8s.io/api package directories (e.g. k8s.io/api/apps/v1, …/v1beta1, …/v1alpha1) follow Kubernetes API group-version semantics: the directory name is the API group version (v1, v1beta1, v1alpha1, etc.), which indicates stability/promotion stage and is the version stamped on Kubernetes objects. Use the package matching the API server’s supported group/version. [1]
- k8s client libraries (client-go, k8s.io/client-go etc.) use module/semver-style tags for the Go module. Historically client-go published v0.x.y tags (and pseudo‑versions) and its tags are not a direct 1:1 mapping to Kubernetes release numbers; client-go follows semantic versioning for its module releases (with branch/tag rules described in the client-go docs/README). In short: object API versions = folder names (v1, v1beta1, …); client library/module versions = semver tags for the Go module (client-go). [2]
Sources:
[1] k8s.io/api package listing (shows v1, v1beta1, v1alpha1 packages).
[2] kubernetes/client-go versioning notes (client-go README/blog describing tag/branch and semver behavior).
---
</parameter>
</invoke>
---
🌐 Web query:
```web
kubernetes client-go v0.34.1 Kubernetes version
```
💡 Result:
client-go v0.34.1 corresponds to the Kubernetes 1.34.x release series (client-go v0.34.x targets Kubernetes v1.34). [1]
Sources:
[1] kubernetes/client-go README (compatibility matrix).
---
🌐 Web query:
```web
kubernetes authentication.k8s.io v1beta1 removal timeline versions
```
💡 Result:
Short answer:
- authentication.k8s.io/v1beta1 was deprecated in Kubernetes v1.19 (released Aug 26, 2020). [1]
- It was removed (stopped being served) in Kubernetes v1.22 (released Aug 4, 2021). [2]
Sources:
- Kubernetes v1.19 release announcement (deprecations). [1]
- Kubernetes blog: API removals in v1.22 (lists authentication.k8s.io/v1beta1 removal). [2]
---
</details>
**Migrate Kubernetes authentication API from v1beta1 to v1—current imports are incompatible with Kubernetes 1.34.**
The k8s.io/api v0.34.1 corresponds to Kubernetes 1.34.x, and authentication.k8s.io/v1beta1 was removed (stopped being served) in Kubernetes v1.22. Harbor's authentication proxy code currently uses only v1beta1 at four locations:
- src/pkg/authproxy/http.go:22
- src/pkg/authproxy/http_test.go:8
- src/server/middleware/security/auth_proxy_test.go:28
- src/core/auth/authproxy/test/server.go:26
Update all imports from `k8s.io/api/authentication/v1beta1` to `k8s.io/api/authentication/v1` before merging. The TokenReview API shape remains the same, so only the import paths and type references need to change.
<details>
<summary>🤖 Prompt for AI Agents</summary>
```
In src/go.mod around lines 78 to 81 and in the four listed source files, the
project still references the removed Kubernetes authentication/v1beta1 API;
update imports from "k8s.io/api/authentication/v1beta1" to
"k8s.io/api/authentication/v1" in these files: src/pkg/authproxy/http.go,
src/pkg/authproxy/http_test.go,
src/server/middleware/security/auth_proxy_test.go,
src/core/auth/authproxy/test/server.go, and adjust any package aliases or type
references accordingly (e.g., authenticationv1beta1.TokenReview ->
authenticationv1.TokenReview or the alias you use) so code compiles against
k8s.io/api v0.34.1.
```
</details>
<!-- This is an auto-generated comment by CodeRabbit -->
| // Get - get config item from config driver | ||
| Get(ctx context.Context, key string) (map[string]any, error) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧩 Analysis chain
Verify all Driver implementations include the new Get method.
The addition of the Get method to the Driver interface is a breaking change that requires all implementations to be updated. According to the AI summary, implementations exist in src/pkg/config/db/cache.go, src/pkg/config/store/store.go, and src/pkg/config/rest/rest.go.
Run the following script to confirm all Driver implementations have been updated with the Get method:
🏁 Script executed:
#!/bin/bash
# Find all types that might implement the Driver interface
ast-grep --pattern $'type $_ struct {
$$$
}
func ($_ *$TYPE) Load($$$) $$$
func ($_ *$TYPE) Save($$$) $$$'
# Search for Get method implementations on potential Driver types
rg -nP --type=go -A3 'func \([^)]+\) Get\(ctx context\.Context, key string\) \(map\[string\]any, error\)'Length of output: 1179
I need to search the codebase directly for the Store and REST implementations mentioned in the review comment.
[/run_scripts]
🏁 Script executed:
#!/bin/bash
# Check if store.go exists and what types it contains
find . -name "store.go" -type f | head -20
# Check if rest.go exists
find . -name "rest.go" -type f | head -20
# Search for Store type definition with Load/Save methods
rg -nP --type=go 'type\s+Store\s+struct' -A 5
# Search for REST type definition with Load/Save methods
rg -nP --type=go 'type\s+REST\s+struct' -A 5Length of output: 692
I need to check the contents of the store.go and rest.go files to verify they have Get method implementations.
[/run_scripts]
🏁 Script executed:
#!/bin/bash
# Check Store implementation in store.go
cat ./src/pkg/config/store/store.go
echo "---"
# Check REST implementation in rest.go
cat ./src/pkg/config/rest/rest.goLength of output: 7101
I need to verify the Driver interface definition and confirm all implementations.
[/run_scripts]
🏁 Script executed:
#!/bin/bash
# Show the Driver interface definition
cat ./src/pkg/config/store/driver.goLength of output: 1087
rest.go Driver implementation does not implement the Get method—it only has a TODO stub returning an error.
The review comment is partially incorrect. While cache.go and the unmentioned db.go properly implement all Driver methods including Get, the rest.go Driver has Get as an unimplemented stub that returns errors.ErrUnsupported. Additionally, the review comment incorrectly identifies store.go as containing a Driver implementation; store.go contains ConfigStore, which is a wrapper that delegates to a Driver, not a Driver implementation itself.
The missing db.go Database type is an actual Driver implementation with a complete Get method.
Fix required: Implement the Get method in rest.go's Driver type (currently lines ~35-37 showing only return nil, errors.ErrUnsupported).
🤖 Prompt for AI Agents
In src/pkg/config/store/driver.go around lines 26-27 and specifically in rest.go
where Driver.Get is currently a TODO stub returning errors.ErrUnsupported
(roughly lines ~35-37), implement the method: perform the HTTP request using the
Driver's REST client and provided context to fetch the key, handle non-2xx
responses by returning a descriptive error, decode the JSON response body into a
map[string]any, close the response body, and return the map and nil error on
success; ensure timeouts/cancellation respect ctx and propagate any
request/decoding errors.
| ctx := context.Background() | ||
| rdb := redis.NewClient(&redis.Options{ | ||
| Addr: fmt.Sprintf("%s:6379", redisHost), // Redis server address | ||
| Password: "", // No password set | ||
| DB: 0, // Use default DB | ||
| }) | ||
| key := "test_max_connection_key" | ||
| maxConn := 10 | ||
| for range 10 { | ||
| result := Limiter.Acquire(ctx, rdb, key, maxConn) | ||
| assert.True(t, result) | ||
| } | ||
| // after max connection reached, it should be false | ||
| result2 := Limiter.Acquire(ctx, rdb, key, maxConn) | ||
| assert.False(t, result2) | ||
|
|
||
| for range 10 { | ||
| Limiter.Release(ctx, rdb, key) | ||
| } | ||
|
|
||
| // connection in redis should be 0 finally | ||
| n, err := rdb.Get(ctx, key).Int() | ||
| assert.Nil(t, err) | ||
| assert.Equal(t, 0, n) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Avoid hard dependency on a live Redis daemon
This test talks to a real Redis at ${REDIS_HOST}:6379; in CI or local dev without Redis it will fail immediately, even though the limiter logic might be correct. Please either spin up an embedded test server (e.g. miniredis) or skip the test when the connection can’t be established so the suite remains self-contained.
| for range 10 { | ||
| result := Limiter.Acquire(ctx, rdb, key, maxConn) | ||
| assert.True(t, result) | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Replace Go 1.22-only for range syntax
for range 10 requires the module go directive to be ≥1.22; the tree still targets Go 1.21, so this won’t even compile. Please switch to a conventional counter loop (e.g. for i := 0; i < maxConn; i++) to keep builds working.
- for range 10 {
+ for i := 0; i < maxConn; i++ {
result := Limiter.Acquire(ctx, rdb, key, maxConn)
assert.True(t, result)
}
@@
- for range 10 {
+ for i := 0; i < maxConn; i++ {
Limiter.Release(ctx, rdb, key)
}📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| for range 10 { | |
| result := Limiter.Acquire(ctx, rdb, key, maxConn) | |
| assert.True(t, result) | |
| } | |
| for i := 0; i < maxConn; i++ { | |
| result := Limiter.Acquire(ctx, rdb, key, maxConn) | |
| assert.True(t, result) | |
| } |
🤖 Prompt for AI Agents
In src/pkg/proxy/connection/limit_test.go around lines 42 to 45, replace the Go
1.22-only `for range 10` construct with a conventional counter loop that
iterates maxConn times: create an index initialized to zero, loop while the
index is less than maxConn, increment the index each iteration, and keep the
body of the loop (calling Limiter.Acquire and asserting the result) unchanged so
the test compiles with Go 1.21.
| func (c *ConnLimiter) Acquire(ctx context.Context, rdb *redis.Client, key string, limit int) bool { | ||
| result, err := acquireScript.Run(ctx, rdb, []string{key}, fmt.Sprintf("%v", limit)).Int() | ||
| if err != nil { | ||
| log.Errorf("failed to get the connection lock in redis, error %v", err) | ||
| return false | ||
| } | ||
| log.Debugf("Acquire script result is %d", result) | ||
| return result == 1 | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Propagate Redis script errors instead of returning false
By returning only false, callers can’t distinguish “limit exceeded” from “Redis command failed”, which leads to spurious 429 responses and broken proxying when Redis hiccups. Please return (bool, error) (or similar) so callers can log and bypass the limiter on Redis failures.
-func (c *ConnLimiter) Acquire(ctx context.Context, rdb *redis.Client, key string, limit int) bool {
- result, err := acquireScript.Run(ctx, rdb, []string{key}, fmt.Sprintf("%v", limit)).Int()
- if err != nil {
- log.Errorf("failed to get the connection lock in redis, error %v", err)
- return false
- }
- log.Debugf("Acquire script result is %d", result)
- return result == 1
+func (c *ConnLimiter) Acquire(ctx context.Context, rdb *redis.Client, key string, limit int) (bool, error) {
+ result, err := acquireScript.Run(ctx, rdb, []string{key}, fmt.Sprintf("%v", limit)).Int()
+ if err != nil {
+ return false, fmt.Errorf("redis acquire script failed: %w", err)
+ }
+ log.Debugf("Acquire script result is %d", result)
+ return result == 1, nil
}📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| func (c *ConnLimiter) Acquire(ctx context.Context, rdb *redis.Client, key string, limit int) bool { | |
| result, err := acquireScript.Run(ctx, rdb, []string{key}, fmt.Sprintf("%v", limit)).Int() | |
| if err != nil { | |
| log.Errorf("failed to get the connection lock in redis, error %v", err) | |
| return false | |
| } | |
| log.Debugf("Acquire script result is %d", result) | |
| return result == 1 | |
| } | |
| func (c *ConnLimiter) Acquire(ctx context.Context, rdb *redis.Client, key string, limit int) (bool, error) { | |
| result, err := acquireScript.Run(ctx, rdb, []string{key}, fmt.Sprintf("%v", limit)).Int() | |
| if err != nil { | |
| return false, fmt.Errorf("redis acquire script failed: %w", err) | |
| } | |
| log.Debugf("Acquire script result is %d", result) | |
| return result == 1, nil | |
| } |
🤖 Prompt for AI Agents
In src/pkg/proxy/connection/limit.go around lines 53 to 61, the Acquire function
swallows Redis script errors and only returns false, making callers unable to
tell a Redis failure from a real "limit exceeded" result; change the function
signature to return (bool, error), propagate and return the Redis error when
acquireScript.Run fails (instead of logging and returning false), keep logging
the error with context (or let the caller decide) and return (false, err); on
success return (result == 1, nil). Also update all call sites to handle the
(bool, error) response and bypass the limiter or log appropriately when error !=
nil.
| "NO_PROJECT": "We couldn't find any projects", | ||
| "CONNECTION_LIMIT": "Max connection to upstream registry", | ||
| "PROXY_CACHE_MAX_UPSTREAM_CONN_TIP": "The max connection to the upstream registry for this proxy cache project, if -1, then there is no limit", | ||
| "PROXY_CACHE_MAX_UPSTREAM_CONN_INPUT_TIP": "Please enter -1 or an integer greater than 0. " | ||
| }, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Localize added Turkish strings and trim trailing spaces
These entries are English; translate to TR and remove the trailing space.
- "NO_PROJECT": "We couldn't find any projects",
- "CONNECTION_LIMIT": "Max connection to upstream registry",
- "PROXY_CACHE_MAX_UPSTREAM_CONN_TIP": "The max connection to the upstream registry for this proxy cache project, if -1, then there is no limit",
- "PROXY_CACHE_MAX_UPSTREAM_CONN_INPUT_TIP": "Please enter -1 or an integer greater than 0. "
+ "NO_PROJECT": "Herhangi bir proje bulamadık",
+ "CONNECTION_LIMIT": "Üst (upstream) kayıt defterine en fazla bağlantı sayısı",
+ "PROXY_CACHE_MAX_UPSTREAM_CONN_TIP": "Bu proxy önbellek projesi için üst kayıt defterine izin verilen en fazla bağlantı sayısı; sınırsız için -1 girin",
+ "PROXY_CACHE_MAX_UPSTREAM_CONN_INPUT_TIP": "Lütfen -1 veya 0'dan büyük bir tam sayı girin."📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| "NO_PROJECT": "We couldn't find any projects", | |
| "CONNECTION_LIMIT": "Max connection to upstream registry", | |
| "PROXY_CACHE_MAX_UPSTREAM_CONN_TIP": "The max connection to the upstream registry for this proxy cache project, if -1, then there is no limit", | |
| "PROXY_CACHE_MAX_UPSTREAM_CONN_INPUT_TIP": "Please enter -1 or an integer greater than 0. " | |
| }, | |
| "NO_PROJECT": "Herhangi bir proje bulamadık", | |
| "CONNECTION_LIMIT": "Üst (upstream) kayıt defterine en fazla bağlantı sayısı", | |
| "PROXY_CACHE_MAX_UPSTREAM_CONN_TIP": "Bu proxy önbellek projesi için üst kayıt defterine izin verilen en fazla bağlantı sayısı; sınırsız için -1 girin", | |
| "PROXY_CACHE_MAX_UPSTREAM_CONN_INPUT_TIP": "Lütfen -1 veya 0'dan büyük bir tam sayı girin." | |
| }, |
| "MSG_SCHEDULE_RESET": "Çöp Toplama programı sıfırlandı", | ||
| "PARAMETERS": "Parameters", | ||
| "DELETE_UNTAGGED": "Allow garbage collection on untagged artifacts", | ||
| "DELETE_TAG": "Allow garbage collection to remove tag files from backend storage", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Translate GC delete_tag label to Turkish
Keep locale consistent; avoid English.
- "DELETE_TAG": "Allow garbage collection to remove tag files from backend storage",
+ "DELETE_TAG": "Çöp toplamaya, etiket dosyalarını arka uç depolamadan kaldırma izni ver",📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| "DELETE_TAG": "Allow garbage collection to remove tag files from backend storage", | |
| "DELETE_TAG": "Çöp toplamaya, etiket dosyalarını arka uç depolamadan kaldırma izni ver", |
🤖 Prompt for AI Agents
In src/portal/src/i18n/lang/tr-tr-lang.json around line 1355, the key
"DELETE_TAG" value is still in English; replace the English phrase with an
appropriate Turkish translation (keeping locale style consistent with other
entries). Update the value to a concise Turkish string that conveys "Allow
garbage collection to remove tag files from backend storage" (for example: "Çöp
toplama işleminin arka uç depolamadaki etiket dosyalarını silmesine izin ver")
and ensure proper JSON escaping/formatting.
| "CONNECTION_LIMIT": "Max connection to upstream registry", | ||
| "PROXY_CACHE_MAX_UPSTREAM_CONN_TIP": "The max connection to the upstream registry for this proxy cache project, if less than 0, then there is no limit", | ||
| "PROXY_CACHE_MAX_UPSTREAM_CONN_INPUT_TIP": "请输入-1或者大于0的整数" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Translate English content to Chinese in the zh-cn locale file.
Lines 274–275 contain English text in a Simplified Chinese translation file, breaking i18n consistency. Line 276 is correctly in Chinese. All three keys should use Chinese translations to provide a proper user experience for Chinese-speaking users.
Suggested corrections:
- Line 274:
"CONNECTION_LIMIT": "Max connection to upstream registry"→"上游registry的最大连接数"or"上游仓库的最大连接数" - Line 275:
"PROXY_CACHE_MAX_UPSTREAM_CONN_TIP": "The max connection to the upstream registry for this proxy cache project, if less than 0, then there is no limit"→"此代理缓存项目与上游仓库的最大连接数,如果小于0则表示无限制"
Line 276 is already correct in Chinese.
- "CONNECTION_LIMIT": "Max connection to upstream registry",
- "PROXY_CACHE_MAX_UPSTREAM_CONN_TIP": "The max connection to the upstream registry for this proxy cache project, if less than 0, then there is no limit",
+ "CONNECTION_LIMIT": "上游仓库的最大连接数",
+ "PROXY_CACHE_MAX_UPSTREAM_CONN_TIP": "此代理缓存项目与上游仓库的最大连接数,如果小于0则表示无限制",
"PROXY_CACHE_MAX_UPSTREAM_CONN_INPUT_TIP": "请输入-1或者大于0的整数"📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| "CONNECTION_LIMIT": "Max connection to upstream registry", | |
| "PROXY_CACHE_MAX_UPSTREAM_CONN_TIP": "The max connection to the upstream registry for this proxy cache project, if less than 0, then there is no limit", | |
| "PROXY_CACHE_MAX_UPSTREAM_CONN_INPUT_TIP": "请输入-1或者大于0的整数" | |
| "CONNECTION_LIMIT": "上游仓库的最大连接数", | |
| "PROXY_CACHE_MAX_UPSTREAM_CONN_TIP": "此代理缓存项目与上游仓库的最大连接数,如果小于0则表示无限制", | |
| "PROXY_CACHE_MAX_UPSTREAM_CONN_INPUT_TIP": "请输入-1或者大于0的整数" |
🤖 Prompt for AI Agents
In src/portal/src/i18n/lang/zh-cn-lang.json around lines 274 to 276, the values
for CONNECTION_LIMIT and PROXY_CACHE_MAX_UPSTREAM_CONN_TIP are in English and
must be translated to Chinese to match the zh-cn locale; replace the value for
"CONNECTION_LIMIT" with a Chinese phrase such as "上游仓库的最大连接数" (or
"上游registry的最大连接数") and replace "PROXY_CACHE_MAX_UPSTREAM_CONN_TIP" with
"此代理缓存项目与上游仓库的最大连接数,如果小于0则表示无限制", leaving the keys unchanged and keeping line
276 as-is.
| if p.MaxUpstreamConnection() > 0 { | ||
| client, err := redis.GetHarborClient() | ||
| if err != nil { | ||
| return errors.NewErrs(err) | ||
| } | ||
| key := upstreamRegistryConnectionKey(art) | ||
| log.Debugf("handle blob, upstream registry connection limit key: %s", key) | ||
| if !connection.Limiter.Acquire(ctx, client, key, p.MaxUpstreamConnection()) { | ||
| log.Infof("current connection exceed max connections to upstream registry") | ||
| // send http code 429 to client | ||
| return tooManyRequestsError | ||
| } | ||
| defer connection.Limiter.Release(context.Background(), client, key) // use background context in defer to avoid been canceled | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Differentiate Redis errors from “limit reached”
Limiter.Acquire currently collapses Redis execution errors into false. When Redis is down, every proxy request will short-circuit with HTTP 429, effectively taking the proxy offline instead of degrading gracefully. Please return the script error separately (e.g. change Acquire to (bool, error)), log the failure, and fall back to serving the request when Redis isn’t reachable.
🤖 Prompt for AI Agents
In src/server/middleware/repoproxy/proxy.go around lines 107-120, the call to
connection.Limiter.Acquire currently treats any Redis/script error as a simple
false and returns HTTP 429; change Acquire to return (bool, error) and update
this code to: call Acquire and check error first — if err != nil log the
redis/script error and proceed (do not return 429) to allow graceful
degradation; only treat a nil error + acquired==false as the rate-limit case and
return tooManyRequestsError; ensure Release is still deferred only when a
successful Acquire returned a non-nil client/token (or otherwise handle nil
client in Release) and keep the defer using background context as before.
| if p.MaxUpstreamConnection() > 0 { | ||
| client, err := redis.GetHarborClient() | ||
| if err != nil { | ||
| return errors.NewErrs(err) | ||
| } | ||
| key := upstreamRegistryConnectionKey(art) | ||
| log.Debugf("handle manifest key %v", key) | ||
| if !connection.Limiter.Acquire(ctx, client, key, p.MaxUpstreamConnection()) { | ||
| log.Infof("current connection exceed max connections to upstream registry") | ||
| // send http code 429 to client | ||
| return tooManyRequestsError | ||
| } | ||
| defer connection.Limiter.Release(context.Background(), client, key) // use background context in defer to avoid been canceled | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same Redis error handling gap as blob path
The manifest path has the same issue: a transient Redis outage makes every manifest fetch look rate-limited. Once Acquire returns an error, treat it as a soft failure and continue rather than returning 429.
🤖 Prompt for AI Agents
In src/server/middleware/repoproxy/proxy.go around lines 251-264, the manifest
path treats any failure from the Redis-based Acquire as a hard rate-limit and
returns 429; change this to treat Acquire errors as soft failures. Call Acquire
and handle both its success/failure and error return: if Acquire returns (false,
nil) then log+return the 429; if Acquire returns (true, nil) then defer Release
with context.Background(); if Acquire returns an error, log a warning/error and
continue without returning 429 (do not defer Release). Ensure Release is only
deferred when Acquire actually succeeded.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
16 issues found across 77 files
Prompt for AI agents (all 16 issues)
Understand the root cause of the following 16 issues and fix them.
<file name="src/portal/src/i18n/lang/zh-cn-lang.json">
<violation number="1" location="src/portal/src/i18n/lang/zh-cn-lang.json:275">
The tooltip tells users that any value less than 0 is accepted for unlimited connections, but the UI only allows -1 (and all other locales document -1 specifically). Please align the wording so administrators aren’t instructed to enter invalid numbers.</violation>
</file>
<file name="src/pkg/proxy/connection/limit.go">
<violation number="1" location="src/pkg/proxy/connection/limit.go:43">
The Lua script sets a one-hour TTL on the counter key, so a long-lived connection outlasting that TTL causes the key to expire and the limit check to reset, allowing new connections that exceed the configured cap. Please avoid expiring the counter while connections are still active, or otherwise ensure the TTL cannot lapse during an active session.</violation>
</file>
<file name="src/portal/src/app/base/left-side-nav/clearing-job/gc-page/gc/gc.component.ts">
<violation number="1" location="src/portal/src/app/base/left-side-nav/clearing-job/gc-page/gc/gc.component.ts:64">
Setting the new delete-tag toggle to true by default breaks existing behavior: before the schedule loads (or if it fails), running GC will send delete_tag: true and remove tags even when the saved configuration says otherwise. Default this flag to false so we don’t mutate data accidentally.</violation>
</file>
<file name="src/portal/src/i18n/lang/es-es-lang.json">
<violation number="1" location="src/portal/src/i18n/lang/es-es-lang.json:276">
This es-es locale string should be translated; leaving English text in the Spanish bundle causes inconsistent UI for Spanish users.</violation>
<violation number="2" location="src/portal/src/i18n/lang/es-es-lang.json:277">
Please localize this tooltip; keeping English text in the es-es locale produces an inconsistent Spanish UI.</violation>
<violation number="3" location="src/portal/src/i18n/lang/es-es-lang.json:1351">
Translate this GC string for the es-es locale instead of leaving the English sentence, otherwise Spanish users see inconsistent language.</violation>
</file>
<file name="src/portal/src/i18n/lang/ru-ru-lang.json">
<violation number="1" location="src/portal/src/i18n/lang/ru-ru-lang.json:260">
Please provide a Russian translation for this new proxy cache label so the ru-RU locale stays localized.</violation>
<violation number="2" location="src/portal/src/i18n/lang/ru-ru-lang.json:1273">
Translate this garbage collection option into Russian to avoid English text leaking into the ru-RU UI.</violation>
</file>
<file name="src/portal/src/i18n/lang/fr-fr-lang.json">
<violation number="1" location="src/portal/src/i18n/lang/fr-fr-lang.json:275">
This locale string should be translated into French so the fr-FR interface does not display English text.</violation>
<violation number="2" location="src/portal/src/i18n/lang/fr-fr-lang.json:1356">
Translate this new garbage-collection label into French to maintain localization quality.</violation>
</file>
<file name="src/portal/src/i18n/lang/de-de-lang.json">
<violation number="1" location="src/portal/src/i18n/lang/de-de-lang.json:275">
Please localize this new string to German so the de-de locale remains consistent for end users.</violation>
</file>
<file name="src/portal/src/app/base/project/project-config/project-policy-config/project-policy-config.component.html">
<violation number="1" location="src/portal/src/app/base/project/project-config/project-policy-config/project-policy-config.component.html:107">
The new MaxUpstreamConn input sets the disabled attribute without property binding, so it stays disabled for all users even when updates are allowed. It should use property binding (`[disabled]`) to respect `allowUpdateProxyCacheConfiguration`.</violation>
</file>
<file name="src/portal/src/app/base/left-side-nav/projects/create-project/create-project.component.ts">
<violation number="1" location="src/portal/src/app/base/left-side-nav/projects/create-project/create-project.component.ts:369">
After validateMaxUpstreamConnections() you are still checking bandwidthError, so invalid max_upstream_conn values are not blocked and no inline error is shown. Please gate on maxUpstreamConnError here.</violation>
</file>
<file name="src/pkg/config/inmemory/manager.go">
<violation number="1" location="src/pkg/config/inmemory/manager.go:60">
Driver.Get should return the stored configuration value instead of ErrUnsupported, otherwise any caller using the in-memory manager to read config via the driver will fail.</violation>
</file>
<file name="make/migrations/postgresql/0180_2.15.0_schema.up.sql">
<violation number="1" location="make/migrations/postgresql/0180_2.15.0_schema.up.sql:13">
This condition only checks whether the sequences have advanced past 1, so an instance with exactly one audit log record (`last_value` = 1, `is_called` = true) is treated as never used and the configuration is not inserted even though usage exists. Consider checking the sequence’s `is_called` flag (or `last_value >= 1` combined with `is_called`) so that a single existing audit log still initializes skip_audit_log_database as false.</violation>
</file>
<file name="src/server/v2.0/handler/user_test.go">
<violation number="1" location="src/server/v2.0/handler/user_test.go:79">
Set this `GetUsername` expectation to run only once; otherwise later scenarios keep getting "testuser" and the admin setup never takes effect.</violation>
</file>
React with 👍 or 👎 to teach cubic. Mention @cubic-dev-ai to give feedback, ask questions, or re-run the review.
| "NO_PROJECT": "未发现任何项目" | ||
| "NO_PROJECT": "未发现任何项目", | ||
| "CONNECTION_LIMIT": "Max connection to upstream registry", | ||
| "PROXY_CACHE_MAX_UPSTREAM_CONN_TIP": "The max connection to the upstream registry for this proxy cache project, if less than 0, then there is no limit", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The tooltip tells users that any value less than 0 is accepted for unlimited connections, but the UI only allows -1 (and all other locales document -1 specifically). Please align the wording so administrators aren’t instructed to enter invalid numbers.
Prompt for AI agents
Address the following comment on src/portal/src/i18n/lang/zh-cn-lang.json at line 275:
<comment>The tooltip tells users that any value less than 0 is accepted for unlimited connections, but the UI only allows -1 (and all other locales document -1 specifically). Please align the wording so administrators aren’t instructed to enter invalid numbers.</comment>
<file context>
@@ -270,7 +270,10 @@
- "NO_PROJECT": "未发现任何项目"
+ "NO_PROJECT": "未发现任何项目",
+ "CONNECTION_LIMIT": "Max connection to upstream registry",
+ "PROXY_CACHE_MAX_UPSTREAM_CONN_TIP": "The max connection to the upstream registry for this proxy cache project, if less than 0, then there is no limit",
+ "PROXY_CACHE_MAX_UPSTREAM_CONN_INPUT_TIP": "请输入-1或者大于0的整数"
},
</file context>
| if current + 1 <= max then | ||
| redis.call('INCRBY', KEYS[1], 1) | ||
| redis.call('EXPIRE', KEYS[1], 3600) -- set expire to avoid always lock |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The Lua script sets a one-hour TTL on the counter key, so a long-lived connection outlasting that TTL causes the key to expire and the limit check to reset, allowing new connections that exceed the configured cap. Please avoid expiring the counter while connections are still active, or otherwise ensure the TTL cannot lapse during an active session.
Prompt for AI agents
Address the following comment on src/pkg/proxy/connection/limit.go at line 43:
<comment>The Lua script sets a one-hour TTL on the counter key, so a long-lived connection outlasting that TTL causes the key to expire and the limit check to reset, allowing new connections that exceed the configured cap. Please avoid expiring the counter while connections are still active, or otherwise ensure the TTL cannot lapse during an active session.</comment>
<file context>
@@ -0,0 +1,79 @@
+
+if current + 1 <= max then
+ redis.call('INCRBY', KEYS[1], 1)
+ redis.call('EXPIRE', KEYS[1], 3600) -- set expire to avoid always lock
+ return 1
+else
</file context>
| ngOnInit() { | ||
| this.getCurrentSchedule(true); | ||
| this.getStatus(); | ||
| this.shouldDeleteTag = true; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Setting the new delete-tag toggle to true by default breaks existing behavior: before the schedule loads (or if it fails), running GC will send delete_tag: true and remove tags even when the saved configuration says otherwise. Default this flag to false so we don’t mutate data accidentally.
Prompt for AI agents
Address the following comment on src/portal/src/app/base/left-side-nav/clearing-job/gc-page/gc/gc.component.ts at line 64:
<comment>Setting the new delete-tag toggle to true by default breaks existing behavior: before the schedule loads (or if it fails), running GC will send delete_tag: true and remove tags even when the saved configuration says otherwise. Default this flag to false so we don’t mutate data accidentally.</comment>
<file context>
@@ -60,6 +61,7 @@ export class GcComponent implements OnInit, OnDestroy {
ngOnInit() {
this.getCurrentSchedule(true);
this.getStatus();
+ this.shouldDeleteTag = true;
}
ngOnDestroy() {
</file context>
| this.shouldDeleteTag = true; | |
| this.shouldDeleteTag = false; |
| "MSG_SCHEDULE_RESET": "Programación de Garbage Collection ha sido reiniciada", | ||
| "PARAMETERS": "Parametros", | ||
| "DELETE_UNTAGGED": "Permitir garbage collection en artefactos no tageados", | ||
| "DELETE_TAG": "Allow garbage collection to remove tag files from backend storage", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Translate this GC string for the es-es locale instead of leaving the English sentence, otherwise Spanish users see inconsistent language.
Prompt for AI agents
Address the following comment on src/portal/src/i18n/lang/es-es-lang.json at line 1351:
<comment>Translate this GC string for the es-es locale instead of leaving the English sentence, otherwise Spanish users see inconsistent language.</comment>
<file context>
@@ -1345,6 +1348,7 @@
"MSG_SCHEDULE_RESET": "Programación de Garbage Collection ha sido reiniciada",
"PARAMETERS": "Parametros",
"DELETE_UNTAGGED": "Permitir garbage collection en artefactos no tageados",
+ "DELETE_TAG": "Allow garbage collection to remove tag files from backend storage",
"EXPLAIN": "GC es una operación que requiere un uso intensivo de recursos informáticos y que puede afectar el rendimiento del registro",
"EXPLAIN_TIME_WINDOW": "Los artefactos cargados en las últimas 2 horas (la ventana predeterminada) se excluyen de la recolección de basura",
</file context>
| "NO_PROJECT": "No pudimos encontrar ningún proyecto" | ||
| "NO_PROJECT": "No pudimos encontrar ningún proyecto", | ||
| "CONNECTION_LIMIT": "Max connection to upstream registry", | ||
| "PROXY_CACHE_MAX_UPSTREAM_CONN_TIP": "The max connection to the upstream registry for this proxy cache project, if -1, then there is no limit", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please localize this tooltip; keeping English text in the es-es locale produces an inconsistent Spanish UI.
Prompt for AI agents
Address the following comment on src/portal/src/i18n/lang/es-es-lang.json at line 277:
<comment>Please localize this tooltip; keeping English text in the es-es locale produces an inconsistent Spanish UI.</comment>
<file context>
@@ -272,7 +272,10 @@
- "NO_PROJECT": "No pudimos encontrar ningún proyecto"
+ "NO_PROJECT": "No pudimos encontrar ningún proyecto",
+ "CONNECTION_LIMIT": "Max connection to upstream registry",
+ "PROXY_CACHE_MAX_UPSTREAM_CONN_TIP": "The max connection to the upstream registry for this proxy cache project, if -1, then there is no limit",
+ "PROXY_CACHE_MAX_UPSTREAM_CONN_INPUT_TIP": "Please enter -1 or an integer greater than 0. "
},
</file context>
| id="max_upstream_conn" | ||
| [(ngModel)]="projectPolicy.MaxUpstreamConn" | ||
| name="max_upstream_conn" | ||
| disabled="!allowUpdateProxyCacheConfiguration" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The new MaxUpstreamConn input sets the disabled attribute without property binding, so it stays disabled for all users even when updates are allowed. It should use property binding ([disabled]) to respect allowUpdateProxyCacheConfiguration.
Prompt for AI agents
Address the following comment on src/portal/src/app/base/project/project-config/project-policy-config/project-policy-config.component.html at line 107:
<comment>The new MaxUpstreamConn input sets the disabled attribute without property binding, so it stays disabled for all users even when updates are allowed. It should use property binding (`[disabled]`) to respect `allowUpdateProxyCacheConfiguration`.</comment>
<file context>
@@ -92,6 +92,35 @@
+ id="max_upstream_conn"
+ [(ngModel)]="projectPolicy.MaxUpstreamConn"
+ name="max_upstream_conn"
+ disabled="!allowUpdateProxyCacheConfiguration"
+ class="clr-input width-164 mr-10 clr-input-underline"
+ autocomplete="off" />
</file context>
| disabled="!allowUpdateProxyCacheConfiguration" | |
| [disabled]="!allowUpdateProxyCacheConfiguration" |
| } | ||
|
|
||
| this.validateMaxUpstreamConnections(); | ||
| if (this.bandwidthError) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
After validateMaxUpstreamConnections() you are still checking bandwidthError, so invalid max_upstream_conn values are not blocked and no inline error is shown. Please gate on maxUpstreamConnError here.
Prompt for AI agents
Address the following comment on src/portal/src/app/base/left-side-nav/projects/create-project/create-project.component.ts at line 369:
<comment>After validateMaxUpstreamConnections() you are still checking bandwidthError, so invalid max_upstream_conn values are not blocked and no inline error is shown. Please gate on maxUpstreamConnError here.</comment>
<file context>
@@ -342,6 +365,12 @@ export class CreateProjectComponent
}
+ this.validateMaxUpstreamConnections();
+ if (this.bandwidthError) {
+ this.inlineAlert.showInlineError(this.maxUpstreamConnError);
+ return;
</file context>
| if (this.bandwidthError) { | |
| if (this.maxUpstreamConnError) { |
|
|
||
| // TODO | ||
| func (d *Driver) Get(_ context.Context, _ string) (map[string]any, error) { | ||
| return nil, errors.ErrUnsupported |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Driver.Get should return the stored configuration value instead of ErrUnsupported, otherwise any caller using the in-memory manager to read config via the driver will fail.
Prompt for AI agents
Address the following comment on src/pkg/config/inmemory/manager.go at line 60:
<comment>Driver.Get should return the stored configuration value instead of ErrUnsupported, otherwise any caller using the in-memory manager to read config via the driver will fail.</comment>
<file context>
@@ -54,6 +55,11 @@ func (d *Driver) Save(_ context.Context, cfg map[string]any) error {
+// TODO
+func (d *Driver) Get(_ context.Context, _ string) (map[string]any, error) {
+ return nil, errors.ErrUnsupported
+}
+
</file context>
| RETURN; | ||
| END IF; | ||
|
|
||
| IF (SELECT last_value FROM audit_log_id_seq) > 1 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This condition only checks whether the sequences have advanced past 1, so an instance with exactly one audit log record (last_value = 1, is_called = true) is treated as never used and the configuration is not inserted even though usage exists. Consider checking the sequence’s is_called flag (or last_value >= 1 combined with is_called) so that a single existing audit log still initializes skip_audit_log_database as false.
Prompt for AI agents
Address the following comment on make/migrations/postgresql/0180_2.15.0_schema.up.sql at line 13:
<comment>This condition only checks whether the sequences have advanced past 1, so an instance with exactly one audit log record (`last_value` = 1, `is_called` = true) is treated as never used and the configuration is not inserted even though usage exists. Consider checking the sequence’s `is_called` flag (or `last_value >= 1` combined with `is_called`) so that a single existing audit log still initializes skip_audit_log_database as false.</comment>
<file context>
@@ -0,0 +1,17 @@
+ RETURN;
+ END IF;
+
+ IF (SELECT last_value FROM audit_log_id_seq) > 1
+ OR (SELECT last_value FROM audit_log_ext_id_seq) > 1 THEN
+ INSERT INTO properties (k, v) VALUES ('skip_audit_log_database', 'false');
</file context>
| { | ||
| url := "/users/2/password" | ||
| uts.Security.On("Can", mock.Anything, mock.Anything, mock.Anything).Return(false).Times(1) | ||
| uts.Security.On("GetUsername").Return("testuser") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Set this GetUsername expectation to run only once; otherwise later scenarios keep getting "testuser" and the admin setup never takes effect.
Prompt for AI agents
Address the following comment on src/server/v2.0/handler/user_test.go at line 79:
<comment>Set this `GetUsername` expectation to run only once; otherwise later scenarios keep getting "testuser" and the admin setup never takes effect.</comment>
<file context>
@@ -76,13 +76,15 @@ func (uts *UserTestSuite) TestUpdateUserPassword() {
{
url := "/users/2/password"
uts.Security.On("Can", mock.Anything, mock.Anything, mock.Anything).Return(false).Times(1)
+ uts.Security.On("GetUsername").Return("testuser")
res, err := uts.Suite.PutJSON(url, &body)
uts.NoError(err)
</file context>
According to the gc performance proposal, harbor will skip to write the tag file into the data storage since we already use the harbor database to manage the tag CRUD. Proposal: goharbor/community#265 fixed #22405 Signed-off-by: wang yan <[email protected]> Co-authored-by: wang yan <[email protected]>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
🧹 Nitpick comments (1)
src/server/registry/manifest_test.go (1)
206-255: Add coverage for percent-encoded referencesThe bug above only shows up when the incoming request keeps
RawPathpopulated (e.g./manifests/%6C%61%74%65%73%74). None of the new tests hit that path, so the regression would slip through again. Please add a test that feeds a percent-encoded reference and asserts the proxied request still uses the computed digest.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (2)
src/server/registry/manifest.go(3 hunks)src/server/registry/manifest_test.go(2 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
src/server/registry/manifest.go (2)
src/lib/http/error.go (1)
SendError(53-67)src/controller/artifact/controller.go (2)
Ctl(64-64)ArtOption(160-163)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: cubic · AI code reviewer
| req.URL.Path = strings.TrimSuffix(req.URL.Path, reference) + dgst.String() | ||
| req.URL.RawPath = req.URL.EscapedPath() | ||
| req.Body = io.NopCloser(bytes.NewReader(data)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fix RawPath when rewriting manifest path
url.URL.EscapedPath() returns the existing RawPath whenever it is populated, so for requests where the client percent-encodes the reference (e.g. /manifests/%6C%61%74%65%73%74) the RawPath still contains the original tag. The proxy then forwards the unmodified tag instead of the computed digest, defeating the main goal of this change. Clear RawPath before recomputing it (and consider backfilling a test for this case).
Apply this diff to address it:
- req.URL.Path = strings.TrimSuffix(req.URL.Path, reference) + dgst.String()
- req.URL.RawPath = req.URL.EscapedPath()
+ req.URL.Path = strings.TrimSuffix(req.URL.Path, reference) + dgst.String()
+ req.URL.RawPath = ""
+ req.URL.RawPath = req.URL.EscapedPath()📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| req.URL.Path = strings.TrimSuffix(req.URL.Path, reference) + dgst.String() | |
| req.URL.RawPath = req.URL.EscapedPath() | |
| req.Body = io.NopCloser(bytes.NewReader(data)) | |
| req.URL.Path = strings.TrimSuffix(req.URL.Path, reference) + dgst.String() | |
| req.URL.RawPath = "" | |
| req.URL.RawPath = req.URL.EscapedPath() | |
| req.Body = io.NopCloser(bytes.NewReader(data)) |
🤖 Prompt for AI Agents
In src/server/registry/manifest.go around lines 202 to 204, when rewriting the
manifest path you must clear req.URL.RawPath before recomputing it because
url.URL.EscapedPath() returns the existing RawPath if set, causing
percent-encoded references to be forwarded unchanged; update the code to set
req.URL.Path = strings.TrimSuffix(req.URL.Path, reference) + dgst.String(), then
set req.URL.RawPath = "" before calling req.URL.EscapedPath()/recomputing
RawPath, and ensure req.Body is reset as before; also add a test that sends a
percent-encoded reference (e.g. /manifests/%6C%61%74%65%73%74) and verifies the
proxied request contains the computed digest instead of the original encoded
tag.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
27 issues found across 79 files
Prompt for AI agents (all 27 issues)
Understand the root cause of the following 27 issues and fix them.
<file name="src/portal/src/i18n/lang/pt-br-lang.json">
<violation number="1" location="src/portal/src/i18n/lang/pt-br-lang.json:273">
This new pt-BR locale string remains in English, so Portuguese users will see untranslated UI text. Please add the Portuguese translation.</violation>
<violation number="2" location="src/portal/src/i18n/lang/pt-br-lang.json:274">
This tooltip string for the pt-BR locale is still English, leaving the Portuguese UI untranslated. Please localize it.</violation>
<violation number="3" location="src/portal/src/i18n/lang/pt-br-lang.json:275">
The input hint for pt-BR stays in English, so the UI shows untranslated guidance. Please translate it to Portuguese.</violation>
<violation number="4" location="src/portal/src/i18n/lang/pt-br-lang.json:1351">
The new pt-BR label for the GC option is left in English, so the localized UI is inconsistent. Please provide the Portuguese translation.</violation>
</file>
<file name="src/portal/src/i18n/lang/es-es-lang.json">
<violation number="1" location="src/portal/src/i18n/lang/es-es-lang.json:276">
Translate the new proxy cache connection limit strings so the Spanish locale stays localized.</violation>
<violation number="2" location="src/portal/src/i18n/lang/es-es-lang.json:1351">
Translate the new garbage collection label so the Spanish locale remains fully localized.</violation>
</file>
<file name="tests/resources/TestCaseBody.robot">
<violation number="1" location="tests/resources/TestCaseBody.robot:26">
The new Remove Port helper hard-codes removal of :9443, so `${cleaned_ip}` still includes other ports (e.g., the default localhost:8080), breaking webhook verification on those setups.</violation>
</file>
<file name="src/portal/src/i18n/lang/tr-tr-lang.json">
<violation number="1" location="src/portal/src/i18n/lang/tr-tr-lang.json:277">
Update the tooltip to use proper pluralization and smoother phrasing so users clearly understand the setting.</violation>
</file>
<file name="src/portal/src/app/base/left-side-nav/clearing-job/gc-page/gc/gc.component.ts">
<violation number="1" location="src/portal/src/app/base/left-side-nav/clearing-job/gc-page/gc/gc.component.ts:144">
When there is no existing GC schedule, this assignment overrides the new default true set in ngOnInit, so fresh runs end up sending delete_tag=false and skip tag cleanup. Please keep the default true in the empty-history case.</violation>
</file>
<file name="src/controller/gc/controller.go">
<violation number="1" location="src/controller/gc/controller.go:80">
Setting `para["delete_tag"]` unconditionally forces the value to `false` whenever the incoming policy omits it, overriding the job's default of deleting tags. Please omit the parameter when the policy doesn't define it so legacy behavior remains intact.</violation>
<violation number="2" location="src/controller/gc/controller.go:209">
Writing `extras["delete_tag"]` unconditionally forces existing GC schedules that never set this flag to disable tag deletion. Please only add the parameter when the policy explicitly supplies a value.</violation>
<violation number="3" location="src/controller/gc/controller.go:239">
Reading `delete_tag` without preserving the default causes historical GC tasks that lacked this extra attribute to surface as `false`. Please default the field to `true` when the extra attribute is absent.</violation>
</file>
<file name="src/pkg/reg/adapter/tencentcr/artifact_registry_test.go">
<violation number="1" location="src/pkg/reg/adapter/tencentcr/artifact_registry_test.go:178">
The new mockAdapter overrides DeleteManifest, so Test_adapter_DeleteManifest now executes the mock implementation instead of the real adapter.DeleteManifest; the test no longer validates production behavior.</violation>
</file>
<file name="src/pkg/config/store/store_test.go">
<violation number="1" location="src/pkg/config/store/store_test.go:35">
The mock blindly type-asserts args.Get(0) to map[string]any. If a test configures Return(nil, ...), args.Get(0) is a nil interface and this cast panics, so we can't exercise valid driver behavior where nil indicates "no config". Please guard the cast (same issue in MockDriver.Get below).</violation>
</file>
<file name="src/portal/src/i18n/lang/ru-ru-lang.json">
<violation number="1" location="src/portal/src/i18n/lang/ru-ru-lang.json:260">
These new proxy-cache strings are still English in the Russian locale file, so the RU UI will display untranslated text. Please provide the Russian translations before merging.</violation>
<violation number="2" location="src/portal/src/i18n/lang/ru-ru-lang.json:1273">
The new garbage-collection label is still English in the Russian locale file, so Russian users will see untranslated copy. Please localize this string before merge.</violation>
</file>
<file name="src/controller/gc/model.go">
<violation number="1" location="src/controller/gc/model.go:25">
Introducing DeleteTag as a plain bool makes existing policies default to false when this field is absent, so legacy garbage-collection policies will now skip tag deletion even though the feature is supposed to remain enabled by default. Use a pointer or explicit defaulting to preserve the intended behaviour for existing data.</violation>
<violation number="2" location="src/controller/gc/model.go:64">
Same defaulting issue as in Policy: Task.DeleteTag is now false when deserializing historical tasks lacking this field, causing garbage-collection runs spawned from old executions to skip tag deletion unexpectedly. Ensure the field defaults to true when missing.</violation>
</file>
<file name="src/server/middleware/repoproxy/proxy.go">
<violation number="1" location="src/server/middleware/repoproxy/proxy.go:114">
Redis failures in Acquire() now cause the handler to return 429 (Too Many Requests) even when the upstream connection limit has not been exceeded, denying legitimate traffic. Please distinguish limiter errors from true limit hits and avoid sending a 429 when Redis cannot be reached.</violation>
</file>
<file name="src/portal/src/app/base/left-side-nav/projects/create-project/create-project.component.ts">
<violation number="1" location="src/portal/src/app/base/left-side-nav/projects/create-project/create-project.component.ts:369">
The submission guard for max_upstream_conn still checks bandwidthError, so invalid max upstream connection values won’t trigger the inline error and the request proceeds with bad data.</violation>
</file>
<file name="src/portal/src/i18n/lang/de-de-lang.json">
<violation number="1" location="src/portal/src/i18n/lang/de-de-lang.json:275">
This de-DE locale string is still in English; please translate it so German users see localized text.</violation>
<violation number="2" location="src/portal/src/i18n/lang/de-de-lang.json:276">
Please localize this tooltip text to German; leaving it in English breaks the de-DE translation.</violation>
<violation number="3" location="src/portal/src/i18n/lang/de-de-lang.json:277">
Translate this de-DE input hint to German so localized users receive instructions in their language.</violation>
</file>
<file name="src/portal/src/i18n/lang/fr-fr-lang.json">
<violation number="1" location="src/portal/src/i18n/lang/fr-fr-lang.json:275">
Cette clé de traduction devrait être localisée en français pour éviter d’afficher du texte anglais dans l’interface fr-FR.</violation>
<violation number="2" location="src/portal/src/i18n/lang/fr-fr-lang.json:1356">
Merci de localiser cette étiquette en français pour la cohérence de la locale fr-FR.</violation>
</file>
<file name="src/portal/src/i18n/lang/zh-cn-lang.json">
<violation number="1" location="src/portal/src/i18n/lang/zh-cn-lang.json:275">
The tooltip claims any value < 0 disables the limit, but validation only allows -1. Update the text to match the actual behavior so users aren’t misled.</violation>
</file>
<file name="src/pkg/proxy/connection/limit_test.go">
<violation number="1" location="src/pkg/proxy/connection/limit_test.go:35">
This unit test depends on a real Redis server at runtime; without Redis running, Limiter.Acquire returns false and the initial assert fails, so the package tests can’t pass. Please mock/stub the limiter or gate the test on an integration setup.</violation>
</file>
React with 👍 or 👎 to teach cubic. Mention @cubic-dev-ai to give feedback, ask questions, or re-run the review.
| "MSG_SCHEDULE_RESET": "Agendamento da limpeza redefinido", | ||
| "PARAMETERS": "Parâmetros", | ||
| "DELETE_UNTAGGED": "Permitir coleta de artefatos sem tags", | ||
| "DELETE_TAG": "Allow garbage collection to remove tag files from backend storage", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The new pt-BR label for the GC option is left in English, so the localized UI is inconsistent. Please provide the Portuguese translation.
Prompt for AI agents
Address the following comment on src/portal/src/i18n/lang/pt-br-lang.json at line 1351:
<comment>The new pt-BR label for the GC option is left in English, so the localized UI is inconsistent. Please provide the Portuguese translation.</comment>
<file context>
@@ -1345,6 +1348,7 @@
"MSG_SCHEDULE_RESET": "Agendamento da limpeza redefinido",
"PARAMETERS": "Parâmetros",
"DELETE_UNTAGGED": "Permitir coleta de artefatos sem tags",
+ "DELETE_TAG": "Allow garbage collection to remove tag files from backend storage",
"EXPLAIN": "A limpeza exige recursos computacionais e pode impactar performance.",
"EXPLAIN_TIME_WINDOW": "Artifacts uploaded in the past 2 hours(the default window) are excluded from garbage collection",
</file context>
| "PROXY_CACHE_ENDPOINT": "Endereço do Proxy Cache", | ||
| "CONNECTION_LIMIT": "Max connection to upstream registry", | ||
| "PROXY_CACHE_MAX_UPSTREAM_CONN_TIP": "The max connection to the upstream registry for this proxy cache project, if -1, then there is no limit", | ||
| "PROXY_CACHE_MAX_UPSTREAM_CONN_INPUT_TIP": "Please enter -1 or an integer greater than 0. " |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The input hint for pt-BR stays in English, so the UI shows untranslated guidance. Please translate it to Portuguese.
Prompt for AI agents
Address the following comment on src/portal/src/i18n/lang/pt-br-lang.json at line 275:
<comment>The input hint for pt-BR stays in English, so the UI shows untranslated guidance. Please translate it to Portuguese.</comment>
<file context>
@@ -269,7 +269,10 @@
+ "PROXY_CACHE_ENDPOINT": "Endereço do Proxy Cache",
+ "CONNECTION_LIMIT": "Max connection to upstream registry",
+ "PROXY_CACHE_MAX_UPSTREAM_CONN_TIP": "The max connection to the upstream registry for this proxy cache project, if -1, then there is no limit",
+ "PROXY_CACHE_MAX_UPSTREAM_CONN_INPUT_TIP": "Please enter -1 or an integer greater than 0. "
},
"PROJECT_DETAIL": {
</file context>
| "PROXY_CACHE_ENDPOINT": "Endereço do Proxy Cache" | ||
| "PROXY_CACHE_ENDPOINT": "Endereço do Proxy Cache", | ||
| "CONNECTION_LIMIT": "Max connection to upstream registry", | ||
| "PROXY_CACHE_MAX_UPSTREAM_CONN_TIP": "The max connection to the upstream registry for this proxy cache project, if -1, then there is no limit", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This tooltip string for the pt-BR locale is still English, leaving the Portuguese UI untranslated. Please localize it.
Prompt for AI agents
Address the following comment on src/portal/src/i18n/lang/pt-br-lang.json at line 274:
<comment>This tooltip string for the pt-BR locale is still English, leaving the Portuguese UI untranslated. Please localize it.</comment>
<file context>
@@ -269,7 +269,10 @@
- "PROXY_CACHE_ENDPOINT": "Endereço do Proxy Cache"
+ "PROXY_CACHE_ENDPOINT": "Endereço do Proxy Cache",
+ "CONNECTION_LIMIT": "Max connection to upstream registry",
+ "PROXY_CACHE_MAX_UPSTREAM_CONN_TIP": "The max connection to the upstream registry for this proxy cache project, if -1, then there is no limit",
+ "PROXY_CACHE_MAX_UPSTREAM_CONN_INPUT_TIP": "Please enter -1 or an integer greater than 0. "
},
</file context>
| "ENDPOINT": "Endereço", | ||
| "PROXY_CACHE_ENDPOINT": "Endereço do Proxy Cache" | ||
| "PROXY_CACHE_ENDPOINT": "Endereço do Proxy Cache", | ||
| "CONNECTION_LIMIT": "Max connection to upstream registry", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This new pt-BR locale string remains in English, so Portuguese users will see untranslated UI text. Please add the Portuguese translation.
Prompt for AI agents
Address the following comment on src/portal/src/i18n/lang/pt-br-lang.json at line 273:
<comment>This new pt-BR locale string remains in English, so Portuguese users will see untranslated UI text. Please add the Portuguese translation.</comment>
<file context>
@@ -269,7 +269,10 @@
"ENDPOINT": "Endereço",
- "PROXY_CACHE_ENDPOINT": "Endereço do Proxy Cache"
+ "PROXY_CACHE_ENDPOINT": "Endereço do Proxy Cache",
+ "CONNECTION_LIMIT": "Max connection to upstream registry",
+ "PROXY_CACHE_MAX_UPSTREAM_CONN_TIP": "The max connection to the upstream registry for this proxy cache project, if -1, then there is no limit",
+ "PROXY_CACHE_MAX_UPSTREAM_CONN_INPUT_TIP": "Please enter -1 or an integer greater than 0. "
</file context>
| "MSG_SCHEDULE_RESET": "Programación de Garbage Collection ha sido reiniciada", | ||
| "PARAMETERS": "Parametros", | ||
| "DELETE_UNTAGGED": "Permitir garbage collection en artefactos no tageados", | ||
| "DELETE_TAG": "Allow garbage collection to remove tag files from backend storage", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Translate the new garbage collection label so the Spanish locale remains fully localized.
Prompt for AI agents
Address the following comment on src/portal/src/i18n/lang/es-es-lang.json at line 1351:
<comment>Translate the new garbage collection label so the Spanish locale remains fully localized.</comment>
<file context>
@@ -1345,6 +1348,7 @@
"MSG_SCHEDULE_RESET": "Programación de Garbage Collection ha sido reiniciada",
"PARAMETERS": "Parametros",
"DELETE_UNTAGGED": "Permitir garbage collection en artefactos no tageados",
+ "DELETE_TAG": "Allow garbage collection to remove tag files from backend storage",
"EXPLAIN": "GC es una operación que requiere un uso intensivo de recursos informáticos y que puede afectar el rendimiento del registro",
"EXPLAIN_TIME_WINDOW": "Los artefactos cargados en las últimas 2 horas (la ventana predeterminada) se excluyen de la recolección de basura",
</file context>
| "PROXY_CACHE_ENDPOINT": "Proxy Cache Endpunkt", | ||
| "NO_PROJECT": "Es konnte kein Projekt gefunden werden" | ||
| "NO_PROJECT": "Es konnte kein Projekt gefunden werden", | ||
| "CONNECTION_LIMIT": "Max connection to upstream registry", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This de-DE locale string is still in English; please translate it so German users see localized text.
Prompt for AI agents
Address the following comment on src/portal/src/i18n/lang/de-de-lang.json at line 275:
<comment>This de-DE locale string is still in English; please translate it so German users see localized text.</comment>
<file context>
@@ -271,7 +271,10 @@
"PROXY_CACHE_ENDPOINT": "Proxy Cache Endpunkt",
- "NO_PROJECT": "Es konnte kein Projekt gefunden werden"
+ "NO_PROJECT": "Es konnte kein Projekt gefunden werden",
+ "CONNECTION_LIMIT": "Max connection to upstream registry",
+ "PROXY_CACHE_MAX_UPSTREAM_CONN_TIP": "The max connection to the upstream registry for this proxy cache project, if -1, then there is no limit",
+ "PROXY_CACHE_MAX_UPSTREAM_CONN_INPUT_TIP": "Please enter -1 or an integer greater than 0. "
</file context>
| "MSG_SCHEDULE_RESET": "La planification de la purge a été réinitialisée", | ||
| "PARAMETERS": "Paramètres", | ||
| "DELETE_UNTAGGED": "Supprimer les artefacts non tagués", | ||
| "DELETE_TAG": "Allow garbage collection to remove tag files from backend storage", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Merci de localiser cette étiquette en français pour la cohérence de la locale fr-FR.
Prompt for AI agents
Address the following comment on src/portal/src/i18n/lang/fr-fr-lang.json at line 1356:
<comment>Merci de localiser cette étiquette en français pour la cohérence de la locale fr-FR.</comment>
<file context>
@@ -1350,6 +1353,7 @@
"MSG_SCHEDULE_RESET": "La planification de la purge a été réinitialisée",
"PARAMETERS": "Paramètres",
"DELETE_UNTAGGED": "Supprimer les artefacts non tagués",
+ "DELETE_TAG": "Allow garbage collection to remove tag files from backend storage",
"EXPLAIN": "Purger est une opération gourmande en puissance de calcul qui peut impacter les performances du registre",
"EXPLAIN_TIME_WINDOW": "Les artefacts téléversés dans les dernières 2 heures (fenêtre de temps par défaut) sont exclues de la purge",
</file context>
| "PROXY_CACHE_ENDPOINT": "Endpoint du Proxy Cache", | ||
| "NO_PROJECT": "Nous n'avons trouvé aucun projet." | ||
| "NO_PROJECT": "Nous n'avons trouvé aucun projet.", | ||
| "CONNECTION_LIMIT": "Max connection to upstream registry", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Cette clé de traduction devrait être localisée en français pour éviter d’afficher du texte anglais dans l’interface fr-FR.
Prompt for AI agents
Address the following comment on src/portal/src/i18n/lang/fr-fr-lang.json at line 275:
<comment>Cette clé de traduction devrait être localisée en français pour éviter d’afficher du texte anglais dans l’interface fr-FR.</comment>
<file context>
@@ -271,7 +271,10 @@
"PROXY_CACHE_ENDPOINT": "Endpoint du Proxy Cache",
- "NO_PROJECT": "Nous n'avons trouvé aucun projet."
+ "NO_PROJECT": "Nous n'avons trouvé aucun projet.",
+ "CONNECTION_LIMIT": "Max connection to upstream registry",
+ "PROXY_CACHE_MAX_UPSTREAM_CONN_TIP": "The max connection to the upstream registry for this proxy cache project, if -1, then there is no limit",
+ "PROXY_CACHE_MAX_UPSTREAM_CONN_INPUT_TIP": "Please enter -1 or an integer greater than 0. "
</file context>
| "NO_PROJECT": "未发现任何项目" | ||
| "NO_PROJECT": "未发现任何项目", | ||
| "CONNECTION_LIMIT": "Max connection to upstream registry", | ||
| "PROXY_CACHE_MAX_UPSTREAM_CONN_TIP": "The max connection to the upstream registry for this proxy cache project, if less than 0, then there is no limit", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The tooltip claims any value < 0 disables the limit, but validation only allows -1. Update the text to match the actual behavior so users aren’t misled.
Prompt for AI agents
Address the following comment on src/portal/src/i18n/lang/zh-cn-lang.json at line 275:
<comment>The tooltip claims any value < 0 disables the limit, but validation only allows -1. Update the text to match the actual behavior so users aren’t misled.</comment>
<file context>
@@ -270,7 +270,10 @@
- "NO_PROJECT": "未发现任何项目"
+ "NO_PROJECT": "未发现任何项目",
+ "CONNECTION_LIMIT": "Max connection to upstream registry",
+ "PROXY_CACHE_MAX_UPSTREAM_CONN_TIP": "The max connection to the upstream registry for this proxy cache project, if less than 0, then there is no limit",
+ "PROXY_CACHE_MAX_UPSTREAM_CONN_INPUT_TIP": "请输入-1或者大于0的整数"
},
</file context>
| } | ||
|
|
||
| ctx := context.Background() | ||
| rdb := redis.NewClient(&redis.Options{ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This unit test depends on a real Redis server at runtime; without Redis running, Limiter.Acquire returns false and the initial assert fails, so the package tests can’t pass. Please mock/stub the limiter or gate the test on an integration setup.
Prompt for AI agents
Address the following comment on src/pkg/proxy/connection/limit_test.go at line 35:
<comment>This unit test depends on a real Redis server at runtime; without Redis running, Limiter.Acquire returns false and the initial assert fails, so the package tests can’t pass. Please mock/stub the limiter or gate the test on an integration setup.</comment>
<file context>
@@ -0,0 +1,59 @@
+ }
+
+ ctx := context.Background()
+ rdb := redis.NewClient(&redis.Options{
+ Addr: fmt.Sprintf("%s:6379", redisHost), // Redis server address
+ Password: "", // No password set
</file context>
Signed-off-by: chlins <[email protected]>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
20 issues found across 80 files
Prompt for AI agents (all 20 issues)
Understand the root cause of the following 20 issues and fix them.
<file name="src/portal/src/app/base/left-side-nav/projects/create-project/create-project.component.ts">
<violation number="1" location="src/portal/src/app/base/left-side-nav/projects/create-project/create-project.component.ts:369">
After validating max upstream connections, the guard still checks bandwidthError, so invalid max_upstream_conn values will never block submission and the inline alert never appears.</violation>
</file>
<file name="src/portal/src/i18n/lang/es-es-lang.json">
<violation number="1" location="src/portal/src/i18n/lang/es-es-lang.json:276">
This new proxy-cache label is left in English inside the es-es locale file, so the Spanish UI will display untranslated text. Please provide the Spanish translation.</violation>
<violation number="2" location="src/portal/src/i18n/lang/es-es-lang.json:278">
The proxy-cache input validation hint is still in English inside the es-es translations, so Spanish users will see mixed-language messaging. Please translate it.</violation>
<violation number="3" location="src/portal/src/i18n/lang/es-es-lang.json:1351">
The garbage-collection toggle text was added in English to the es-es locale, so the UI will display untranslated content. Provide the Spanish translation to keep the locale consistent.</violation>
</file>
<file name="src/pkg/reg/adapter/tencentcr/artifact_registry_test.go">
<violation number="1" location="src/pkg/reg/adapter/tencentcr/artifact_registry_test.go:178">
The tests override DeleteManifest on the mock adapter, so the new cases never execute the real adapter.DeleteManifest implementation; they only validate the mock’s duplicate logic, leaving production behavior untested.</violation>
</file>
<file name="src/server/v2.0/handler/gc.go">
<violation number="1" location="src/server/v2.0/handler/gc.go:103">
Scheduled GC policies likewise lose tag deletion because delete_tag is copied only when provided; existing schedules without the field now run with DeleteTag=false, violating the documented default true behavior.</violation>
</file>
<file name="src/portal/src/app/base/left-side-nav/clearing-job/gc-page/gc/gc.component.ts">
<violation number="1" location="src/portal/src/app/base/left-side-nav/clearing-job/gc-page/gc/gc.component.ts:144">
When no GC schedule exists the UI now forces delete_tag=false, which overrides the backend default of true and causes new schedules to retain backend tag files even though the server expects them to be deleted by default. Align the UI fallback with the backend default to avoid surprising behavior.</violation>
</file>
<file name="src/portal/src/i18n/lang/de-de-lang.json">
<violation number="1" location="src/portal/src/i18n/lang/de-de-lang.json:1354">
The newly added GC label is still English in the de-DE locale file, leaving the feature untranslated for German users; translate the string to German.</violation>
</file>
<file name="src/portal/src/i18n/lang/fr-fr-lang.json">
<violation number="1" location="src/portal/src/i18n/lang/fr-fr-lang.json:275">
This French locale label stays in English, so users of the fr-FR UI will see untranslated text. Please provide the French translation to keep the localization consistent.</violation>
<violation number="2" location="src/portal/src/i18n/lang/fr-fr-lang.json:276">
The tooltip text for the proxy-cache connection limit remains English in the fr-FR locale, leading to inconsistent localization. Translate it to French like the neighboring tooltips.</violation>
<violation number="3" location="src/portal/src/i18n/lang/fr-fr-lang.json:1356">
The newly added garbage-collection option label stays in English in the French locale, resulting in untranslated UI text. Translate it to French like the other GC labels.</violation>
</file>
<file name="src/portal/src/i18n/lang/ko-kr-lang.json">
<violation number="1" location="src/portal/src/i18n/lang/ko-kr-lang.json:275">
New proxy-cache label shown in the Korean locale remains English, so users selecting ko-KR will see untranslated UI text for the upstream connection limit control.</violation>
<violation number="2" location="src/portal/src/i18n/lang/ko-kr-lang.json:276">
Tooltip for the new proxy-cache upstream connection limit is left in English inside the Korean locale file, so the ko-KR UI surfaces untranslated explanatory text.</violation>
<violation number="3" location="src/portal/src/i18n/lang/ko-kr-lang.json:277">
Input validation hint for the upstream connection limit remains English in the ko-KR locale, leaving users without a localized instruction.</violation>
</file>
<file name=".github/workflows/housekeeping-stale-issues-prs.yaml">
<violation number="1" location=".github/workflows/housekeeping-stale-issues-prs.yaml:10">
Pin the actions/stale step to the immutable commit for v10.0.0 instead of a mutable tag so the workflow can’t run altered code if the tag gets retargeted.</violation>
</file>
<file name="src/portal/src/app/base/project/project-config/project-policy-config/project-policy-config.component.html">
<violation number="1" location="src/portal/src/app/base/project/project-config/project-policy-config/project-policy-config.component.html:111">
The added connection-limit field renders `maxUpstreamConnError`, but the component never updates this flag or validates `projectPolicy.MaxUpstreamConn`, so invalid inputs produce no feedback and the tooltip/icon never appear.</violation>
</file>
<file name="make/migrations/postgresql/0180_2.15.0_schema.up.sql">
<violation number="1" location="make/migrations/postgresql/0180_2.15.0_schema.up.sql:13">
The migration determines prior audit-log usage via `last_value > 1` on the audit log sequences, but sequences report `last_value = 1` both before any insert and after the first insert. Deployments with only one stored audit log are therefore treated as if the tables were unused, so the `skip_audit_log_database` property is never created and environment defaults can disable database auditing after upgrade. Consider checking the sequence’s `is_called` flag or querying the audit_log tables for existing rows instead.</violation>
</file>
<file name="src/portal/src/i18n/lang/ru-ru-lang.json">
<violation number="1" location="src/portal/src/i18n/lang/ru-ru-lang.json:261">
The tooltip text for the proxy-cache connection limit was added to the Russian locale file but left in English, leaving the new UI help untranslated.</violation>
<violation number="2" location="src/portal/src/i18n/lang/ru-ru-lang.json:262">
The RU locale entry for the proxy-cache connection limit validation tip is still English and includes a trailing space, so the UI shows untranslated text with stray whitespace.</violation>
<violation number="3" location="src/portal/src/i18n/lang/ru-ru-lang.json:1273">
The Russian locale entry for the new garbage-collection delete-tag option remains in English, so Russian users will see untranslated text in the GC settings.</violation>
</file>
Reply to cubic to teach it or ask questions. Re-run a review with @cubic-dev-ai review this PR
| } | ||
|
|
||
| this.validateMaxUpstreamConnections(); | ||
| if (this.bandwidthError) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
After validating max upstream connections, the guard still checks bandwidthError, so invalid max_upstream_conn values will never block submission and the inline alert never appears.
Prompt for AI agents
Address the following comment on src/portal/src/app/base/left-side-nav/projects/create-project/create-project.component.ts at line 369:
<comment>After validating max upstream connections, the guard still checks bandwidthError, so invalid max_upstream_conn values will never block submission and the inline alert never appears.</comment>
<file context>
@@ -342,6 +365,12 @@ export class CreateProjectComponent
}
+ this.validateMaxUpstreamConnections();
+ if (this.bandwidthError) {
+ this.inlineAlert.showInlineError(this.maxUpstreamConnError);
+ return;
</file context>
| if (this.bandwidthError) { | |
| if (this.maxUpstreamConnError) { |
| "MSG_SCHEDULE_RESET": "Programación de Garbage Collection ha sido reiniciada", | ||
| "PARAMETERS": "Parametros", | ||
| "DELETE_UNTAGGED": "Permitir garbage collection en artefactos no tageados", | ||
| "DELETE_TAG": "Allow garbage collection to remove tag files from backend storage", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The garbage-collection toggle text was added in English to the es-es locale, so the UI will display untranslated content. Provide the Spanish translation to keep the locale consistent.
Prompt for AI agents
Address the following comment on src/portal/src/i18n/lang/es-es-lang.json at line 1351:
<comment>The garbage-collection toggle text was added in English to the es-es locale, so the UI will display untranslated content. Provide the Spanish translation to keep the locale consistent.</comment>
<file context>
@@ -1345,6 +1348,7 @@
"MSG_SCHEDULE_RESET": "Programación de Garbage Collection ha sido reiniciada",
"PARAMETERS": "Parametros",
"DELETE_UNTAGGED": "Permitir garbage collection en artefactos no tageados",
+ "DELETE_TAG": "Allow garbage collection to remove tag files from backend storage",
"EXPLAIN": "GC es una operación que requiere un uso intensivo de recursos informáticos y que puede afectar el rendimiento del registro",
"EXPLAIN_TIME_WINDOW": "Los artefactos cargados en las últimas 2 horas (la ventana predeterminada) se excluyen de la recolección de basura",
</file context>
| "NO_PROJECT": "No pudimos encontrar ningún proyecto", | ||
| "CONNECTION_LIMIT": "Max connection to upstream registry", | ||
| "PROXY_CACHE_MAX_UPSTREAM_CONN_TIP": "The max connection to the upstream registry for this proxy cache project, if -1, then there is no limit", | ||
| "PROXY_CACHE_MAX_UPSTREAM_CONN_INPUT_TIP": "Please enter -1 or an integer greater than 0. " |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The proxy-cache input validation hint is still in English inside the es-es translations, so Spanish users will see mixed-language messaging. Please translate it.
Prompt for AI agents
Address the following comment on src/portal/src/i18n/lang/es-es-lang.json at line 278:
<comment>The proxy-cache input validation hint is still in English inside the es-es translations, so Spanish users will see mixed-language messaging. Please translate it.</comment>
<file context>
@@ -272,7 +272,10 @@
+ "NO_PROJECT": "No pudimos encontrar ningún proyecto",
+ "CONNECTION_LIMIT": "Max connection to upstream registry",
+ "PROXY_CACHE_MAX_UPSTREAM_CONN_TIP": "The max connection to the upstream registry for this proxy cache project, if -1, then there is no limit",
+ "PROXY_CACHE_MAX_UPSTREAM_CONN_INPUT_TIP": "Please enter -1 or an integer greater than 0. "
},
"PROJECT_DETAIL": {
</file context>
| "PROXY_CACHE_ENDPOINT": "Proxy Cache Endpoint", | ||
| "NO_PROJECT": "No pudimos encontrar ningún proyecto" | ||
| "NO_PROJECT": "No pudimos encontrar ningún proyecto", | ||
| "CONNECTION_LIMIT": "Max connection to upstream registry", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This new proxy-cache label is left in English inside the es-es locale file, so the Spanish UI will display untranslated text. Please provide the Spanish translation.
Prompt for AI agents
Address the following comment on src/portal/src/i18n/lang/es-es-lang.json at line 276:
<comment>This new proxy-cache label is left in English inside the es-es locale file, so the Spanish UI will display untranslated text. Please provide the Spanish translation.</comment>
<file context>
@@ -272,7 +272,10 @@
"PROXY_CACHE_ENDPOINT": "Proxy Cache Endpoint",
- "NO_PROJECT": "No pudimos encontrar ningún proyecto"
+ "NO_PROJECT": "No pudimos encontrar ningún proyecto",
+ "CONNECTION_LIMIT": "Max connection to upstream registry",
+ "PROXY_CACHE_MAX_UPSTREAM_CONN_TIP": "The max connection to the upstream registry for this proxy cache project, if -1, then there is no limit",
+ "PROXY_CACHE_MAX_UPSTREAM_CONN_INPUT_TIP": "Please enter -1 or an integer greater than 0. "
</file context>
| return nil | ||
| } | ||
|
|
||
| func (m *mockAdapter) DeleteManifest(repository, reference string) error { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The tests override DeleteManifest on the mock adapter, so the new cases never execute the real adapter.DeleteManifest implementation; they only validate the mock’s duplicate logic, leaving production behavior untested.
Prompt for AI agents
Address the following comment on src/pkg/reg/adapter/tencentcr/artifact_registry_test.go at line 178:
<comment>The tests override DeleteManifest on the mock adapter, so the new cases never execute the real adapter.DeleteManifest implementation; they only validate the mock’s duplicate logic, leaving production behavior untested.</comment>
<file context>
@@ -130,41 +163,72 @@ func Test_adapter_listCandidateNamespaces(t *testing.T) {
+ return nil
+}
+
+func (m *mockAdapter) DeleteManifest(repository, reference string) error {
+ parts := strings.Split(repository, "/")
+ if len(parts) != 2 {
</file context>
| class="clr-input width-164 mr-10 clr-input-underline" | ||
| autocomplete="off" /> | ||
| <clr-icon | ||
| *ngIf="maxUpstreamConnError" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The added connection-limit field renders maxUpstreamConnError, but the component never updates this flag or validates projectPolicy.MaxUpstreamConn, so invalid inputs produce no feedback and the tooltip/icon never appear.
Prompt for AI agents
Address the following comment on src/portal/src/app/base/project/project-config/project-policy-config/project-policy-config.component.html at line 111:
<comment>The added connection-limit field renders `maxUpstreamConnError`, but the component never updates this flag or validates `projectPolicy.MaxUpstreamConn`, so invalid inputs produce no feedback and the tooltip/icon never appear.</comment>
<file context>
@@ -92,6 +92,35 @@
+ class="clr-input width-164 mr-10 clr-input-underline"
+ autocomplete="off" />
+ <clr-icon
+ *ngIf="maxUpstreamConnError"
+ class="clr-validate-icon"
+ shape="exclamation-circle"></clr-icon>
</file context>
| RETURN; | ||
| END IF; | ||
|
|
||
| IF (SELECT last_value FROM audit_log_id_seq) > 1 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The migration determines prior audit-log usage via last_value > 1 on the audit log sequences, but sequences report last_value = 1 both before any insert and after the first insert. Deployments with only one stored audit log are therefore treated as if the tables were unused, so the skip_audit_log_database property is never created and environment defaults can disable database auditing after upgrade. Consider checking the sequence’s is_called flag or querying the audit_log tables for existing rows instead.
Prompt for AI agents
Address the following comment on make/migrations/postgresql/0180_2.15.0_schema.up.sql at line 13:
<comment>The migration determines prior audit-log usage via `last_value > 1` on the audit log sequences, but sequences report `last_value = 1` both before any insert and after the first insert. Deployments with only one stored audit log are therefore treated as if the tables were unused, so the `skip_audit_log_database` property is never created and environment defaults can disable database auditing after upgrade. Consider checking the sequence’s `is_called` flag or querying the audit_log tables for existing rows instead.</comment>
<file context>
@@ -0,0 +1,17 @@
+ RETURN;
+ END IF;
+
+ IF (SELECT last_value FROM audit_log_id_seq) > 1
+ OR (SELECT last_value FROM audit_log_ext_id_seq) > 1 THEN
+ INSERT INTO properties (k, v) VALUES ('skip_audit_log_database', 'false');
</file context>
| "MSG_SCHEDULE_RESET": "Расписание для сборки мусора сброшено", | ||
| "PARAMETERS": "Параметры", | ||
| "DELETE_UNTAGGED": "Разрешить сборку мусора для непомеченных артефактов", | ||
| "DELETE_TAG": "Allow garbage collection to remove tag files from backend storage", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The Russian locale entry for the new garbage-collection delete-tag option remains in English, so Russian users will see untranslated text in the GC settings.
Prompt for AI agents
Address the following comment on src/portal/src/i18n/lang/ru-ru-lang.json at line 1273:
<comment>The Russian locale entry for the new garbage-collection delete-tag option remains in English, so Russian users will see untranslated text in the GC settings.</comment>
<file context>
@@ -1267,6 +1270,7 @@
"MSG_SCHEDULE_RESET": "Расписание для сборки мусора сброшено",
"PARAMETERS": "Параметры",
"DELETE_UNTAGGED": "Разрешить сборку мусора для непомеченных артефактов",
+ "DELETE_TAG": "Allow garbage collection to remove tag files from backend storage",
"EXPLAIN": "GC — это ресурсоемкая операция, которая может повлиять на производительность реестра",
"DRY_RUN_SUCCESS": "Сухой запуск успешно запущен"
</file context>
| "NO_PROJECT": "Мы не смогли найти никаких проектов", | ||
| "CONNECTION_LIMIT": "Max connection to upstream registry", | ||
| "PROXY_CACHE_MAX_UPSTREAM_CONN_TIP": "The max connection to the upstream registry for this proxy cache project, if -1, then there is no limit", | ||
| "PROXY_CACHE_MAX_UPSTREAM_CONN_INPUT_TIP": "Please enter -1 or an integer greater than 0. " |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The RU locale entry for the proxy-cache connection limit validation tip is still English and includes a trailing space, so the UI shows untranslated text with stray whitespace.
Prompt for AI agents
Address the following comment on src/portal/src/i18n/lang/ru-ru-lang.json at line 262:
<comment>The RU locale entry for the proxy-cache connection limit validation tip is still English and includes a trailing space, so the UI shows untranslated text with stray whitespace.</comment>
<file context>
@@ -256,7 +256,10 @@
+ "NO_PROJECT": "Мы не смогли найти никаких проектов",
+ "CONNECTION_LIMIT": "Max connection to upstream registry",
+ "PROXY_CACHE_MAX_UPSTREAM_CONN_TIP": "The max connection to the upstream registry for this proxy cache project, if -1, then there is no limit",
+ "PROXY_CACHE_MAX_UPSTREAM_CONN_INPUT_TIP": "Please enter -1 or an integer greater than 0. "
},
"PROJECT_DETAIL": {
</file context>
| "NO_PROJECT": "Мы не смогли найти никаких проектов" | ||
| "NO_PROJECT": "Мы не смогли найти никаких проектов", | ||
| "CONNECTION_LIMIT": "Max connection to upstream registry", | ||
| "PROXY_CACHE_MAX_UPSTREAM_CONN_TIP": "The max connection to the upstream registry for this proxy cache project, if -1, then there is no limit", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The tooltip text for the proxy-cache connection limit was added to the Russian locale file but left in English, leaving the new UI help untranslated.
Prompt for AI agents
Address the following comment on src/portal/src/i18n/lang/ru-ru-lang.json at line 261:
<comment>The tooltip text for the proxy-cache connection limit was added to the Russian locale file but left in English, leaving the new UI help untranslated.</comment>
<file context>
@@ -256,7 +256,10 @@
- "NO_PROJECT": "Мы не смогли найти никаких проектов"
+ "NO_PROJECT": "Мы не смогли найти никаких проектов",
+ "CONNECTION_LIMIT": "Max connection to upstream registry",
+ "PROXY_CACHE_MAX_UPSTREAM_CONN_TIP": "The max connection to the upstream registry for this proxy cache project, if -1, then there is no limit",
+ "PROXY_CACHE_MAX_UPSTREAM_CONN_INPUT_TIP": "Please enter -1 or an integer greater than 0. "
},
</file context>
fix: resolve 'docker-compose: command not found' error Add fallback to support Docker Compose V2 plugin format when standalone docker-compose binary is not available. Signed-off-by: coldenchen <[email protected]> Co-authored-by: coldenchen <[email protected]>
Signed-off-by: chlins <[email protected]>
|


Syncing with upstream
Summary by cubic
Sync repo with Harbor v2.15.0 and add per‑project upstream connection limits for proxy cache. Stop writing tag files to backend storage and add a delete‑tag option in GC; also include env/migration support to control audit‑log storage, plus CI and dependency updates.
New Features
Bug Fixes
Written for commit c3c95e7. Summary will update automatically on new commits.
Summary by CodeRabbit
New Features
Documentation
Chores
✏️ Tip: You can customize this high-level summary in your review settings.