Skip to content

Remove the integrity hash annotation - #4643

Merged
nikola-jokic merged 2 commits into
masterfrom
nikola-jokic-remove-integrity-hash-annotation
Sep 11, 2026
Merged

Remove the integrity hash annotation#4643
nikola-jokic merged 2 commits into
masterfrom
nikola-jokic-remove-integrity-hash-annotation

Conversation

@nikola-jokic

@nikola-jokic nikola-jokic commented Sep 9, 2026

Copy link
Copy Markdown
Collaborator

Layer 6 of a 7-part split of #4575.

What

Mechanical dead-code removal of the actions.github.com/integrity-hash annotation and everything that fed it.

  • controllers/actions.github.com/resourcebuilder.go: delete the annotationKeyIntegrityHash constant, the remaining hash helpers (scaleSetListenerConfigIntegrityHash, scaleSetListenerServiceAccountIntegrityHash, scaleSetRoleIntegrityHash, scaleSetListenerRoleBindingIntegrityHash, autoscalingListenerProxySecretIntegrityHash, ephemeralRunnerSetProxySecretZIdentityHash), and every call site that stamps the annotation onto an object. newAutoscalingListener now starts from var annotations map[string]string.
  • controllers/actions.github.com/resourcecache.go: drop the integrity-hash fallback branch in newResourceCacheObjectRef.
  • apis/actions.github.com/v1alpha1: delete AutoscalingListenerSpec.Hash() and EphemeralRunnerSpec.Hash() plus the now-unused hash imports.
  • Tests updated to assert the annotation is absent; TestEphemeralRunnerSetProxySecretZIdentityHash becomes TestEphemeralRunnerSetProxySecretMetadata.

Why this is safe

Layers 2-4 already removed every reader of the integrity hash, so all that remained were write-only dead paths. Nothing in this PR changes reconcile behaviour.

Behavioural implication

Newly built objects no longer carry actions.github.com/integrity-hash. Update detection is handled entirely by the mechanisms introduced in layers 2-4.

Two upgrade consequences are worth stating precisely, both now covered by tests in resourcebuilder_legacy_annotation_test.go:

  1. Existing listeners are recreated once. AutoscalingRunnerSetReconciler compares the live listener's annotations against the desired ones with cmp.Equal, so a listener created by an older controller — which carries the annotation — no longer matches and is deleted and rebuilt on the first reconcile after upgrade. This is a one-time rollout, not a loop: the replacement comes from the same code path and carries no annotation, so the next comparison matches. It is also not additional churn in practice, because the listener runs the manager's own image (CONTROLLER_MANAGER_CONTAINER_IMAGE), so any controller version upgrade already changes Spec.Image and forces the same recreation.

  2. The annotation is not migrated off objects that already have it. Reconcilers that update an object in place merge live annotations under the desired ones (mergeAnnotations(live, desired)), so a key that is merely absent from the desired set survives. Pre-existing EphemeralRunnerSets, service accounts, roles, role bindings and proxy/config Secrets therefore keep the annotation. Since layers 2-4 removed every reader, it is inert metadata rather than a behavioural leftover. Actively stripping it would mean patching every managed object across every scale set on upgrade — a deliberate migration, and a separate decision from this removal.

Validation

  • go build ./..., go vet ./..., gofmt -l apis/ controllers/ — clean
  • make manifests leaves git status --porcelain empty (CRDs in sync)
  • go test ./controllers/actions.github.com/... ./apis/...ok (envtest, 238s)
  • Both new tests mutation-checked: re-stamping the annotation fails the first, stripping the key in mergeAnnotations fails the second.

Copilot AI left a comment

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.

Copilot review overview

🟢 Approval recommended

The changes are mechanical dead-code removal consistent with the stated migration plan, and the updated tests align with the intended absence of the annotation.

Review tier: Lite
Findings: None

What changed in this PR

