Repository: kubernetes-sigs/cluster-api
Pull request #9182 (2023-08-14 14:32:38)

🌱 Makefile: run doctoc only once
Signed-off-by: Stefan Büringer buringerst@vmware.com

<!-- Thanks for sending a pull request! Here are some tips for you:
    1. If this is your first time, please read our contributor guidelines: https://github.com/kubernetes-sigs/cluster-api/blob/main/CONTRIBUTING.md#contributing-a-patch and developer guide https://github.com/kubernetes-sigs/cluster-api/blob/main/docs/book/src/developer/guide.md

    2. Please add an icon to the title of this PR (see https://sigs.k8s.io/cluster-api/CONTRIBUTING.md#contributing-a-patch), and delete this line and similar ones
    the icon will be either ⚠️ (:warning:, major or breaking changes), ✨ (:sparkles:, feature additions), 🐛 (:bug:, patch and bugfixes), 📖 (:book:, documentation or proposals), or 🌱 (:seedling:, minor or other) 

-->

**What this PR does / why we need it**:

**Which issue(s) this PR fixes** *(optional, in `fixes #<issue number>(, fixes #<issue_number>, ...)` format, will close the issue(s) when PR gets merged)*:
Fixes #

<!-- 
Please label this pull request according to what area(s) you are addressing. For reference on PR/issue labels, see: https://github.com/kubernetes-sigs/cluster-api/labels?q=area+

Area example:
/area runtime-sdk
-->

k8s-ci-robot: This PR is currently missing an area label, which is used to identify the modified component when generating release notes.

Area labels can be added by org members by writing `/area ${COMPONENT}` in a comment

Please see the [labels list](https://github.com/kubernetes/test-infra/blob/master/label_sync/labels.md#labels-that-apply-to-kubernetes-sigscluster-api-for-both-issues-and-prs) for possible areas.


<details>

Instructions for interacting with me using PR comments are available [here](https://git.k8s.io/community/contributors/guide/pull-requests.md).  If you have questions or suggestions related to my behavior, please file an issue against the [kubernetes/test-infra](https://github.com/kubernetes/test-infra/issues/new?title=Prow%20issue:) repository.
</details>
k8s-ci-robot: [APPROVALNOTIFIER] This PR is **NOT APPROVED**

This pull-request has been approved by:
**Once this PR has been reviewed and has the lgtm label**, please ask for approval from [sbueringer](https://github.com/sbueringer). For more information see [the Kubernetes Code Review Process](https://git.k8s.io/community/contributors/guide/owners.md#the-code-review-process).

The full list of commands accepted by this bot can be found [here](https://go.k8s.io/bot-commands?repo=kubernetes-sigs%2Fcluster-api).

<details open>
Needs approval from an approver in each of these files:

- **[OWNERS](https://github.com/kubernetes-sigs/cluster-api/blob/main/OWNERS)**

Approvers can indicate their approval by writing `/approve` in a comment
Approvers can cancel approval by writing `/approve cancel` in a comment
</details>
<!-- META={"approvers":["sbueringer"]} -->
k8s-ci-robot: [APPROVALNOTIFIER] This PR is **APPROVED**

This pull-request has been approved by: *<a href="https://github.com/kubernetes-sigs/cluster-api/pull/9182#pullrequestreview-1576997791" title="Approved">killianmuldoon</a>*

The full list of commands accepted by this bot can be found [here](https://go.k8s.io/bot-commands?repo=kubernetes-sigs%2Fcluster-api).

The pull request process is described [here](https://git.k8s.io/community/contributors/guide/owners.md#the-code-review-process)

<details >
Needs approval from an approver in each of these files:

- ~~[OWNERS](https://github.com/kubernetes-sigs/cluster-api/blob/main/OWNERS)~~ [killianmuldoon]

Approvers can indicate their approval by writing `/approve` in a comment
Approvers can cancel approval by writing `/approve cancel` in a comment
</details>
<!-- META={"approvers":[]} -->
fabriziopandini: nice catch
/lgtm
sbueringer: Diff'ing this sort of stuff between CAPI & CAPV has its advantages.. :joy;

Patch:
diff --git a/.github/workflows/pr-dependabot.yaml b/.github/workflows/pr-dependabot.yaml
index 44c14bf6a..d3b2f1d63 100644
--- a/.github/workflows/pr-dependabot.yaml
+++ b/.github/workflows/pr-dependabot.yaml
@@ -24,7 +24,7 @@ jobs:
       id: vars
       run: echo "go_version=$(make go-version)" >> $GITHUB_OUTPUT
     - name: Set up Go
-      uses: actions/setup-go@93397bea11091df50f3d7e59dc26a7711a8bcfbe # tag=v4.1.0
+      uses: actions/setup-go@fac708d6674e30b6ba41289acaab6d4b75aa0753 # tag=v4.0.1
       with:
         go-version: ${{ steps.vars.outputs.go_version }}
     - uses: actions/cache@88522ab9f39a2ea568f7027eddc7d8d8bc9d59c8 # tag=v3.3.1
diff --git a/.github/workflows/pr-golangci-lint.yaml b/.github/workflows/pr-golangci-lint.yaml
index 12b00a39d..68624dfbf 100644
--- a/.github/workflows/pr-golangci-lint.yaml
+++ b/.github/workflows/pr-golangci-lint.yaml
@@ -24,12 +24,11 @@ jobs:
         id: vars
         run: echo "go_version=$(make go-version)" >> $GITHUB_OUTPUT
       - name: Set up Go
-        uses: actions/setup-go@93397bea11091df50f3d7e59dc26a7711a8bcfbe # tag=v4.1.0
+        uses: actions/setup-go@fac708d6674e30b6ba41289acaab6d4b75aa0753 # tag=v4.0.1
         with:
           go-version: ${{ steps.vars.outputs.go_version }}
       - name: golangci-lint
         uses: golangci/golangci-lint-action@639cd343e1d3b897ff35927a75193d57cfcba299 # tag=v3.6.0
         with:
           version: v1.54.1
-          args: --out-format=colored-line-number
           working-directory: ${{matrix.working-directory}}
diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml
index c7eb22995..d76225d8b 100644
--- a/.github/workflows/release.yaml
+++ b/.github/workflows/release.yaml
@@ -23,7 +23,7 @@ jobs:
       - name: Calculate go version
         run: echo "go_version=$(make go-version)" >> $GITHUB_ENV
       - name: Set up Go
-        uses: actions/setup-go@93397bea11091df50f3d7e59dc26a7711a8bcfbe # tag=v4.1.0
+        uses: actions/setup-go@fac708d6674e30b6ba41289acaab6d4b75aa0753 # tag=v4.0.1
         with:
           go-version: ${{ env.go_version }}
       - name: generate release artifacts
diff --git a/.github/workflows/weekly-security-scan.yaml b/.github/workflows/weekly-security-scan.yaml
index ada88d79e..be7bfaf21 100644
--- a/.github/workflows/weekly-security-scan.yaml
+++ b/.github/workflows/weekly-security-scan.yaml
@@ -25,7 +25,7 @@ jobs:
       id: vars
       run: echo "go_version=$(make go-version)" >> $GITHUB_OUTPUT
     - name: Set up Go
-      uses: actions/setup-go@93397bea11091df50f3d7e59dc26a7711a8bcfbe # tag=v4.1.0
+      uses: actions/setup-go@fac708d6674e30b6ba41289acaab6d4b75aa0753 # tag=v4.0.1
       with:
         go-version: ${{ steps.vars.outputs.go_version }}
     - name: Run verify security target
diff --git a/Makefile b/Makefile
index 2e385fbe9..c805f8435 100644
--- a/Makefile
+++ b/Makefile
@@ -605,7 +605,7 @@ APIDIFF_OLD_COMMIT ?= $(shell git rev-parse origin/main)
 apidiff: $(GO_APIDIFF) ## Check for API differences
 	$(GO_APIDIFF) $(APIDIFF_OLD_COMMIT) --print-compatible
 
-ALL_VERIFY_CHECKS = doctoc boilerplate shellcheck tiltfile modules gen conversions doctoc capi-book-summary
+ALL_VERIFY_CHECKS = boilerplate shellcheck tiltfile modules gen conversions doctoc capi-book-summary
 
 .PHONY: verify
 verify: $(addprefix verify-,$(ALL_VERIFY_CHECKS)) lint-dockerfiles ## Run all verify-* targets
diff --git a/bootstrap/kubeadm/internal/controllers/kubeadmconfig_controller.go b/bootstrap/kubeadm/internal/controllers/kubeadmconfig_controller.go
index dd0d572f2..18e1fce57 100644
--- a/bootstrap/kubeadm/internal/controllers/kubeadmconfig_controller.go
+++ b/bootstrap/kubeadm/internal/controllers/kubeadmconfig_controller.go
@@ -22,7 +22,7 @@ import (
 	"strconv"
 	"time"
 
-	"github.com/blang/semver/v4"
+	"github.com/blang/semver"
 	"github.com/go-logr/logr"
 	"github.com/pkg/errors"
 	corev1 "k8s.io/api/core/v1"
diff --git a/bootstrap/kubeadm/types/utils.go b/bootstrap/kubeadm/types/utils.go
index 7372d9378..0ee8c23bb 100644
--- a/bootstrap/kubeadm/types/utils.go
+++ b/bootstrap/kubeadm/types/utils.go
@@ -18,7 +18,7 @@ limitations under the License.
 package utils
 
 import (
-	"github.com/blang/semver/v4"
+	"github.com/blang/semver"
 	"github.com/pkg/errors"
 	"k8s.io/apimachinery/pkg/runtime"
 	"k8s.io/apimachinery/pkg/runtime/schema"
diff --git a/cmd/clusterctl/api/v1alpha3/metadata_type.go b/cmd/clusterctl/api/v1alpha3/metadata_type.go
index 0009c160b..0eacecbf4 100644
--- a/cmd/clusterctl/api/v1alpha3/metadata_type.go
+++ b/cmd/clusterctl/api/v1alpha3/metadata_type.go
@@ -17,7 +17,7 @@ limitations under the License.
 package v1alpha3
 
 import (
-	"github.com/blang/semver/v4"
+	"github.com/blang/semver"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 	"k8s.io/apimachinery/pkg/util/version"
 )
diff --git a/cmd/clusterctl/client/cluster/cert_manager.go b/cmd/clusterctl/client/cluster/cert_manager.go
index 2c73c5d4b..954c401b9 100644
--- a/cmd/clusterctl/client/cluster/cert_manager.go
+++ b/cmd/clusterctl/client/cluster/cert_manager.go
@@ -21,7 +21,7 @@ import (
 	_ "embed"
 	"time"
 
-	"github.com/blang/semver/v4"
+	"github.com/blang/semver"
 	"github.com/pkg/errors"
 	corev1 "k8s.io/api/core/v1"
 	apierrors "k8s.io/apimachinery/pkg/api/errors"
diff --git a/cmd/clusterctl/client/config/cert_manager_client.go b/cmd/clusterctl/client/config/cert_manager_client.go
index 5ea44244a..ea3858c27 100644
--- a/cmd/clusterctl/client/config/cert_manager_client.go
+++ b/cmd/clusterctl/client/config/cert_manager_client.go
@@ -29,7 +29,7 @@ const (
 	CertManagerConfigKey = "cert-manager"
 
 	// CertManagerDefaultVersion defines the default cert-manager version to be used by clusterctl.
-	CertManagerDefaultVersion = "v1.12.3"
+	CertManagerDefaultVersion = "v1.12.2"
 
 	// CertManagerDefaultURL defines the default cert-manager repository url to be used by clusterctl.
 	// NOTE: At runtime CertManagerDefaultVersion may be replaced with the
diff --git a/cmd/clusterctl/client/repository/repository_github.go b/cmd/clusterctl/client/repository/repository_github.go
index ab51f41fb..5cddd0128 100644
--- a/cmd/clusterctl/client/repository/repository_github.go
+++ b/cmd/clusterctl/client/repository/repository_github.go
@@ -28,7 +28,7 @@ import (
 	"strings"
 	"time"
 
-	"github.com/blang/semver/v4"
+	"github.com/blang/semver"
 	"github.com/google/go-github/v53/github"
 	"github.com/pkg/errors"
 	"golang.org/x/oauth2"
diff --git a/cmd/clusterctl/cmd/version_checker.go b/cmd/clusterctl/cmd/version_checker.go
index f0334225c..c195a5eb0 100644
--- a/cmd/clusterctl/cmd/version_checker.go
+++ b/cmd/clusterctl/cmd/version_checker.go
@@ -26,7 +26,7 @@ import (
 	"time"
 
 	"github.com/adrg/xdg"
-	"github.com/blang/semver/v4"
+	"github.com/blang/semver"
 	"github.com/google/go-github/v53/github"
 	"github.com/pkg/errors"
 	"golang.org/x/oauth2"
diff --git a/controlplane/kubeadm/api/v1beta1/kubeadm_control_plane_webhook.go b/controlplane/kubeadm/api/v1beta1/kubeadm_control_plane_webhook.go
index 84b55b454..9db8198d2 100644
--- a/controlplane/kubeadm/api/v1beta1/kubeadm_control_plane_webhook.go
+++ b/controlplane/kubeadm/api/v1beta1/kubeadm_control_plane_webhook.go
@@ -21,7 +21,7 @@ import (
 	"fmt"
 	"strings"
 
-	"github.com/blang/semver/v4"
+	"github.com/blang/semver"
 	"github.com/coredns/corefile-migration/migration"
 	jsonpatch "github.com/evanphx/json-patch/v5"
 	"github.com/pkg/errors"
@@ -140,7 +140,6 @@ func (in *KubeadmControlPlane) ValidateUpdate(old runtime.Object) (admission.War
 	// For example, {"spec", "*"} will allow any path under "spec" to change.
 	allowedPaths := [][]string{
 		{"metadata", "*"},
-		{spec, kubeadmConfigSpec, "useExperimentalRetryJoin"},
 		{spec, kubeadmConfigSpec, clusterConfiguration, "etcd", "local", "imageRepository"},
 		{spec, kubeadmConfigSpec, clusterConfiguration, "etcd", "local", "imageTag"},
 		{spec, kubeadmConfigSpec, clusterConfiguration, "etcd", "local", "extraArgs"},
diff --git a/controlplane/kubeadm/internal/controllers/controller.go b/controlplane/kubeadm/internal/controllers/controller.go
index f71bdec07..73c2ae7b9 100644
--- a/controlplane/kubeadm/internal/controllers/controller.go
+++ b/controlplane/kubeadm/internal/controllers/controller.go
@@ -22,7 +22,7 @@ import (
 	"strings"
 	"time"
 
-	"github.com/blang/semver/v4"
+	"github.com/blang/semver"
 	"github.com/pkg/errors"
 	corev1 "k8s.io/api/core/v1"
 	apierrors "k8s.io/apimachinery/pkg/api/errors"
@@ -85,6 +85,12 @@ type KubeadmControlPlaneReconciler struct {
 
 	managementCluster         internal.ManagementCluster
 	managementClusterUncached internal.ManagementCluster
+
+	// disableInPlacePropagation should only be used for tests. This is used to skip
+	// some parts of the controller that need SSA as the current test setup does not
+	// support SSA. This flag should be dropped after all affected tests are migrated
+	// to envtest.
+	disableInPlacePropagation bool
 	ssaCache                  ssa.Cache
 }
 
@@ -369,8 +375,10 @@ func (r *KubeadmControlPlaneReconciler) reconcile(ctx context.Context, controlPl
 		return result, err
 	}
 
-	if err := r.syncMachines(ctx, controlPlane); err != nil {
-		return ctrl.Result{}, errors.Wrap(err, "failed to sync Machines")
+	if !r.disableInPlacePropagation {
+		if err := r.syncMachines(ctx, controlPlane); err != nil {
+			return ctrl.Result{}, errors.Wrap(err, "failed to sync Machines")
+		}
 	}
 
 	// Aggregate the operational state of all the machines; while aggregating we are adding the
diff --git a/controlplane/kubeadm/internal/controllers/remediation.go b/controlplane/kubeadm/internal/controllers/remediation.go
index 698612437..d1c8fd44e 100644
--- a/controlplane/kubeadm/internal/controllers/remediation.go
+++ b/controlplane/kubeadm/internal/controllers/remediation.go
@@ -22,7 +22,7 @@ import (
 	"fmt"
 	"time"
 
-	"github.com/blang/semver/v4"
+	"github.com/blang/semver"
 	"github.com/go-logr/logr"
 	"github.com/pkg/errors"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
diff --git a/controlplane/kubeadm/internal/controllers/scale.go b/controlplane/kubeadm/internal/controllers/scale.go
index 66608e60a..4ed1682c2 100644
--- a/controlplane/kubeadm/internal/controllers/scale.go
+++ b/controlplane/kubeadm/internal/controllers/scale.go
@@ -20,7 +20,7 @@ import (
 	"context"
 	"strings"
 
-	"github.com/blang/semver/v4"
+	"github.com/blang/semver"
 	"github.com/pkg/errors"
 	corev1 "k8s.io/api/core/v1"
 	apierrors "k8s.io/apimachinery/pkg/api/errors"
diff --git a/controlplane/kubeadm/internal/controllers/upgrade.go b/controlplane/kubeadm/internal/controllers/upgrade.go
index f51bce9d8..b1528283d 100644
--- a/controlplane/kubeadm/internal/controllers/upgrade.go
+++ b/controlplane/kubeadm/internal/controllers/upgrade.go
@@ -19,7 +19,7 @@ package controllers
 import (
 	"context"
 
-	"github.com/blang/semver/v4"
+	"github.com/blang/semver"
 	"github.com/pkg/errors"
 	ctrl "sigs.k8s.io/controller-runtime"
 
diff --git a/controlplane/kubeadm/internal/workload_cluster.go b/controlplane/kubeadm/internal/workload_cluster.go
index 9d7de352b..4112106f5 100644
--- a/controlplane/kubeadm/internal/workload_cluster.go
+++ b/controlplane/kubeadm/internal/workload_cluster.go
@@ -29,7 +29,7 @@ import (
 	"reflect"
 	"time"
 
-	"github.com/blang/semver/v4"
+	"github.com/blang/semver"
 	"github.com/pkg/errors"
 	appsv1 "k8s.io/api/apps/v1"
 	corev1 "k8s.io/api/core/v1"
diff --git a/controlplane/kubeadm/internal/workload_cluster_coredns.go b/controlplane/kubeadm/internal/workload_cluster_coredns.go
index 5699c9c06..9ebf7eda9 100644
--- a/controlplane/kubeadm/internal/workload_cluster_coredns.go
+++ b/controlplane/kubeadm/internal/workload_cluster_coredns.go
@@ -22,7 +22,7 @@ import (
 	"reflect"
 	"strings"
 
-	"github.com/blang/semver/v4"
+	"github.com/blang/semver"
 	"github.com/coredns/corefile-migration/migration"
 	"github.com/pkg/errors"
 	appsv1 "k8s.io/api/apps/v1"
diff --git a/controlplane/kubeadm/internal/workload_cluster_etcd.go b/controlplane/kubeadm/internal/workload_cluster_etcd.go
index bb4c4d417..3b3662a29 100644
--- a/controlplane/kubeadm/internal/workload_cluster_etcd.go
+++ b/controlplane/kubeadm/internal/workload_cluster_etcd.go
@@ -19,7 +19,7 @@ package internal
 import (
 	"context"
 
-	"github.com/blang/semver/v4"
+	"github.com/blang/semver"
 	"github.com/pkg/errors"
 	kerrors "k8s.io/apimachinery/pkg/util/errors"
 
diff --git a/controlplane/kubeadm/internal/workload_cluster_rbac.go b/controlplane/kubeadm/internal/workload_cluster_rbac.go
index eb22e3480..d714c6329 100644
--- a/controlplane/kubeadm/internal/workload_cluster_rbac.go
+++ b/controlplane/kubeadm/internal/workload_cluster_rbac.go
@@ -20,7 +20,7 @@ import (
 	"context"
 	"fmt"
 
-	"github.com/blang/semver/v4"
+	"github.com/blang/semver"
 	"github.com/pkg/errors"
 	rbacv1 "k8s.io/api/rbac/v1"
 	apierrors "k8s.io/apimachinery/pkg/api/errors"
diff --git a/docs/book/src/clusterctl/commands/init.md b/docs/book/src/clusterctl/commands/init.md
index 34479acef..73092f46c 100644
--- a/docs/book/src/clusterctl/commands/init.md
+++ b/docs/book/src/clusterctl/commands/init.md
@@ -190,7 +190,7 @@ If this happens, there are no guarantees about the proper functioning of `cluste
 Cluster API providers require a cert-manager version supporting the `cert-manager.io/v1` API to be installed in the cluster.
 
 While doing init, clusterctl checks if there is a version of cert-manager already installed. If not, clusterctl will
-install a default version (currently cert-manager v1.12.3). See [clusterctl configuration](../configuration.md) for
+install a default version (currently cert-manager v1.12.2). See [clusterctl configuration](../configuration.md) for
 available options to customize this operation.
 
 <aside class="note warning">
diff --git a/docs/book/src/developer/guide.md b/docs/book/src/developer/guide.md
index 350f6148a..3c055812b 100644
--- a/docs/book/src/developer/guide.md
+++ b/docs/book/src/developer/guide.md
@@ -81,7 +81,7 @@ The generated binary can be found at ./hack/tools/bin/envsubst
 You'll need to deploy [cert-manager] components on your [management cluster][mcluster], using `kubectl`
 
 ```bash
-kubectl apply -f https://github.com/cert-manager/cert-manager/releases/download/v1.12.3/cert-manager.yaml
+kubectl apply -f https://github.com/cert-manager/cert-manager/releases/download/v1.12.2/cert-manager.yaml
 ```
 
 Ensure the cert-manager webhook service is ready before creating the Cluster API components.
diff --git a/exp/addons/api/v1beta1/clusterresourceset_types.go b/exp/addons/api/v1beta1/clusterresourceset_types.go
index 2800bf190..e64dccd29 100644
--- a/exp/addons/api/v1beta1/clusterresourceset_types.go
+++ b/exp/addons/api/v1beta1/clusterresourceset_types.go
@@ -140,5 +140,5 @@ type ClusterResourceSetList struct {
 }
 
 func init() {
-	objectTypes = append(objectTypes, &ClusterResourceSet{}, &ClusterResourceSetList{})
+	SchemeBuilder.Register(&ClusterResourceSet{}, &ClusterResourceSetList{})
 }
diff --git a/exp/addons/api/v1beta1/clusterresourcesetbinding_types.go b/exp/addons/api/v1beta1/clusterresourcesetbinding_types.go
index 299112258..d58c46461 100644
--- a/exp/addons/api/v1beta1/clusterresourcesetbinding_types.go
+++ b/exp/addons/api/v1beta1/clusterresourcesetbinding_types.go
@@ -152,5 +152,5 @@ type ClusterResourceSetBindingList struct {
 }
 
 func init() {
-	objectTypes = append(objectTypes, &ClusterResourceSetBinding{}, &ClusterResourceSetBindingList{})
+	SchemeBuilder.Register(&ClusterResourceSetBinding{}, &ClusterResourceSetBindingList{})
 }
diff --git a/exp/addons/api/v1beta1/groupversion_info.go b/exp/addons/api/v1beta1/groupversion_info.go
index f02006147..c21f20bde 100644
--- a/exp/addons/api/v1beta1/groupversion_info.go
+++ b/exp/addons/api/v1beta1/groupversion_info.go
@@ -20,26 +20,17 @@ limitations under the License.
 package v1beta1
 
 import (
-	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
-	"k8s.io/apimachinery/pkg/runtime"
 	"k8s.io/apimachinery/pkg/runtime/schema"
+	"sigs.k8s.io/controller-runtime/pkg/scheme"
 )
 
 var (
 	// GroupVersion is group version used to register these objects.
 	GroupVersion = schema.GroupVersion{Group: "addons.cluster.x-k8s.io", Version: "v1beta1"}
 
-	// schemeBuilder is used to add go types to the GroupVersionKind scheme.
-	schemeBuilder = runtime.NewSchemeBuilder(addKnownTypes)
+	// SchemeBuilder is used to add go types to the GroupVersionKind scheme.
+	SchemeBuilder = &scheme.Builder{GroupVersion: GroupVersion}
 
 	// AddToScheme adds the types in this group-version to the given scheme.
-	AddToScheme = schemeBuilder.AddToScheme
-
-	objectTypes = []runtime.Object{}
+	AddToScheme = SchemeBuilder.AddToScheme
 )
-
-func addKnownTypes(scheme *runtime.Scheme) error {
-	scheme.AddKnownTypes(GroupVersion, objectTypes...)
-	metav1.AddToGroupVersion(scheme, GroupVersion)
-	return nil
-}
diff --git a/exp/api/v1beta1/groupversion_info.go b/exp/api/v1beta1/groupversion_info.go
index fd5c24e95..c92eaed36 100644
--- a/exp/api/v1beta1/groupversion_info.go
+++ b/exp/api/v1beta1/groupversion_info.go
@@ -20,26 +20,17 @@ limitations under the License.
 package v1beta1
 
 import (
-	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
-	"k8s.io/apimachinery/pkg/runtime"
 	"k8s.io/apimachinery/pkg/runtime/schema"
+	"sigs.k8s.io/controller-runtime/pkg/scheme"
 )
 
 var (
 	// GroupVersion is group version used to register these objects.
 	GroupVersion = schema.GroupVersion{Group: "cluster.x-k8s.io", Version: "v1beta1"}
 
-	// schemeBuilder is used to add go types to the GroupVersionKind scheme.
-	schemeBuilder = runtime.NewSchemeBuilder(addKnownTypes)
+	// SchemeBuilder is used to add go types to the GroupVersionKind scheme.
+	SchemeBuilder = &scheme.Builder{GroupVersion: GroupVersion}
 
 	// AddToScheme adds the types in this group-version to the given scheme.
-	AddToScheme = schemeBuilder.AddToScheme
-
-	objectTypes = []runtime.Object{}
+	AddToScheme = SchemeBuilder.AddToScheme
 )
-
-func addKnownTypes(scheme *runtime.Scheme) error {
-	scheme.AddKnownTypes(GroupVersion, objectTypes...)
-	metav1.AddToGroupVersion(scheme, GroupVersion)
-	return nil
-}
diff --git a/exp/api/v1beta1/machinepool_types.go b/exp/api/v1beta1/machinepool_types.go
index a2fc2957b..3d08de826 100644
--- a/exp/api/v1beta1/machinepool_types.go
+++ b/exp/api/v1beta1/machinepool_types.go
@@ -249,5 +249,5 @@ type MachinePoolList struct {
 }
 
 func init() {
-	objectTypes = append(objectTypes, &MachinePool{}, &MachinePoolList{})
+	SchemeBuilder.Register(&MachinePool{}, &MachinePoolList{})
 }
diff --git a/exp/ipam/api/v1alpha1/groupversion_info.go b/exp/ipam/api/v1alpha1/groupversion_info.go
index 221e76501..7be93c0c9 100644
--- a/exp/ipam/api/v1alpha1/groupversion_info.go
+++ b/exp/ipam/api/v1alpha1/groupversion_info.go
@@ -20,26 +20,17 @@ limitations under the License.
 package v1alpha1
 
 import (
-	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
-	"k8s.io/apimachinery/pkg/runtime"
 	"k8s.io/apimachinery/pkg/runtime/schema"
+	"sigs.k8s.io/controller-runtime/pkg/scheme"
 )
 
 var (
 	// GroupVersion is group version used to register these objects.
 	GroupVersion = schema.GroupVersion{Group: "ipam.cluster.x-k8s.io", Version: "v1alpha1"}
 
-	// schemeBuilder is used to add go types to the GroupVersionKind scheme.
-	schemeBuilder = runtime.NewSchemeBuilder(addKnownTypes)
+	// SchemeBuilder is used to add go types to the GroupVersionKind scheme.
+	SchemeBuilder = &scheme.Builder{GroupVersion: GroupVersion}
 
 	// AddToScheme adds the types in this group-version to the given scheme.
-	AddToScheme = schemeBuilder.AddToScheme
-
-	objectTypes = []runtime.Object{}
+	AddToScheme = SchemeBuilder.AddToScheme
 )
-
-func addKnownTypes(scheme *runtime.Scheme) error {
-	scheme.AddKnownTypes(GroupVersion, objectTypes...)
-	metav1.AddToGroupVersion(scheme, GroupVersion)
-	return nil
-}
diff --git a/exp/ipam/api/v1alpha1/ipaddress_types.go b/exp/ipam/api/v1alpha1/ipaddress_types.go
index b40982d96..01af31d26 100644
--- a/exp/ipam/api/v1alpha1/ipaddress_types.go
+++ b/exp/ipam/api/v1alpha1/ipaddress_types.go
@@ -65,5 +65,5 @@ type IPAddressList struct {
 }
 
 func init() {
-	objectTypes = append(objectTypes, &IPAddress{}, &IPAddressList{})
+	SchemeBuilder.Register(&IPAddress{}, &IPAddressList{})
 }
diff --git a/exp/ipam/api/v1alpha1/ipaddressclaim_types.go b/exp/ipam/api/v1alpha1/ipaddressclaim_types.go
index 16df8605e..af259b415 100644
--- a/exp/ipam/api/v1alpha1/ipaddressclaim_types.go
+++ b/exp/ipam/api/v1alpha1/ipaddressclaim_types.go
@@ -76,5 +76,5 @@ type IPAddressClaimList struct {
 }
 
 func init() {
-	objectTypes = append(objectTypes, &IPAddressClaim{}, &IPAddressClaimList{})
+	SchemeBuilder.Register(&IPAddressClaim{}, &IPAddressClaimList{})
 }
diff --git a/exp/ipam/api/v1alpha1/zz_generated.deepcopy.go b/exp/ipam/api/v1alpha1/zz_generated.deepcopy.go
index ea5de78b8..88cc359b9 100644
--- a/exp/ipam/api/v1alpha1/zz_generated.deepcopy.go
+++ b/exp/ipam/api/v1alpha1/zz_generated.deepcopy.go
@@ -22,7 +22,7 @@ limitations under the License.
 package v1alpha1
 
 import (
-	"k8s.io/apimachinery/pkg/runtime"
+	runtime "k8s.io/apimachinery/pkg/runtime"
 	"sigs.k8s.io/cluster-api/api/v1beta1"
 )
 
diff --git a/exp/runtime/api/v1alpha1/extensionconfig_types.go b/exp/runtime/api/v1alpha1/extensionconfig_types.go
index bd8c3e5d0..de426e366 100644
--- a/exp/runtime/api/v1alpha1/extensionconfig_types.go
+++ b/exp/runtime/api/v1alpha1/extensionconfig_types.go
@@ -197,7 +197,7 @@ type ExtensionConfigList struct {
 }
 
 func init() {
-	objectTypes = append(objectTypes, &ExtensionConfig{}, &ExtensionConfigList{})
+	SchemeBuilder.Register(&ExtensionConfig{}, &ExtensionConfigList{})
 }
 
 const (
diff --git a/exp/runtime/api/v1alpha1/groupversion_info.go b/exp/runtime/api/v1alpha1/groupversion_info.go
index 856a1ef0b..bac33a979 100644
--- a/exp/runtime/api/v1alpha1/groupversion_info.go
+++ b/exp/runtime/api/v1alpha1/groupversion_info.go
@@ -20,26 +20,17 @@ limitations under the License.
 package v1alpha1
 
 import (
-	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
-	"k8s.io/apimachinery/pkg/runtime"
 	"k8s.io/apimachinery/pkg/runtime/schema"
+	"sigs.k8s.io/controller-runtime/pkg/scheme"
 )
 
 var (
 	// GroupVersion is group version used to register these objects.
 	GroupVersion = schema.GroupVersion{Group: "runtime.cluster.x-k8s.io", Version: "v1alpha1"}
 
-	// schemeBuilder is used to add go types to the GroupVersionKind scheme.
-	schemeBuilder = runtime.NewSchemeBuilder(addKnownTypes)
+	// SchemeBuilder is used to add go types to the GroupVersionKind scheme.
+	SchemeBuilder = &scheme.Builder{GroupVersion: GroupVersion}
 
 	// AddToScheme adds the types in this group-version to the given scheme.
-	AddToScheme = schemeBuilder.AddToScheme
-
-	objectTypes = []runtime.Object{}
+	AddToScheme = SchemeBuilder.AddToScheme
 )
-
-func addKnownTypes(scheme *runtime.Scheme) error {
-	scheme.AddKnownTypes(GroupVersion, objectTypes...)
-	metav1.AddToGroupVersion(scheme, GroupVersion)
-	return nil
-}
diff --git a/exp/runtime/api/v1alpha1/zz_generated.deepcopy.go b/exp/runtime/api/v1alpha1/zz_generated.deepcopy.go
index 49f65c3e8..50a0cc037 100644
--- a/exp/runtime/api/v1alpha1/zz_generated.deepcopy.go
+++ b/exp/runtime/api/v1alpha1/zz_generated.deepcopy.go
@@ -23,7 +23,7 @@ package v1alpha1
 
 import (
 	"k8s.io/apimachinery/pkg/apis/meta/v1"
-	"k8s.io/apimachinery/pkg/runtime"
+	runtime "k8s.io/apimachinery/pkg/runtime"
 	"sigs.k8s.io/cluster-api/api/v1beta1"
 )
 
diff --git a/go.mod b/go.mod
index a2c393560..782100a84 100644
--- a/go.mod
+++ b/go.mod
@@ -6,6 +6,7 @@ require (
 	github.com/MakeNowJust/heredoc v1.0.0
 	github.com/Masterminds/sprig/v3 v3.2.3
 	github.com/adrg/xdg v0.4.0
+	github.com/blang/semver v3.5.1+incompatible
 	github.com/coredns/corefile-migration v1.0.20
 	github.com/davecgh/go-spew v1.1.1
 	github.com/docker/distribution v2.8.2+incompatible
@@ -55,7 +56,6 @@ require (
 	github.com/antlr/antlr4/runtime/Go/antlr v1.4.10 // indirect
 	github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a // indirect
 	github.com/beorn7/perks v1.0.1 // indirect
-	github.com/blang/semver/v4 v4.0.0
 	github.com/cespare/xxhash/v2 v2.2.0 // indirect
 	github.com/chai2010/gettext-go v1.0.2 // indirect
 	github.com/coredns/caddy v1.1.0 // indirect
@@ -127,7 +127,7 @@ require (
 	golang.org/x/term v0.11.0 // indirect
 	golang.org/x/text v0.12.0
 	golang.org/x/time v0.3.0 // indirect
-	gomodules.xyz/jsonpatch/v2 v2.4.0
+	gomodules.xyz/jsonpatch/v2 v2.3.0
 	google.golang.org/appengine v1.6.7 // indirect
 	google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1 // indirect
 	google.golang.org/protobuf v1.31.0 // indirect
@@ -145,6 +145,7 @@ require (
 
 require (
 	github.com/ProtonMail/go-crypto v0.0.0-20230217124315-7d5c6f04bbb8 // indirect
+	github.com/blang/semver/v4 v4.0.0 // indirect
 	github.com/cloudflare/circl v1.3.3 // indirect
 	github.com/daviddengcn/go-colortext v1.0.0 // indirect
 	github.com/emicklei/go-restful/v3 v3.9.0 // indirect
diff --git a/go.sum b/go.sum
index 0a67015d4..0de4131ee 100644
--- a/go.sum
+++ b/go.sum
@@ -80,6 +80,8 @@ github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
 github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
 github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs=
 github.com/bketelsen/crypt v0.0.3-0.20200106085610-5cbc8cc4026c/go.mod h1:MKsuJmJgSg28kpZDP6UIiPt0e0Oz0kqKNGyRaWEPv84=
+github.com/blang/semver v3.5.1+incompatible h1:cQNTCjp13qL8KC3Nbxr/y2Bqb63oX6wdnnjpJbkM4JQ=
+github.com/blang/semver v3.5.1+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk=
 github.com/blang/semver/v4 v4.0.0 h1:1PFHFE6yCCTv8C1TeyNNarDzntLi7wMI5i/pzqYIsAM=
 github.com/blang/semver/v4 v4.0.0/go.mod h1:IbckMUScFkM3pff0VJDNKRiT6TG/YpiHIM2yvyW5YoQ=
 github.com/buger/jsonparser v1.1.1/go.mod h1:6RYKKt7H4d4+iWqouImQ9R2FZql3VbhNgx27UK13J/0=
@@ -822,8 +824,8 @@ golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8T
 golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
 golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
 golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
-gomodules.xyz/jsonpatch/v2 v2.4.0 h1:Ci3iUJyx9UeRx7CeFN8ARgGbkESwJK+KB9lLcWxY/Zw=
-gomodules.xyz/jsonpatch/v2 v2.4.0/go.mod h1:AH3dM2RI6uoBZxn3LVrfvJ3E0/9dG4cSrbuBJT4moAY=
+gomodules.xyz/jsonpatch/v2 v2.3.0 h1:8NFhfS6gzxNqjLIYnZxg319wZ5Qjnx4m/CcX+Klzazc=
+gomodules.xyz/jsonpatch/v2 v2.3.0/go.mod h1:AH3dM2RI6uoBZxn3LVrfvJ3E0/9dG4cSrbuBJT4moAY=
 google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE=
 google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M=
 google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg=
diff --git a/hack/kind-install-for-capd.sh b/hack/kind-install-for-capd.sh
index a0d3474c0..a9bc88882 100755
--- a/hack/kind-install-for-capd.sh
+++ b/hack/kind-install-for-capd.sh
@@ -31,8 +31,7 @@ if [[ "${TRACE-0}" == "1" ]]; then
 fi
 
 KIND_CLUSTER_NAME=${CAPI_KIND_CLUSTER_NAME:-"capi-test"}
-# See: https://kind.sigs.k8s.io/docs/user/configuration/#ip-family
-KIND_NETWORK_IPFAMILY=${KIND_NETWORK_IPFAMILY:-"dual"}
+
 
 # 1. If kind cluster already exists exit.
 if [[ "$(kind get clusters)" =~ .*"${KIND_CLUSTER_NAME}".* ]]; then
@@ -60,7 +59,7 @@ cat <<EOF | kind create cluster --name="$KIND_CLUSTER_NAME"  --config=-
 kind: Cluster
 apiVersion: kind.x-k8s.io/v1alpha4
 networking:
-  ipFamily: ${KIND_NETWORK_IPFAMILY}
+  ipFamily: dual
 nodes:
 - role: control-plane
   extraMounts:
diff --git a/hack/tools/go.mod b/hack/tools/go.mod
index 5dc4772e6..fd3cea0fd 100644
--- a/hack/tools/go.mod
+++ b/hack/tools/go.mod
@@ -8,7 +8,7 @@ replace sigs.k8s.io/cluster-api/test => ../../test
 
 require (
 	cloud.google.com/go/storage v1.31.0
-	github.com/blang/semver/v4 v4.0.0
+	github.com/blang/semver v3.5.1+incompatible
 	github.com/pkg/errors v0.9.1
 	github.com/spf13/pflag v1.0.5
 	github.com/valyala/fastjson v1.6.4
@@ -45,6 +45,7 @@ require (
 	github.com/antlr/antlr4/runtime/Go/antlr v1.4.10 // indirect
 	github.com/asaskevich/govalidator v0.0.0-20200428143746-21a406dcc535 // indirect
 	github.com/beorn7/perks v1.0.1 // indirect
+	github.com/blang/semver/v4 v4.0.0 // indirect
 	github.com/cespare/xxhash/v2 v2.2.0 // indirect
 	github.com/cloudflare/circl v1.3.3 // indirect
 	github.com/coredns/caddy v1.1.0 // indirect
@@ -118,7 +119,7 @@ require (
 	golang.org/x/text v0.12.0 // indirect
 	golang.org/x/time v0.3.0 // indirect
 	golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect
-	gomodules.xyz/jsonpatch/v2 v2.4.0 // indirect
+	gomodules.xyz/jsonpatch/v2 v2.3.0 // indirect
 	google.golang.org/appengine v1.6.7 // indirect
 	google.golang.org/genproto v0.0.0-20230803162519-f966b187b2e5 // indirect
 	google.golang.org/genproto/googleapis/api v0.0.0-20230803162519-f966b187b2e5 // indirect
diff --git a/hack/tools/go.sum b/hack/tools/go.sum
index 3ad40c9a6..cba73fc71 100644
--- a/hack/tools/go.sum
+++ b/hack/tools/go.sum
@@ -81,6 +81,8 @@ github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
 github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
 github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs=
 github.com/bketelsen/crypt v0.0.3-0.20200106085610-5cbc8cc4026c/go.mod h1:MKsuJmJgSg28kpZDP6UIiPt0e0Oz0kqKNGyRaWEPv84=
+github.com/blang/semver v3.5.1+incompatible h1:cQNTCjp13qL8KC3Nbxr/y2Bqb63oX6wdnnjpJbkM4JQ=
+github.com/blang/semver v3.5.1+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk=
 github.com/blang/semver/v4 v4.0.0 h1:1PFHFE6yCCTv8C1TeyNNarDzntLi7wMI5i/pzqYIsAM=
 github.com/blang/semver/v4 v4.0.0/go.mod h1:IbckMUScFkM3pff0VJDNKRiT6TG/YpiHIM2yvyW5YoQ=
 github.com/buger/jsonparser v1.1.1/go.mod h1:6RYKKt7H4d4+iWqouImQ9R2FZql3VbhNgx27UK13J/0=
@@ -742,8 +744,8 @@ golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8T
 golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
 golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 h1:H2TDz8ibqkAF6YGhCdN3jS9O0/s90v0rJh3X/OLHEUk=
 golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8=
-gomodules.xyz/jsonpatch/v2 v2.4.0 h1:Ci3iUJyx9UeRx7CeFN8ARgGbkESwJK+KB9lLcWxY/Zw=
-gomodules.xyz/jsonpatch/v2 v2.4.0/go.mod h1:AH3dM2RI6uoBZxn3LVrfvJ3E0/9dG4cSrbuBJT4moAY=
+gomodules.xyz/jsonpatch/v2 v2.3.0 h1:8NFhfS6gzxNqjLIYnZxg319wZ5Qjnx4m/CcX+Klzazc=
+gomodules.xyz/jsonpatch/v2 v2.3.0/go.mod h1:AH3dM2RI6uoBZxn3LVrfvJ3E0/9dG4cSrbuBJT4moAY=
 google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE=
 google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M=
 google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg=
diff --git a/hack/tools/mdbook/releaselink/releaselink.go b/hack/tools/mdbook/releaselink/releaselink.go
index 96d9cf99f..4bd707e19 100644
--- a/hack/tools/mdbook/releaselink/releaselink.go
+++ b/hack/tools/mdbook/releaselink/releaselink.go
@@ -28,7 +28,7 @@ import (
 	"reflect"
 	"strings"
 
-	"github.com/blang/semver/v4"
+	"github.com/blang/semver"
 	"golang.org/x/tools/go/vcs"
 	"sigs.k8s.io/kubebuilder/docs/book/utils/plugin"
 
diff --git a/internal/contract/controlplane.go b/internal/contract/controlplane.go
index 7bbc306e7..df322ddcd 100644
--- a/internal/contract/controlplane.go
+++ b/internal/contract/controlplane.go
@@ -19,7 +19,7 @@ package contract
 import (
 	"sync"
 
-	"github.com/blang/semver/v4"
+	"github.com/blang/semver"
 	"github.com/pkg/errors"
 	"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
 	"k8s.io/utils/pointer"
diff --git a/internal/controllers/machineset/machineset_preflight.go b/internal/controllers/machineset/machineset_preflight.go
index c9ce691e8..00d5d67fc 100644
--- a/internal/controllers/machineset/machineset_preflight.go
+++ b/internal/controllers/machineset/machineset_preflight.go
@@ -22,7 +22,7 @@ import (
 	"strings"
 	"time"
 
-	"github.com/blang/semver/v4"
+	"github.com/blang/semver"
 	"github.com/pkg/errors"
 	"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
 	"k8s.io/apimachinery/pkg/runtime/schema"
diff --git a/internal/goproxy/goproxy.go b/internal/goproxy/goproxy.go
index 3448de0fa..a44bd0ce1 100644
--- a/internal/goproxy/goproxy.go
+++ b/internal/goproxy/goproxy.go
@@ -28,7 +28,7 @@ import (
 	"strings"
 	"time"
 
-	"github.com/blang/semver/v4"
+	"github.com/blang/semver"
 	"github.com/pkg/errors"
 	"k8s.io/apimachinery/pkg/util/wait"
 )
diff --git a/internal/util/kubeadm/kubeadm.go b/internal/util/kubeadm/kubeadm.go
index a35d98401..bd6902711 100644
--- a/internal/util/kubeadm/kubeadm.go
+++ b/internal/util/kubeadm/kubeadm.go
@@ -17,7 +17,7 @@ limitations under the License.
 // Package kubeadm contains utils related to kubeadm.
 package kubeadm
 
-import "github.com/blang/semver/v4"
+import "github.com/blang/semver"
 
 const (
 	// DefaultImageRepository is the new default Kubernetes image registry.
diff --git a/internal/webhooks/cluster.go b/internal/webhooks/cluster.go
index 61eff982d..2e0da4f57 100644
--- a/internal/webhooks/cluster.go
+++ b/internal/webhooks/cluster.go
@@ -24,7 +24,7 @@ import (
 	"strings"
 	"time"
 
-	"github.com/blang/semver/v4"
+	"github.com/blang/semver"
 	"github.com/pkg/errors"
 	apierrors "k8s.io/apimachinery/pkg/api/errors"
 	"k8s.io/apimachinery/pkg/runtime"
diff --git a/util/collections/machine_collection.go b/util/collections/machine_collection.go
index 83a50ad94..2958ee5d6 100644
--- a/util/collections/machine_collection.go
+++ b/util/collections/machine_collection.go
@@ -30,7 +30,7 @@ package collections
 import (
 	"sort"
 
-	"github.com/blang/semver/v4"
+	"github.com/blang/semver"
 
 	clusterv1 "sigs.k8s.io/cluster-api/api/v1beta1"
 	"sigs.k8s.io/cluster-api/util/conditions"
diff --git a/util/collections/machine_filters.go b/util/collections/machine_filters.go
index 12c2e20f8..d85661012 100644
--- a/util/collections/machine_filters.go
+++ b/util/collections/machine_filters.go
@@ -19,7 +19,7 @@ package collections
 import (
 	"time"
 
-	"github.com/blang/semver/v4"
+	"github.com/blang/semver"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 	"k8s.io/apimachinery/pkg/labels"
 	"k8s.io/apimachinery/pkg/selection"
diff --git a/util/util.go b/util/util.go
index d72947ecf..9edcf9123 100644
--- a/util/util.go
+++ b/util/util.go
@@ -27,7 +27,7 @@ import (
 	"strings"
 	"time"
 
-	"github.com/blang/semver/v4"
+	"github.com/blang/semver"
 	"github.com/pkg/errors"
 	corev1 "k8s.io/api/core/v1"
 	apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
diff --git a/util/version/version.go b/util/version/version.go
index 601f934bd..277ed6105 100644
--- a/util/version/version.go
+++ b/util/version/version.go
@@ -22,7 +22,7 @@ import (
 	"strconv"
 	"strings"
 
-	"github.com/blang/semver/v4"
+	"github.com/blang/semver"
 	"github.com/pkg/errors"
 )
 


Test patch:
diff --git a/.github/workflows/weekly-test-release.yaml b/.github/workflows/weekly-test-release.yaml
index 77c9b30ff..0c4c6f662 100644
--- a/.github/workflows/weekly-test-release.yaml
+++ b/.github/workflows/weekly-test-release.yaml
@@ -32,7 +32,7 @@ jobs:
       - name: Calculate go version
         run: echo "go_version=$(make go-version)" >> $GITHUB_ENV
       - name: Set up Go
-        uses: actions/setup-go@93397bea11091df50f3d7e59dc26a7711a8bcfbe # tag=v4.1.0
+        uses: actions/setup-go@fac708d6674e30b6ba41289acaab6d4b75aa0753 # tag=v4.0.1
         with:
           go-version: ${{ env.go_version }}
       - name: Test release
diff --git a/bootstrap/kubeadm/types/utils_test.go b/bootstrap/kubeadm/types/utils_test.go
index 62a0a72d4..5153d834a 100644
--- a/bootstrap/kubeadm/types/utils_test.go
+++ b/bootstrap/kubeadm/types/utils_test.go
@@ -19,7 +19,7 @@ package utils
 import (
 	"testing"
 
-	"github.com/blang/semver/v4"
+	"github.com/blang/semver"
 	"github.com/google/go-cmp/cmp"
 	. "github.com/onsi/gomega"
 	"k8s.io/apimachinery/pkg/runtime/schema"
diff --git a/controlplane/kubeadm/api/v1beta1/kubeadm_control_plane_webhook_test.go b/controlplane/kubeadm/api/v1beta1/kubeadm_control_plane_webhook_test.go
index 3b26d0130..cd230eb61 100644
--- a/controlplane/kubeadm/api/v1beta1/kubeadm_control_plane_webhook_test.go
+++ b/controlplane/kubeadm/api/v1beta1/kubeadm_control_plane_webhook_test.go
@@ -698,11 +698,6 @@ func TestKubeadmControlPlaneValidateUpdate(t *testing.T) {
 		"/invalid-key": "foo",
 	}
 
-	beforeUseExperimentalRetryJoin := before.DeepCopy()
-	beforeUseExperimentalRetryJoin.Spec.KubeadmConfigSpec.UseExperimentalRetryJoin = true //nolint:staticcheck
-	updateUseExperimentalRetryJoin := before.DeepCopy()
-	updateUseExperimentalRetryJoin.Spec.KubeadmConfigSpec.UseExperimentalRetryJoin = false //nolint:staticcheck
-
 	tests := []struct {
 		name                  string
 		enableIgnitionFeature bool
@@ -1055,12 +1050,6 @@ func TestKubeadmControlPlaneValidateUpdate(t *testing.T) {
 			before:                before,
 			kcp:                   invalidMetadata,
 		},
-		{
-			name:      "should allow changes to useExperimentalRetryJoin",
-			expectErr: false,
-			before:    beforeUseExperimentalRetryJoin,
-			kcp:       updateUseExperimentalRetryJoin,
-		},
 	}
 
 	for _, tt := range tests {
diff --git a/controlplane/kubeadm/internal/controllers/controller_test.go b/controlplane/kubeadm/internal/controllers/controller_test.go
index 6f1808c47..8f8f73472 100644
--- a/controlplane/kubeadm/internal/controllers/controller_test.go
+++ b/controlplane/kubeadm/internal/controllers/controller_test.go
@@ -28,7 +28,7 @@ import (
 	"testing"
 	"time"
 
-	"github.com/blang/semver/v4"
+	"github.com/blang/semver"
 	. "github.com/onsi/gomega"
 	appsv1 "k8s.io/api/apps/v1"
 	corev1 "k8s.io/api/core/v1"
@@ -1332,7 +1332,7 @@ kubernetesVersion: metav1.16.1`,
 				Status: internal.ClusterStatus{},
 			},
 		},
-		ssaCache: ssa.NewCache(),
+		disableInPlacePropagation: true,
 	}
 
 	result, err := r.Reconcile(ctx, ctrl.Request{NamespacedName: util.ObjectKey(kcp)})
diff --git a/controlplane/kubeadm/internal/controllers/fakes_test.go b/controlplane/kubeadm/internal/controllers/fakes_test.go
index ebc04e404..7f5a962e2 100644
--- a/controlplane/kubeadm/internal/controllers/fakes_test.go
+++ b/controlplane/kubeadm/internal/controllers/fakes_test.go
@@ -20,7 +20,7 @@ import (
 	"context"
 	"time"
 
-	"github.com/blang/semver/v4"
+	"github.com/blang/semver"
 	"github.com/pkg/errors"
 	"sigs.k8s.io/controller-runtime/pkg/client"
 
diff --git a/controlplane/kubeadm/internal/controllers/scale_test.go b/controlplane/kubeadm/internal/controllers/scale_test.go
index 393e08de4..a74cf0025 100644
--- a/controlplane/kubeadm/internal/controllers/scale_test.go
+++ b/controlplane/kubeadm/internal/controllers/scale_test.go
@@ -213,13 +213,14 @@ func TestKubeadmControlPlaneReconciler_scaleUpControlPlane(t *testing.T) {
 			managementCluster:         fmc,
 			managementClusterUncached: fmc,
 			recorder:                  record.NewFakeRecorder(32),
+			disableInPlacePropagation: true,
 		}
 
 		controlPlane, adoptableMachineFound, err := r.initControlPlaneScope(ctx, cluster, kcp)
 		g.Expect(err).ToNot(HaveOccurred())
 		g.Expect(adoptableMachineFound).To(BeFalse())
 
-		result, err := r.scaleUpControlPlane(context.Background(), controlPlane)
+		result, err := r.reconcile(context.Background(), controlPlane)
 		g.Expect(err).ToNot(HaveOccurred())
 		g.Expect(result).To(Equal(ctrl.Result{RequeueAfter: preflightFailedRequeueAfter}))
 
diff --git a/controlplane/kubeadm/internal/controllers/upgrade_test.go b/controlplane/kubeadm/internal/controllers/upgrade_test.go
index 78e4db4e9..ea591525a 100644
--- a/controlplane/kubeadm/internal/controllers/upgrade_test.go
+++ b/controlplane/kubeadm/internal/controllers/upgrade_test.go
@@ -35,7 +35,6 @@ import (
 	bootstrapv1 "sigs.k8s.io/cluster-api/bootstrap/kubeadm/api/v1beta1"
 	"sigs.k8s.io/cluster-api/controlplane/kubeadm/internal"
 	"sigs.k8s.io/cluster-api/internal/test/builder"
-	"sigs.k8s.io/cluster-api/internal/util/ssa"
 	"sigs.k8s.io/cluster-api/util"
 	"sigs.k8s.io/cluster-api/util/collections"
 )
@@ -94,7 +93,7 @@ func TestKubeadmControlPlaneReconciler_RolloutStrategy_ScaleUp(t *testing.T) {
 				Status: internal.ClusterStatus{Nodes: 1},
 			},
 		},
-		ssaCache: ssa.NewCache(),
+		disableInPlacePropagation: true,
 	}
 	controlPlane := &internal.ControlPlane{
 		KCP:      kcp,
diff --git a/controlplane/kubeadm/internal/workload_cluster_coredns_test.go b/controlplane/kubeadm/internal/workload_cluster_coredns_test.go
index 38e6aa1f4..bac6124e7 100644
--- a/controlplane/kubeadm/internal/workload_cluster_coredns_test.go
+++ b/controlplane/kubeadm/internal/workload_cluster_coredns_test.go
@@ -19,7 +19,7 @@ package internal
 import (
 	"testing"
 
-	"github.com/blang/semver/v4"
+	"github.com/blang/semver"
 	"github.com/google/go-cmp/cmp"
 	. "github.com/onsi/gomega"
 	"github.com/pkg/errors"
diff --git a/controlplane/kubeadm/internal/workload_cluster_etcd_test.go b/controlplane/kubeadm/internal/workload_cluster_etcd_test.go
index e80e869a5..9972cd283 100644
--- a/controlplane/kubeadm/internal/workload_cluster_etcd_test.go
+++ b/controlplane/kubeadm/internal/workload_cluster_etcd_test.go
@@ -21,7 +21,7 @@ import (
 	"errors"
 	"testing"
 
-	"github.com/blang/semver/v4"
+	"github.com/blang/semver"
 	"github.com/google/go-cmp/cmp"
 	. "github.com/onsi/gomega"
 	pb "go.etcd.io/etcd/api/v3/etcdserverpb"
diff --git a/controlplane/kubeadm/internal/workload_cluster_rbac_test.go b/controlplane/kubeadm/internal/workload_cluster_rbac_test.go
index 3463e10ad..f4f93e3d6 100644
--- a/controlplane/kubeadm/internal/workload_cluster_rbac_test.go
+++ b/controlplane/kubeadm/internal/workload_cluster_rbac_test.go
@@ -20,7 +20,7 @@ import (
 	"errors"
 	"testing"
 
-	"github.com/blang/semver/v4"
+	"github.com/blang/semver"
 	. "github.com/onsi/gomega"
 	rbacv1 "k8s.io/api/rbac/v1"
 	apierrors "k8s.io/apimachinery/pkg/api/errors"
diff --git a/controlplane/kubeadm/internal/workload_cluster_test.go b/controlplane/kubeadm/internal/workload_cluster_test.go
index b0e900387..f1540168a 100644
--- a/controlplane/kubeadm/internal/workload_cluster_test.go
+++ b/controlplane/kubeadm/internal/workload_cluster_test.go
@@ -21,7 +21,7 @@ import (
 	"errors"
 	"testing"
 
-	"github.com/blang/semver/v4"
+	"github.com/blang/semver"
 	"github.com/google/go-cmp/cmp"
 	. "github.com/onsi/gomega"
 	appsv1 "k8s.io/api/apps/v1"
diff --git a/internal/goproxy/goproxy_test.go b/internal/goproxy/goproxy_test.go
index f25f69b83..c914fa6f2 100644
--- a/internal/goproxy/goproxy_test.go
+++ b/internal/goproxy/goproxy_test.go
@@ -25,7 +25,7 @@ import (
 	"testing"
 	"time"
 
-	"github.com/blang/semver/v4"
+	"github.com/blang/semver"
 	. "github.com/onsi/gomega"
 )
 
diff --git a/internal/util/kubeadm/kubeadm_test.go b/internal/util/kubeadm/kubeadm_test.go
index 2f4639b9f..4e1f7c81f 100644
--- a/internal/util/kubeadm/kubeadm_test.go
+++ b/internal/util/kubeadm/kubeadm_test.go
@@ -20,7 +20,7 @@ import (
 	"fmt"
 	"testing"
 
-	"github.com/blang/semver/v4"
+	"github.com/blang/semver"
 	. "github.com/onsi/gomega"
 )
 
diff --git a/scripts/ci-e2e-lib.sh b/scripts/ci-e2e-lib.sh
index bf673e009..3a5af5016 100644
--- a/scripts/ci-e2e-lib.sh
+++ b/scripts/ci-e2e-lib.sh
@@ -204,9 +204,9 @@ EOL
 # the actual test run less sensible to the network speed.
 kind:prepullAdditionalImages () {
   # Pulling cert manager images so we can pre-load in kind nodes
-  kind::prepullImage "quay.io/jetstack/cert-manager-cainjector:v1.12.3"
-  kind::prepullImage "quay.io/jetstack/cert-manager-webhook:v1.12.3"
-  kind::prepullImage "quay.io/jetstack/cert-manager-controller:v1.12.3"
+  kind::prepullImage "quay.io/jetstack/cert-manager-cainjector:v1.12.2"
+  kind::prepullImage "quay.io/jetstack/cert-manager-webhook:v1.12.2"
+  kind::prepullImage "quay.io/jetstack/cert-manager-controller:v1.12.2"
 }
 
 # kind:prepullImage pre-pull a docker image if no already present locally.
diff --git a/test/e2e/cluster_upgrade_runtimesdk_test.go b/test/e2e/cluster_upgrade_runtimesdk_test.go
index b8a6af160..5596311b3 100644
--- a/test/e2e/cluster_upgrade_runtimesdk_test.go
+++ b/test/e2e/cluster_upgrade_runtimesdk_test.go
@@ -20,7 +20,7 @@ limitations under the License.
 package e2e
 
 import (
-	"github.com/blang/semver/v4"
+	"github.com/blang/semver"
 	. "github.com/onsi/ginkgo/v2"
 	. "github.com/onsi/gomega"
 	"k8s.io/utils/pointer"
diff --git a/test/e2e/common.go b/test/e2e/common.go
index 0e4990ed8..c0c46ae23 100644
--- a/test/e2e/common.go
+++ b/test/e2e/common.go
@@ -21,7 +21,7 @@ import (
 	"fmt"
 	"path/filepath"
 
-	"github.com/blang/semver/v4"
+	"github.com/blang/semver"
 	. "github.com/onsi/ginkgo/v2"
 	"github.com/onsi/gomega/types"
 	corev1 "k8s.io/api/core/v1"
diff --git a/test/e2e/config/docker.yaml b/test/e2e/config/docker.yaml
index 618ad842a..647502970 100644
--- a/test/e2e/config/docker.yaml
+++ b/test/e2e/config/docker.yaml
@@ -23,11 +23,11 @@ images:
   loadBehavior: tryLoad
 - name: gcr.io/k8s-staging-cluster-api/test-extension-{ARCH}:dev
   loadBehavior: tryLoad
-- name: quay.io/jetstack/cert-manager-cainjector:v1.12.3
+- name: quay.io/jetstack/cert-manager-cainjector:v1.12.2
   loadBehavior: tryLoad
-- name: quay.io/jetstack/cert-manager-webhook:v1.12.3
+- name: quay.io/jetstack/cert-manager-webhook:v1.12.2
   loadBehavior: tryLoad
-- name: quay.io/jetstack/cert-manager-controller:v1.12.3
+- name: quay.io/jetstack/cert-manager-controller:v1.12.2
   loadBehavior: tryLoad
 
 providers:
diff --git a/test/extension/handlers/topologymutation/handler.go b/test/extension/handlers/topologymutation/handler.go
index dc61ce921..1cae18815 100644
--- a/test/extension/handlers/topologymutation/handler.go
+++ b/test/extension/handlers/topologymutation/handler.go
@@ -25,7 +25,7 @@ import (
 	"context"
 	"fmt"
 
-	"github.com/blang/semver/v4"
+	"github.com/blang/semver"
 	"github.com/pkg/errors"
 	apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
 	"k8s.io/apimachinery/pkg/runtime"
diff --git a/test/framework/clusterctl/repository.go b/test/framework/clusterctl/repository.go
index 42c855a54..ff2067828 100644
--- a/test/framework/clusterctl/repository.go
+++ b/test/framework/clusterctl/repository.go
@@ -28,7 +28,7 @@ import (
 	"regexp"
 	"strings"
 
-	"github.com/blang/semver/v4"
+	"github.com/blang/semver"
 	. "github.com/onsi/gomega"
 	"github.com/pkg/errors"
 
diff --git a/test/framework/daemonset_helpers.go b/test/framework/daemonset_helpers.go
index a8322309a..40510638e 100644
--- a/test/framework/daemonset_helpers.go
+++ b/test/framework/daemonset_helpers.go
@@ -19,7 +19,7 @@ package framework
 import (
 	"context"
 
-	"github.com/blang/semver/v4"
+	"github.com/blang/semver"
 	. "github.com/onsi/ginkgo/v2"
 	. "github.com/onsi/gomega"
 	appsv1 "k8s.io/api/apps/v1"
diff --git a/test/framework/kubernetesversions/versions.go b/test/framework/kubernetesversions/versions.go
index 4af7cc3f8..6340229a1 100644
--- a/test/framework/kubernetesversions/versions.go
+++ b/test/framework/kubernetesversions/versions.go
@@ -23,7 +23,7 @@ import (
 	"net/http"
 	"strings"
 
-	"github.com/blang/semver/v4"
+	"github.com/blang/semver"
 	"github.com/pkg/errors"
 )
 
diff --git a/test/go.mod b/test/go.mod
index c3f1c4840..1cc32a7ed 100644
--- a/test/go.mod
+++ b/test/go.mod
@@ -5,7 +5,7 @@ go 1.20
 replace sigs.k8s.io/cluster-api => ../
 
 require (
-	github.com/blang/semver/v4 v4.0.0
+	github.com/blang/semver v3.5.1+incompatible
 	github.com/docker/docker v24.0.5+incompatible
 	github.com/docker/go-connections v0.4.0
 	github.com/emicklei/go-restful/v3 v3.10.2
@@ -51,6 +51,7 @@ require (
 	github.com/antlr/antlr4/runtime/Go/antlr v1.4.10 // indirect
 	github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a // indirect
 	github.com/beorn7/perks v1.0.1 // indirect
+	github.com/blang/semver/v4 v4.0.0 // indirect
 	github.com/cenkalti/backoff/v4 v4.1.3 // indirect
 	github.com/cespare/xxhash/v2 v2.2.0 // indirect
 	github.com/cloudflare/circl v1.3.3 // indirect
@@ -142,7 +143,7 @@ require (
 	golang.org/x/text v0.12.0 // indirect
 	golang.org/x/time v0.3.0 // indirect
 	golang.org/x/tools v0.9.3 // indirect
-	gomodules.xyz/jsonpatch/v2 v2.4.0 // indirect
+	gomodules.xyz/jsonpatch/v2 v2.3.0 // indirect
 	google.golang.org/appengine v1.6.7 // indirect
 	google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1 // indirect
 	google.golang.org/protobuf v1.31.0 // indirect
diff --git a/test/go.sum b/test/go.sum
index 37c0fb146..4978eb7a9 100644
--- a/test/go.sum
+++ b/test/go.sum
@@ -85,6 +85,8 @@ github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
 github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
 github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs=
 github.com/bketelsen/crypt v0.0.3-0.20200106085610-5cbc8cc4026c/go.mod h1:MKsuJmJgSg28kpZDP6UIiPt0e0Oz0kqKNGyRaWEPv84=
+github.com/blang/semver v3.5.1+incompatible h1:cQNTCjp13qL8KC3Nbxr/y2Bqb63oX6wdnnjpJbkM4JQ=
+github.com/blang/semver v3.5.1+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk=
 github.com/blang/semver/v4 v4.0.0 h1:1PFHFE6yCCTv8C1TeyNNarDzntLi7wMI5i/pzqYIsAM=
 github.com/blang/semver/v4 v4.0.0/go.mod h1:IbckMUScFkM3pff0VJDNKRiT6TG/YpiHIM2yvyW5YoQ=
 github.com/buger/jsonparser v1.1.1/go.mod h1:6RYKKt7H4d4+iWqouImQ9R2FZql3VbhNgx27UK13J/0=
@@ -843,8 +845,8 @@ golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8T
 golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
 golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
 golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
-gomodules.xyz/jsonpatch/v2 v2.4.0 h1:Ci3iUJyx9UeRx7CeFN8ARgGbkESwJK+KB9lLcWxY/Zw=
-gomodules.xyz/jsonpatch/v2 v2.4.0/go.mod h1:AH3dM2RI6uoBZxn3LVrfvJ3E0/9dG4cSrbuBJT4moAY=
+gomodules.xyz/jsonpatch/v2 v2.3.0 h1:8NFhfS6gzxNqjLIYnZxg319wZ5Qjnx4m/CcX+Klzazc=
+gomodules.xyz/jsonpatch/v2 v2.3.0/go.mod h1:AH3dM2RI6uoBZxn3LVrfvJ3E0/9dG4cSrbuBJT4moAY=
 google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE=
 google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M=
 google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg=
diff --git a/test/infrastructure/docker/exp/internal/docker/nodepool.go b/test/infrastructure/docker/exp/internal/docker/nodepool.go
index 12920be70..08683dea8 100644
--- a/test/infrastructure/docker/exp/internal/docker/nodepool.go
+++ b/test/infrastructure/docker/exp/internal/docker/nodepool.go
@@ -25,7 +25,7 @@ import (
 	"strings"
 	"time"
 
-	"github.com/blang/semver/v4"
+	"github.com/blang/semver"
 	"github.com/pkg/errors"
 	corev1 "k8s.io/api/core/v1"
 	"k8s.io/klog/v2"
diff --git a/test/infrastructure/docker/internal/docker/machine.go b/test/infrastructure/docker/internal/docker/machine.go
index 96c9df5ed..c65c9a882 100644
--- a/test/infrastructure/docker/internal/docker/machine.go
+++ b/test/infrastructure/docker/internal/docker/machine.go
@@ -26,7 +26,7 @@ import (
 	"strings"
 	"time"
 
-	"github.com/blang/semver/v4"
+	"github.com/blang/semver"
 	"github.com/go-logr/logr"
 	"github.com/pkg/errors"
 	corev1 "k8s.io/api/core/v1"
diff --git a/test/infrastructure/docker/internal/provisioning/cloudinit/adapter_test.go b/test/infrastructure/docker/internal/provisioning/cloudinit/adapter_test.go
index 1a4fdcea8..759d0550b 100644
--- a/test/infrastructure/docker/internal/provisioning/cloudinit/adapter_test.go
+++ b/test/infrastructure/docker/internal/provisioning/cloudinit/adapter_test.go
@@ -19,7 +19,7 @@ package cloudinit
 import (
 	"testing"
 
-	"github.com/blang/semver/v4"
+	"github.com/blang/semver"
 	. "github.com/onsi/gomega"
 
 	"sigs.k8s.io/cluster-api/test/infrastructure/docker/internal/provisioning"
diff --git a/test/infrastructure/docker/internal/provisioning/cloudinit/writefiles.go b/test/infrastructure/docker/internal/provisioning/cloudinit/writefiles.go
index aa47d0db2..6e31a29f9 100644
--- a/test/infrastructure/docker/internal/provisioning/cloudinit/writefiles.go
+++ b/test/infrastructure/docker/internal/provisioning/cloudinit/writefiles.go
@@ -25,7 +25,7 @@ import (
 	"path/filepath"
 	"strings"
 
-	"github.com/blang/semver/v4"
+	"github.com/blang/semver"
 	"github.com/pkg/errors"
 	"sigs.k8s.io/yaml"
 
diff --git a/test/infrastructure/docker/internal/provisioning/cloudinit/writefiles_test.go b/test/infrastructure/docker/internal/provisioning/cloudinit/writefiles_test.go
index 28902c292..28077c652 100644
--- a/test/infrastructure/docker/internal/provisioning/cloudinit/writefiles_test.go
+++ b/test/infrastructure/docker/internal/provisioning/cloudinit/writefiles_test.go
@@ -21,7 +21,7 @@ import (
 	"compress/gzip"
 	"testing"
 
-	"github.com/blang/semver/v4"
+	"github.com/blang/semver"
 	"github.com/google/go-cmp/cmp"
 	. "github.com/onsi/gomega"
 
diff --git a/test/infrastructure/kind/mapper.go b/test/infrastructure/kind/mapper.go
index d6db884d7..4bdb5e77f 100644
--- a/test/infrastructure/kind/mapper.go
+++ b/test/infrastructure/kind/mapper.go
@@ -37,7 +37,7 @@ package kind
 import (
 	"fmt"
 
-	"github.com/blang/semver/v4"
+	"github.com/blang/semver"
 
 	clusterapicontainer "sigs.k8s.io/cluster-api/util/container"
 )
diff --git a/test/infrastructure/kind/mapper_test.go b/test/infrastructure/kind/mapper_test.go
index 863669112..42bf2556d 100644
--- a/test/infrastructure/kind/mapper_test.go
+++ b/test/infrastructure/kind/mapper_test.go
@@ -19,7 +19,7 @@ package kind
 import (
 	"testing"
 
-	"github.com/blang/semver/v4"
+	"github.com/blang/semver"
 	. "github.com/onsi/gomega"
 )
 
diff --git a/util/util_test.go b/util/util_test.go
index 748ca0cbc..c736c02b6 100644
--- a/util/util_test.go
+++ b/util/util_test.go
@@ -21,7 +21,7 @@ import (
 	"fmt"
 	"testing"
 
-	"github.com/blang/semver/v4"
+	"github.com/blang/semver"
 	. "github.com/onsi/gomega"
 	corev1 "k8s.io/api/core/v1"
 	"k8s.io/apimachinery/pkg/api/meta"
diff --git a/util/version/version_test.go b/util/version/version_test.go
index abe9501b0..a76ea9d2c 100644
--- a/util/version/version_test.go
+++ b/util/version/version_test.go
@@ -19,7 +19,7 @@ package version
 import (
 	"testing"
 
-	"github.com/blang/semver/v4"
+	"github.com/blang/semver"
 	. "github.com/onsi/gomega"
 )