Script 'mail_helper' called by obssrc
Hello community,
here is the log from the commit of package gitlab-container-registry for
openSUSE:Factory checked in at 2025-06-06 22:42:28
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/gitlab-container-registry (Old)
and /work/SRC/openSUSE:Factory/.gitlab-container-registry.new.19631 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "gitlab-container-registry"
Fri Jun 6 22:42:28 2025 rev:7 rq:1283454 version:4.23.1
Changes:
--------
---
/work/SRC/openSUSE:Factory/gitlab-container-registry/gitlab-container-registry.changes
2025-06-02 22:02:07.541115766 +0200
+++
/work/SRC/openSUSE:Factory/.gitlab-container-registry.new.19631/gitlab-container-registry.changes
2025-06-06 22:42:52.756362346 +0200
@@ -1,0 +2,20 @@
+Thu Jun 05 20:10:03 UTC 2025 - Johannes Kastl
<[email protected]>
+
+- Update to version 4.23.1:
+ * Bug Fixes
+ - api/gitlab/v1: fix repository cache initialization (d135234)
+ - remmove cloudsql incompatible migrations (ef66c26)
+ - Stat call should properly handle unprefixed configurations in
+ s3_v2 storage driver (4b67a75)
+ * Reverts
+ - revert 7fed33f9 (ede0ad3)
+ - revert ef66c261 (d00e168)
+ * Build
+ - deps: update module github.com/alicebob/miniredis/v2 to
+ v2.35.0 (f554f29)
+ - deps: update module google.golang.org/api to v0.235.0
+ (5313f8f)
+ - deps: update module google.golang.org/api to v0.236.0
+ (38034e4)
+
+-------------------------------------------------------------------
Old:
----
gitlab-container-registry-4.23.0.obscpio
New:
----
gitlab-container-registry-4.23.1.obscpio
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ gitlab-container-registry.spec ++++++
--- /var/tmp/diff_new_pack.TeE0wt/_old 2025-06-06 22:42:54.200422192 +0200
+++ /var/tmp/diff_new_pack.TeE0wt/_new 2025-06-06 22:42:54.204422358 +0200
@@ -17,7 +17,7 @@
Name: gitlab-container-registry
-Version: 4.23.0
+Version: 4.23.1
Release: 0
Summary: The GitLab Container Registry
License: Apache-2.0
++++++ _service ++++++
--- /var/tmp/diff_new_pack.TeE0wt/_old 2025-06-06 22:42:54.236423684 +0200
+++ /var/tmp/diff_new_pack.TeE0wt/_new 2025-06-06 22:42:54.240423850 +0200
@@ -3,7 +3,7 @@
<param
name="url">https://gitlab.com/gitlab-org/container-registry.git</param>
<param name="scm">git</param>
<param name="exclude">.git</param>
- <param name="revision">v4.23.0-gitlab</param>
+ <param name="revision">v4.23.1-gitlab</param>
<param name="versionformat">@PARENT_TAG@</param>
<param name="versionrewrite-pattern">v(.*)-gitlab</param>
<param name="changesgenerate">enable</param>
++++++ _servicedata ++++++
--- /var/tmp/diff_new_pack.TeE0wt/_old 2025-06-06 22:42:54.264424844 +0200
+++ /var/tmp/diff_new_pack.TeE0wt/_new 2025-06-06 22:42:54.268425010 +0200
@@ -1,6 +1,6 @@
<servicedata>
<service name="tar_scm">
<param
name="url">https://gitlab.com/gitlab-org/container-registry.git</param>
- <param
name="changesrevision">ff993bd5c4889e5a2943c4da7b9456487564dba5</param></service></servicedata>
+ <param
name="changesrevision">89261ccc3ffb86dbc02d374380f9ae986d4c013b</param></service></servicedata>
(No newline at EOF)
++++++ gitlab-container-registry-4.23.0.obscpio ->
gitlab-container-registry-4.23.1.obscpio ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/gitlab-container-registry-4.23.0/CHANGELOG.md
new/gitlab-container-registry-4.23.1/CHANGELOG.md
--- old/gitlab-container-registry-4.23.0/CHANGELOG.md 2025-06-02
17:00:01.000000000 +0200
+++ new/gitlab-container-registry-4.23.1/CHANGELOG.md 2025-06-05
18:31:56.000000000 +0200
@@ -1,3 +1,22 @@
+##
[4.23.1](https://gitlab.com/gitlab-org/container-registry/compare/v4.23.0-gitlab...v4.23.1-gitlab)
(2025-06-05)
+
+### 🐛 Bug Fixes 🐛
+
+* **api/gitlab/v1:** fix repository cache initialization
([d135234](https://gitlab.com/gitlab-org/container-registry/commit/d1352341cee75fd185f0a67b1f75f2599fc68057))
+* remmove cloudsql incompatible migrations
([ef66c26](https://gitlab.com/gitlab-org/container-registry/commit/ef66c261a2d8e3433a7c0b6be24c90e8b32d1538))
+* Stat call should properly handle unprefixed configurations in s3_v2 storage
driver
([4b67a75](https://gitlab.com/gitlab-org/container-registry/commit/4b67a753fd4232d5898fc36abddd15b4d0aa61b4))
+
+### ⏮️️ Reverts ⏮️️
+
+* revert 7fed33f9
([ede0ad3](https://gitlab.com/gitlab-org/container-registry/commit/ede0ad3ae0642477413b6d99e2e6cce681712e9b))
+* revert ef66c261a2d8e3433a7c0b6be24c90e8b32d1538
([d00e168](https://gitlab.com/gitlab-org/container-registry/commit/d00e1684606eb3b7c62b42db1e9ffd435c2fb6a6))
+
+### ⚙️ Build ⚙️
+
+* **deps:** update module github.com/alicebob/miniredis/v2 to v2.35.0
([f554f29](https://gitlab.com/gitlab-org/container-registry/commit/f554f291f63df19b87fcfe9b88bad0de00ae9721))
+* **deps:** update module google.golang.org/api to v0.235.0
([5313f8f](https://gitlab.com/gitlab-org/container-registry/commit/5313f8f87d6736a0d12d89a62c3f34afb27c6269))
+* **deps:** update module google.golang.org/api to v0.236.0
([38034e4](https://gitlab.com/gitlab-org/container-registry/commit/38034e4723d2b4e120584dc4c469a67310763e3b))
+
##
[4.23.0](https://gitlab.com/gitlab-org/container-registry/compare/v4.22.0-gitlab...v4.23.0-gitlab)
(2025-06-02)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/gitlab-container-registry-4.23.0/go.mod
new/gitlab-container-registry-4.23.1/go.mod
--- old/gitlab-container-registry-4.23.0/go.mod 2025-06-02 17:00:01.000000000
+0200
+++ new/gitlab-container-registry-4.23.1/go.mod 2025-06-05 18:31:56.000000000
+0200
@@ -13,7 +13,7 @@
github.com/Azure/azure-sdk-for-go/sdk/storage/azblob v1.6.1
github.com/DATA-DOG/go-sqlmock v1.5.2
github.com/Shopify/toxiproxy/v2 v2.12.0
- github.com/alicebob/miniredis/v2 v2.34.0
+ github.com/alicebob/miniredis/v2 v2.35.0
github.com/aws/aws-sdk-go v1.55.5
github.com/aws/aws-sdk-go-v2 v1.36.3
github.com/aws/aws-sdk-go-v2/config v1.29.14
@@ -59,7 +59,7 @@
golang.org/x/oauth2 v0.30.0
golang.org/x/sync v0.14.0
golang.org/x/time v0.11.0
- google.golang.org/api v0.234.0
+ google.golang.org/api v0.236.0
gopkg.in/yaml.v2 v2.4.0
)
@@ -86,7 +86,6 @@
github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/metric
v0.51.0 // indirect
github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/resourcemapping
v0.51.0 // indirect
github.com/Microsoft/go-winio v0.6.2 // indirect
- github.com/alicebob/gopher-json v0.0.0-20230218143504-906a9b012302 //
indirect
github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.10 //
indirect
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.30 // indirect
github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.34 // indirect
@@ -210,8 +209,8 @@
golang.org/x/text v0.25.0 // indirect
google.golang.org/genproto v0.0.0-20250505200425-f936aa4a68b2 //
indirect
google.golang.org/genproto/googleapis/api
v0.0.0-20250505200425-f936aa4a68b2 // indirect
- google.golang.org/genproto/googleapis/rpc
v0.0.0-20250512202823-5a2f75b736a9 // indirect
- google.golang.org/grpc v1.72.1 // indirect
+ google.golang.org/genproto/googleapis/rpc
v0.0.0-20250528174236-200df99c418a // indirect
+ google.golang.org/grpc v1.72.2 // indirect
google.golang.org/protobuf v1.36.6 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/gitlab-container-registry-4.23.0/go.sum
new/gitlab-container-registry-4.23.1/go.sum
--- old/gitlab-container-registry-4.23.0/go.sum 2025-06-02 17:00:01.000000000
+0200
+++ new/gitlab-container-registry-4.23.1/go.sum 2025-06-05 18:31:56.000000000
+0200
@@ -132,10 +132,8 @@
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod
h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod
h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod
h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho=
-github.com/alicebob/gopher-json v0.0.0-20230218143504-906a9b012302
h1:uvdUDbHQHO85qeSydJtItA4T55Pw6BtAejd0APRJOCE=
-github.com/alicebob/gopher-json v0.0.0-20230218143504-906a9b012302/go.mod
h1:SGnFV6hVsYE877CKEZ6tDNTjaSXYUk6QqoIK6PrAtcc=
-github.com/alicebob/miniredis/v2 v2.34.0
h1:mBFWMaJSNL9RwdGRyEDoAAv8OQc5UlEhLDQggTglU/0=
-github.com/alicebob/miniredis/v2 v2.34.0/go.mod
h1:kWShP4b58T1CW0Y5dViCd5ztzrDqRWqM3nksiyXk5s8=
+github.com/alicebob/miniredis/v2 v2.35.0
h1:QwLphYqCEAo1eu1TqPRN2jgVMPBweeQcR21jeqDCONI=
+github.com/alicebob/miniredis/v2 v2.35.0/go.mod
h1:TcL7YfarKPGDAthEtl5NBeHZfeUQj6OXMm/+iu5cLMM=
github.com/antihax/optional v1.0.0/go.mod
h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY=
github.com/apache/thrift v0.12.0/go.mod
h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ=
github.com/apache/thrift v0.13.0/go.mod
h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ=
@@ -1179,8 +1177,8 @@
google.golang.org/api v0.50.0/go.mod
h1:4bNT5pAuq5ji4SRZm+5QIkjny9JAyVD/3gaSihNefaw=
google.golang.org/api v0.51.0/go.mod
h1:t4HdrdoNgyN5cbEfm7Lum0lcLDLiise1F8qDKX00sOU=
google.golang.org/api v0.54.0/go.mod
h1:7C4bFFOvVDGXjfDTAsgGwDgAxRDeQ4X8NvUedIt6z3k=
-google.golang.org/api v0.234.0 h1:d3sAmYq3E9gdr2mpmiWGbm9pHsA/KJmyiLkwKfHBqU4=
-google.golang.org/api v0.234.0/go.mod
h1:QpeJkemzkFKe5VCE/PMv7GsUfn9ZF+u+q1Q7w6ckxTg=
+google.golang.org/api v0.236.0 h1:CAiEiDVtO4D/Qja2IA9VzlFrgPnK3XVMmRoJZlSWbc0=
+google.golang.org/api v0.236.0/go.mod
h1:X1WF9CU2oTc+Jml1tiIxGmWFK/UZezdqEu09gcxZAj4=
google.golang.org/appengine v1.1.0/go.mod
h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
google.golang.org/appengine v1.2.0/go.mod
h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
google.golang.org/appengine v1.4.0/go.mod
h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
@@ -1244,8 +1242,8 @@
google.golang.org/genproto v0.0.0-20250505200425-f936aa4a68b2/go.mod
h1:49MsLSx0oWMOZqcpB3uL8ZOkAh1+TndpJ8ONoCBWiZk=
google.golang.org/genproto/googleapis/api v0.0.0-20250505200425-f936aa4a68b2
h1:vPV0tzlsK6EzEDHNNH5sa7Hs9bd7iXR7B1tSiPepkV0=
google.golang.org/genproto/googleapis/api
v0.0.0-20250505200425-f936aa4a68b2/go.mod
h1:pKLAc5OolXC3ViWGI62vvC0n10CpwAtRcTNCFwTKBEw=
-google.golang.org/genproto/googleapis/rpc v0.0.0-20250512202823-5a2f75b736a9
h1:IkAfh6J/yllPtpYFU0zZN1hUPYdT0ogkBT/9hMxHjvg=
-google.golang.org/genproto/googleapis/rpc
v0.0.0-20250512202823-5a2f75b736a9/go.mod
h1:qQ0YXyHHx3XkvlzUtpXDkS29lDSafHMZBAZDc03LQ3A=
+google.golang.org/genproto/googleapis/rpc v0.0.0-20250528174236-200df99c418a
h1:v2PbRU4K3llS09c7zodFpNePeamkAwG3mPrAery9VeE=
+google.golang.org/genproto/googleapis/rpc
v0.0.0-20250528174236-200df99c418a/go.mod
h1:qQ0YXyHHx3XkvlzUtpXDkS29lDSafHMZBAZDc03LQ3A=
google.golang.org/grpc v1.17.0/go.mod
h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs=
google.golang.org/grpc v1.19.0/go.mod
h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
google.golang.org/grpc v1.20.0/go.mod
h1:chYK+tFQF0nDUGJgXMSgLCQk3phJEuONr2DCgLDdAQM=
@@ -1275,8 +1273,8 @@
google.golang.org/grpc v1.38.0/go.mod
h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM=
google.golang.org/grpc v1.39.0/go.mod
h1:PImNr+rS9TWYb2O4/emRugxiyHZ5JyHW5F+RPnDzfrE=
google.golang.org/grpc v1.39.1/go.mod
h1:PImNr+rS9TWYb2O4/emRugxiyHZ5JyHW5F+RPnDzfrE=
-google.golang.org/grpc v1.72.1 h1:HR03wO6eyZ7lknl75XlxABNVLLFc2PAb6mHlYh756mA=
-google.golang.org/grpc v1.72.1/go.mod
h1:wH5Aktxcg25y1I3w7H69nHfXdOG3UiadoBtjh3izSDM=
+google.golang.org/grpc v1.72.2 h1:TdbGzwb82ty4OusHWepvFWGLgIbNo1/SUynEN0ssqv8=
+google.golang.org/grpc v1.72.2/go.mod
h1:wH5Aktxcg25y1I3w7H69nHfXdOG3UiadoBtjh3izSDM=
google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0/go.mod
h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw=
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod
h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod
h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/gitlab-container-registry-4.23.0/registry/datastore/migrations/premigrations/20250421061041_create_trigger_for_media_type_id_convert_to_bigint.go
new/gitlab-container-registry-4.23.1/registry/datastore/migrations/premigrations/20250421061041_create_trigger_for_media_type_id_convert_to_bigint.go
---
old/gitlab-container-registry-4.23.0/registry/datastore/migrations/premigrations/20250421061041_create_trigger_for_media_type_id_convert_to_bigint.go
2025-06-02 17:00:01.000000000 +0200
+++
new/gitlab-container-registry-4.23.1/registry/datastore/migrations/premigrations/20250421061041_create_trigger_for_media_type_id_convert_to_bigint.go
2025-06-05 18:31:56.000000000 +0200
@@ -22,10 +22,22 @@
LANGUAGE plpgsql;`,
// Create the trigger to fire on INSERT and
UPDATE
- `CREATE TRIGGER
set_media_type_id_convert_to_bigint
- BEFORE INSERT OR UPDATE ON manifests
- FOR EACH ROW
- EXECUTE PROCEDURE
set_media_type_id_convert_to_bigint ()`,
+ `DO $$
+ BEGIN
+ IF NOT EXISTS (
+ SELECT
+ 1
+ FROM
+ pg_trigger
+ WHERE
+ tgname =
'set_media_type_id_convert_to_bigint') THEN
+ CREATE TRIGGER
set_media_type_id_convert_to_bigint
+ BEFORE INSERT OR UPDATE
ON manifests
+ FOR EACH ROW
+ EXECUTE PROCEDURE
set_media_type_id_convert_to_bigint ();
+ END IF;
+ END
+ $$`,
},
Down: []string{
"DROP TRIGGER IF EXISTS
set_media_type_id_convert_to_bigint ON manifests",
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/gitlab-container-registry-4.23.0/registry/handlers/app.go
new/gitlab-container-registry-4.23.1/registry/handlers/app.go
--- old/gitlab-container-registry-4.23.0/registry/handlers/app.go
2025-06-02 17:00:01.000000000 +0200
+++ new/gitlab-container-registry-4.23.1/registry/handlers/app.go
2025-06-05 18:31:56.000000000 +0200
@@ -1603,6 +1603,13 @@
ctx.queueBridge = app.queueBridge(ctx, r)
}
+ // Initialize repository cache
+ if app.redisCache != nil {
+ ctx.repoCache =
datastore.NewCentralRepositoryCache(app.redisCache)
+ } else {
+ ctx.repoCache = datastore.NewSingleRepositoryCache()
+ }
+
dispatch(ctx, r).ServeHTTP(w, r)
// Automated error response handling here. Handlers may return
their
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/gitlab-container-registry-4.23.0/registry/handlers/app_test.go
new/gitlab-container-registry-4.23.1/registry/handlers/app_test.go
--- old/gitlab-container-registry-4.23.0/registry/handlers/app_test.go
2025-06-02 17:00:01.000000000 +0200
+++ new/gitlab-container-registry-4.23.1/registry/handlers/app_test.go
2025-06-05 18:31:56.000000000 +0200
@@ -15,12 +15,17 @@
"testing"
"time"
- "github.com/docker/distribution/internal/feature"
+ "github.com/sirupsen/logrus"
+ "github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
+ "go.uber.org/mock/gomock"
"github.com/docker/distribution/configuration"
dcontext "github.com/docker/distribution/context"
+ "github.com/docker/distribution/internal/feature"
"github.com/docker/distribution/reference"
"github.com/docker/distribution/registry/api/errcode"
+ v1 "github.com/docker/distribution/registry/api/gitlab/v1"
"github.com/docker/distribution/registry/api/urls"
v2 "github.com/docker/distribution/registry/api/v2"
"github.com/docker/distribution/registry/auth"
@@ -28,16 +33,13 @@
"github.com/docker/distribution/registry/datastore"
dmocks "github.com/docker/distribution/registry/datastore/mocks"
imocks "github.com/docker/distribution/registry/internal/mocks"
+ iredis "github.com/docker/distribution/registry/internal/redis"
"github.com/docker/distribution/registry/internal/testutil"
"github.com/docker/distribution/registry/storage"
memorycache
"github.com/docker/distribution/registry/storage/cache/memory"
_ "github.com/docker/distribution/registry/storage/driver/filesystem"
"github.com/docker/distribution/registry/storage/driver/testdriver"
dtestutil "github.com/docker/distribution/testutil"
- "github.com/sirupsen/logrus"
- "github.com/stretchr/testify/assert"
- "github.com/stretchr/testify/require"
- "go.uber.org/mock/gomock"
)
// TestAppDistribtionDispatcher builds an application with a test dispatcher
and
@@ -1041,3 +1043,81 @@
})
}
}
+
+// TestDispatcherGitlab_RepoCacheInitialization ensures that ctx.repoCache is
properly initialized
+// when the database is enabled in the GitLab v1 API dispatcher.
+func TestDispatcherGitlab_RepoCacheInitialization(t *testing.T) {
+ driver := testdriver.New()
+ ctx := dtestutil.NewContextWithLogger(t)
+ registry, err := storage.NewRegistry(ctx, driver)
+ require.NoError(t, err)
+
+ testCases := []struct {
+ name string
+ redisCache bool
+ expectedType any
+ }{
+ {
+ name: "with redis cache",
+ redisCache: true,
+ expectedType:
datastore.NewCentralRepositoryCache(&iredis.Cache{}),
+ },
+ {
+ name: "without redis cache",
+ redisCache: false,
+ expectedType: datastore.NewSingleRepositoryCache(),
+ },
+ }
+
+ for _, tc := range testCases {
+ t.Run(tc.name, func(t *testing.T) {
+ app := &App{
+ Config: &configuration.Configuration{
+ Database: configuration.Database{
+ Enabled: true,
+ },
+ },
+ Context: ctx,
+ driver: driver,
+ registry: registry,
+ // Bypass authorization logic
+ accessController: nil,
+ }
+
+ if tc.redisCache {
+ // Create a mock Redis cache
+ app.redisCache = &iredis.Cache{}
+ }
+
+ // Initialize the app's router to get proper GitLab v1
routes
+ require.NoError(t, app.initMetaRouter())
+
+ // Create a test dispatcher that captures the context
+ var capturedContext *Context
+ testDispatcher := func(ctx *Context, _ *http.Request)
http.Handler {
+ capturedContext = ctx
+ return http.HandlerFunc(func(w
http.ResponseWriter, _ *http.Request) {
+ w.WriteHeader(http.StatusOK)
+ })
+ }
+
+ // Register our test dispatcher for the GitLab v1 base
route
+ app.registerGitlab(v1.Base, testDispatcher)
+
+ // Create a test request to the GitLab v1 base endpoint
+ req := httptest.NewRequest(http.MethodGet,
v1.Base.Path, nil)
+ w := httptest.NewRecorder()
+
+ // Use the app's router to serve the request, which
will properly set up route context
+ app.ServeHTTP(w, req)
+
+ // Verify the context was captured
+ require.NotNil(t, capturedContext, "context should be
captured")
+
+ // Check repoCache initialization
+ require.NotNil(t, capturedContext.repoCache, "repoCache
should not be nil when database is enabled")
+ // Verify the type of cache based on Redis availability
+ require.IsType(t, tc.expectedType,
capturedContext.repoCache, "repoCache should be of expected type")
+ })
+ }
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/gitlab-container-registry-4.23.0/registry/storage/driver/s3-aws/v2/s3.go
new/gitlab-container-registry-4.23.1/registry/storage/driver/s3-aws/v2/s3.go
---
old/gitlab-container-registry-4.23.0/registry/storage/driver/s3-aws/v2/s3.go
2025-06-02 17:00:01.000000000 +0200
+++
new/gitlab-container-registry-4.23.1/registry/storage/driver/s3-aws/v2/s3.go
2025-06-05 18:31:56.000000000 +0200
@@ -429,11 +429,18 @@
}
func (d *driver) statHead(ctx context.Context, path string)
(*storagedriver.FileInfoFields, error) {
+ // NOTE(prozlach): This is to cover for the cases when the
rootDirectory of
+ // the driver is either "" or "/".
+ key := d.s3Path(path)
+ if key == "" {
+ key = "/"
+ }
+
resp, err := d.S3.HeadObject(
ctx,
&s3.HeadObjectInput{
Bucket: ptr.String(d.Bucket),
- Key: ptr.String(d.s3Path(path)),
+ Key: &key,
},
)
if err != nil {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/gitlab-container-registry-4.23.0/registry/storage/driver/testsuites/testsuites.go
new/gitlab-container-registry-4.23.1/registry/storage/driver/testsuites/testsuites.go
---
old/gitlab-container-registry-4.23.0/registry/storage/driver/testsuites/testsuites.go
2025-06-02 17:00:01.000000000 +0200
+++
new/gitlab-container-registry-4.23.1/registry/storage/driver/testsuites/testsuites.go
2025-06-05 18:31:56.000000000 +0200
@@ -752,6 +752,9 @@
if s.StorageDriver.Name() == "inmemory" {
s.T().Skip("In-memory driver is known to have OOM issues with
large uploads.")
}
+ if s.StorageDriver.Name() == "filesystem" {
+ s.T().Skip("filesystem driver tests are running on tmpfs and it
does not do chunking so this test would not bring much value")
+ }
if slices.Contains([]string{s3_common.V1DriverName,
s3_common.V1DriverNameAlt}, s.StorageDriver.Name()) {
s.T().Skip("S3 v1 driver has chunk size limitations which
aren't planned to be fixed")
}
@@ -2011,117 +2014,165 @@
err := s.StorageDriver.PutContent(s.ctx, filePath, contentA)
require.NoError(s.T(), err)
-
err = s.StorageDriver.PutContent(s.ctx, filePathAux, contentA)
require.NoError(s.T(), err)
-
defer s.deletePath(s.StorageDriver, firstPart(dirPath))
+ if s.StorageDriver.Name() != "filesystem" {
+ err = s.StorageDriverRootless.PutContent(s.ctx, filePath,
contentA)
+ require.NoError(s.T(), err)
+ err = s.StorageDriverRootless.PutContent(s.ctx, filePathAux,
contentA)
+ require.NoError(s.T(), err)
+ defer s.deletePath(s.StorageDriverRootless, firstPart(dirPath))
+ }
+
// Call to stat on root directory. The storage healthcheck performs this
// exact call to Stat.
// PathNotFoundErrors are not considered health check failures. Some
// drivers will return a not found here, while others will not return an
// error at all. If we get an error, ensure it's a not found.
- s.Run("RootDirectory", func() {
- fi, err := s.StorageDriver.Stat(s.ctx, "/")
- if err != nil {
- assert.ErrorAs(s.T(), err,
new(storagedriver.PathNotFoundError))
- } else {
- assert.NotNil(s.T(), fi)
- assert.Equal(s.T(), "/", fi.Path())
- assert.True(s.T(), fi.IsDir())
+ for _, name := range []string{"prefixed", "unprefixed"} {
+ var drv storagedriver.StorageDriver
+ switch name {
+ case "prefixed":
+ drv = s.StorageDriver
+ case "unprefixed":
+ drv = s.StorageDriverRootless
}
- })
- s.Run("NonExistentDir", func() {
- fi, err := s.StorageDriver.Stat(s.ctx, dirPath+"foo")
- require.Error(s.T(), err)
- assert.ErrorIs(s.T(), err, storagedriver.PathNotFoundError{ //
nolint: testifylint
- DriverName: s.StorageDriver.Name(),
- Path: dirPath + "foo",
+ s.Run(fmt.Sprintf("RootDirectory - %s", name), func() {
+ if s.StorageDriver.Name() == "filesystem" && name ==
"unprefixed" {
+ s.T().Skip("filesystem driver does not support
prefix-less operation")
+ }
+
+ fi, err := drv.Stat(s.ctx, "/")
+ if err != nil {
+ assert.ErrorAs(s.T(), err,
new(storagedriver.PathNotFoundError))
+ } else {
+ assert.NotNil(s.T(), fi)
+ assert.Equal(s.T(), "/", fi.Path())
+ assert.True(s.T(), fi.IsDir())
+ }
})
- assert.Nil(s.T(), fi)
- })
- s.Run("NonExistentPath", func() {
- fi, err := s.StorageDriver.Stat(s.ctx, filePath+"bar")
- require.Error(s.T(), err)
- assert.ErrorIs(s.T(), err, storagedriver.PathNotFoundError{ //
nolint: testifylint
- DriverName: s.StorageDriver.Name(),
- Path: filePath + "bar",
+ s.Run(fmt.Sprintf("NonExistentDir - %s", name), func() {
+ if s.StorageDriver.Name() == "filesystem" && name ==
"unprefixed" {
+ s.T().Skip("filesystem driver does not support
prefix-less operation")
+ }
+
+ fi, err := drv.Stat(s.ctx, dirPath+"foo")
+ require.Error(s.T(), err)
+ assert.ErrorIs(s.T(), err,
storagedriver.PathNotFoundError{ // nolint: testifylint
+ DriverName: drv.Name(),
+ Path: dirPath + "foo",
+ })
+ assert.Nil(s.T(), fi)
})
- assert.Nil(s.T(), fi)
- })
- s.Run("FileExists", func() {
- fi, err := s.StorageDriver.Stat(s.ctx, filePath)
- require.NoError(s.T(), err)
- require.NotNil(s.T(), fi)
- assert.Equal(s.T(), filePath, fi.Path())
- assert.Equal(s.T(), int64(len(contentA)), fi.Size())
- assert.False(s.T(), fi.IsDir())
- })
+ s.Run(fmt.Sprintf("NonExistentPath - %s", name), func() {
+ if s.StorageDriver.Name() == "filesystem" && name ==
"unprefixed" {
+ s.T().Skip("filesystem driver does not support
prefix-less operation")
+ }
- s.Run("ModTime", func() {
- fi, err := s.StorageDriver.Stat(s.ctx, filePath)
- require.NoError(s.T(), err)
- assert.NotNil(s.T(), fi)
- createdTime := fi.ModTime()
+ fi, err := drv.Stat(s.ctx, filePath+"bar")
+ require.Error(s.T(), err)
+ assert.ErrorIs(s.T(), err,
storagedriver.PathNotFoundError{ // nolint: testifylint
+ DriverName: drv.Name(),
+ Path: filePath + "bar",
+ })
+ assert.Nil(s.T(), fi)
+ })
- // Sleep and modify the file
- time.Sleep(time.Second * 10)
- err = s.StorageDriver.PutContent(s.ctx, filePath, contentB)
- require.NoError(s.T(), err)
+ s.Run(fmt.Sprintf("FileExists - %s", name), func() {
+ if s.StorageDriver.Name() == "filesystem" && name ==
"unprefixed" {
+ s.T().Skip("filesystem driver does not support
prefix-less operation")
+ }
- fi, err = s.StorageDriver.Stat(s.ctx, filePath)
- require.NoError(s.T(), err)
- require.NotNil(s.T(), fi)
- modTime := fi.ModTime()
+ fi, err := drv.Stat(s.ctx, filePath)
+ require.NoError(s.T(), err)
+ require.NotNil(s.T(), fi)
+ assert.Equal(s.T(), filePath, fi.Path())
+ assert.Equal(s.T(), int64(len(contentA)), fi.Size())
+ assert.False(s.T(), fi.IsDir())
+ })
- // Check if the modification time is after the creation time.
- // In case of cloud storage services, storage frontend nodes
might have
- // time drift between them, however that should be solved with
sleeping
- // before update.
- assert.Greaterf(
- s.T(),
- modTime,
- createdTime,
- "modtime (%s) is before the creation time (%s)",
modTime, createdTime,
- )
- })
+ s.Run(fmt.Sprintf("ModTime - %s", name), func() {
+ if s.StorageDriver.Name() == "filesystem" && name ==
"unprefixed" {
+ s.T().Skip("filesystem driver does not support
prefix-less operation")
+ }
- // Call on directory with one "file"
- // (do not check ModTime as dirs don't need to support it)
- s.Run("DirWithFile", func() {
- fi, err := s.StorageDriver.Stat(s.ctx, dirPath)
- require.NoError(s.T(), err)
- require.NotNil(s.T(), fi)
- assert.Equal(s.T(), dirPath, fi.Path())
- assert.Zero(s.T(), fi.Size())
- assert.True(s.T(), fi.IsDir())
- })
+ fi, err := drv.Stat(s.ctx, filePath)
+ require.NoError(s.T(), err)
+ assert.NotNil(s.T(), fi)
+ createdTime := fi.ModTime()
- // Call on directory with another "subdirectory"
- s.Run("DirWithSubDir", func() {
- fi, err := s.StorageDriver.Stat(s.ctx, dirPathBase)
- require.NoError(s.T(), err)
- require.NotNil(s.T(), fi)
- assert.Equal(s.T(), dirPathBase, fi.Path())
- assert.Zero(s.T(), fi.Size())
- assert.True(s.T(), fi.IsDir())
- })
+ // Sleep and modify the file
+ time.Sleep(time.Second * 10)
+ err = drv.PutContent(s.ctx, filePath, contentB)
+ require.NoError(s.T(), err)
+
+ fi, err = drv.Stat(s.ctx, filePath)
+ require.NoError(s.T(), err)
+ require.NotNil(s.T(), fi)
+ modTime := fi.ModTime()
+
+ // Check if the modification time is after the creation
time.
+ // In case of cloud storage services, storage frontend
nodes might have
+ // time drift between them, however that should be
solved with sleeping
+ // before update.
+ assert.Greaterf(
+ s.T(),
+ modTime,
+ createdTime,
+ "modtime (%s) is before the creation time
(%s)", modTime, createdTime,
+ )
+ })
- // Call on a partial name of the directory. This should result in
- // not-found, as partial match is still not a match for a directory.
- s.Run("DirPartialPrefix", func() {
- fi, err := s.StorageDriver.Stat(s.ctx, partialPath)
- require.Error(s.T(), err)
- assert.ErrorIs(s.T(), err, storagedriver.PathNotFoundError{ //
nolint: testifylint
- DriverName: s.StorageDriver.Name(),
- Path: partialPath,
+ // Call on directory with one "file"
+ // (do not check ModTime as dirs don't need to support it)
+ s.Run(fmt.Sprintf("DirWithFile - %s", name), func() {
+ if s.StorageDriver.Name() == "filesystem" && name ==
"unprefixed" {
+ s.T().Skip("filesystem driver does not support
prefix-less operation")
+ }
+
+ fi, err := drv.Stat(s.ctx, dirPath)
+ require.NoError(s.T(), err)
+ require.NotNil(s.T(), fi)
+ assert.Equal(s.T(), dirPath, fi.Path())
+ assert.Zero(s.T(), fi.Size())
+ assert.True(s.T(), fi.IsDir())
})
- assert.Nil(s.T(), fi)
- })
+
+ // Call on directory with another "subdirectory"
+ s.Run(fmt.Sprintf("DirWithSubDir - %s", name), func() {
+ if s.StorageDriver.Name() == "filesystem" && name ==
"unprefixed" {
+ s.T().Skip("filesystem driver does not support
prefix-less operation")
+ }
+
+ fi, err := drv.Stat(s.ctx, dirPathBase)
+ require.NoError(s.T(), err)
+ require.NotNil(s.T(), fi)
+ assert.Equal(s.T(), dirPathBase, fi.Path())
+ assert.Zero(s.T(), fi.Size())
+ assert.True(s.T(), fi.IsDir())
+ })
+
+ // Call on a partial name of the directory. This should result
in
+ // not-found, as partial match is still not a match for a
directory.
+ s.Run(fmt.Sprintf("DirPartialPrefix - %s", name), func() {
+ if s.StorageDriver.Name() == "filesystem" && name ==
"unprefixed" {
+ s.T().Skip("filesystem driver does not support
prefix-less operation")
+ }
+
+ fi, err := drv.Stat(s.ctx, partialPath)
+ require.Error(s.T(), err)
+ assert.ErrorIs(s.T(), err,
storagedriver.PathNotFoundError{ // nolint: testifylint
+ DriverName: drv.Name(),
+ Path: partialPath,
+ })
+ assert.Nil(s.T(), fi)
+ })
+ }
}
// TestPutContentMultipleTimes checks that if storage driver can overwrite the
content
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/gitlab-container-registry-4.23.0/script/repo_health.py
new/gitlab-container-registry-4.23.1/script/repo_health.py
--- old/gitlab-container-registry-4.23.0/script/repo_health.py 1970-01-01
01:00:00.000000000 +0100
+++ new/gitlab-container-registry-4.23.1/script/repo_health.py 2025-06-05
18:31:56.000000000 +0200
@@ -0,0 +1,223 @@
+#!/usr/bin/env python3
+import os
+import re
+import subprocess
+from datetime import datetime, timedelta
+
+
+def parse_codeowners(codeowners_path):
+ """Parse the CODEOWNERS file and return a list of patterns."""
+ if not os.path.exists(codeowners_path):
+ print(f"Error: CODEOWNERS file not found at {codeowners_path}")
+ return []
+
+ patterns = []
+ # current_section = None
+
+ with open(codeowners_path, 'r') as f:
+ for line in f:
+ # Skip empty lines
+ line = line.strip()
+ if not line:
+ continue
+
+ # Skip comments
+ if line.startswith('#'):
+ continue
+
+ # Check for section headers [Section Name]
+ section_match = re.match(r'^\[(.*?)\]', line)
+ if section_match:
+ # current_section = section_match.group(1).strip()
+ # Skip section headers, they're not patterns
+ continue
+
+ # Extract the pattern (first part before the owners)
+ # Owners start with @ symbol
+ parts = line.split('@', 1)
+
+ if len(parts) >= 1:
+ # The pattern is everything before the first @ symbol
+ pattern = parts[0].strip()
+
+ # Special case: if pattern is exactly "/" it means the whole
repo and
+ # we do not count it as this is a catch-all for files without
owners.
+ # Skip empty patterns
+ if not pattern or pattern == "/":
+ continue
+
+ # Add pattern to the list
+ patterns.append(pattern)
+
+ # Additional debug information (remove in production)
+ # print(f"Section: {current_section}, Pattern: {pattern}")
+
+ return patterns
+
+
+def is_file_covered(file_path, codeowners_patterns):
+ """Check if a file is covered by any specific pattern in CODEOWNERS."""
+ for pattern in codeowners_patterns:
+ regex_pattern = pattern.replace(
+ '.', '\\.').replace('*', '.*').replace('?', '.')
+
+ if pattern.startswith('/'):
+ regex_pattern = "^" + regex_pattern.lstrip('/')
+
+ if re.search(regex_pattern, file_path):
+ return True
+
+ return False
+
+
+def count_lines_in_file(file_path):
+ """Count the number of lines in a file."""
+ try:
+ with open(file_path, 'r', encoding='utf-8', errors='ignore') as f:
+ return sum(1 for _ in f)
+ except Exception as e:
+ print(f"Error counting lines in {file_path}: {e}")
+ return 0
+
+
+def get_commits_in_last_year():
+ """Get all commits from the last 12 months."""
+ one_year_ago = (datetime.now() - timedelta(days=365)).strftime('%Y-%m-%d')
+ try:
+ result = subprocess.run(
+ ['git', 'log', '--since', one_year_ago, '--format=%H'],
+ capture_output=True, text=True, check=True
+ )
+ commits = result.stdout.strip().split('\n')
+ return [c for c in commits if c] # Filter out empty strings
+ except subprocess.CalledProcessError as e:
+ print(f"Error getting commits: {e}")
+ return []
+
+
+def get_files_changed_in_commit(commit_hash):
+ """Get all files changed in a specific commit."""
+ try:
+ result = subprocess.run(
+ ['git', 'diff-tree', '--no-commit-id',
+ '--name-only', '-r', commit_hash],
+ capture_output=True, text=True, check=True
+ )
+ files = result.stdout.strip().split('\n')
+ return [f for f in files if f] # Filter out empty strings
+ except subprocess.CalledProcessError as e:
+ print(f"Error getting files for commit {commit_hash}: {e}")
+ return []
+
+
+def get_repo_root():
+ """Determine the repository root."""
+ try:
+ result = subprocess.run(
+ ['git', 'rev-parse', '--show-toplevel'],
+ capture_output=True, text=True, check=True
+ )
+ return result.stdout.strip()
+ except subprocess.CalledProcessError:
+ # If git command fails, return relative path based on script location
+ script_dir = os.path.dirname(os.path.abspath(__file__))
+ # Go up one level from script directory
+ return os.path.dirname(script_dir)
+
+
+def main():
+ # Get repository root
+ repo_root = get_repo_root()
+ print(f"Repository root: {repo_root}")
+
+ # Path to CODEOWNERS file relative to script
+ codeowners_path = os.path.normpath(
+ os.path.join(repo_root, '.gitlab/CODEOWNERS'))
+
+ print(f"Looking for CODEOWNERS file at: {codeowners_path}")
+
+ # Parse CODEOWNERS file
+ codeowners_patterns = parse_codeowners(codeowners_path)
+ if not codeowners_patterns:
+ print("No valid patterns found in CODEOWNERS file")
+ return
+
+ print(f"Found {len(codeowners_patterns)} patterns in CODEOWNERS file")
+
+ # Change directory to repository root
+ os.chdir(repo_root)
+
+ # Find all Go files in the repository
+ go_files = []
+ for root, _, files in os.walk('.'):
+ if '.git' in root:
+ continue
+ for file in files:
+ if file.endswith('.go') and not file.endswith('_test.go'):
+ file_path = os.path.join(root, file)
+ go_files.append(file_path)
+
+ # Count lines of code and check coverage
+ total_loc = 0
+ covered_loc = 0
+ covered_files = []
+ uncovered_files = []
+
+ for file_path in go_files:
+ # Normalize path for pattern matching
+ normalized_path = file_path
+ if normalized_path.startswith('./'):
+ normalized_path = normalized_path[2:]
+
+ # Count lines
+ loc = count_lines_in_file(file_path)
+ total_loc += loc
+
+ # Check if covered by CODEOWNERS
+ if is_file_covered(normalized_path, codeowners_patterns):
+ covered_loc += loc
+ covered_files.append(normalized_path)
+ else:
+ uncovered_files.append(normalized_path)
+
+ # Get commits in the last 12 months
+ commits = get_commits_in_last_year()
+ total_commits = len(commits)
+
+ # Count commits touching uncovered files
+ uncovered_commits = set()
+ for commit in commits:
+ changed_files = get_files_changed_in_commit(commit)
+ # Normalize paths
+ changed_files = [f if not f.startswith(
+ './') else f[2:] for f in changed_files]
+ # Filter for Go files only
+ changed_go_files = [f for f in changed_files if f.endswith('.go')]
+
+ # Check if any uncovered file was touched
+ for changed_file in changed_go_files:
+ if changed_file in uncovered_files:
+ uncovered_commits.add(commit)
+ break
+
+ # Print results
+ print(f"Total Go files: {len(go_files)}")
+ print(
+ f"Files covered by CODEOWNERS: {len(covered_files)}
({len(covered_files)/len(go_files)*100:.2f}%)")
+ print(
+ f"Files not covered by CODEOWNERS: {len(uncovered_files)}
({len(uncovered_files)/len(go_files)*100:.2f}%)")
+ print()
+ print(f"Total lines of Go code: {total_loc}")
+ print(
+ f"Lines covered by CODEOWNERS: {covered_loc}
({covered_loc/total_loc*100:.2f}%)")
+ print(
+ f"Lines not covered by CODEOWNERS: {total_loc - covered_loc}
({(total_loc - covered_loc)/total_loc*100:.2f}%)")
+ print()
+ print(f"Total commits in the last 12 months: {total_commits}")
+ uncovered_commit_count = len(uncovered_commits)
+ print(
+ f"Commits touching files not covered by CODEOWNERS:
{uncovered_commit_count} ({uncovered_commit_count/total_commits*100:.2f}%)")
+
+
+if __name__ == "__main__":
+ main()
++++++ gitlab-container-registry.obsinfo ++++++
--- /var/tmp/diff_new_pack.TeE0wt/_old 2025-06-06 22:42:55.312468278 +0200
+++ /var/tmp/diff_new_pack.TeE0wt/_new 2025-06-06 22:42:55.316468443 +0200
@@ -1,5 +1,5 @@
name: gitlab-container-registry
-version: 4.23.0
-mtime: 1748876401
-commit: ff993bd5c4889e5a2943c4da7b9456487564dba5
+version: 4.23.1
+mtime: 1749141116
+commit: 89261ccc3ffb86dbc02d374380f9ae986d4c013b
++++++ vendor.tar.gz ++++++
/work/SRC/openSUSE:Factory/gitlab-container-registry/vendor.tar.gz
/work/SRC/openSUSE:Factory/.gitlab-container-registry.new.19631/vendor.tar.gz
differ: char 13, line 1