This PR removes the write-only actions.github.com/integrity-hash annotation and the helper hashing APIs that previously fed it, completing another layer in the migration to the newer update-detection mechanisms introduced in earlier layers (#4575 context).

Changes:

  • Removes integrity-hash annotation stamping and associated helper hash functions from the resource builder.
  • Simplifies resource-cache object ref versioning by dropping the integrity-hash fallback branch.
  • Removes now-unused Hash() helper methods from v1alpha1 spec types and updates tests to assert the annotation is absent.
File Description
controllers/​actions.github.com/​resourcebuilder.go Deletes integrity-hash constant, helper hash functions, and all annotation write call sites.
controllers/​actions.github.com/​resourcecache.go Removes integrity-hash fallback when deriving cache object “resource versions.”
apis/​actions.github.com/​v1alpha1/​autoscalinglistener_types.go Drops AutoscalingListenerSpec.Hash() and unused hash import.
apis/​actions.github.com/​v1alpha1/​ephemeralrunner_types.go Drops EphemeralRunnerSpec.Hash() and unused hash import.
controllers/​actions.github.com/​resourcebuilder_test.go Updates assertions to ensure the integrity-hash annotation is not present; renames proxy secret test accordingly.
controllers/​actions.github.com/​resourcecache_test.go Removes integrity-hash annotation setup from test fixtures.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

@humh25

humh25 commented Sep 9, 2026 via email

Copy link
Copy Markdown

rentziass
rentziass previously approved these changes Sep 10, 2026
@nikola-jokic
nikola-jokic force-pushed the nikola-jokic-remove-integrity-hash-annotation branch from 19dc280 to a3569dc Compare September 10, 2026 09:13
@nikola-jokic
nikola-jokic force-pushed the nikola-jokic-remove-integrity-hash-annotation branch from a3569dc to bcb101e Compare September 10, 2026 09:20
@nikola-jokic
nikola-jokic force-pushed the nikola-jokic-remove-integrity-hash-annotation branch from bcb101e to 58c7973 Compare September 10, 2026 09:52
@nikola-jokic
nikola-jokic requested a lite review from Copilot September 10, 2026 11:17

Copilot AI left a comment

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.

Copilot review overview

🟡 Changes recommended

Legacy annotations are not cleaned up, and existing listeners may be unnecessarily recreated during upgrade.

Once you've addressed the issues Copilot identified, you can request another Copilot review.

Review tier: Lite
Findings: 1 High severity · 1 Medium severity

New issues introduced by this change (2)
Severity Finding
High severity controllers/​actions.github.com/​resourcebuilder.go — Existing AutoscalingListener objects still carry the annotation written by the previous builder.…
Medium severity controllers/​actions.github.com/​resourcebuilder.go — This only removes the key from newly built desired objects; it does not remove the legacy…
Suppressed comments (1)

controllers/actions.github.com/resourcebuilder_test.go:231

  • This assertion only covers a newly constructed Secret. Secrets created before this change still contain the old integrity annotation, and the EphemeralRunnerSet reconciler merges live annotations into the desired set before patching (ephemeralrunnerset_controller.go:644-655), so the old key is preserved indefinitely and managed proxy Secrets do not actually lose it after upgrade. Add legacy-key cleanup to reconciliation or narrow the stated removal behavior, with an existing-Secret test.
	assert.NotContains(t, proxySecret.Annotations, "actions.github.com/integrity-hash")

Comment thread controllers/actions.github.com/resourcebuilder.go
Comment thread controllers/actions.github.com/resourcebuilder.go

Copilot AI left a comment

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.

Copilot review overview

🟡 Changes recommended

Resolve the exported API compatibility breaks and the empty-annotations reconciliation loop.

Once you've addressed the issues Copilot identified, you can request another Copilot review.

Review tier: Lite
Findings: 2 High severity

New issues introduced by this change (2)
Severity Finding
High severity apis/​actions.github.com/​v1alpha1/​autoscalinglistener_types.go — Removing AutoscalingListenerSpec.Hash() is source-incompatible for downstream Go consumers of…
High severity apis/​actions.github.com/​v1alpha1/​ephemeralrunner_types.go — Removing EphemeralRunnerSpec.Hash() is source-incompatible for downstream Go consumers of this…
Issues resolved since last review (2)
Severity Finding
Medium severity controllers/​actions.github.com/​resourcebuilder.go — This only removes the key from newly built desired objects; it does not remove the legacy… View resolved comment
High severity controllers/​actions.github.com/​resourcebuilder.go — Existing AutoscalingListener objects still carry the annotation written by the previous builder.… View resolved comment
Suppressed comments (1)

controllers/actions.github.com/resourcebuilder.go:183

  • When AutoscalingListenerMetadata.Annotations is an explicitly empty map, mergeAnnotations returns a non-nil empty map. The desired listener is compared with cmp.Equal against the live annotations, but metadata.annotations is omitted when this object is serialized, so the created listener is read back with a nil map; nil and empty maps compare unequal and the reconciler will delete/recreate it on every pass. Normalize empty annotations to nil before assigning it to the listener (and add a regression test for empty metadata).
	var annotations map[string]string

	if autoscalingRunnerSet.Spec.AutoscalingListenerMetadata != nil {
		labels = b.filterAndMergeLabels(autoscalingRunnerSet.Spec.AutoscalingListenerMetadata.Labels, labels)
		annotations = b.mergeAnnotations(autoscalingRunnerSet.Spec.AutoscalingListenerMetadata.Annotations, annotations)

@@ -87,10 +86,6 @@ type AutoscalingListenerSpec struct {
ListenerConfig *ListenerConfig `json:"listenerConfig,omitempty"`
}

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

This is fine

@@ -133,10 +132,6 @@ type EphemeralRunnerSpec struct {
corev1.PodTemplateSpec `json:",inline"`
}

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

This is fine

@nikola-jokic
nikola-jokic force-pushed the nikola-jokic-remove-integrity-hash-annotation branch from 5905d48 to e3246d7 Compare September 10, 2026 16:20
@nikola-jokic
nikola-jokic force-pushed the nikola-jokic-remove-integrity-hash-annotation branch from e3246d7 to 752765e Compare September 10, 2026 20:56
rentziass
rentziass previously approved these changes Sep 11, 2026
Base automatically changed from nikola-jokic-ers-scale-up-after-cleanup to master September 11, 2026 13:29
nikola-jokic and others added 2 commits September 11, 2026 15:29
Layers 2-4 removed every reader of the actions.github.com/integrity-hash
annotation, so what remained were write-only dead paths. Delete the
annotation constant, all remaining hash helpers that computed it, the
call sites that stamped it onto objects, the integrity-hash fallback in
newResourceCacheObjectRef, and the now-unused AutoscalingListenerSpec.Hash
and EphemeralRunnerSpec.Hash methods.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Code review raised two upgrade consequences of no longer stamping
actions.github.com/integrity-hash. Both are real, and neither is covered
by a test, so cover them.

The AutoscalingRunnerSet reconciler compares a live listener's annotations
against the desired ones exactly, so a listener created by an older
controller is replaced on the first reconcile after an upgrade. That
rollout is one-time rather than a loop, because the replacement is built
by the same path and carries no annotation. It is not additional either:
the listener runs the manager's own image, so a controller upgrade already
forces the same recreation through the Spec comparison.

Reconcilers that update objects in place merge live annotations under the
desired ones, so the annotation survives on objects that already carry it.
Nothing reads it any more, so it is inert metadata; stripping it would mean
patching every managed object on upgrade, which is a separate decision.

Both tests were mutation-checked: re-stamping the annotation fails the
first, and stripping the key in mergeAnnotations fails the second.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
@nikola-jokic
nikola-jokic force-pushed the nikola-jokic-remove-integrity-hash-annotation branch from 6b6011c to 099703a Compare September 11, 2026 13:29
@nikola-jokic
nikola-jokic merged commit 03328aa into master Sep 11, 2026
28 checks passed
@nikola-jokic
nikola-jokic deleted the nikola-jokic-remove-integrity-hash-annotation branch September 11, 2026 16:27
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.

4 participants