.DEFAULT_GOAL := help # Root directory of the project (absolute path). ROOTDIR=$(dir $(abspath $(lastword $(MAKEFILE_LIST)))) # Used to populate version variable in main package. VERSION ?= $(shell git describe --match 'v[0-9]*' --dirty='.m' --always) REVISION ?= $(shell git rev-parse HEAD)$(shell if ! git diff --no-ext-diff --quiet --exit-code; then echo .m; fi) # default compose command COMPOSE ?= docker compose PKG=github.com/distribution/distribution/v3 # Project packages. PACKAGES=$(shell go list -tags "${BUILDTAGS}" ./... | grep -v /vendor/) INTEGRATION_PACKAGE=${PKG} COVERAGE_PACKAGES=$(filter-out ${PKG}/registry/storage/driver/%,${PACKAGES}) IMAGE_REPO ?= distribution/distribution IMAGE_TAG ?= latest IMAGE_NAME ?= $(IMAGE_REPO):$(IMAGE_TAG) # Project binaries. COMMANDS=registry digest registry-api-descriptor-template # Allow turning off function inlining and variable registerization ifeq (${DISABLE_OPTIMIZATION},true) GO_GCFLAGS=-gcflags "-N -l" VERSION:="$(VERSION)-noopt" endif WHALE = "+" # Go files # TESTFLAGS_RACE= GOFILES=$(shell find . -type f -name '*.go') GO_TAGS=$(if $(BUILDTAGS),-tags "$(BUILDTAGS)",) GO_LDFLAGS=-ldflags '-extldflags "-Wl,-z,now" -s -w -X $(PKG)/version.Version=$(VERSION) -X $(PKG)/version.Revision=$(REVISION) -X $(PKG)/version.Package=$(PKG) $(EXTRA_LDFLAGS)' BINARIES=$(addprefix bin/,$(COMMANDS)) # Flags passed to `go test` TESTFLAGS ?= -v $(TESTFLAGS_RACE) TESTFLAGS_PARALLEL ?= 8 .PHONY: all build binaries clean test test-race test-full integration test-coverage validate lint validate-git validate-vendor vendor mod-outdated image .DEFAULT: all .PHONY: FORCE FORCE: ##@ Build # This only needs to be generated by hand when cutting full releases. version/version.go: @echo "$(WHALE) $@" ./version/version.sh > $@ bin/%: cmd/% FORCE ## build individual binary @echo "$(WHALE) $@${BINARY_SUFFIX}" @go build -buildmode=pie ${GO_GCFLAGS} ${GO_BUILD_FLAGS} -o $@${BINARY_SUFFIX} ${GO_LDFLAGS} --ldflags '-extldflags "-Wl,-z,now" -s' ${GO_TAGS} ./$< binaries: $(BINARIES) ## build binaries @echo "$(WHALE) $@" build: ## build go packages @echo "$(WHALE) $@" @go build -buildmode=pie ${GO_GCFLAGS} ${GO_BUILD_FLAGS} ${GO_LDFLAGS} --ldflags '-extldflags "-Wl,-z,now" -s' ${GO_TAGS} $(PACKAGES) image: ## build docker image IMAGE_NAME= docker buildx bake --set "*.tags=${IMAGE_NAME}" image-local clean: ## clean up binaries @echo "$(WHALE) $@" @rm -f $(BINARIES) vendor: ## update vendor $(eval $@_TMP_OUT := $(shell mktemp -d -t buildx-output.XXXXXXXXXX)) docker buildx bake --set "*.output=$($@_TMP_OUT)" update-vendor rm -rf ./vendor cp -R "$($@_TMP_OUT)"/out/* . rm -rf $($@_TMP_OUT)/* mod-outdated: ## check outdated dependencies docker buildx bake $@ ##@ Test test: ## run tests, except integration test with test.short @echo "$(WHALE) $@" @go test ${GO_TAGS} -test.short ${TESTFLAGS} $(filter-out ${INTEGRATION_PACKAGE},${PACKAGES}) test-race: ## run tests, except integration test with test.short and race @echo "$(WHALE) $@" @go test ${GO_TAGS} -race -test.short ${TESTFLAGS} $(filter-out ${INTEGRATION_PACKAGE},${PACKAGES}) test-full: ## run tests, except integration tests @echo "$(WHALE) $@" @go test ${GO_TAGS} ${TESTFLAGS} $(filter-out ${INTEGRATION_PACKAGE},${PACKAGES}) integration: ## run integration tests @echo "$(WHALE) $@" @go test ${TESTFLAGS} -parallel ${TESTFLAGS_PARALLEL} ${INTEGRATION_PACKAGE} test-coverage: ## run unit tests and generate test coverprofiles @echo "$(WHALE) $@" @rm -f coverage.txt @go test ${GO_TAGS} -i ${TESTFLAGS} $(filter-out ${INTEGRATION_PACKAGE},${COVERAGE_PACKAGES}) 2> /dev/null @( for pkg in $(filter-out ${INTEGRATION_PACKAGE},${COVERAGE_PACKAGES}); do \ go test ${GO_TAGS} ${TESTFLAGS} \ -cover \ -coverprofile=profile.out \ -covermode=atomic $$pkg || exit; \ if [ -f profile.out ]; then \ cat profile.out >> coverage.txt; \ rm profile.out; \ fi; \ done ) .PHONY: test-cloud-storage test-cloud-storage: start-cloud-storage run-s3-tests stop-cloud-storage ## run cloud storage driver tests .PHONY: start-cloud-storage start-cloud-storage: ## start local cloud storage (minio) $(COMPOSE) -f tests/docker-compose-storage.yml up minio minio-init -d .PHONY: stop-cloud-storage stop-cloud-storage: ## stop local cloud storage (minio) $(COMPOSE) -f tests/docker-compose-storage.yml down .PHONY: reset-cloud-storage reset-cloud-storage: ## reset (stop, delete, start) local cloud storage (minio) $(COMPOSE) -f tests/docker-compose-storage.yml down @mkdir -p tests/miniodata/distribution @rm -rf tests/miniodata/distribution/* tests/miniodata/.minio.sys $(COMPOSE) -f tests/docker-compose-storage.yml up minio minio-init -d .PHONY: run-s3-tests run-s3-tests: start-cloud-storage ## run S3 storage driver integration tests AWS_ACCESS_KEY=distribution \ AWS_SECRET_KEY=password \ AWS_REGION=us-east-1 \ S3_BUCKET=images-local \ S3_ENCRYPT=false \ REGION_ENDPOINT=http://127.0.0.1:9000 \ S3_SECURE=false \ S3_ACCELERATE=false \ AWS_S3_FORCE_PATH_STYLE=true \ go test ${TESTFLAGS} -count=1 ./registry/storage/driver/s3-aws/... .PHONY: start-e2e-s3-env start-e2e-s3-env: ## starts E2E S3 storage test environment (S3, Redis, registry) $(COMPOSE) -f tests/docker-compose-e2e-cloud-storage.yml up -d .PHONY: stop-e2e-s3-env stop-e2e-s3-env: ## stops E2E S3 storage test environment (S3, Redis, registry) $(COMPOSE) -f tests/docker-compose-e2e-cloud-storage.yml down ##@ Validate lint: ## run all linters docker buildx bake $@ validate: ## run all validators docker buildx bake $@ validate-git: ## validate git docker buildx bake $@ validate-vendor: ## validate vendor docker buildx bake $@ .PHONY: help help: @awk 'BEGIN {FS = ":.*##"; printf "\nUsage:\n make \033[36m\033[0m\n"} /^[a-zA-Z0-9_\/%-]+:.*?##/ { printf " \033[36m%-27s\033[0m %s\n", $$1, $$2 } /^##@/ { printf "\n\033[1m%s\033[0m\n", substr($$0, 5) } ' $(MAKEFILE_LIST) @echo "" @echo "Go binaries: $(BINARIES)" @echo "Docker image: $(IMAGE_NAME)"