detached c573276

fix: apply CodeRabbit auto-fixes

Fixed 4 file(s) based on 4 unresolved review comments.

Co-authored-by: CodeRabbit <noreply@coderabbit.ai>
commit
c573276830d4125ff59ca43de2e7b227eb4dba8a
author
coderabbitai[bot] · · 2026-04-26 07:19 UTC
committer
GitHub · · 2026-04-26 07:19 UTC
parent
c69eeb8
signature
GPG UnverifiedB5690EEEBB952194 The key is unknown
4 files · +27 -22
M internal/app/migrate_env.go +2 -3
@@ -10,7 +10,6 @@ import (
1010
1111 "github.com/bnema/gordon/internal/adapters/out/domainsecrets"
1212 "github.com/bnema/gordon/internal/domain"
13- domainerrors "github.com/bnema/gordon/internal/domain"
1413 )
1514
1615 func migrateEnvFilesToPass(envDir string, passStore *domainsecrets.PassStore, log zerowrap.Logger) error {
@@ -86,7 +85,7 @@ func migrateEnvFile(envDir, name string, passStore *domainsecrets.PassStore, log
8685 }
8786
8887 if len(existingKeys) > 0 {
89- return fmt.Errorf("%w: pass secrets already exist for %s (found %d keys); refusing to delete plaintext env file automatically", domainerrors.ErrSecretNotFound, domainName, len(existingKeys))
88+ return fmt.Errorf("%w: pass secrets already exist for %s (found %d keys); refusing to delete plaintext env file automatically", domain.ErrSecretsAlreadyExist, domainName, len(existingKeys))
9089 }
9190 if err := passStore.Set(domainName, secrets); err != nil {
9291 return fmt.Errorf("failed to migrate secrets for %s: %w", domainName, err)
@@ -186,7 +185,7 @@ func migrateAttachmentEnvFile(envDir, name string, passStore *domainsecrets.Pass
186185 }
187186
188187 if len(existingKeys) > 0 {
189- return fmt.Errorf("%w: pass secrets already exist for attachment %s (found %d keys); refusing to delete plaintext env file automatically", domainerrors.ErrSecretNotFound, containerName, len(existingKeys))
188+ return fmt.Errorf("%w: pass secrets already exist for attachment %s (found %d keys); refusing to delete plaintext env file automatically", domain.ErrSecretsAlreadyExist, containerName, len(existingKeys))
190189 }
191190 if err := passStore.SetAttachment(containerName, secrets); err != nil {
192191 return fmt.Errorf("failed to migrate attachment secrets for %s: %w", containerName, err)
@@ -10,7 +10,6 @@ import (
10 10
11 "github.com/bnema/gordon/internal/adapters/out/domainsecrets"11 "github.com/bnema/gordon/internal/adapters/out/domainsecrets"
12 "github.com/bnema/gordon/internal/domain"12 "github.com/bnema/gordon/internal/domain"
13- domainerrors "github.com/bnema/gordon/internal/domain"
14 )13 )
15 14
16 func migrateEnvFilesToPass(envDir string, passStore *domainsecrets.PassStore, log zerowrap.Logger) error {15 func migrateEnvFilesToPass(envDir string, passStore *domainsecrets.PassStore, log zerowrap.Logger) error {
@@ -86,7 +85,7 @@ func migrateEnvFile(envDir, name string, passStore *domainsecrets.PassStore, log
86 }85 }
87 86
88 if len(existingKeys) > 0 {87 if len(existingKeys) > 0 {
89- return fmt.Errorf("%w: pass secrets already exist for %s (found %d keys); refusing to delete plaintext env file automatically", domainerrors.ErrSecretNotFound, domainName, len(existingKeys))88+ return fmt.Errorf("%w: pass secrets already exist for %s (found %d keys); refusing to delete plaintext env file automatically", domain.ErrSecretsAlreadyExist, domainName, len(existingKeys))
90 }89 }
91 if err := passStore.Set(domainName, secrets); err != nil {90 if err := passStore.Set(domainName, secrets); err != nil {
92 return fmt.Errorf("failed to migrate secrets for %s: %w", domainName, err)91 return fmt.Errorf("failed to migrate secrets for %s: %w", domainName, err)
@@ -186,7 +185,7 @@ func migrateAttachmentEnvFile(envDir, name string, passStore *domainsecrets.Pass
186 }185 }
187 186
188 if len(existingKeys) > 0 {187 if len(existingKeys) > 0 {
189- return fmt.Errorf("%w: pass secrets already exist for attachment %s (found %d keys); refusing to delete plaintext env file automatically", domainerrors.ErrSecretNotFound, containerName, len(existingKeys))188+ return fmt.Errorf("%w: pass secrets already exist for attachment %s (found %d keys); refusing to delete plaintext env file automatically", domain.ErrSecretsAlreadyExist, containerName, len(existingKeys))
190 }189 }
191 if err := passStore.SetAttachment(containerName, secrets); err != nil {190 if err := passStore.SetAttachment(containerName, secrets); err != nil {
192 return fmt.Errorf("failed to migrate attachment secrets for %s: %w", containerName, err)191 return fmt.Errorf("failed to migrate attachment secrets for %s: %w", containerName, err)
M internal/domain/errors.go +1 -0
@@ -57,6 +57,7 @@ var (
5757 // Environment errors
5858 ErrEnvFileNotFound = errors.New("environment file not found")
5959 ErrSecretNotFound = errors.New("secret not found")
60+ ErrSecretsAlreadyExist = errors.New("secrets already exist")
6061 ErrProviderNotFound = errors.New("secret provider not found")
6162 ErrInvalidContainerName = errors.New("invalid container name")
6263
@@ -57,6 +57,7 @@ var (
57 // Environment errors57 // Environment errors
58 ErrEnvFileNotFound = errors.New("environment file not found")58 ErrEnvFileNotFound = errors.New("environment file not found")
59 ErrSecretNotFound = errors.New("secret not found")59 ErrSecretNotFound = errors.New("secret not found")
60+ ErrSecretsAlreadyExist = errors.New("secrets already exist")
60 ErrProviderNotFound = errors.New("secret provider not found")61 ErrProviderNotFound = errors.New("secret provider not found")
61 ErrInvalidContainerName = errors.New("invalid container name")62 ErrInvalidContainerName = errors.New("invalid container name")
62 63
M internal/usecase/container/service.go +12 -7
@@ -569,7 +569,7 @@ func (s *Service) prepareDeployResources(ctx context.Context, route domain.Route
569569 log.WrapErr(err, "failed to cleanup orphaned containers")
570570 }
571571
572- imageRef, err := s.buildValidatedImageRef(route.Image)
572+ imageRef, err := s.buildValidatedImageRef(ctx, route.Image)
573573 if err != nil {
574574 return nil, err
575575 }
@@ -1679,9 +1679,9 @@ func (s *Service) startLogCollection(ctx context.Context, containerID, domainNam
16791679 }
16801680 }
16811681
1682-func (s *Service) buildValidatedImageRef(image string) (string, error) {
1682+func (s *Service) buildValidatedImageRef(ctx context.Context, image string) (string, error) {
16831683 imageRef := s.buildImageRef(image)
1684- if err := s.validateImageRef(imageRef); err != nil {
1684+ if err := s.validateImageRef(ctx, imageRef); err != nil {
16851685 return "", err
16861686 }
16871687 return imageRef, nil
@@ -1762,11 +1762,11 @@ func hasExplicitRegistry(image string) bool {
17621762 return false
17631763 }
17641764
1765-func (s *Service) validateImageRef(imageRef string) error {
1765+func (s *Service) validateImageRef(ctx context.Context, imageRef string) error {
17661766 if !hasExplicitRegistry(imageRef) {
17671767 return nil
17681768 }
1769- return s.validateExternalImageRef(context.Background(), imageRef, imageRegistry(imageRef))
1769+ return s.validateExternalImageRef(ctx, imageRef, imageRegistry(imageRef))
17701770 }
17711771
17721772 func (s *Service) validateImagePullRef(ctx context.Context, imageRef string) error {
@@ -1821,6 +1821,11 @@ func imageRegistryForPolicy(imageRef string) string {
18211821 return "docker.io"
18221822 }
18231823
1824+// normalizeRegistry normalizes a registry string for comparison purposes only.
1825+// This function is used by sameRegistry to determine if two registry strings
1826+// refer to the same registry. The output intentionally strips IPv6 brackets
1827+// (e.g., "[fd00::1]:5000" -> "fd00::1:5000") which is acceptable for equality
1828+// checks but the result MUST NOT be used to construct or emit valid registry URLs.
18241829 func normalizeRegistry(registry string) string {
18251830 registry = strings.ToLower(strings.TrimSuffix(strings.TrimSpace(registry), "."))
18261831 registry = strings.TrimSuffix(registry, "/")
@@ -2573,7 +2578,7 @@ func (s *Service) deployAttachedService(ctx context.Context, ownerDomain, servic
25732578 log.Info().Str(zerowrap.FieldService, serviceImage).Msg("deploying attached service")
25742579
25752580 // Ensure image (canonical ref is returned; internal pulls may use the local registry).
2576- imageRef, err := s.buildValidatedImageRef(serviceImage)
2581+ imageRef, err := s.buildValidatedImageRef(ctx, serviceImage)
25772582 if err != nil {
25782583 return err
25792584 }
@@ -2680,7 +2685,7 @@ func (s *Service) attachmentEnv(ctx context.Context, containerName, imageRef str
26802685 }
26812686
26822687 func (s *Service) attachmentEnvDrifted(ctx context.Context, existing *domain.Container, containerName, serviceImage string) (bool, error) {
2683- imageRef, err := s.buildValidatedImageRef(serviceImage)
2688+ imageRef, err := s.buildValidatedImageRef(ctx, serviceImage)
26842689 if err != nil {
26852690 return false, err
26862691 }
@@ -569,7 +569,7 @@ func (s *Service) prepareDeployResources(ctx context.Context, route domain.Route
569 log.WrapErr(err, "failed to cleanup orphaned containers")569 log.WrapErr(err, "failed to cleanup orphaned containers")
570 }570 }
571 571
572- imageRef, err := s.buildValidatedImageRef(route.Image)572+ imageRef, err := s.buildValidatedImageRef(ctx, route.Image)
573 if err != nil {573 if err != nil {
574 return nil, err574 return nil, err
575 }575 }
@@ -1679,9 +1679,9 @@ func (s *Service) startLogCollection(ctx context.Context, containerID, domainNam
1679 }1679 }
1680 }1680 }
1681 1681
1682-func (s *Service) buildValidatedImageRef(image string) (string, error) {1682+func (s *Service) buildValidatedImageRef(ctx context.Context, image string) (string, error) {
1683 imageRef := s.buildImageRef(image)1683 imageRef := s.buildImageRef(image)
1684- if err := s.validateImageRef(imageRef); err != nil {1684+ if err := s.validateImageRef(ctx, imageRef); err != nil {
1685 return "", err1685 return "", err
1686 }1686 }
1687 return imageRef, nil1687 return imageRef, nil
@@ -1762,11 +1762,11 @@ func hasExplicitRegistry(image string) bool {
1762 return false1762 return false
1763 }1763 }
1764 1764
1765-func (s *Service) validateImageRef(imageRef string) error {1765+func (s *Service) validateImageRef(ctx context.Context, imageRef string) error {
1766 if !hasExplicitRegistry(imageRef) {1766 if !hasExplicitRegistry(imageRef) {
1767 return nil1767 return nil
1768 }1768 }
1769- return s.validateExternalImageRef(context.Background(), imageRef, imageRegistry(imageRef))1769+ return s.validateExternalImageRef(ctx, imageRef, imageRegistry(imageRef))
1770 }1770 }
1771 1771
1772 func (s *Service) validateImagePullRef(ctx context.Context, imageRef string) error {1772 func (s *Service) validateImagePullRef(ctx context.Context, imageRef string) error {
@@ -1821,6 +1821,11 @@ func imageRegistryForPolicy(imageRef string) string {
1821 return "docker.io"1821 return "docker.io"
1822 }1822 }
1823 1823
1824+// normalizeRegistry normalizes a registry string for comparison purposes only.
1825+// This function is used by sameRegistry to determine if two registry strings
1826+// refer to the same registry. The output intentionally strips IPv6 brackets
1827+// (e.g., "[fd00::1]:5000" -> "fd00::1:5000") which is acceptable for equality
1828+// checks but the result MUST NOT be used to construct or emit valid registry URLs.
1824 func normalizeRegistry(registry string) string {1829 func normalizeRegistry(registry string) string {
1825 registry = strings.ToLower(strings.TrimSuffix(strings.TrimSpace(registry), "."))1830 registry = strings.ToLower(strings.TrimSuffix(strings.TrimSpace(registry), "."))
1826 registry = strings.TrimSuffix(registry, "/")1831 registry = strings.TrimSuffix(registry, "/")
@@ -2573,7 +2578,7 @@ func (s *Service) deployAttachedService(ctx context.Context, ownerDomain, servic
2573 log.Info().Str(zerowrap.FieldService, serviceImage).Msg("deploying attached service")2578 log.Info().Str(zerowrap.FieldService, serviceImage).Msg("deploying attached service")
2574 2579
2575 // Ensure image (canonical ref is returned; internal pulls may use the local registry).2580 // Ensure image (canonical ref is returned; internal pulls may use the local registry).
2576- imageRef, err := s.buildValidatedImageRef(serviceImage)2581+ imageRef, err := s.buildValidatedImageRef(ctx, serviceImage)
2577 if err != nil {2582 if err != nil {
2578 return err2583 return err
2579 }2584 }
@@ -2680,7 +2685,7 @@ func (s *Service) attachmentEnv(ctx context.Context, containerName, imageRef str
2680 }2685 }
2681 2686
2682 func (s *Service) attachmentEnvDrifted(ctx context.Context, existing *domain.Container, containerName, serviceImage string) (bool, error) {2687 func (s *Service) attachmentEnvDrifted(ctx context.Context, existing *domain.Container, containerName, serviceImage string) (bool, error) {
2683- imageRef, err := s.buildValidatedImageRef(serviceImage)2688+ imageRef, err := s.buildValidatedImageRef(ctx, serviceImage)
2684 if err != nil {2689 if err != nil {
2685 return false, err2690 return false, err
2686 }2691 }
M internal/usecase/container/service_test.go +12 -12
@@ -4202,15 +4202,15 @@ func TestService_BuildValidatedImageRef_RegistryPolicy(t *testing.T) {
42024202 AllowedRegistries: []string{"docker.io"},
42034203 }, nil)
42044204
4205- ref, err := svc.buildValidatedImageRef("myapp:latest")
4205+ ref, err := svc.buildValidatedImageRef(context.Background(), "myapp:latest")
42064206 require.NoError(t, err)
42074207 assert.Equal(t, "registry.example.com/myapp:latest", ref)
42084208
4209- ref, err = svc.buildValidatedImageRef("registry.example.com/myapp:latest")
4209+ ref, err = svc.buildValidatedImageRef(context.Background(), "registry.example.com/myapp:latest")
42104210 require.NoError(t, err)
42114211 assert.Equal(t, "registry.example.com/myapp:latest", ref)
42124212
4213- ref, err = svc.buildValidatedImageRef("docker.io/library/nginx:latest")
4213+ ref, err = svc.buildValidatedImageRef(context.Background(), "docker.io/library/nginx:latest")
42144214 require.NoError(t, err)
42154215 assert.Equal(t, "docker.io/library/nginx:latest", ref)
42164216
@@ -4222,7 +4222,7 @@ func TestService_BuildValidatedImageRef_RegistryPolicy(t *testing.T) {
42224222 "169.254.169.254/app:latest",
42234223 } {
42244224 t.Run(image, func(t *testing.T) {
4225- _, err := svc.buildValidatedImageRef(image)
4225+ _, err := svc.buildValidatedImageRef(context.Background(), image)
42264226 require.Error(t, err)
42274227 })
42284228 }
@@ -4231,7 +4231,7 @@ func TestService_BuildValidatedImageRef_RegistryPolicy(t *testing.T) {
42314231 func TestService_BuildValidatedImageRef_RejectsExternalRegistryWhenAllowlistEmpty(t *testing.T) {
42324232 svc := NewService(nil, nil, nil, nil, Config{}, nil)
42334233
4234- _, err := svc.buildValidatedImageRef("ghcr.io/acme/app:latest")
4234+ _, err := svc.buildValidatedImageRef(context.Background(), "ghcr.io/acme/app:latest")
42354235 require.Error(t, err)
42364236 assert.Contains(t, err.Error(), "images.allowed_registries")
42374237
@@ -4248,33 +4248,33 @@ func TestService_BuildValidatedImageRef_RequireDigestOnlyForExternalAllowedRegis
42484248 AllowedRegistries: []string{"docker.io"},
42494249 }, nil)
42504250
4251- _, err := svc.buildValidatedImageRef("docker.io/library/nginx:latest")
4251+ _, err := svc.buildValidatedImageRef(context.Background(), "docker.io/library/nginx:latest")
42524252 require.Error(t, err)
42534253
42544254 err = svc.validateImagePullRef(context.Background(), "nginx:latest")
42554255 require.Error(t, err)
42564256
4257- _, err = svc.buildValidatedImageRef("docker.io/library/nginx@sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa")
4257+ _, err = svc.buildValidatedImageRef(context.Background(), "docker.io/library/nginx@sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa")
42584258 require.NoError(t, err)
42594259
4260- _, err = svc.buildValidatedImageRef("docker.io/library/nginx@sha256:not-a-digest")
4260+ _, err = svc.buildValidatedImageRef(context.Background(), "docker.io/library/nginx@sha256:not-a-digest")
42614261 require.Error(t, err)
42624262
4263- ref, err := svc.buildValidatedImageRef("myapp:latest")
4263+ ref, err := svc.buildValidatedImageRef(context.Background(), "myapp:latest")
42644264 require.NoError(t, err)
42654265 assert.Equal(t, "registry.example.com/myapp:latest", ref)
42664266
4267- _, err = svc.buildValidatedImageRef("registry.example.com/myapp:latest")
4267+ _, err = svc.buildValidatedImageRef(context.Background(), "registry.example.com/myapp:latest")
42684268 require.NoError(t, err)
42694269 }
42704270
42714271 func TestService_BuildValidatedImageRef_AllowedRegistryMatchesPort(t *testing.T) {
42724272 svc := NewService(nil, nil, nil, nil, Config{AllowedRegistries: []string{"docker.io:5000"}}, nil)
42734273
4274- _, err := svc.buildValidatedImageRef("docker.io:5000/app:latest")
4274+ _, err := svc.buildValidatedImageRef(context.Background(), "docker.io:5000/app:latest")
42754275 require.NoError(t, err)
42764276
4277- _, err = svc.buildValidatedImageRef("docker.io:5001/app:latest")
4277+ _, err = svc.buildValidatedImageRef(context.Background(), "docker.io:5001/app:latest")
42784278 require.Error(t, err)
42794279 }
42804280
@@ -4202,15 +4202,15 @@ func TestService_BuildValidatedImageRef_RegistryPolicy(t *testing.T) {
4202 AllowedRegistries: []string{"docker.io"},4202 AllowedRegistries: []string{"docker.io"},
4203 }, nil)4203 }, nil)
4204 4204
4205- ref, err := svc.buildValidatedImageRef("myapp:latest")4205+ ref, err := svc.buildValidatedImageRef(context.Background(), "myapp:latest")
4206 require.NoError(t, err)4206 require.NoError(t, err)
4207 assert.Equal(t, "registry.example.com/myapp:latest", ref)4207 assert.Equal(t, "registry.example.com/myapp:latest", ref)
4208 4208
4209- ref, err = svc.buildValidatedImageRef("registry.example.com/myapp:latest")4209+ ref, err = svc.buildValidatedImageRef(context.Background(), "registry.example.com/myapp:latest")
4210 require.NoError(t, err)4210 require.NoError(t, err)
4211 assert.Equal(t, "registry.example.com/myapp:latest", ref)4211 assert.Equal(t, "registry.example.com/myapp:latest", ref)
4212 4212
4213- ref, err = svc.buildValidatedImageRef("docker.io/library/nginx:latest")4213+ ref, err = svc.buildValidatedImageRef(context.Background(), "docker.io/library/nginx:latest")
4214 require.NoError(t, err)4214 require.NoError(t, err)
4215 assert.Equal(t, "docker.io/library/nginx:latest", ref)4215 assert.Equal(t, "docker.io/library/nginx:latest", ref)
4216 4216
@@ -4222,7 +4222,7 @@ func TestService_BuildValidatedImageRef_RegistryPolicy(t *testing.T) {
4222 "169.254.169.254/app:latest",4222 "169.254.169.254/app:latest",
4223 } {4223 } {
4224 t.Run(image, func(t *testing.T) {4224 t.Run(image, func(t *testing.T) {
4225- _, err := svc.buildValidatedImageRef(image)4225+ _, err := svc.buildValidatedImageRef(context.Background(), image)
4226 require.Error(t, err)4226 require.Error(t, err)
4227 })4227 })
4228 }4228 }
@@ -4231,7 +4231,7 @@ func TestService_BuildValidatedImageRef_RegistryPolicy(t *testing.T) {
4231 func TestService_BuildValidatedImageRef_RejectsExternalRegistryWhenAllowlistEmpty(t *testing.T) {4231 func TestService_BuildValidatedImageRef_RejectsExternalRegistryWhenAllowlistEmpty(t *testing.T) {
4232 svc := NewService(nil, nil, nil, nil, Config{}, nil)4232 svc := NewService(nil, nil, nil, nil, Config{}, nil)
4233 4233
4234- _, err := svc.buildValidatedImageRef("ghcr.io/acme/app:latest")4234+ _, err := svc.buildValidatedImageRef(context.Background(), "ghcr.io/acme/app:latest")
4235 require.Error(t, err)4235 require.Error(t, err)
4236 assert.Contains(t, err.Error(), "images.allowed_registries")4236 assert.Contains(t, err.Error(), "images.allowed_registries")
4237 4237
@@ -4248,33 +4248,33 @@ func TestService_BuildValidatedImageRef_RequireDigestOnlyForExternalAllowedRegis
4248 AllowedRegistries: []string{"docker.io"},4248 AllowedRegistries: []string{"docker.io"},
4249 }, nil)4249 }, nil)
4250 4250
4251- _, err := svc.buildValidatedImageRef("docker.io/library/nginx:latest")4251+ _, err := svc.buildValidatedImageRef(context.Background(), "docker.io/library/nginx:latest")
4252 require.Error(t, err)4252 require.Error(t, err)
4253 4253
4254 err = svc.validateImagePullRef(context.Background(), "nginx:latest")4254 err = svc.validateImagePullRef(context.Background(), "nginx:latest")
4255 require.Error(t, err)4255 require.Error(t, err)
4256 4256
4257- _, err = svc.buildValidatedImageRef("docker.io/library/nginx@sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa")4257+ _, err = svc.buildValidatedImageRef(context.Background(), "docker.io/library/nginx@sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa")
4258 require.NoError(t, err)4258 require.NoError(t, err)
4259 4259
4260- _, err = svc.buildValidatedImageRef("docker.io/library/nginx@sha256:not-a-digest")4260+ _, err = svc.buildValidatedImageRef(context.Background(), "docker.io/library/nginx@sha256:not-a-digest")
4261 require.Error(t, err)4261 require.Error(t, err)
4262 4262
4263- ref, err := svc.buildValidatedImageRef("myapp:latest")4263+ ref, err := svc.buildValidatedImageRef(context.Background(), "myapp:latest")
4264 require.NoError(t, err)4264 require.NoError(t, err)
4265 assert.Equal(t, "registry.example.com/myapp:latest", ref)4265 assert.Equal(t, "registry.example.com/myapp:latest", ref)
4266 4266
4267- _, err = svc.buildValidatedImageRef("registry.example.com/myapp:latest")4267+ _, err = svc.buildValidatedImageRef(context.Background(), "registry.example.com/myapp:latest")
4268 require.NoError(t, err)4268 require.NoError(t, err)
4269 }4269 }
4270 4270
4271 func TestService_BuildValidatedImageRef_AllowedRegistryMatchesPort(t *testing.T) {4271 func TestService_BuildValidatedImageRef_AllowedRegistryMatchesPort(t *testing.T) {
4272 svc := NewService(nil, nil, nil, nil, Config{AllowedRegistries: []string{"docker.io:5000"}}, nil)4272 svc := NewService(nil, nil, nil, nil, Config{AllowedRegistries: []string{"docker.io:5000"}}, nil)
4273 4273
4274- _, err := svc.buildValidatedImageRef("docker.io:5000/app:latest")4274+ _, err := svc.buildValidatedImageRef(context.Background(), "docker.io:5000/app:latest")
4275 require.NoError(t, err)4275 require.NoError(t, err)
4276 4276
4277- _, err = svc.buildValidatedImageRef("docker.io:5001/app:latest")4277+ _, err = svc.buildValidatedImageRef(context.Background(), "docker.io:5001/app:latest")
4278 require.Error(t, err)4278 require.Error(t, err)
4279 }4279 }
4280 4280

Keyboard shortcuts

Single-key shortcuts are on. ctrl k and esc work whatever this says.

ctrl k :
go to a section, branch, tag, file or repository
?
this list
j k
move the row cursor down / up
enter
open the row under the cursor; on Files, a directory opens or closes in place
↑ ↓ ← → home end
in the file tree (focus on a row): previous / next row, close / open a directory or go to its parent / first entry, first / last row. They never open a file
l h
on Files: open a directory or a file / close a directory or go up to its parent, then to the parent page. Elsewhere: into the side panel (on a merge request, its files) / back to the content; there j k move between its controls
g g G
first / last row
/
filter the list; on Files, find a file anywhere in the repository (esc clears, enter opens the best match)
b
switch branch or tag
g s g f g c g b g m g i g r g a
tabs: summary, files, commits, branches & tags, merge requests, issues, releases, actions (when available)
g h
home
w
wide mode: use the whole width of the screen, or not (remembered)
y
copy a permalink pinned to the commit
d u x
diff: split / unified / collapse or expand all
e E
diff: the whole file in view / every file, with the lines the hunks hide
n
merge request: next note in the diff
esc
close a dialog, leave a field

Branches 7

Tags 106

↑↓ moveenter openesc close