Skip to content
Open
Show file tree
Hide file tree
Changes from 43 commits
Commits
Show all changes
46 commits
Select commit Hold shift + click to select a range
b1d41ce
bump base to v2.15.0 (#22316)
wy65701436 Sep 3, 2025
19c60ea
Remove port 9443 from harbor IP for webhook event check (#22320)
stonezdj Sep 5, 2025
8262d0a
Remove GCR replication because GCR account is removed (#22309)
stonezdj Sep 5, 2025
2c6de87
chore(deps): bump github.com/stretchr/testify from 1.10.0 to 1.11.1 i…
dependabot[bot] Sep 8, 2025
1e18d90
chore(deps): bump github.com/aws/aws-sdk-go from 1.55.6 to 1.55.8 in …
dependabot[bot] Sep 10, 2025
d81beb3
chore(deps): bump github.com/go-ldap/ldap/v3 from 3.4.10 to 3.4.11 in…
dependabot[bot] Sep 10, 2025
7781d64
chore(deps): bump aws-actions/configure-aws-credentials from 4.2.1 to…
dependabot[bot] Sep 11, 2025
d0ad35e
chore(deps): bump actions/setup-node from 4 to 5 (#22325)
dependabot[bot] Sep 11, 2025
08a6300
chore(deps): bump actions/stale from 9.1.0 to 10.0.0 (#22323)
dependabot[bot] Sep 11, 2025
a7e990c
chore(deps): bump golang.org/x/text from 0.27.0 to 0.29.0 in /src (#2…
dependabot[bot] Sep 11, 2025
c122380
chore(deps): bump github.com/volcengine/volcengine-go-sdk from 1.1.29…
dependabot[bot] Sep 12, 2025
0f1edd0
Remove p2p preheat by event testcase (#22354)
stonezdj Sep 15, 2025
a0cdadb
chore(deps): bump github.com/volcengine/volcengine-go-sdk from 1.1.32…
dependabot[bot] Sep 15, 2025
c588d79
chore(deps): bump golang.org/x/time from 0.12.0 to 0.13.0 in /src (#2…
dependabot[bot] Sep 16, 2025
921b0d3
chore(deps): bump k8s.io/client-go from 0.33.3 to 0.34.1 in /src (#22…
dependabot[bot] Sep 16, 2025
430a8a7
chore(deps): bump github.com/golang-migrate/migrate/v4 from 4.18.1 to…
dependabot[bot] Sep 17, 2025
81fc902
chore(deps): bump github.com/coreos/go-oidc/v3 from 3.12.0 to 3.15.0 …
dependabot[bot] Sep 17, 2025
9cc824f
chore(deps): bump go.opentelemetry.io/contrib/instrumentation/github.…
dependabot[bot] Sep 24, 2025
47586cd
Update badges (#22139)
Vad1mo Sep 25, 2025
1a7eb31
add tag deletion option for gc (#22382)
wy65701436 Sep 29, 2025
4da6070
fix robot issue-21406 (#22387)
wy65701436 Sep 29, 2025
c004f2d
Add max_upstream_conn parameter for each proxy_cache project (#22348)
stonezdj Sep 30, 2025
d0934b2
Add UI for limit upstream registry connection (#22406)
stonezdj Oct 10, 2025
e706647
Update and improve zh-TW Traditional Chinese locale (#22423)
PeterDaveHello Oct 13, 2025
6e15beb
Allow disable audit log to DB when initialize (#22452)
wy65701436 Oct 17, 2025
4d3c023
Update zh-TW Traditional Chinese locale (#22468)
PeterDaveHello Oct 17, 2025
c878bbf
add migraiton sql for skip_audit_log_database (#22487)
wy65701436 Oct 23, 2025
5402ac7
refactor: use strings.Builder to improve performance (#22453)
rocksload Oct 24, 2025
01f848e
refactor: replace Split in loops with more efficient SplitSeq (#22494)
rustversion Oct 24, 2025
c305a80
refactor the logic to init skip_audit_log_database (#22493)
wy65701436 Oct 24, 2025
5a0e81e
Configure dependabot to update the release-2.14.0 branch (#22503)
reasonerjt Oct 28, 2025
575aed0
chore(deps): bump golang.org/x/net from 0.41.0 to 0.46.0 in /src (#22…
dependabot[bot] Oct 28, 2025
bdee4da
Remove legacy switch from decodeFilters after UI bug #12579 fix (#22510)
intojhanurag Oct 29, 2025
4103e3f
chore(deps): bump github.com/volcengine/volcengine-go-sdk from 1.1.34…
dependabot[bot] Oct 29, 2025
ce6e76a
chore(deps): bump actions/upload-artifact from 4 to 5 (#22509)
dependabot[bot] Oct 29, 2025
eb401aa
fix robot call the users api (#22492)
wy65701436 Oct 29, 2025
b0e54ca
Update Release note template and dependabot labels (#22528)
OrlinVasilev Oct 29, 2025
e9bc2c3
docs: minor improvement for docs (#22526)
geogrego Oct 30, 2025
71bbd56
test:add-filterToPatterns-unit-test (#22511)
intojhanurag Oct 31, 2025
985d5c3
ci(workflows): update runner to oracle-vm-24cpu-96gb-x86-64 (#22455)
chlins Oct 31, 2025
80daa2d
refactor: replace HasPrefix+TrimPrefix with CutPrefix (#22520)
dulanting Nov 5, 2025
8f7e4bb
Add unit test for DeleteManifest method in TencentCR adapter (#22537)
intojhanurag Nov 5, 2025
95003aa
disable land tag in the backend storage (#22507)
wy65701436 Nov 6, 2025
26f6310
fix(registry): correct parameter in upload status query (#22574)
chlins Nov 19, 2025
8c3f0c6
fix: support both docker-compose v1 and docker compose v2 (#22581)
Coldchen99 Nov 26, 2025
c3c95e7
ci(workflows): simplify label pattern in label_check (#22596)
chlins Nov 28, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 12 additions & 2 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,16 @@ updates:
schedule:
interval: "weekly"
labels:
- "release-note/update"

- "release-note/bump-version"
- "branch/main"

- package-ecosystem: "gomod"
directory: "/src"
schedule:
interval: "weekly"
target-branch: "release-2.14.0"
labels:
- "release-note/bump-version"
- "branch/release-2.14.0"

# More will be needed
6 changes: 5 additions & 1 deletion .github/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,10 @@ changelog:
labels:
- release-note/deprecation

- title: Bump Component Version 🤖
labels:
- release-note/bump-version

- title: Other Changes
labels:
- "*"
- "*"
29 changes: 19 additions & 10 deletions .github/workflows/CI.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ env:
UI_BUILDER_VERSION: 1.6.0

on:
# the paths-ignore is the same as the paths in pass-CI.yml, they should be synced together
# see https://web.archive.org/web/20230506145443/https://docs.github.com/en/repositories/configuring-branches-and-merges-in-your-repository/managing-protected-branches/troubleshooting-required-status-checks#handling-skipped-but-required-checks
pull_request:
paths-ignore:
- 'docs/**'
Expand All @@ -23,22 +25,29 @@ on:
- '!tests/**.sh'
- '!tests/apitests/**'
- '!tests/ci/**'
- '!tests/resources/**'
- '!tests/robot-cases/**'
- '!tests/robot-cases/Group1-Nightly/**'
push:
# the paths-ignore is the same as the paths in pass-CI.yml, they should be synced together
paths-ignore:
- 'docs/**'
- '**.md'
- 'tests/**'
- '!tests/**.sh'
- '!tests/apitests/**'
- '!tests/ci/**'
- '!tests/resources/**'
- '!tests/robot-cases/**'
- '!tests/robot-cases/Group1-Nightly/**'

jobs:
UTTEST:
env:
UTTEST: true
runs-on:
#- self-hosted
- ubuntu-latest
- oracle-vm-24cpu-96gb-x86-64
timeout-minutes: 100
steps:
- name: Set up Go 1.23
Expand Down Expand Up @@ -99,7 +108,7 @@ jobs:
APITEST_DB: true
runs-on:
#- self-hosted
- ubuntu-latest
- oracle-vm-24cpu-96gb-x86-64
timeout-minutes: 100
steps:
- name: Set up Go 1.23
Expand Down Expand Up @@ -149,7 +158,7 @@ jobs:
bash ./tests/showtime.sh ./tests/ci/api_run.sh DB $IP
df -h
- name: upload_logs
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@v5
with:
name: db-api-harbor-logs.tar.gz
path: /home/runner/work/harbor/harbor/src/github.com/goharbor/harbor/integration_logs.tar.gz
Expand All @@ -159,7 +168,7 @@ jobs:
APITEST_DB: true
runs-on:
#- self-hosted
- ubuntu-latest
- oracle-vm-24cpu-96gb-x86-64
timeout-minutes: 100
steps:
- name: Set up Go 1.23
Expand Down Expand Up @@ -209,7 +218,7 @@ jobs:
bash ./tests/showtime.sh ./tests/ci/api_run.sh PROXY_CACHE $IP
df -h
- name: upload_logs
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@v5
with:
name: proxy-api-harbor-logs.tar.gz
path: /home/runner/work/harbor/harbor/src/github.com/goharbor/harbor/integration_logs.tar.gz
Expand All @@ -219,7 +228,7 @@ jobs:
APITEST_LDAP: true
runs-on:
#- self-hosted
- ubuntu-latest
- oracle-vm-24cpu-96gb-x86-64
timeout-minutes: 100
steps:
- name: Set up Go 1.23
Expand Down Expand Up @@ -267,7 +276,7 @@ jobs:
bash ./tests/showtime.sh ./tests/ci/api_run.sh LDAP $IP
df -h
- name: upload_logs
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@v5
with:
name: ldap-api-harbor-logs.tar.gz
path: /home/runner/work/harbor/harbor/src/github.com/goharbor/harbor/integration_logs.tar.gz
Expand All @@ -277,7 +286,7 @@ jobs:
OFFLINE: true
runs-on:
#- self-hosted
- ubuntu-latest
- oracle-vm-24cpu-96gb-x86-64
timeout-minutes: 100
steps:
- name: Set up Go 1.23
Expand Down Expand Up @@ -329,10 +338,10 @@ jobs:
UI_UT: true
runs-on:
#- self-hosted
- ubuntu-latest
- oracle-vm-24cpu-96gb-x86-64
timeout-minutes: 100
steps:
- uses: actions/setup-node@v4
- uses: actions/setup-node@v5
with:
node-version: '18'
- uses: actions/checkout@v5
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/build-package.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,10 @@ jobs:
env:
BUILD_PACKAGE: true
runs-on:
- ubuntu-22.04
- oracle-vm-24cpu-96gb-x86-64
steps:
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v4.2.1
uses: aws-actions/configure-aws-credentials@v5.0.0
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/conformance_test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,10 @@ jobs:
CONFORMANCE_TEST: true
runs-on:
#- self-hosted
- ubuntu-latest
- oracle-vm-24cpu-96gb-x86-64
steps:
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v4.2.1
uses: aws-actions/configure-aws-credentials@v5.0.0
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/housekeeping-stale-issues-prs.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ jobs:
stale:
runs-on: ubuntu-latest
steps:
- uses: actions/stale@v9.1.0
- uses: actions/stale@v10.0.0
Copy link

@cubic-dev-ai cubic-dev-ai bot Nov 19, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Prompt for AI agents
Address the following comment on .github/workflows/housekeeping-stale-issues-prs.yaml at line 10:

<comment>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.</comment>

<file context>
@@ -7,7 +7,7 @@ jobs:
     runs-on: ubuntu-latest
     steps:
-      - uses: actions/[email protected]
+      - uses: actions/[email protected]
         with:
           stale-issue-message: &#39;This issue is being marked stale due to a period of inactivity. If this issue is still relevant, please comment or remove the stale label. Otherwise, this issue will close in 30 days.&#39;
</file context>
Suggested change
- uses: actions/stale@v10.0.0
- uses: actions/stale@3a9db7e6a41a89f618792c92c0e97cc736e1b13f
Fix with Cubic

with:
stale-issue-message: 'This issue is being marked stale due to a period of inactivity. If this issue is still relevant, please comment or remove the stale label. Otherwise, this issue will close in 30 days.'
stale-pr-message: 'This PR is being marked stale due to a period of inactivty. If this PR is still relevant, please comment or remove the stale label. Otherwise, this PR will close in 30 days.'
Expand Down
2 changes: 2 additions & 0 deletions .github/workflows/pass-CI.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ name: CI

on:
pull_request:
# the paths is the same as the paths-ignore in CI.yml, they should be synced together
paths:
- 'docs/**'
- '**.md'
Expand All @@ -13,6 +14,7 @@ on:
- '!tests/robot-cases/**'
- '!tests/robot-cases/Group1-Nightly/**'
push:
# the paths is the same as the paths-ignore in CI.yml, they should be synced together
paths:
- 'docs/**'
- '**.md'
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/publish_release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ on:

jobs:
release:
runs-on: ubuntu-22.04
runs-on: oracle-vm-24cpu-96gb-x86-64
steps:
- uses: actions/checkout@v5
- name: Setup env
Expand All @@ -20,7 +20,7 @@ jobs:
echo "BRANCH=$(echo $release | jq -r '.target_commitish')" >> $GITHUB_ENV
echo "PRERELEASE=$(echo $release | jq -r '.prerelease')" >> $GITHUB_ENV
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v4.2.1
uses: aws-actions/configure-aws-credentials@v5.0.0
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
Expand Down
10 changes: 4 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,15 +1,13 @@
# Harbor

[![CI](https://github.com/goharbor/harbor/workflows/CI/badge.svg?branch=main&event=push)](https://github.com/goharbor/harbor/actions?query=event%3Apush+branch%3Amain+workflow%3ACI+)
[![Coverage Status](https://codecov.io/gh/goharbor/harbor/branch/main/graph/badge.svg)](https://codecov.io/gh/goharbor/harbor)
[![CI](https://github.com/goharbor/harbor/actions/workflows/CI.yml/badge.svg)](https://github.com/goharbor/harbor/actions/workflows/CI.yml)
[![Go Report Card](https://goreportcard.com/badge/github.com/goharbor/harbor)](https://goreportcard.com/report/github.com/goharbor/harbor)
[![Coverage Status](https://codecov.io/gh/goharbor/harbor/branch/main/graph/badge.svg)](https://codecov.io/gh/goharbor/harbor)
[![CII Best Practices](https://bestpractices.coreinfrastructure.org/projects/2095/badge)](https://bestpractices.coreinfrastructure.org/projects/2095)
[![Codacy Badge](https://app.codacy.com/project/badge/Grade/792fe1755edc4d6e91f4c3469f553389)](https://www.codacy.com/gh/goharbor/harbor/dashboard?utm_source=github.com&amp;utm_medium=referral&amp;utm_content=goharbor/harbor&amp;utm_campaign=Badge_Grade)
![Code scanning - action](https://github.com/goharbor/harbor/workflows/Code%20scanning%20-%20action/badge.svg)
[![Nightly Status](https://us-central1-eminent-nation-87317.cloudfunctions.net/harbor-nightly-result)](https://www.googleapis.com/storage/v1/b/harbor-nightly/o)
![CONFORMANCE_TEST](https://github.com/goharbor/harbor/workflows/CONFORMANCE_TEST/badge.svg)
![OCI Distribution Conformance Tests](https://github.com/goharbor/harbor/workflows/CONFORMANCE_TEST/badge.svg)
[![FOSSA Status](https://app.fossa.com/api/projects/git%2Bgithub.com%2Fgoharbor%2Fharbor.svg?type=shield)](https://app.fossa.com/projects/git%2Bgithub.com%2Fgoharbor%2Fharbor?ref=badge_shield)
[![Artifact HUB](https://img.shields.io/endpoint?url=https://artifacthub.io/badge/repository/harbor)](https://artifacthub.io/packages/helm/harbor/harbor)
[![Helm Chart on Artifact Hub](https://img.shields.io/endpoint?url=https://artifacthub.io/badge/repository/harbor)](https://artifacthub.io/packages/helm/harbor/harbor)
</br>

|![notification](https://raw.githubusercontent.com/goharbor/website/master/docs/img/readme/bell-outline-badged.svg)Community Meeting|
Expand Down
2 changes: 1 addition & 1 deletion VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
v2.14.0
v2.15.0
4 changes: 4 additions & 0 deletions api/v2.0/swagger.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -7321,6 +7321,10 @@ definitions:
type: string
description: 'The bandwidth limit of proxy cache, in Kbps (kilobits per second). It limits the communication between Harbor and the upstream registry, not the client and the Harbor.'
x-nullable: true
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
ProjectSummary:
type: object
properties:
Expand Down
17 changes: 17 additions & 0 deletions make/migrations/postgresql/0180_2.15.0_schema.up.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
/*
Initialize skip_audit_log_database configuration based on existing audit log usage - Only insert the configuration if it doesn't already exist
1. If tables exist and show evidence of previous usage
set skip_audit_log_database to false
2. If tables exist but show no evidence of usage, don't create the configuration record
*/
DO $$
BEGIN
IF EXISTS (SELECT 1 FROM properties WHERE k = 'skip_audit_log_database') THEN
RETURN;
END IF;

IF (SELECT last_value FROM audit_log_id_seq) > 1
Copy link

@cubic-dev-ai cubic-dev-ai bot Nov 6, 2025

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 &gt;= 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) &gt; 1
+       OR (SELECT last_value FROM audit_log_ext_id_seq) &gt; 1 THEN
+        INSERT INTO properties (k, v) VALUES (&#39;skip_audit_log_database&#39;, &#39;false&#39;);
</file context>
Fix with Cubic

Copy link

@cubic-dev-ai cubic-dev-ai bot Nov 19, 2025

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 &gt; 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) &gt; 1
+       OR (SELECT last_value FROM audit_log_ext_id_seq) &gt; 1 THEN
+        INSERT INTO properties (k, v) VALUES (&#39;skip_audit_log_database&#39;, &#39;false&#39;);
</file context>
Fix with Cubic

OR (SELECT last_value FROM audit_log_ext_id_seq) > 1 THEN
INSERT INTO properties (k, v) VALUES ('skip_audit_log_database', 'false');
END IF;
END $$;
7 changes: 4 additions & 3 deletions src/common/api/base.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import (
"fmt"
"net/http"
"strconv"
"strings"

"github.com/beego/beego/v2/core/validation"
"github.com/beego/beego/v2/server/web"
Expand Down Expand Up @@ -98,11 +99,11 @@ func (b *BaseAPI) Validate(v any) (bool, error) {
}

if !isValid {
message := ""
var message strings.Builder
for _, e := range validator.Errors {
message += fmt.Sprintf("%s %s \n", e.Field, e.Message)
message.WriteString(fmt.Sprintf("%s %s \n", e.Field, e.Message))
}
return false, errors.New(message)
return false, errors.New(message.String())
}
return true, nil
}
Expand Down
4 changes: 2 additions & 2 deletions src/common/secret/request.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,8 @@ func FromRequest(req *http.Request) string {
return ""
}
auth := req.Header.Get("Authorization")
if strings.HasPrefix(auth, HeaderPrefix) {
return strings.TrimPrefix(auth, HeaderPrefix)
if after, ok := strings.CutPrefix(auth, HeaderPrefix); ok {
return after
}
return ""
}
Expand Down
3 changes: 3 additions & 0 deletions src/controller/gc/controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ type controller struct {
func (c *controller) Start(ctx context.Context, policy Policy, trigger string) (int64, error) {
para := make(map[string]any)
para["delete_untagged"] = policy.DeleteUntagged
para["delete_tag"] = policy.DeleteTag
Copy link

@cubic-dev-ai cubic-dev-ai bot Nov 6, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Prompt for AI agents
Address the following comment on src/controller/gc/controller.go at line 80:

<comment>Setting `para[&quot;delete_tag&quot;]` unconditionally forces the value to `false` whenever the incoming policy omits it, overriding the job&#39;s default of deleting tags. Please omit the parameter when the policy doesn&#39;t define it so legacy behavior remains intact.</comment>

<file context>
@@ -77,6 +77,7 @@ type controller struct {
 func (c *controller) Start(ctx context.Context, policy Policy, trigger string) (int64, error) {
 	para := make(map[string]any)
 	para[&quot;delete_untagged&quot;] = policy.DeleteUntagged
+	para[&quot;delete_tag&quot;] = policy.DeleteTag
 	para[&quot;dry_run&quot;] = policy.DryRun
 	para[&quot;workers&quot;] = policy.Workers
</file context>
Fix with Cubic

para["dry_run"] = policy.DryRun
para["workers"] = policy.Workers
para["redis_url_reg"] = policy.ExtraAttrs["redis_url_reg"]
Expand Down Expand Up @@ -205,6 +206,7 @@ func (c *controller) GetSchedule(ctx context.Context) (*scheduler.Schedule, erro
func (c *controller) CreateSchedule(ctx context.Context, cronType, cron string, policy Policy) (int64, error) {
extras := make(map[string]any)
extras["delete_untagged"] = policy.DeleteUntagged
extras["delete_tag"] = policy.DeleteTag
Copy link

@cubic-dev-ai cubic-dev-ai bot Nov 6, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Prompt for AI agents
Address the following comment on src/controller/gc/controller.go at line 209:

<comment>Writing `extras[&quot;delete_tag&quot;]` 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.</comment>

<file context>
@@ -205,6 +206,7 @@ func (c *controller) GetSchedule(ctx context.Context) (*scheduler.Schedule, erro
 func (c *controller) CreateSchedule(ctx context.Context, cronType, cron string, policy Policy) (int64, error) {
 	extras := make(map[string]any)
 	extras[&quot;delete_untagged&quot;] = policy.DeleteUntagged
+	extras[&quot;delete_tag&quot;] = policy.DeleteTag
 	extras[&quot;workers&quot;] = policy.Workers
 	return c.schedulerMgr.Schedule(ctx, job.GarbageCollectionVendorType, -1, cronType, cron, job.GarbageCollectionVendorType, policy, extras)
</file context>
Fix with Cubic

extras["workers"] = policy.Workers
return c.schedulerMgr.Schedule(ctx, job.GarbageCollectionVendorType, -1, cronType, cron, job.GarbageCollectionVendorType, policy, extras)
}
Expand Down Expand Up @@ -234,6 +236,7 @@ func convertTask(task *task.Task) *Task {
StatusMessage: task.StatusMessage,
RunCount: task.RunCount,
DeleteUntagged: task.GetBoolFromExtraAttrs("delete_untagged"),
DeleteTag: task.GetBoolFromExtraAttrs("delete_tag"),
Copy link

@cubic-dev-ai cubic-dev-ai bot Nov 6, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Prompt for AI agents
Address the following comment on src/controller/gc/controller.go at line 239:

<comment>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.</comment>

<file context>
@@ -234,6 +236,7 @@ func convertTask(task *task.Task) *Task {
 		StatusMessage:  task.StatusMessage,
 		RunCount:       task.RunCount,
 		DeleteUntagged: task.GetBoolFromExtraAttrs(&quot;delete_untagged&quot;),
+		DeleteTag:      task.GetBoolFromExtraAttrs(&quot;delete_tag&quot;),
 		DryRun:         task.GetBoolFromExtraAttrs(&quot;dry_run&quot;),
 		Workers:        int(task.GetNumFromExtraAttrs(&quot;workers&quot;)),
</file context>
Fix with Cubic

DryRun: task.GetBoolFromExtraAttrs("dry_run"),
Workers: int(task.GetNumFromExtraAttrs("workers")),
JobID: task.JobID,
Expand Down
2 changes: 2 additions & 0 deletions src/controller/gc/controller_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ func (g *gcCtrTestSuite) TestStart() {
dataMap := make(map[string]any)
p := Policy{
DeleteUntagged: true,
DeleteTag: true,
ExtraAttrs: dataMap,
}
id, err := g.ctl.Start(nil, p, task.ExecutionTriggerManual)
Expand Down Expand Up @@ -149,6 +150,7 @@ func (g *gcCtrTestSuite) TestCreateSchedule() {
dataMap := make(map[string]any)
p := Policy{
DeleteUntagged: true,
DeleteTag: true,
ExtraAttrs: dataMap,
Workers: 3,
}
Expand Down
2 changes: 2 additions & 0 deletions src/controller/gc/model.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import (
type Policy struct {
Trigger *Trigger `json:"trigger"`
DeleteUntagged bool `json:"deleteuntagged"`
DeleteTag bool `json:"deletetag"`
Copy link

@cubic-dev-ai cubic-dev-ai bot Nov 6, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Prompt for AI agents
Address the following comment on src/controller/gc/model.go at line 25:

<comment>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.</comment>

<file context>
@@ -22,6 +22,7 @@ import (
 type Policy struct {
 	Trigger        *Trigger       `json:&quot;trigger&quot;`
 	DeleteUntagged bool           `json:&quot;deleteuntagged&quot;`
+	DeleteTag      bool           `json:&quot;deletetag&quot;`
 	DryRun         bool           `json:&quot;dryrun&quot;`
 	Workers        int            `json:&quot;workers&quot;`
</file context>
Fix with Cubic

DryRun bool `json:"dryrun"`
Workers int `json:"workers"`
ExtraAttrs map[string]any `json:"extra_attrs"`
Expand Down Expand Up @@ -60,6 +61,7 @@ type Task struct {
StatusMessage string
RunCount int32
DeleteUntagged bool
DeleteTag bool
Copy link

@cubic-dev-ai cubic-dev-ai bot Nov 6, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Prompt for AI agents
Address the following comment on src/controller/gc/model.go at line 64:

<comment>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.</comment>

<file context>
@@ -60,6 +61,7 @@ type Task struct {
 	StatusMessage  string
 	RunCount       int32
 	DeleteUntagged bool
+	DeleteTag      bool
 	DryRun         bool
 	Workers        int
</file context>
Fix with Cubic

DryRun bool
Workers int
JobID string
Expand Down
2 changes: 1 addition & 1 deletion src/controller/registry/controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -214,7 +214,7 @@ func getWhitelistedAdapters(ctx context.Context) map[string]struct{} {
return nil
}
adapterWhitelist := make(map[string]struct{})
for _, adapter := range strings.Split(adapterWhitelistRaw, ",") {
for adapter := range strings.SplitSeq(adapterWhitelistRaw, ",") {
adapter = strings.TrimSpace(adapter)
if adapter != "" {
adapterWhitelist[adapter] = struct{}{}
Expand Down
Loading