mirror of
https://github.com/opentffoundation/opentf.git
synced 2026-02-13 16:00:34 -05:00
Before Go 1.21 we relied on third-party and custom tooling to manage which version of Go we were using for development, testing, and release builds. However, modern Go toolchains have built-in support for selecting an appropriate toolchain based on metadata in the go.mod file, and so we had previously removed most uses of the .go-version file and were maintaining it just as a remnant of the old state of things. This replaces our last remaining use of the ".go-version" file with a small tool that extracts the Go version from the go.mod file, and then removes the ".go-version" file completely. The "go" and "toolchain" directives in go.mod are now our single source of truth about which version of Go we're currently using for OpenTofu. (It may be possible to rework the Dockerfile for the consul backend to handle Go version selection in a different way so that we'd no longer need even this "selected-go-version" tool, but that's beyond the scope of this commit which aims to leave it unmodified to make sure the effective testing behavior for that backend is unchanged for now.) Signed-off-by: Martin Atkins <mart@degeneration.co.uk>
241 lines
8.6 KiB
Makefile
241 lines
8.6 KiB
Makefile
.POSIX:
|
|
|
|
export PATH := $(abspath bin/):${PATH}
|
|
|
|
# Dependency versions
|
|
LICENSEI_VERSION = 0.9.0
|
|
|
|
# run Go tests and generate a coverage report
|
|
#
|
|
# NOTE:
|
|
# The coverage counters are to be updated atomically,
|
|
# which is useful for tests that run in parallel.
|
|
.PHONY: test-with-coverage
|
|
test-with-coverage:
|
|
go test -coverprofile=coverage.out -covermode=atomic ./...
|
|
go tool cover -html=coverage.out -o coverage.html
|
|
|
|
# run the unit tests across all packages in the tofu project
|
|
.PHONY: test
|
|
test:
|
|
go test -v ./...
|
|
|
|
EXT := $(shell go env GOEXE)
|
|
|
|
# build tofu binary in the current directory with the version set to the git tag
|
|
# or commit hash if there is no tag.
|
|
.PHONY: build
|
|
build:
|
|
go build -ldflags "-X main.version=$(shell git describe --tags --always --dirty)" -o tofu$(EXT) ./cmd/tofu
|
|
|
|
# generate runs `go generate` to build the dynamically generated
|
|
# source files, except the protobuf stubs which are built instead with
|
|
# "make protobuf".
|
|
.PHONY: generate
|
|
generate:
|
|
go generate ./...
|
|
|
|
# We separate the protobuf generation because most development tasks on
|
|
# OpenTofu do not involve changing protobuf files and protoc is not a
|
|
# go-gettable dependency and so getting it installed can be inconvenient.
|
|
#
|
|
# If you are working on changes to protobuf interfaces, run this Makefile
|
|
# target to be sure to regenerate all of the protobuf stubs using the expected
|
|
# versions of protoc and the protoc Go plugins.
|
|
.PHONY: protobuf
|
|
protobuf:
|
|
go tool protobuf-compile .
|
|
|
|
# Golangci-lint is installed first and then run twice to cover all platforms.
|
|
.PHONY: golangci-lint
|
|
golangci-lint:
|
|
GOBIN=$(PWD)/tools go install github.com/golangci/golangci-lint/v2/cmd/golangci-lint@v2.6.0
|
|
GOOS=windows tools/golangci-lint${EXT} run --timeout 60m ./...
|
|
GOOS=linux tools/golangci-lint${EXT} run --timeout 60m ./...
|
|
|
|
# Run license check
|
|
.PHONY: license-check
|
|
license-check:
|
|
go mod vendor
|
|
licensei cache --debug
|
|
licensei check --debug
|
|
licensei header --debug
|
|
rm -rf vendor/
|
|
git diff --exit-code
|
|
|
|
# Install dependencies
|
|
deps: bin/licensei
|
|
deps:
|
|
|
|
bin/licensei: bin/licensei-${LICENSEI_VERSION}
|
|
@ln -sf licensei-${LICENSEI_VERSION} bin/licensei
|
|
bin/licensei-${LICENSEI_VERSION}:
|
|
@mkdir -p bin
|
|
curl -sfL https://git.io/licensei | bash -s v${LICENSEI_VERSION}
|
|
@mv bin/licensei $@
|
|
|
|
# disallow any parallelism (-j) for Make. This is necessary since some
|
|
# commands during the build process create temporary files that collide
|
|
# under parallel conditions.
|
|
.NOTPARALLEL:
|
|
|
|
# Integration tests
|
|
#
|
|
|
|
.PHONY: list-integration-tests
|
|
list-integration-tests: ## Lists tests.
|
|
@ grep -h -E '^(test|integration)-.+:.*?## .*$$' $(MAKEFILE_LIST) | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[1m%-30s\033[0m %s\n", $$1, $$2}'
|
|
|
|
# integration test with s3 as backend
|
|
.PHONY: test-s3
|
|
|
|
define infoTestS3
|
|
Test requires:
|
|
* AWS Credentials to be configured
|
|
- https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-files.html
|
|
- https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-envvars.html
|
|
* IAM Permissions in us-west-2
|
|
- S3 CRUD operations on buckets which will follow the pattern tofu-test-*
|
|
- DynamoDB CRUD operations on a Table named dynamoTable
|
|
|
|
endef
|
|
|
|
test-s3: ## Runs tests with s3 bucket as the backend.
|
|
@ $(info $(infoTestS3))
|
|
@ TF_S3_TEST=1 go test ./internal/backend/remote-state/s3/...
|
|
|
|
# integration test with gcp as backend
|
|
.PHONY: test-gcp
|
|
|
|
define infoTestGCP
|
|
This test requires a working set of default credentials on the host.
|
|
You can configure those by running `gcloud auth application-default login`.
|
|
Additionally, you'll need to set the following environment variables:
|
|
- GOOGLE_REGION to a valid GCP region, e.g. us-west1
|
|
- GOOGLE_PROJECT to a valid GCP project ID
|
|
|
|
Note: The GCP tests leave behind a keyring, because those can't easily be deleted. It will be reused across test runs.
|
|
|
|
endef
|
|
|
|
test-gcp: ## Runs tests with gcp as the backend.
|
|
@ $(info $(infoTestGCP))
|
|
@ TF_ACC=1 go test ./internal/backend/remote-state/gcs/...
|
|
@ echo "Note: this test has left behind a keyring, because those can't easily be deleted. It will be reused across test runs."
|
|
|
|
# integration test with postgres as backend
|
|
.PHONY: test-pg test-pg-clean
|
|
|
|
PG_PORT := 5432
|
|
|
|
define infoTestPg
|
|
Test requires:
|
|
* Docker: https://docs.docker.com/engine/install/
|
|
* Port: $(PG_PORT)
|
|
|
|
endef
|
|
|
|
test-pg: ## Runs tests with local Postgres instance as the backend.
|
|
@ $(info $(infoTestPg))
|
|
@ echo "Starting database"
|
|
@ make test-pg-clean
|
|
@ docker run --rm -d --name tofu-pg \
|
|
-p $(PG_PORT):5432 \
|
|
-e POSTGRES_PASSWORD=tofu \
|
|
-e POSTGRES_USER=tofu \
|
|
postgres:16-alpine3.17 1> /dev/null
|
|
@ docker exec tofu-pg /bin/bash -c 'until psql -U tofu -c "\q" 2> /dev/null; do echo "Database is getting ready, waiting"; sleep 1; done'
|
|
@ DATABASE_URL="postgres://tofu:tofu@localhost:$(PG_PORT)/tofu?sslmode=disable" \
|
|
TF_PG_TEST=1 go test ./internal/backend/remote-state/pg/...
|
|
|
|
test-pg-clean: ## Cleans environment after `test-pg`.
|
|
@ docker rm -f tofu-pg 2> /dev/null
|
|
|
|
# integration test with Azure as backend
|
|
.PHONY: test-azure
|
|
|
|
test-azure: ## Directs the developer to follow a runbook describing how to run Azure integration tests.
|
|
@ echo "To run Azure integration tests, please follow the runbook in internal/backend/remote-state/azure/README.md".
|
|
@ exit 1 # don't want the user to miss this
|
|
|
|
# integration test with Consul as backend
|
|
.PHONY: test-consul test-consul-clean
|
|
|
|
define infoTestConsul
|
|
Test requires:
|
|
* Docker: https://docs.docker.com/engine/install/
|
|
|
|
endef
|
|
|
|
GO_VER := `go tool github.com/opentofu/opentofu/tools/selected-go-version`
|
|
|
|
test-consul: ## Runs tests using in docker container using Consul as the backend.
|
|
@ $(info $(infoTestConsul))
|
|
@ echo "Build docker image with Consul and Go v$(GO_VER)"
|
|
@ cd ./internal/backend/remote-state/consul &&\
|
|
docker build --build-arg="GO_VERSION=${GO_VER}" -t tofu-consul --progress=plain . &> /dev/null
|
|
@ echo "Run tests"
|
|
@ docker run --rm --name tofu-consul -v $(PWD):/app -e TF_CONSUL_TEST=1 -t tofu-consul \
|
|
test ./internal/backend/remote-state/consul/...
|
|
|
|
test-consul-clean: ## Cleans environment after `test-consul`.
|
|
@ docker rmi -f tofu-consul:latest
|
|
|
|
# integration test with kubernetes as backend
|
|
.PHONY: test-kubernetes test-kubernetes-clean
|
|
|
|
define infoTestK8s
|
|
Test requires:
|
|
* Git client
|
|
* Docker: https://docs.docker.com/engine/install/
|
|
Note! Please make sure that the docker configurations satisfy requirements: https://kind.sigs.k8s.io/docs/user/quick-start#settings-for-docker-desktop
|
|
|
|
endef
|
|
|
|
KIND_VERSION := v0.20.0
|
|
|
|
test-kubernetes: test-kubernetes-clean ## Runs tests with a local kubernetes cluster as the backend.
|
|
@ $(info $(infoTestK8s))
|
|
@ echo "Installing KinD $(KIND_VERSION): https://kind.sigs.k8s.io/docs/user/quick-start/#installing-with-make"
|
|
@ git clone -c advice.detachedHead=false -q https://github.com/kubernetes-sigs/kind -b $(KIND_VERSION) /tmp/kind-repo 1> /dev/null && \
|
|
cd /tmp/kind-repo &&\
|
|
make build 1> /dev/null &&\
|
|
mv ./bin/kind /tmp/tofuk8s &&\
|
|
cd .. && rm -rf kind-repo
|
|
@ echo "Provisioning a cluster"
|
|
@ /tmp/tofuk8s -q create cluster --name tofu-kubernetes
|
|
@ /tmp/tofuk8s -q export kubeconfig --name tofu-kubernetes --kubeconfig /tmp/tofu-k8s-config
|
|
@ echo "Running tests"
|
|
@ KUBE_CONFIG_PATHS=/tmp/tofu-k8s-config TF_K8S_TEST=1 go test ./internal/backend/remote-state/kubernetes/...
|
|
@ echo "Deleting provisioned cluster"
|
|
@ make test-kubernetes-clean
|
|
|
|
test-kubernetes-clean: ## Cleans environment after `test-kubernetes`.
|
|
@ test -s /tmp/tofu-k8s-config && rm /tmp/tofu-k8s-config || echo "" > /dev/null
|
|
@ test -s /tmp/tofuk8s && (/tmp/tofuk8s -q delete cluster --name tofu-kubernetes && rm /tmp/tofuk8s) || echo "" > /dev/null
|
|
|
|
.PHONY:
|
|
test-linux-install-instructions:
|
|
@cd "$(CURDIR)/website/docs/intro/install" && ./test-install-instructions.sh
|
|
|
|
.PHONY:
|
|
integration-tests: test-s3 test-pg test-consul test-kubernetes integration-tests-clean ## Runs all integration tests test.
|
|
|
|
.PHONY:
|
|
integration-tests-clean: test-pg-clean test-consul-clean test-kubernetes-clean ## Cleans environment after all integration tests.
|
|
|
|
.PHONY: help
|
|
help: ## Prints this help message.
|
|
@echo ""
|
|
@echo "Opentofu Makefile"
|
|
@echo ""
|
|
@echo "Usage: make [target]"
|
|
@echo ""
|
|
@echo "The available targets for execution are listed below."
|
|
@echo ""
|
|
@echo "Targets:"
|
|
@awk 'BEGIN {FS = ":.*$$"; OFS = ""} \
|
|
/^# .*$$/ { doc=$$0; sub(/^# /, "", doc); next } \
|
|
/^[a-zA-Z0-9_-]+:.*## .*$$/ { target=$$1; sub(/:$$/, "", target); desc=$$0; sub(/^[^#]*## /, "", desc); if (!seen[target]++) { printf "\033[1m%-30s\033[0m %s\n", target, desc } } \
|
|
/^[a-zA-Z0-9_-]+:.*$$/ { target=$$1; sub(/:$$/, "", target); if (!seen[target]++) { if (doc != "") { printf "\033[1m%-30s\033[0m %s\n", target, doc; doc="" } else { printf "\033[1m%-30s\033[0m\n", target } } }' $(MAKEFILE_LIST)
|