Skip to content

feat: Edit annotations for the argocd-server service#2095

Draft
MaayanGalindez wants to merge 3 commits intoargoproj-labs:masterfrom
MaayanGalindez:feature/argocd-cr-service-annotation
Draft

feat: Edit annotations for the argocd-server service#2095
MaayanGalindez wants to merge 3 commits intoargoproj-labs:masterfrom
MaayanGalindez:feature/argocd-cr-service-annotation

Conversation

@MaayanGalindez
Copy link
Copy Markdown

@MaayanGalindez MaayanGalindez commented Feb 24, 2026

What type of PR is this?

/kind enhancement

What does this PR do / why we need it:

this PR adds the ability to control the argocd-server service annotations, most of the users won't benefit from this PR but it'll help for me and my team to have a cleaner argocd setup, we use terraform to create resources in argocd which requires gRPC ingress (already a feature) but in our case we need to add some annotations to the service before using gRPC in our CNI.

Have you updated the necessary documentation?

I don't think there's any required documentation to be updated or created

  • Documentation update is required by this PR.
  • Documentation has been updated.

Which issue(s) this PR fixes:

Fixes #651

How to test changes / Special notes to the reviewer:

In the argocd manifest:

spec:
  server:
    service:
      annotations:
        test.kubernetes.io/test: test

and then observe if there's annotations created in the argocd-server service,
Thanks for taking the time to review this :).

Summary by CodeRabbit

  • New Features

    • Support for custom annotations on ArgoCD server services: specify annotations in the ArgoCD spec to apply metadata to the generated Service resources (schema and operator now accept an annotations map).
  • Bug Fixes / Behavior

    • Reconciliation now merges and syncs user-defined service annotations so they are preserved and applied during updates.
  • Tests

    • Added tests covering annotation reconciliation and OpenShift Auto TLS interaction to ensure annotations are preserved and applied correctly.

@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Feb 24, 2026

📝 Walkthrough

Walkthrough

Adds an Annotations map to the ArgoCD server Service spec across API versions, updates deepcopy logic and CRD schemas, propagates annotations during service reconciliation (merging with AutoTLS annotations), and adds tests covering annotation reconciliation and OpenShift auto-TLS interaction.

Changes

Cohort / File(s) Summary
Type Definitions
api/v1alpha1/argocd_types.go, api/v1beta1/argocd_types.go
Added Annotations map[string]string (JSON annotations,omitempty) to ArgoCDServerServiceSpec.
Generated Deep Copy Methods
api/v1alpha1/zz_generated.deepcopy.go, api/v1beta1/zz_generated.deepcopy.go
Deep-copy logic added for Annotations map; ArgoCDServerSpec.DeepCopyInto now deep-copies the Service field instead of direct assignment.
CRD Schema Definitions
config/crd/bases/argoproj.io_argocds.yaml, deploy/olm-catalog/.../argoproj.io_argocds.yaml, bundle/manifests/argoproj.io_argocds.yaml
Extended CRD schemas to include optional annotations object (additionalProperties: string) for server/backend Service specs in v1alpha1 and v1beta1.
Reconciliation Logic
controllers/argocd/service.go
Propagate cr.Spec.Server.Service.Annotations into generated Service; compare/merge with existing Service annotations (preserve AutoTLS-related annotations) and update when different.
Test Coverage
controllers/argocd/service_test.go
Added subtests verifying server Service annotations are applied and preserved alongside OpenShift auto-TLS annotation handling.

Sequence Diagram(s)

sequenceDiagram
    participant User as User / CR
    participant Controller as ArgoCD Controller
    participant KubeAPI as Kubernetes API (Service)
    participant Existing as Existing Service
    User->>Controller: Create/Update ArgoCD CR with Service.Annotations
    Controller->>Controller: Build desired Service (includes Annotations)
    Controller->>KubeAPI: Get Existing Service
    alt Service exists
        KubeAPI->>Controller: Return Existing Service
        Controller->>Controller: Merge/preserve AutoTLS annotations, compare annotations
        alt Annotations differ
            Controller->>KubeAPI: Update Service.annotations
            KubeAPI->>Existing: Patch annotations
        end
    else Service missing
        Controller->>KubeAPI: Create Service with annotations
    end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Suggested reviewers

  • chengfang
  • svghadi

Poem

