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 
<opensuse_buildserv...@ojkastl.de>
+
+- 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

Reply via email to