# Set SHELL to 'strict mode' without using .SHELLFLAGS for max compatibility. # See https://fieldnotes.tech/how-to-shell-for-compatible-makefiles/ SHELL := /usr/bin/env bash -euo pipefail -c CIRCLECI := circleci --skip-update-check # Set up some documentation/help message variables. # We do not attempt to install the CircleCI CLI from this Makefile. CCI_INSTALL_LINK := https://circleci.com/docs/2.0/local-cli/\#installation CCI_INSTALL_MSG := Please install CircleCI CLI. See $(CCI_INSTALL_LINK) CCI_VERSION := $(shell $(CIRCLECI) version 2> /dev/null) ifeq ($(CCI_VERSION),) # Attempting to use the CLI fails with installation instructions. CIRCLECI := echo '$(CCI_INSTALL_MSG)'; exit 1; \# endif SOURCE_DIR := config SOURCE_YML := $(shell [ ! -d $(SOURCE_DIR) ] || find $(SOURCE_DIR) -name '*.yml') CONFIG_SOURCE := Makefile $(SOURCE_YML) | $(SOURCE_DIR) OUT := config.yml TMP := .tmp/config-processed CONFIG_PACKED := .tmp/config-packed default: help help: @echo "Usage:" @echo " make ci-config: recompile config.yml from $(SOURCE_DIR)/" @echo " make ci-verify: verify that config.yml is a true mapping from $(SOURCE_DIR)/" @echo @echo "Diagnostics:" @[ -z "$(CCI_VERSION)" ] || echo " circleci-cli version $(CCI_VERSION)" @[ -n "$(CCI_VERSION)" ] || echo " $(CCI_INSTALL_MSG)" $(SOURCE_DIR): @echo No source directory $(SOURCE_DIR) found.; exit 1 # Make sure our .tmp dir exists. $(shell [ -d .tmp ] || mkdir .tmp) .PHONY: ci-config ci-config: $(OUT) .PHONY: ci-verify ci-verify: config-up-to-date @$(CIRCLECI) config validate $(OUT) define GENERATED_FILE_HEADER ### *** ### WARNING: DO NOT manually EDIT or MERGE this file, it is generated by 'make ci-config'. ### INSTEAD: Edit or merge the source in $(SOURCE_DIR)/ then run 'make ci-config'. ### *** endef export GENERATED_FILE_HEADER # GEN_CONFIG writes the config to a temporary file. If the whole process succeeds, # it then moves that file to $@. This makes is an atomic operation, so if it fails # make doesn't consider a half-baked file up to date. define GEN_CONFIG @$(CIRCLECI) config pack $(SOURCE_DIR) > $(CONFIG_PACKED) @echo "$$GENERATED_FILE_HEADER" > $@.tmp || { rm -f $@; exit 1; } @$(CIRCLECI) config process $(CONFIG_PACKED) >> $@.tmp || { rm -f $@.tmp; exit 1; } @mv -f $@.tmp $@ endef $(OUT): $(CONFIG_SOURCE) $(GEN_CONFIG) @echo "$@ updated" $(TMP): $(CONFIG_SOURCE) $(GEN_CONFIG) .PHONY: config-up-to-date config-up-to-date: $(TMP) # Note this must not depend on $(OUT)! @if diff config.yml $<; then \ echo "Generated $(OUT) is up to date!"; \ else \ echo "Generated $(OUT) is out of date, run make $(CONFIG) to update."; \ exit 1; \ fi