🐰 I hopped into types and CRD light,
Added tiny labels to guide service flight,
The controller tends annotations with care,
Merging AutoTLS and what users bear,
Now DNS and routes can dance at night.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'feat: Edit annotations for the argocd-server service' accurately describes the main change: adding ability to control annotations on the argocd-server Service via the ArgoCD custom resource.
Linked Issues check ✅ Passed The PR fully implements issue #651's requirement: provides a way to set annotations on argocd-server Service via CR spec.server.service.annotations, allowing users to supply arbitrary annotation key/value pairs for external-dns and other integrations.
Out of Scope Changes check ✅ Passed All changes are directly related to implementing service annotations: API type definitions, deepcopy methods, CRD schemas, service reconciliation logic, and corresponding test coverage. No unrelated modifications detected.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
  • 📝 Generate docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
controllers/argocd/service.go (1)

498-549: ⚠️ Potential issue | 🟠 Major

Avoid wiping existing annotations when spec.server.service.annotations is unset.

Right now svc.Annotations is only populated when len(...) > 0, but the update path always compares and overwrites annotations. This can remove existing annotations (including the OpenShift autoTLS annotation when the TLS secret already exists, or cluster-added annotations) even when users did not opt in to managing them. It also aliases the CR map directly.

Consider gating annotation reconciliation on a non‑nil spec map and deep‑copying/merging with the autoTLS annotation instead of replacing the map.

