diff --git a/Makefile b/Makefile
index 0961c8bc7..07a72d6ed 100644
--- a/Makefile
+++ b/Makefile
@@ -52,9 +52,7 @@ include make/help.mk
.PHONY: clean
## Remove the kind cluster and everything that was built. The downloaded images
## and tools are kept intact to avoid re-downloading everything. To really wipe
-## out everything, run the command:
-##
-## rm -rf bin
+## out everything, use `make clean-all` instead.
##
## @category Development
clean:
@@ -62,3 +60,7 @@ clean:
bin/tools/kind delete cluster --name=$(shell cat bin/scratch/kind-exists 2>/dev/null || echo $(KIND_CLUSTER_NAME)) -q 2>/dev/null || true
rm -rf $(filter-out bin/downloaded,$(wildcard bin/*))
rm -rf bazel-bin bazel-cert-manager bazel-out bazel-testlogs
+
+.PHONY: clean-all
+clean-all: clean
+ rm -rf bin/
diff --git a/make/ci.mk b/make/ci.mk
index 9c692e7b0..b7c37b3b4 100644
--- a/make/ci.mk
+++ b/make/ci.mk
@@ -1,6 +1,10 @@
__PYTHON := python3
.PHONY: ci-presubmit
+## Run all checks (but not Go tests) which should pass before any given pull
+## request or change is merged.
+##
+## @category CI
ci-presubmit: verify-imports verify-chart verify-errexit verify-boilerplate
.PHONY: verify-imports
diff --git a/make/help.mk b/make/help.mk
index d79bec90c..ad5521fd8 100644
--- a/make/help.mk
+++ b/make/help.mk
@@ -50,7 +50,6 @@ default_category_tag_end :=
DEFAULT_CATEGORY = General
.PHONY: help
-## Show the help.
help:
@echo "Usage: make [$(TARGET_STYLED_HELP_NAME) [$(TARGET_STYLED_HELP_NAME) ...]] [$(ARGUMENTS_HELP_NAME) [$(ARGUMENTS_HELP_NAME) ...]]"
@cat ${MAKEFILE_LIST} \
diff --git a/make/release.mk b/make/release.mk
index 721bfdd17..8d76f22fe 100644
--- a/make/release.mk
+++ b/make/release.mk
@@ -6,19 +6,29 @@
CMREL_KEY ?=
.PHONY: release-artifacts
-# Build all release artifacts which might be run or used locally, except
-# for anything signed.
+## Build all release artifacts which might be run or used locally, except
+## for anything signed.
+##
+## Useful to check that all binaries and manifests on all platforms can be
+## built without errors.
+##
+## @category Release
release-artifacts: server-binaries cmctl kubectl-cert_manager helm-chart release-containers release-manifests
.PHONY: release-artifacts-signed
# Same as `release`, except it also signs the Helm chart. Requires CMREL_KEY
# to be configured.
+# Note that this doesn't sign containers, since it's tricky to do that before
+# a release is staged. Instead we sign them after we push them to a registry.
release-artifacts-signed: release-artifacts
$(MAKE) --no-print-directory helm-chart-signature
.PHONY: release
-## Create a full release ready to be staged, including containers bundled for
-## distribution. Requires CMREL_KEY to be configured.
+## Create a complete release ready to be staged, including containers bundled for
+## distribution and all signatures.
+##
+## Since this command signs artifacts, this requires CMREL_KEY to be configured.
+## Prefer `make release-artifacts` locally.
##
## @category Release
release: release-artifacts-signed
diff --git a/make/test.mk b/make/test.mk
index 9333cc081..60a9e4817 100644
--- a/make/test.mk
+++ b/make/test.mk
@@ -16,16 +16,18 @@ test: setup-integration-tests bin/tools/gotestsum bin/tools/etcd bin/tools/kubec
$(GOTESTSUM) -- $(WHAT)
.PHONY: test-ci
-# test-ci runs all unit and integration tests and writes a JUnit report of
-# the results. WHAT also works here.
-#
-# The reason we are hiding the fuzz tests is because there are over 50,000
-# XML lines with fuzz test cases, which means the Prow UI struggles
-# displaying the JUnit results. We are hiding lines that look like this:
-#
-#
-#
+## test-ci runs all unit and integration tests and writes a JUnit report of
+## the results. WHAT can be used to limit which tests are run; see help for
+## `make test` for more details.
+##
+## Fuzz tests are hidden from JUnit output, because they're noisy and can cause
+## issues with dashboards and UIs.
+##
+## @category CI
test-ci: setup-integration-tests bin/tools/gotestsum bin/tools/etcd bin/tools/kubectl bin/tools/kube-apiserver
+ @# Fuzz tests are hidden from JUnit output because they can break dashboards.
+ @# They look like this:
+ @#
@mkdir -p $(ARTIFACTS)
$(GOTESTSUM) --junitfile $(ARTIFACTS)/junit_make-test-ci.xml \
--post-run-command $$'bash -c "awk \'$$1 \!~ /\\/fuzz_\\d+// { print $$2 }\' - $$GOTESTSUM_JUNITFILE >/tmp/$$$$ && mv /tmp/$$$$ $$GOTESTSUM_JUNITFILE"' \
@@ -33,7 +35,7 @@ test-ci: setup-integration-tests bin/tools/gotestsum bin/tools/etcd bin/tools/ku
.PHONY: unit-test
## Same as `test` but only runs the unit tests. By "unit tests", we mean tests
-## that are quick to run and don't require dependencies like a Kubernetes, etcd,
+## that are quick to run and don't require dependencies like Kubernetes, etcd,
## or an apiserver.
##
## @category Development
diff --git a/make/tools.mk b/make/tools.mk
index 9bc75c45a..b706f880f 100644
--- a/make/tools.mk
+++ b/make/tools.mk
@@ -109,6 +109,13 @@ vendor-go: bin/tools/go
unvendor-go: bin/tools/go
rm -rf bin/tools/go bin/tools/goroot
+.PHONY: which-go
+## Print the version and path of go which will be used for building and
+## testing in Makefile commands. Vendored go will have a path in ./bin
+which-go: | $(DEPENDS_ON_GO)
+ @$(GO) version
+ @echo "go binary used for above version information: $(GO)"
+
# In Prow, the pod has the folder "bin/downloaded" mounted into the
# container. For some reason, even though the permissions are correct,
# binaries that are mounted with hostPath can't be executed. When in CI, we