This repository has been archived by the owner on Oct 10, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 192
/
build.mk
355 lines (310 loc) · 13.2 KB
/
build.mk
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
# Copyright 2023 VMware, Inc. All Rights Reserved.
# SPDX-License-Identifier: Apache-2.0
.DEFAULT_GOAL := help
REGISTRY_PORT := 8000
REGISTRY_ENDPOINT := localhost:$(REGISTRY_PORT)
PACKAGE_PREFIX := $(REGISTRY_ENDPOINT)
REGISTRY_NAME := tanzu-integration-registry
DOCKER := DOCKER_BUILDKIT=1 docker
MAKE := make
IMG_DEFAULT_TAG := latest
IMG_VERSION_OVERRIDE ?= $(IMG_DEFAULT_TAG)
GOPROXY ?= "https://proxy.golang.org,direct"
PLATFORM=local
# Step 2 in the [Build Tooling For Integrations documentation](https://github.com/vmware-tanzu/build-tooling-for-integrations/blob/main/docs/build-tooling-getting-started.md)
# explains how to set the COMPONENTS variable.
COMPONENTS ?= capabilities/client \
capabilities/controller.capabilities-controller-manager.capabilities \
featuregates/client \
featuregates/controller.featuregates-controller-manager.featuregates \
readiness/controller.readiness-controller-manager.readiness
BUILD_TOOLING_CONTAINER_IMAGE ?= ghcr.io/vmware-tanzu/build-tooling
PACKAGING_CONTAINER_IMAGE ?= ghcr.io/vmware-tanzu/package-tooling
VERSION ?= v0.2.0
CLI_PLUGIN_VERSION ?= v0.0.1
IMGPKG_VERSION ?= v0.11.0
# Utility functions check for main.go in component path.
find_main_go = $(shell find $(1) -name main.go)
check_main_go = $(if $(call find_main_go,$(1)),Found,NotFound)
##
## Project Initialization Targets
##
# Bootstraps a project by creating a copy of the Tanzu build container Dockerfile
# into the project's root directory (alongside Makefile).
# This target also installs a local registry if the build is being done in a
# non-CI environment and it makes sure that the Tanzu packaging container is up to date.
bootstrap: install-registry check-copy-build-container install-package-container
install-registry:
ifneq ($(IS_CI),)
@echo "Running in CI mode. Skipping local registry setup."
else
ifeq ($(shell $(DOCKER) ps -q -f name=$(REGISTRY_NAME) 2> /dev/null),)
@echo "Deploying a local Docker registry for Tanzu Integrations"
$(DOCKER) run -d -p $(REGISTRY_PORT):5000 --restart=always --name $(REGISTRY_NAME) registry:2
@echo
endif
@echo "Registry for Tanzu Integrations available at $(REGISTRY_ENDPOINT)"
endif
check-copy-build-container:
ifneq ("$(wildcard Dockerfile)","")
$(eval COPY_BUILD_CONTAINER := $(shell bash -c 'read -p "There is already a Dockerfile in this project. Overwrite? [y/N]: " do_copy; echo $$do_copy'))
else
$(eval COPY_BUILD_CONTAINER := Y)
endif
@$(MAKE) -s COPY_BUILD_CONTAINER=$(COPY_BUILD_CONTAINER) copy-build-container
copy-build-container:
ifneq ($(filter y Y, $(COPY_BUILD_CONTAINER)),)
@$(DOCKER) run --name tanzu-build-tooling $(BUILD_TOOLING_CONTAINER_IMAGE):$(VERSION)
@$(DOCKER) cp tanzu-build-tooling:/Dockerfile ./Dockerfile
@$(DOCKER) cp tanzu-build-tooling:/.golangci.yaml ./.golangci.yaml
@echo Added Dockerfile for containerize build to $(PWD)
@$(DOCKER) rm tanzu-build-tooling 1> /dev/null
endif
install-package-container:
@$(DOCKER) pull $(PACKAGING_CONTAINER_IMAGE):$(VERSION)
.PHONY: bootstrap install-registry check-copy-build-container copy-build-container install-package-container
.PHONY: init
# Fetch the Dockerfile and pull image needed to build packages
init:
$(DOCKER) run --rm -v ${PWD}:/workspace --entrypoint /bin/sh $(BUILD_TOOLING_CONTAINER_IMAGE):$(VERSION) -c "cp Dockerfile /workspace && cp .golangci.yaml /workspace"
$(DOCKER) pull $(PACKAGING_CONTAINER_IMAGE):$(VERSION)
##
## Other Targets
##
.PHONY: docker-build-all
# Run linter, tests and build images
docker-build-all: $(COMPONENTS)
.PHONY: docker-publish-all
# Push images of all components
docker-publish-all: PUBLISH_IMAGES:=true
docker-publish-all: $(COMPONENTS)
.PHONY: build-all cli-plugin-build
# Run linter, tests and build binaries
build-all: BUILD_BIN:=true
build-all: $(COMPONENTS)
.PHONY: package-all
# Generate package bundles and push them to a registry
package-all: package-bundle-generate-all package-bundle-push-all
.PHONY: $(COMPONENTS)
$(COMPONENTS):
$(eval COMPONENT_PATH = $(word 1,$(subst ., ,$@)))
$(eval IMAGE_NAME = $(word 2,$(subst ., ,$@)))
$(eval PACKAGE_PATH = $(word 3,$(subst ., ,$@)))
$(eval IMAGE = $(IMAGE_NAME):$(IMG_VERSION_OVERRIDE))
$(eval DEFAULT_IMAGE = $(IMAGE_NAME):$(IMG_DEFAULT_TAG))
$(eval IMAGE = $(shell if [ ! -z "$(OCI_REGISTRY)" ]; then echo $(OCI_REGISTRY)/$(IMAGE_NAME):$(IMG_VERSION_OVERRIDE); else echo $(IMAGE); fi))
$(eval COMPONENT = $(shell if [ -z "$(COMPONENT_PATH)" ]; then echo "."; else echo $(COMPONENT_PATH); fi))
@if [ "$(PUBLISH_IMAGES)" = "true" ]; then \
if [ "$(call check_main_go,$(COMPONENT))" = "Found" ]; then \
$(MAKE) validate-component IMAGE_NAME=$(IMAGE_NAME) PACKAGE_PATH=$(PACKAGE_PATH) || exit 1; \
$(MAKE) publish IMAGE=$(IMAGE) DEFAULT_IMAGE=$(DEFAULT_IMAGE) PACKAGE_PATH=$(PACKAGE_PATH) BUILD_BIN=$(BUILD_BIN); \
fi \
else \
$(MAKE) build COMPONENT=$(COMPONENT) IMAGE_NAME=$(IMAGE_NAME) IMAGE=$(IMAGE) PACKAGE_PATH=$(PACKAGE_PATH) BUILD_BIN=$(BUILD_BIN); \
fi
.PHONY: validate-component
validate-component:
ifeq ($(strip $(IMAGE_NAME)),)
$(error Image name of the component is not set in COMPONENTS variable, check https://github.com/vmware-tanzu/build-tooling-for-integrations/blob/main/docs/build-tooling-getting-started.md#steps-to-use-the-build-tooling for more help)
else ifeq ($(strip $(PACKAGE_PATH)),)
$(error Path to the package of the component is not set in COMPONENTS variable, check https://github.com/vmware-tanzu/build-tooling-for-integrations/blob/main/docs/build-tooling-getting-started.md#steps-to-use-the-build-tooling for more help)
endif
.PHONY: build
build:
$(MAKE) COMPONENT=$(COMPONENT) lint
$(MAKE) COMPONENT=$(COMPONENT) test
@if [ "$(call check_main_go,$(COMPONENT))" = "Found" ]; then \
if [ "$(BUILD_BIN)" = "true" ]; then \
$(MAKE) COMPONENT=$(COMPONENT) binary-build; \
else \
$(MAKE) validate-component IMAGE_NAME=$(IMAGE_NAME) PACKAGE_PATH=$(PACKAGE_PATH) || exit 1; \
$(MAKE) docker-build IMAGE=$(IMAGE) COMPONENT=$(COMPONENT); \
fi \
fi
.PHONY: publish
publish:
$(MAKE) IMAGE=$(IMAGE) docker-publish
$(MAKE) KBLD_CONFIG_FILE_PATH=packages/$(PACKAGE_PATH)/kbld-config.yaml DEFAULT_IMAGE=$(DEFAULT_IMAGE) IMAGE=$(IMAGE) kbld-image-replace
.PHONY: lint
# Run linting
lint:
ifneq ($(strip $(COMPONENT)),.)
cp .golangci.yaml $(COMPONENT)
$(DOCKER) build . -f Dockerfile --target lint --build-arg COMPONENT=$(COMPONENT) --build-arg GOPROXY_ARG=$(GOPROXY)
rm -rf $(COMPONENT)/.golangci.yaml
else
$(DOCKER) build . -f Dockerfile --target lint --build-arg COMPONENT=$(COMPONENT) --build-arg GOPROXY_ARG=$(GOPROXY)
endif
.PHONY: fmt
# Run go fmt against code
fmt:
$(DOCKER) build . -f Dockerfile --target fmt --build-arg COMPONENT=$(COMPONENT) --build-arg GOPROXY_ARG=$(GOPROXY)
.PHONY: vet
# Perform static analysis of code
vet:
$(DOCKER) build . -f Dockerfile --target vet --build-arg COMPONENT=$(COMPONENT) --build-arg GOPROXY_ARG=$(GOPROXY)
.PHONY: test
# Run tests
test: fmt vet
$(DOCKER) build . -f Dockerfile --target test --build-arg COMPONENT=$(COMPONENT) --build-arg GOPROXY_ARG=$(GOPROXY)
@$(DOCKER) build . -f Dockerfile --target unit-test-coverage --build-arg COMPONENT=$(COMPONENT) --build-arg GOPROXY_ARG=$(GOPROXY) --output build/$(COMPONENT)/coverage
.PHONY: binary-build
# Build the binary
binary-build:
$(DOCKER) build . -f Dockerfile --build-arg LD_FLAGS="$(LD_FLAGS)" --target bin --output build/$(COMPONENT)/bin --platform ${PLATFORM} --build-arg COMPONENT=$(COMPONENT) --build-arg GOPROXY_ARG=$(GOPROXY)
.PHONY: docker-build
# Build docker image
docker-build:
$(DOCKER) build . -t $(IMAGE) -f Dockerfile --target image --platform linux/amd64 --build-arg LD_FLAGS="$(LD_FLAGS)" --build-arg COMPONENT=$(COMPONENT) --build-arg GOPROXY_ARG=$(GOPROXY)
.PHONY: docker-publish
# Publish docker image
docker-publish:
$(DOCKER) push $(IMAGE)
# Tanzu CLI Plugin Builder is used to compile and publish Tanzu CLI plugins.
# https://github.com/vmware-tanzu/tanzu-cli/tree/main/cmd/plugin/builder
.PHONY: cli-plugin-builder-install
plugin-builder-install:
docker build . -f Dockerfile --target cli-plugin-builder-install
.PHONY: cli-plugin-build
CLI_PLUGIN_TARGETS := $(addprefix cli-plugin-build-, $(shell if [ -z "$(CLI_PLUGINS)" ]; then printf "$(shell [ -d "cmd/plugin" ] && cd cmd/plugin && printf "%s" */ | sed 's/\// /g' && cd ../..)"; else printf "$(CLI_PLUGINS)"; fi))
cli-plugin-build: install-registry cli-plugin-builder-install
$(MAKE) $(CLI_PLUGIN_TARGETS)
.PHONY: cli-plugin-build-%
cli-plugin-build-%:
$(MAKE) COMPONENT=cmd/plugin/$* lint
$(MAKE) COMPONENT=cmd/plugin/$* test
$(DOCKER) build --network=host . -f Dockerfile \
--target cli-plugin-build \
--output build \
--build-arg IMGPKG_VERSION=$(IMGPKG_VERSION) \
--build-arg CLI_PLUGIN_VERSION=$(CLI_PLUGIN_VERSION) \
--build-arg OCI_REGISTRY=$(REGISTRY_ENDPOINT) \
--build-arg CLI_PLUGIN=$* \
--build-arg COMPONENT=cmd/plugin/$* \
--build-arg CLI_PLUGIN_GO_FLAGS=$(CLI_PLUGIN_GO_FLAGS)
.PHONY: cli-plugin-publish
cli-plugin-publish: cli-plugin-builder-install
$(DOCKER) build . -f Dockerfile \
--target cli-plugin-publish \
--build-arg IMGPKG_VERSION=$(IMGPKG_VERSION) \
--build-arg REPOSITORY=$(OCI_REGISTRY) \
--build-arg IMGPKG_USERNAME=$(REGISTRY_USERNAME) \
--build-arg IMGPKG_PASSWORD=$(REGISTRY_PASSWORD) \
--build-arg PUBLISHER=$(PUBLISHER) \
--build-arg VENDOR=$(VENDOR) \
--build-arg COMPONENT=cmd/plugin/*
.PHONY: kbld-image-replace
# Add newImage in kbld-config.yaml
kbld-image-replace:
@$(DOCKER) run \
-e OPERATIONS=kbld_replace \
-e KBLD_CONFIG_FILE_PATH=$(KBLD_CONFIG_FILE_PATH) \
-e DEFAULT_IMAGE=$(DEFAULT_IMAGE) \
-e NEW_IMAGE=$(IMAGE) \
-e SRC_PATH=$(SRC_PATH) \
-v /var/run/docker.sock:/var/run/docker.sock \
-v $(PWD):/workspace \
$(PACKAGING_CONTAINER_IMAGE):$(VERSION)
.PHONY: package-bundle-generate
# Generate package bundle for a particular package
package-bundle-generate:
@$(DOCKER) run \
-e OPERATIONS=package_bundle_generate \
-e PACKAGE_NAME=$(PACKAGE_NAME) \
-e THICK=true \
-e OCI_REGISTRY=$(OCI_REGISTRY) \
-e PACKAGE_VERSION=$(PACKAGE_VERSION) \
-e PACKAGE_SUB_VERSION=$(PACKAGE_SUB_VERSION) \
-e SRC_PATH=$(SRC_PATH) \
-v /var/run/docker.sock:/var/run/docker.sock \
-v $(PWD):/workspace \
$(PACKAGING_CONTAINER_IMAGE):$(VERSION)
.PHONY: package-bundle-generate-all
# Generate package bundle for all packages
package-bundle-generate-all:
@$(DOCKER) run \
-e OPERATIONS=package_bundle_all_generate \
-e PACKAGE_REPOSITORY=$(PACKAGE_REPOSITORY) \
-e THICK=true \
-e OCI_REGISTRY=$(OCI_REGISTRY) \
-e PACKAGE_VERSION=$(PACKAGE_VERSION) \
-e PACKAGE_SUB_VERSION=$(PACKAGE_SUB_VERSION) \
-e SRC_PATH=$(SRC_PATH) \
-v /var/run/docker.sock:/var/run/docker.sock \
-v $(PWD):/workspace \
$(PACKAGING_CONTAINER_IMAGE):$(VERSION)
.PHONY: package-bundle-push
# Push a particular package bundle
package-bundle-push:
@$(DOCKER) run \
-e OPERATIONS=package_bundle_push \
-e PACKAGE_NAME=$(PACKAGE_NAME) \
-e OCI_REGISTRY=$(OCI_REGISTRY) \
-e PACKAGE_VERSION=$(PACKAGE_VERSION) \
-e PACKAGE_SUB_VERSION=$(PACKAGE_SUB_VERSION) \
-e REGISTRY_USERNAME=$(REGISTRY_USERNAME) \
-e REGISTRY_PASSWORD=$(REGISTRY_PASSWORD) \
-e REGISTRY_SERVER=$(REGISTRY_SERVER) \
-e SRC_PATH=$(SRC_PATH) \
-v /var/run/docker.sock:/var/run/docker.sock \
-v $(PWD):/workspace \
$(PACKAGING_CONTAINER_IMAGE):$(VERSION)
.PHONY: package-bundle-push-all
# Push all package bundles
package-bundle-push-all:
@$(DOCKER) run \
-e OPERATIONS=package_bundle_all_push \
-e PACKAGE_REPOSITORY=$(PACKAGE_REPOSITORY) \
-e OCI_REGISTRY=$(OCI_REGISTRY) \
-e PACKAGE_VERSION=$(PACKAGE_VERSION) \
-e PACKAGE_SUB_VERSION=$(PACKAGE_SUB_VERSION) \
-e REGISTRY_USERNAME=$(REGISTRY_USERNAME) \
-e REGISTRY_PASSWORD=$(REGISTRY_PASSWORD) \
-e REGISTRY_SERVER=$(REGISTRY_SERVER) \
-e SRC_PATH=$(SRC_PATH) \
-v /var/run/docker.sock:/var/run/docker.sock \
-v $(PWD):/workspace \
$(PACKAGING_CONTAINER_IMAGE):$(VERSION)
.PHONY: repo-bundle-generate
# Generate repo bundle
repo-bundle-generate:
@$(DOCKER) run \
-e OPERATIONS=repo_bundle_generate \
-e PACKAGE_REPOSITORY=$(PACKAGE_REPOSITORY) \
-e OCI_REGISTRY=$(OCI_REGISTRY) \
-e REPO_BUNDLE_VERSION=$(REPO_BUNDLE_VERSION) \
-e REPO_BUNDLE_SUB_VERSION=$(REPO_BUNDLE_SUB_VERSION) \
-e PACKAGE_VALUES_FILE=$(PACKAGE_VALUES_FILE) \
-e SRC_PATH=$(SRC_PATH) \
-v /var/run/docker.sock:/var/run/docker.sock \
-v $(PWD):/workspace \
$(PACKAGING_CONTAINER_IMAGE):$(VERSION)
.PHONY: repo-bundle-push
# Push repo bundle
repo-bundle-push:
@$(DOCKER) run \
-e OPERATIONS=repo_bundle_push \
-e PACKAGE_REPOSITORY=$(PACKAGE_REPOSITORY) \
-e OCI_REGISTRY=$(OCI_REGISTRY) \
-e REPO_BUNDLE_VERSION=$(REPO_BUNDLE_VERSION) \
-e REPO_BUNDLE_SUB_VERSION=$(REPO_BUNDLE_SUB_VERSION) \
-e REGISTRY_USERNAME=$(REGISTRY_USERNAME) \
-e REGISTRY_PASSWORD=$(REGISTRY_PASSWORD) \
-e REGISTRY_SERVER=$(REGISTRY_SERVER) \
-e SRC_PATH=$(SRC_PATH) \
-v /var/run/docker.sock:/var/run/docker.sock \
-v $(PWD):/workspace \
$(PACKAGING_CONTAINER_IMAGE):$(VERSION)
.PHONY: package-vendir-sync
# Performs vendir sync on each package
package-vendir-sync:
@$(DOCKER) run \
-e OPERATIONS=vendir_sync \
-e SRC_PATH=$(SRC_PATH) \
-v /var/run/docker.sock:/var/run/docker.sock \
-v $(PWD):/workspace \
$(PACKAGING_CONTAINER_IMAGE):$(VERSION)
.PHONY: help
# Show help
help:
@cat $(MAKEFILE_LIST) | $(DOCKER) run --rm -i xanders/make-help