🛠️ Suggested fix
- // Add annotations if specified without deleteing annotations from `ensureAutoTLSAnnotation()`
- if len(cr.Spec.Server.Service.Annotations) > 0 {
-     if svc.Annotations == nil {
-         svc.Annotations = make(map[string]string)
-         svc.Annotations = cr.Spec.Server.Service.Annotations
-     } else {
-         for k, v := range cr.Spec.Server.Service.Annotations {
-             svc.Annotations[k] = v
-         }
-     }
- }
+ // Add annotations if explicitly specified without clobbering AutoTLS or external annotations.
+ if cr.Spec.Server.Service.Annotations != nil {
+     desired := map[string]string{}
+     for k, v := range svc.Annotations { // preserves AutoTLS if set
+         desired[k] = v
+     }
+     for k, v := range cr.Spec.Server.Service.Annotations {
+         desired[k] = v
+     }
+     svc.Annotations = desired
+ }
...
- if !reflect.DeepEqual(svc.Annotations, existingSVC.Annotations) {
+ if cr.Spec.Server.Service.Annotations != nil &&
+     !reflect.DeepEqual(svc.Annotations, existingSVC.Annotations) {
     existingSVC.Annotations = svc.Annotations
     if changed {
         explanation += ", "
     }
     explanation += "service annotations"
     changed = true
 }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@controllers/argocd/service.go` around lines 498 - 549, The current logic
overwrites existingSVC.Annotations with svc.Annotations (and aliases the CR map)
even when cr.Spec.Server.Service.Annotations is nil/empty; change reconciliation
so annotations are only replaced/merged when the CR explicitly provides a
non-nil map: when building svc, do not assign svc.Annotations =
cr.Spec.Server.Service.Annotations directly; instead create a new map copy and
merge entries from cr.Spec.Server.Service.Annotations into svc.Annotations only
if cr.Spec.Server.Service.Annotations != nil, and when updating existingSVC
preserve any annotations not managed by the CR by merging the autoTLS annotation
from ensureAutoTLSAnnotation and the CR-provided keys rather than replacing the
entire map; ensure you deep-copy maps to avoid aliasing the CR's map.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@controllers/argocd/service_test.go`:
- Around line 146-187: The tests "Server Service annotations update" and "Server
Service annotations update with Openshift auto TLS annotation" call
argoutil.SetRouteAPIFound(...) and do not restore the global flag, causing
cross-test leakage; update each subtest to capture the previous state (e.g.,
prev := argoutil.IsRouteAPIFound() or read current value), then defer restoring
it with argoutil.SetRouteAPIFound(prev) (or call SetRouteAPIFound(false) after
the first subtest) so the global Route API flag used by reconcileServerService
and related asserts is reset at test end.

---

Outside diff comments:
In `@controllers/argocd/service.go`:
- Around line 498-549: The current logic overwrites existingSVC.Annotations with
svc.Annotations (and aliases the CR map) even when
cr.Spec.Server.Service.Annotations is nil/empty; change reconciliation so
annotations are only replaced/merged when the CR explicitly provides a non-nil
map: when building svc, do not assign svc.Annotations =
cr.Spec.Server.Service.Annotations directly; instead create a new map copy and
merge entries from cr.Spec.Server.Service.Annotations into svc.Annotations only
if cr.Spec.Server.Service.Annotations != nil, and when updating existingSVC
preserve any annotations not managed by the CR by merging the autoTLS annotation
from ensureAutoTLSAnnotation and the CR-provided keys rather than replacing the
entire map; ensure you deep-copy maps to avoid aliasing the CR's map.

ℹ️ Review info

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 61e675b and c212a12.

📒 Files selected for processing (9)
  • api/v1alpha1/argocd_types.go
  • api/v1alpha1/zz_generated.deepcopy.go
  • api/v1beta1/argocd_types.go
  • api/v1beta1/zz_generated.deepcopy.go
  • bundle/manifests/argoproj.io_argocds.yaml
  • config/crd/bases/argoproj.io_argocds.yaml
  • controllers/argocd/service.go
  • controllers/argocd/service_test.go
  • deploy/olm-catalog/argocd-operator/0.18.0/argoproj.io_argocds.yaml
🔥 Files not summarized due to errors (1)
  • bundle/manifests/argoproj.io_argocds.yaml: Error: Server error: no LLM provider could handle the message

Signed-off-by: Maayan Galindez <maayangg2005@gmail.com>
@MaayanGalindez MaayanGalindez force-pushed the feature/argocd-cr-service-annotation branch from c212a12 to 2973d26 Compare February 24, 2026 13:04
Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

♻️ Duplicate comments (1)
controllers/argocd/service_test.go (1)

146-187: SetRouteAPIFound global not restored after subtests — already flagged.

Both subtests mutate the package-level routeAPIFound flag without restoring it, which can affect subsequent tests in the same run.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@controllers/argocd/service_test.go` around lines 146 - 187, The tests call
the package-level flag setter argoutil.SetRouteAPIFound and do not restore the
original routeAPIFound value, causing global state leakage between subtests;
update each subtest that calls argoutil.SetRouteAPIFound (e.g., the "Server
Service annotations update" and "Server Service annotations update with
Openshift auto TLS annotation" cases) to capture the current routeAPIFound value
before changing it and defer restoring it (or call SetRouteAPIFound with the
saved value in a defer) immediately after saving so the global flag is returned
to its original state after the subtest finishes.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@controllers/argocd/service_test.go`:
- Line 173: The comment "Existing Server is found and has the argoCD new Server
Service Type" is stale/misleading for this subtest which asserts annotations;
update that comment (and the subtest description string if present) to reference
annotations (e.g., "Existing Server is found and has the argoCD Server
annotations") so the comment matches the test intent and assertions in the test
block.

In `@controllers/argocd/service.go`:
- Around line 498-508: The svc.Annotations nil-branch currently makes
svc.Annotations alias cr.Spec.Server.Service.Annotations and also wastes a make
call; instead always allocate a fresh map for svc.Annotations and copy entries
from cr.Spec.Server.Service.Annotations into it (same behavior as the non-nil
branch) to avoid mutating the CR in-memory; update the block that reads/sets
svc.Annotations (and thus what later gets assigned to existingSVC.Annotations)
so both branches use a newly allocated map and a loop to copy keys from
cr.Spec.Server.Service.Annotations.

---

Duplicate comments:
In `@controllers/argocd/service_test.go`:
- Around line 146-187: The tests call the package-level flag setter
argoutil.SetRouteAPIFound and do not restore the original routeAPIFound value,
causing global state leakage between subtests; update each subtest that calls
argoutil.SetRouteAPIFound (e.g., the "Server Service annotations update" and
"Server Service annotations update with Openshift auto TLS annotation" cases) to
capture the current routeAPIFound value before changing it and defer restoring
it (or call SetRouteAPIFound with the saved value in a defer) immediately after
saving so the global flag is returned to its original state after the subtest
finishes.

ℹ️ Review info

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between c212a12 and 2973d26.

📒 Files selected for processing (9)
  • api/v1alpha1/argocd_types.go
  • api/v1alpha1/zz_generated.deepcopy.go
  • api/v1beta1/argocd_types.go
  • api/v1beta1/zz_generated.deepcopy.go
  • bundle/manifests/argoproj.io_argocds.yaml
  • config/crd/bases/argoproj.io_argocds.yaml
  • controllers/argocd/service.go
  • controllers/argocd/service_test.go
  • deploy/olm-catalog/argocd-operator/0.18.0/argoproj.io_argocds.yaml
🚧 Files skipped from review as they are similar to previous changes (3)
  • api/v1alpha1/argocd_types.go
  • api/v1beta1/argocd_types.go
  • api/v1beta1/zz_generated.deepcopy.go

Signed-off-by: Maayan Galindez <maayangg2005@gmail.com>
Signed-off-by: Maayan Galindez <maayangg2005@gmail.com>
Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

♻️ Duplicate comments (1)
controllers/argocd/service_test.go (1)

146-187: SetRouteAPIFound is still not reset after each subtest — cross-test pollution remains.

Both subtests mutate the package-level Route API flag but never restore it. After TestReconcileServerService completes, the flag is left as true, which can affect subsequent tests in the same package.

🧪 Suggested fix
 	t.Run("Server Service annotations update", func(t *testing.T) {
 		// Reconcile with previous existing Server Service with different Annotations
 		argoutil.SetRouteAPIFound(false)
+		t.Cleanup(func() { argoutil.SetRouteAPIFound(false) })
 		a.Spec.Server.Service.Annotations = map[string]string{"test.kubernetes.io/test": "test"}

 	t.Run("Server Service annotations update with Openshift auto TLS annotation", func(t *testing.T) {
 		// Reconcile with previous existing Server Service with different Annotations and the AutoTLSAnnotation
 		argoutil.SetRouteAPIFound(true)
+		t.Cleanup(func() { argoutil.SetRouteAPIFound(false) })
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@controllers/argocd/service_test.go` around lines 146 - 187, Test subtests
mutate the package-level Route API flag via argoutil.SetRouteAPIFound and never
restore it, causing cross-test pollution; fix by capturing the original flag
value before each subtest (or at test start) and restoring it after the subtest
(use defer to reset) wherever argoutil.SetRouteAPIFound(...) is called in
TestReconcileServerService (references: argoutil.SetRouteAPIFound, the subtests
"Server Service annotations update" and "Server Service annotations update with
Openshift auto TLS annotation", and the reconciler method
r.reconcileServerService) so the global state is returned to its prior value for
other tests.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@controllers/argocd/service.go`:
- Around line 540-547: The code replaces existingSVC.Annotations with
svc.Annotations, which wipes annotations managed by other controllers; instead
merge annotations: iterate svc.Annotations and copy/overwrite those keys into
existingSVC.Annotations, and only remove keys that this controller previously
managed (track or hardcode the AutoTLS key handled by ensureAutoTLSAnnotation)
rather than clearing all absent keys; update the change detection logic around
svc.Annotations/existingSVC.Annotations and the explanation string to reflect
only additive updates or managed-key removals (refer to svc.Annotations,
existingSVC.Annotations and ensureAutoTLSAnnotation to locate the logic).

---

Duplicate comments:
In `@controllers/argocd/service_test.go`:
- Around line 146-187: Test subtests mutate the package-level Route API flag via
argoutil.SetRouteAPIFound and never restore it, causing cross-test pollution;
fix by capturing the original flag value before each subtest (or at test start)
and restoring it after the subtest (use defer to reset) wherever
argoutil.SetRouteAPIFound(...) is called in TestReconcileServerService
(references: argoutil.SetRouteAPIFound, the subtests "Server Service annotations
update" and "Server Service annotations update with Openshift auto TLS
annotation", and the reconciler method r.reconcileServerService) so the global
state is returned to its prior value for other tests.

ℹ️ Review info

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 2973d26 and 43e1360.

📒 Files selected for processing (2)
  • controllers/argocd/service.go
  • controllers/argocd/service_test.go

Comment on lines +540 to +547
if !reflect.DeepEqual(svc.Annotations, existingSVC.Annotations) {
existingSVC.Annotations = svc.Annotations
if changed {
explanation += ", "
}
explanation += "service annotations"
changed = true
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Full annotation replacement silently wipes annotations not managed by this controller.

svc.Annotations contains only AutoTLS and user-specified annotations. existingSVC (fetched from the API at line 513) may carry additional annotations set by other controllers, CNI plugins, service mesh, or kubectl/Terraform. Assigning existingSVC.Annotations = svc.Annotations at line 541 deletes all such external annotations on every reconcile that detects any diff.

Before this PR, ensureAutoTLSAnnotation only added or removed a single specific key, leaving all other annotations intact. This PR introduces a regression for any annotation not explicitly listed in cr.Spec.Server.Service.Annotations.

A minimal fix without tackling full ownership tracking is to merge user annotations additively and handle removals only for keys previously known to be operator-managed:

🐛 Proposed fix – merge user annotations instead of full replacement
-		if !reflect.DeepEqual(svc.Annotations, existingSVC.Annotations) {
-			existingSVC.Annotations = svc.Annotations
-			if changed {
-				explanation += ", "
-			}
-			explanation += "service annotations"
-			changed = true
-		}
+		// Merge user-specified annotations onto existingSVC without wiping externally-set keys.
+		for k, v := range cr.Spec.Server.Service.Annotations {
+			if existingSVC.Annotations == nil {
+				existingSVC.Annotations = make(map[string]string)
+			}
+			if existingSVC.Annotations[k] != v {
+				existingSVC.Annotations[k] = v
+				if !changed {
+					explanation = "service annotations"
+				} else {
+					explanation += ", service annotations"
+				}
+				changed = true
+				break // explanation already updated; loop continues updating the map
+			}
+		}
+		// Note: removal of annotations that were previously in the CR but are now
+		// absent requires ownership tracking (e.g. a "last-applied-annotations"
+		// annotation) and is deferred to a follow-up.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@controllers/argocd/service.go` around lines 540 - 547, The code replaces
existingSVC.Annotations with svc.Annotations, which wipes annotations managed by
other controllers; instead merge annotations: iterate svc.Annotations and
copy/overwrite those keys into existingSVC.Annotations, and only remove keys
that this controller previously managed (track or hardcode the AutoTLS key
handled by ensureAutoTLSAnnotation) rather than clearing all absent keys; update
the change detection logic around svc.Annotations/existingSVC.Annotations and
the explanation string to reflect only additive updates or managed-key removals
(refer to svc.Annotations, existingSVC.Annotations and ensureAutoTLSAnnotation
to locate the logic).

@MaayanGalindez MaayanGalindez marked this pull request as draft February 24, 2026 15:50
Type corev1.ServiceType `json:"type"`

// Annotations is the map of annotations to apply to the Server Service.
Annotations map[string]string `json:"annotations,omitempty"`
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

cant we rely on metadata.Annotations ?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

I’m thinking about renaming it to ExtraAnnotations and changing how it works.

I don’t want to rely on metadata.annotations because I’d prefer a more declarative way to add annotations to the server service. This would make it clearer that certain annotations are required for gRPC ingress to work with our CNI.

It should also help new team members, so they don’t have to guess that these annotations need to be added manually. In addition, it could make deploying Argo CD across multiple sites and instances easier and more consistent.

Thanks again for the review. I’d really appreciate any feedback. And if I misunderstood something or if you think this feature isn’t necessary, I’m happy to hear your opinion.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

IMHO, this can be achieved using the existing metadata.annotations field in Kubernetes. Since metadata is already a well-defined and structured section (like labels, annotations, etc.), it is more consistent and future-proof to rely on it instead of introducing a new custom annotations field in the CRD.

If we start adding separate fields for annotations now, we may eventually need similar fields for labels or other metadata as well. Continuously extending the CRD in this way could unnecessarily increase its length and complexity.

We should also keep in mind that Kubernetes enforces a size limit on annotations. The maximum total size of all annotations (combined keys and values) for a single object is 256 KiB (262,144 bytes). If this limit is exceeded, the API server will reject the object. This is an important constraint to consider in the design.

If an additional field is truly necessary, it would be better to follow the same metadata structure used by Kubernetes objects. That would keep the design consistent and aligned with Kubernetes conventions.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Thanks for the detailed feedback, I definitely understand your point about keeping things aligned with the existing metadata structure and avoiding unnecessary CRD expansion. That makes sense from a consistency and long term maintenance perspective.

I’m not strongly attached to a specific implementation. The main goal here is to make it possible to add annotations to the Argo CD server Service in a way that can be defined and documented directly in the CR. It would also make this configuration automated for users who deploy the Argo CD CR via Terraform or other Argo CD instances, similar to how we currently handle ingress annotations.

If you feel this feature doesn’t provide enough value or doesn’t align with the project’s direction, I’m completely fine with closing the PR. But if there’s a preferred way to support this kind of feature, I’d really appreciate your guidance:

  • How would you like to see this implemented?
  • How should conflicts or overrides behave?
  • Should there be additional restrictions or validation around which annotations can be set?

I’m happy to rework the proposal to better match the project’s conventions, just let me know what direction you’d prefer :).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add service annotations

2 participants