# cert-manager Make Tooling This directory contains tools and scripts used to create development and testing environments for cert-manager, centered around the use of [GNU Make](https://www.gnu.org/software/make/). Most tasks that a developer might encounter day-to-day are documented in `make help`; you can view that documentation by changing to the root of a cert-manager checkout and simply running: ```console make help ``` If you think that the documentation in `make help` is insufficient or that an important make target isn't documented, we'd consider that a bug. Please feel free to raise an issue! Most of the rest of the documentation for the cert-manager build system is on the [cert-manager website](https://cert-manager.io/docs/): - [Building cert-manager](https://cert-manager.io/docs/contributing/building/) - A guide to different commands which are useful for building cert-manager components locally. - [CRDs](https://cert-manager.io/docs/contributing/crds/) - Information on updating, verifying and generating code centered around the cert-manager [CRDs](https://kubernetes.io/docs/concepts/extend-kubernetes/api-extension/custom-resources/). - [Developing with Kind](https://cert-manager.io/docs/contributing/kind/) - Setting up a local development cluster using [Kind](https://kind.sigs.k8s.io) - [Running End-to-End Tests](https://cert-manager.io/docs/contributing/e2e/) - Details on cert-manager's end-to-end test suite and how it can be run ## Changing the Makefiles When adding or changing a make target, you might want to consider a few questions which could have a significant effect on the performance of your changes. ### Should it be documented? If you want your target to appear when a user runs `make help`, you can add a documentation comment to it which starts with `##`. ```make .PHONY: kind-version ## kind-version prints the version of kind. ## ## Bet you didn't expect that, huh? ## ## @category Development kind-version: | $(NEEDS_KIND) @$(KIND) --version ``` Categories are loosely defined; check the output of `make help` for examples of the kinds of categories we already have. Regular comments above a target should start with a single `#`. ### Should it be `.PHONY`? > A phony target is one that is not really the name of a file; rather it is just a name for a recipe to be executed when you make an explicit request. The [GNU Make documentation](https://www.gnu.org/software/make/manual/html_node/Phony-Targets.html) gives the above definition for `.PHONY` targets, and is worth reading if you're adding a new target since getting this wrong can lead to either spurious rebuilds or unexpected failures to execute your target. Put short: If a target doesn't create a file with the same name as the target, it should be `.PHONY`. Mark the target as `.PHONY` by adding the declaration directly above the target, with any documentation comments in between. For example: ```make .PHONY: my-target ## Does something awesome! ## ## @category Awesomeness my-target: @echo Something awesome! ``` ### Target Dependencies / Prerequisites Make has [two types of dependency](https://www.gnu.org/software/make/manual/html_node/Prerequisite-Types.html): "normal" and "order-only". When creating or changing a target, you should choose the type based on what your dependency is. ⚠️ If your dependency is a `.PHONY` target, you should think very hard about whether to include it. A `.PHONY` dependency will force your target to be rebuilt every single time. That's rarely what you want. If your dependency is a directory or a tool, it should likely be order-only since you don't want to rebuild your target when those dependencies change. Otherwise, your dependency should be normal. For example: ```make $(BINDIR)/awesome-stuff/my-file: README.md | $(BINDIR)/awesome-stuff $(NEEDS_KIND) # write the kind version to $(BINDIR)/awesome-stuff/my-file $(KIND) --version > $@ # append README.md cat README.md >> $@ ``` This target will be rebuilt if `README.md` changes, but not if the installed version of kind changes or the `$(BINDIR)/awesome-stuff` folder changes. The dependencies you'll need will inevitably depend on the target you're writing. If in doubt, feel free to ask! ## Tool Dependencies The scripts used by make commonly require additional tooling, such as access to `kubectl`, `helm`, `kind` and a bunch of other things. The build system is capable of downloading and provisioning most of these tools without any user interaction. For example, if an end-to-end test requires `kind`, then `kind` will be downloaded and that version will be used regardless of whether you have `kind` installed on your system. Usually, that's what you want; it ensures that you're using the exact same tools - at the same versions - as other developers. Some tools must be installed locally, however. The build system will alert you if a required tool cannot be found, and these tools are documented [on the website](https://cert-manager.io/docs/contributing/building/#prerequisites). Specifically, note that you can choose to use your system version of Go or to [download a vendored copy](https://cert-manager.io/docs/contributing/building/#go-versions).