This commit is contained in:
aynic.os 2021-06-02 00:54:33 +02:00
parent 8661d103e5
commit 85ffdb7096
38 changed files with 509 additions and 405 deletions

View File

@ -136,9 +136,9 @@
with_items: '{{ec2_tags.tags.services.split(" ")}}'
when: ec2_tags.tags is defined and ec2_tags.tags.env is defined and ec2_tags.tags.services is defined and ec2_tags.tags.user is defined
- name: aws - run make deploy in docker containers
- name: aws - run make deploy-hook in docker containers
delegate_to: "{{ec2_tags.tags.user}}_{{ec2_tags.tags.env}}_{{item|replace('/','_')|regex_replace(':.*','')}}"
raw: "command -v make || exit 0 && make deploy CONTAINER={{ec2_tags.tags.user}}_{{ec2_tags.tags.env}}_{{item|replace('/','_')|regex_replace(':.*','')}} HOST={{ansible_ec2_local_ipv4}}"
raw: "command -v make || exit 0 && make deploy-hook CONTAINER={{ec2_tags.tags.user}}_{{ec2_tags.tags.env}}_{{item|replace('/','_')|regex_replace(':.*','')}} HOST={{ansible_ec2_local_ipv4}}"
tags: 'aws'
with_items: '{{ec2_tags.tags.services.split(" ")}}'
when: ec2_tags.tags is defined and ec2_tags.tags.env is defined and ec2_tags.tags.services is defined and ec2_tags.tags.user is defined

View File

@ -1,46 +1,40 @@
##
# BUILD
# target build: Build application docker images on local host
.PHONY: build
build: docker-compose-build ## Build application docker images
# target build@%: Build application docker images to deploy
.PHONY: build@% app-build
build@%: myos-base
$(eval DRYRUN_IGNORE := true)
$(eval SERVICES ?= $(shell $(call docker-compose,--log-level critical config --services)))
$(eval DRYRUN_IGNORE := false)
$(eval docker_images += $(foreach service,$(SERVICES),$(if $(shell docker images -q $(DOCKER_REPOSITORY)/$(service):$(DOCKER_IMAGE_TAG) 2>/dev/null),$(service))))
$(eval build_app := $(or $(filter $(DOCKER_BUILD_CACHE),false),$(filter-out $(docker_images),$(SERVICES))))
$(if $(build_app),$(call make,build-init app-build),$(if $(filter $(VERBOSE),true),$(foreach service,$(SERVICES),echo "docker image $(DOCKER_REPOSITORY)/$(service):$(DOCKER_IMAGE_TAG) has id $(shell docker images -q $(DOCKER_REPOSITORY)/$(service):$(DOCKER_IMAGE_TAG) 2>/dev/null)" &&) true))
# target build-env: Build .env file in docker $(SERVICE) to deploy
# target build-env: Build .env file in docker SERVICE to deploy
# on local host
.PHONY: build-env
build-env: SERVICE ?= $(DOCKER_SERVICE)
build-env: bootstrap
$(call docker-compose-exec,$(SERVICE),rm -f .env && make .env ENV=$(ENV) && echo BUILD=true >> .env && echo BUILD_DATE='"\'"'$(shell date "+%d/%m/%Y %H:%M:%S %z" 2>/dev/null)'"\'"' >> .env && echo BUILD_STATUS='"\'"'$(shell git status -uno --porcelain 2>/dev/null)'"\'"' >> .env && echo DOCKER=false >> .env && $(foreach var,$(BUILD_ENV_VARS),$(if $($(var)),sed -i '/^$(var)=/d' .env && echo $(var)='$($(var))' >> .env &&)) true)
$(call docker-compose-exec,$(SERVICE), \
rm -f .env \
&& make .env ENV=$(ENV) \
&& echo BUILD=true >> .env \
&& echo BUILD_DATE='"\'"'$(shell date "+%d/%m/%Y %H:%M:%S %z" 2>/dev/null)'"\'"' >> .env \
&& echo BUILD_STATUS='"\'"'$(shell git status -uno --porcelain 2>/dev/null)'"\'"' >> .env \
&& echo DOCKER=false >> .env \
&& $(foreach var,$(BUILD_ENV_VARS), \
$(if $($(var)),sed -i '/^$(var)=/d' .env && echo $(var)='$($(var))' >> .env &&) \
) true \
)
# target build-init: Empty build directory
# on local host
.PHONY: build-init
build-init:
$(ECHO) rm -rf build && $(ECHO) mkdir -p build
# target build-shared: Create shared folder in docker $(SERVICE) to deploy
# target build-shared: Create SHARED folder in docker SERVICE to deploy
# on local host
.PHONY: build-shared
build-shared: SERVICE ?= $(DOCKER_SERVICE)
build-shared: bootstrap
$(call docker-compose-exec,$(SERVICE),mkdir -p /$(notdir $(SHARED)) && $(foreach folder,$(SHARED_FOLDERS),rm -rf $(folder) && mkdir -p $(dir $(folder)) && ln -s /$(notdir $(SHARED))/$(notdir $(folder)) $(folder) &&) true)
# target rebuild: Rebuild application docker images on local host
.PHONY: rebuild
rebuild: docker-compose-rebuild ## Rebuild application dockers images
# target rebuild@%: Rebuild application docker images on local host
.PHONY: rebuild@%
rebuild@%: ## Rebuild application dockers images
$(call make,build@$* DOCKER_BUILD_CACHE=false)
# target rebuild-images: Rebuild docker/* images
.PHONY: rebuild-images
rebuild-images: docker-rebuild-images ## Rebuild docker/* images
$(call docker-compose-exec,$(SERVICE), \
mkdir -p /$(notdir $(SHARED)) \
&& $(foreach folder,$(SHARED_FOLDERS), \
rm -rf $(folder) \
&& mkdir -p $(dir $(folder)) \
&& ln -s /$(notdir $(SHARED))/$(notdir $(folder)) $(folder) \
&& \
) true \
)

View File

@ -1,10 +0,0 @@
##
# CLEAN
.PHONY: clean app-clean
clean: app-clean docker-compose-down .env-clean ## Clean application and docker images
# target clean@%: Clean deployed application and docker images
.PHONY: clean@%
clean@%:
$(call make,docker-compose-down DOCKER_COMPOSE_DOWN_OPTIONS='--rmi all -v')

View File

@ -1,66 +1,155 @@
##
# COMMON
# target bootstrap: Update application files and start dockers
# on local host
.PHONY: bootstrap
bootstrap: bootstrap-git bootstrap-docker app-bootstrap ## Bootstrap application
bootstrap: bootstrap-git bootstrap-docker app-bootstrap ## Update application files and start dockers
# target bootstrap-docker: Build and start application dockers
# on local host
.PHONY: boostrap-docker
bootstrap-docker: docker-network-create
$(call make,docker-compose-up)
# target bootstrap-git: Fire update-app
.PHONY: bootstrap-git
bootstrap-git: bootstrap-git-$(APP_DIR)
bootstrap-git: update-app
# target bootstrap-git-%: Clone GIT_REPOSITORY in folder %
# on local host
.PHONY: bootstrap-git-%
bootstrap-git-%:
if ! git config remote.origin.url > /dev/null ; \
then git clone $(GIT_REPOSITORY) $*; \
then git clone $(QUIET) $(GIT_REPOSITORY) $*; \
fi
# target build: Build application docker images to run
# on local host
.PHONY: build
build: docker-compose-build ## Build application docker images
# target build@%: Build application docker images to deploy of % ENV
# on local host
.PHONY: build@% app-build
build@%: myos-base
$(eval DRYRUN_IGNORE := true)
$(eval SERVICES ?= $(shell $(call docker-compose,--log-level critical config --services)))
$(eval DRYRUN_IGNORE := false)
$(eval docker_images += $(foreach service,$(SERVICES),$(if $(shell docker images -q $(DOCKER_REPOSITORY)/$(service):$(DOCKER_IMAGE_TAG) 2>/dev/null),$(service))))
$(eval build_app := $(or $(filter $(DOCKER_BUILD_CACHE),false),$(filter-out $(docker_images),$(SERVICES))))
$(if $(build_app), \
$(call make,build-init app-build), \
$(if $(filter $(VERBOSE),true), \
$(foreach service,$(SERVICES), \
echo "docker image $(DOCKER_REPOSITORY)/$(service):$(DOCKER_IMAGE_TAG) has id $(shell docker images -q $(DOCKER_REPOSITORY)/$(service):$(DOCKER_IMAGE_TAG) 2>/dev/null)" && \
) true \
) \
)
# target clean: Clean application and docker images
# on local host
.PHONY: clean app-clean
clean: app-clean docker-compose-down .env-clean ## Clean application and docker images
# target clean@%: Clean deployed application and docker images of % ENV
# on local host
.PHONY: clean@%
clean@%:
$(call make,docker-compose-down DOCKER_COMPOSE_DOWN_OPTIONS='--rmi all -v')
# target config: View application docker compose file
# on local host
.PHONY: config
config: docker-compose-config ## View docker compose file
config: docker-compose-config ## View application docker compose file
# target connect: Connect to docker SERVICE
# on local host
.PHONY: connect
connect: docker-compose-connect ## Connect to docker $(SERVICE)
connect: docker-compose-connect ## Connect to docker SERVICE
# target connect@%: Connect to docker SERVICE of % ENV
# on first remote host
.PHONY: connect@%
connect@%: SERVICE ?= $(DOCKER_SERVICE)
connect@%: ## Connect to docker $(SERVICE) on first remote host
connect@%:
$(call make,ssh-connect,$(MYOS),APP SERVICE)
# target deploy: Fire deploy@ENV
.PHONY: deploy
deploy: deploy@$(ENV) ## Deploy application dockers
# target down: Remove application dockers
# on local host
.PHONY: down
down: docker-compose-down ## Remove application dockers
# target exec: Exec command in docker SERVICE
# on local host
.PHONY: exec
exec: ## Exec a command in docker $(SERVICE)
exec: ## Exec command in docker SERVICE
ifneq (,$(filter $(ENV),$(ENV_DEPLOY)))
$(call exec,$(ARGS))
else
$(call make,docker-compose-exec,,ARGS)
endif
# target exec@%: Exec command in docker SERVICE of % ENV
# on all remote hosts
.PHONY: exec@%
exec@%: SERVICE ?= $(DOCKER_SERVICE)
exec@%: ## Exec a command in docker $(SERVICE) on all remote hosts
exec@%:
$(call make,ssh-exec,$(MYOS),APP ARGS SERVICE)
# target install app-install: Install application
# on local host
.PHONY: install app-install
install: app-install ## Install application
# target logs: Display application dockers logs
# on local host
.PHONY: logs
logs: docker-compose-logs ## Display application dockers logs
# target ps: List application dockers
# on local host
.PHONY: ps
ps: docker-compose-ps ## List application dockers
# target rebuild: Rebuild application docker images
# on local host
.PHONY: rebuild
rebuild: docker-compose-rebuild ## Rebuild application dockers images
# target rebuild@%: Rebuild application docker images
# on local host
.PHONY: rebuild@%
rebuild@%:
$(call make,build@$* DOCKER_BUILD_CACHE=false)
# target recreate: Recreate application dockers
# on local host
.PHONY: recreate
recreate: docker-compose-recreate app-start ## Recreate application dockers
# target reinstall: Fire clean and call install target
# on local host
.PHONY: reinstall
reinstall: clean ## Reinstall application
$(call make,.env)
$(call make,install)
# target release: Fire release-create
.PHONY: release
release: release-create ## Create release VERSION
# target restart: Restart application dockers
# on local host
.PHONY: restart
restart: docker-compose-restart app-start ## Restart application
# target run: Run command in a new docker SERVICE
# on local host
.PHONY: run
run: ## Run a command in a new docker
ifneq (,$(filter $(ENV),$(ENV_DEPLOY)))
@ -69,27 +158,34 @@ else
$(call make,docker-compose-run,,ARGS)
endif
# target run@%: Run command in a new docker SERVICE of % ENV
# on all remote hosts
.PHONY: run@%
run@%: SERVICE ?= $(DOCKER_SERVICE)
run@%: ## Run a command on all remote hosts
run@%:
$(call make,ssh-run,$(MYOS),APP ARGS)
# target scale: Scale SERVICE application to NUM dockers
# on local host
.PHONY: scale
scale: docker-compose-scale ## Scale application to NUM dockers
scale: docker-compose-scale ## Scale SERVICE application to NUM dockers
# target ssh@%: Connect to % ENV
# on first remote host
.PHONY: ssh@%
ssh@%: ## Connect to first remote host
ssh@%:
$(call make,ssh,$(MYOS),APP)
# target stack: Call docker-stack function with each value of $(STACK)
# target stack: Call docker-stack for each STACK
## it updates COMPOSE_FILE with all .yml files of the current stack
.PHONY: stack
stack:
$(foreach stackz,$(STACK),$(call docker-stack,$(stackz)))
# target stack-%: Call docker-compose-* command on a given stack
## ex: calling stack-base-up will fire the docker-compose-up target on the base stack
## it splits $* on dashes and extracts stack from the beginning of $* and command
## from the last part of $*
# target stack-%: Call docker-compose-% target on a given stack
## it splits % on dashes and extracts stack from the beginning and command from
## the last part of %
## ex: stack-base-up will fire the docker-compose-up target in the base stack
.PHONY: stack-%
stack-%:
$(eval stack := $(subst -$(lastword $(subst -, ,$*)),,$*))
@ -98,26 +194,40 @@ stack-%:
$(if $(filter $(command),$(filter-out %-%,$(patsubst docker-compose-%,%,$(filter docker-compose-%,$(MAKE_TARGETS))))), \
$(call make,docker-compose-$(command) STACK="$(stack)" $(if $(filter node,$(stack)),COMPOSE_PROJECT_NAME=$(COMPOSE_PROJECT_NAME_NODE)),,ARGS COMPOSE_IGNORE_ORPHANS SERVICE)))
# target start: Start application dockers
# on local host
.PHONY: start
start: docker-compose-start ## Start application dockers
# target stop: Stop application dockers
# on local host
.PHONY: stop
stop: docker-compose-stop ## Stop application dockers
# target tests app-tests: Test application
# on local host
.PHONY: tests app-tests
tests: app-tests ## Test application
# target up: Create and start application dockers
# on local host
.PHONY: up
up: docker-compose-up app-start ## Create application dockers
# target update app-update: Update application files
# on local host
.PHONY: update app-update
update: update-app app-update ## Update application
update: update-app app-update ## Update application files
# target upgrade app-upgrade: Upgrade application
# on local host
.PHONY: upgrade app-upgrade
upgrade: update app-upgrade release-upgrade ## Upgrade application
# target %: Always fired target
## this target is fired everytime make is runned to call the stack target and
## update COMPOSE_FILE variable with all .yml files of the current project stack
## it fires the stack and %-rule-exists targets everytime
%: FORCE stack %-rule-exists ;
# target %-rule-exists: Print a warning message if $* target does not exists
# target %-rule-exists: Print a warning message if % target does not exists
%-rule-exists:
$(if $(filter $*,$(MAKECMDGOALS)),$(if $(filter-out $*,$(MAKE_TARGETS)),printf "${COLOR_BROWN}WARNING${COLOR_RESET}: ${COLOR_GREEN}target${COLOR_RESET} $* ${COLOR_GREEN}not available in app${COLOR_RESET} $(APP).\n" >&2))

View File

@ -72,9 +72,11 @@ endif
ifeq ($(DOCKER), true)
# function docker-compose: Run docker-compose with arg 1
define docker-compose
$(call run,docker/compose:$(COMPOSE_VERSION) $(patsubst %,-f %,$(COMPOSE_FILE)) -p $(COMPOSE_PROJECT_NAME) $(1))
endef
# function docker-compose-exec: Run docker-compose-exec with arg 2 in service 1
define docker-compose-exec
$(call run,docker/compose:$(COMPOSE_VERSION) $(patsubst %,-f %,$(COMPOSE_FILE)) -p $(COMPOSE_PROJECT_NAME) exec -T $(1) sh -c '$(2)')
endef
@ -91,6 +93,7 @@ endef
endif
# function docker-build: Build docker image
define docker-build
$(eval path := $(patsubst %/,%,$(1)))
$(eval tag := $(or $(2),$(DOCKER_REPOSITORY)/$(lastword $(subst /, ,$(path))):$(DOCKER_IMAGE_TAG)))
@ -99,6 +102,7 @@ define docker-build
$(eval build_image := $(or $(filter $(DOCKER_BUILD_CACHE),false),$(if $(image_id),,true)))
$(if $(build_image),$(ECHO) docker build $(DOCKER_BUILD_ARGS) --build-arg DOCKER_BUILD_DIR="$(path)" --tag $(tag) $(if $(target),--target $(target)) -f $(path)/Dockerfile .,$(if $(filter $(VERBOSE),true),echo "docker image $(tag) has id $(image_id)",true))
endef
# function docker-commit: Commit docker image
define docker-commit
$(eval service := $(or $(1),$(DOCKER_SERVICE)))
$(eval container := $(or $(2),$(firstword $(shell $(call docker-compose,--log-level critical ps -q $(service))))))
@ -107,6 +111,7 @@ define docker-commit
$(if $(filter $(VERBOSE),true),echo docker commit $(container) $(repository):$(tag))
$(ECHO) docker commit $(container) $(repository):$(tag)
endef
# function docker-push: Push docker image
define docker-push
$(eval service := $(or $(1),$(DOCKER_SERVICE)))
$(eval name := $(or $(2),$(DOCKER_REGISTRY_REPOSITORY)/$(service)))
@ -114,8 +119,7 @@ define docker-push
$(if $(filter $(VERBOSE),true),echo docker push $(name):$(tag))
$(ECHO) docker push $(name):$(tag)
endef
##
# docker-stack
# function docker-stack: Call itself recursively for each stack to expand stacks
# docker-stack: if 1st arg is a variable and can be expand to values, it calls
# itself again, once whith each value, else calls docker-stack-update function
# 1st arg: stacks, extract it from stack_names:stack_versions
@ -125,8 +129,7 @@ define docker-stack
$(eval versions := $(or $(if $(findstring :,$(1)),$(lastword $(subst :, ,$(1)))),$(2)))
$(if $($(stacks)),$(foreach substack,$($(stacks)),$(call docker-stack,$(substack),$(if $(findstring :,$(1)),$(versions)))),$(call docker-stack-update,$(stacks),$(versions)))
endef
##
# docker-stack-update
# function docker-stack-update: Update COMPOSE_FILE with .yml files of the stack
# docker-stack-update: adds all .yml files of the stack to COMPOSE_FILE variable
# and update the .env file with the .env.dist files of the stack
# 1st arg: stack_path/stack_name:stack_version
@ -144,6 +147,7 @@ define docker-stack-update
$(eval COMPOSE_FILE += $(wildcard $(path)/$(name).yml $(path)/$(name).$(ENV).yml $(path)/$(name).$(ENV).$(version).yml $(path)/$(name).$(version).yml))
$(if $(wildcard $(path)/.env.dist),$(call .env,,$(path)/.env.dist,$(wildcard $(PARAMETERS)/$(ENV)/$(APP)/.env $(path)/.env.$(ENV) .env)))
endef
# function docker-tag: Tag docker image
define docker-tag
$(eval service := $(or $(1),$(DOCKER_SERVICE)))
$(eval source := $(or $(2),$(DOCKER_REPOSITORY)/$(service)))

View File

@ -1,7 +1,8 @@
# function install-parameters: copy PARAMETERS files to application config folder
define install-parameters
$(eval path:=$(or $(1),$(APP)))
$(eval file:=$(or $(2),$(DOCKER_SERVICE)/parameters.yml))
$(eval dest:=$(or $(3),app/config))
$(eval file:=$(or $(2),$(DOCKER_SERVICE)))
$(eval dest:=$(or $(3),config))
$(eval env:=$(or $(4),$(ENV)))
$(if $(wildcard $(dest)/$(file)),,$(if $(wildcard $(PARAMETERS)/$(env)/$(path)/$(file)),$(ECHO) cp -a $(PARAMETERS)/$(env)/$(path)/$(file) $(dest)))
endef

View File

@ -1,24 +1,29 @@
##
# DEPLOY
.PHONY: deploy app-deploy
# target deploy: Run post install hooks in the deployed application
## Called by ansible after creation of the docker application on remote host
deploy: app-deploy deploy-ping ## Run post install hooks in the deployed application
.PHONY: deploy@%
# target deploy@%: Deploy application docker images
## tag and push docker images to docker registry
## run ansible-pull on hosts to pull docker images from the registry
## tag and push docker images as latest to docker registry
## it tags and pushes docker images to docker registry
## it runs ansible-pull on hosts to pull docker images from the registry
## it tags and pushes docker images as latest to docker registry
.PHONY: deploy@%
deploy@%: myos-base build@% ## Deploy application docker images
$(call make,docker-login docker-tag docker-push)
$(call make,myos-ansible-pull@$(ENV) ANSIBLE_DOCKER_IMAGE_TAG=$(VERSION) ANSIBLE_TAGS=aws,,APP AWS_ACCESS_KEY_ID AWS_SECRET_ACCESS_KEY)
$(call make,docker-tag-latest docker-push-latest)
.PHONY: deploy-ping
deploy-ping: deploy-ping-hook
# target deploy-hook: Fire app-deploy deploy-hook-ping
## it is called by ansible in the application dockers launched on remote hosts
.PHONY: deploy-hook app-deploy
deploy-hook: app-deploy deploy-hook-ping
.PHONY: deploy-ping-hook
deploy-ping-hook:
curl -X POST --data-urlencode 'payload={"text": "$(DEPLOY_HOOK_TEXT)"}' $(DEPLOY_HOOK_URL) ||:
# target deploy-hook-ping: Fire deploy-hook-ping-curl
.PHONY: deploy-hook-ping
deploy-hook-ping: deploy-hook-ping-curl
# target deploy-hook-ping-curl: Post install hook to curl DEPLOY_HOOK_URL
.PHONY: deploy-hook-ping-curl
deploy-hook-ping-curl:
$(if $(DEPLOY_HOOK_URL),$(ECHO) curl -X POST --data-urlencode \
'payload={"text": "$(DEPLOY_HOOK_TEXT)"}' \
$(DEPLOY_HOOK_URL) \
||: )

View File

@ -1,10 +1,12 @@
##
# DOCKER
# target docker-build: Fire docker-images-myos and call docker-build-% target for each DOCKER_IMAGES
.PHONY: docker-build
docker-build: docker-images-myos
$(foreach image,$(or $(SERVICE),$(DOCKER_IMAGES)),$(call make,docker-build-$(image)))
# target docker-build-%: Call docker-build for each Dockerfile in docker/% folder
.PHONY: docker-build-%
docker-build-%:
if grep -q DOCKER_REPOSITORY docker/$*/Dockerfile 2>/dev/null; then $(eval DOCKER_BUILD_ARGS:=$(subst $(DOCKER_REPOSITORY),$(DOCKER_REPOSITORY_MYOS),$(DOCKER_BUILD_ARGS))) true; fi
@ -12,6 +14,7 @@ docker-build-%:
$(if $(findstring :,$*),$(eval DOCKERFILES := $(wildcard docker/$(subst :,/,$*)/Dockerfile)),$(eval DOCKERFILES := $(wildcard docker/$*/*/Dockerfile)))
$(foreach dockerfile,$(DOCKERFILES),$(call docker-build,$(dir $(dockerfile)),$(DOCKER_REPOSITORY)/$(word 2,$(subst /, ,$(dir $(dockerfile)))):$(lastword $(subst /, ,$(dir $(dockerfile)))),"") && true)
# target docker-commit: Call docker-commit for each SERVICES
.PHONY: docker-commit
docker-commit:
$(eval DRYRUN_IGNORE := true)
@ -19,6 +22,7 @@ docker-commit:
$(eval DRYRUN_IGNORE := false)
$(foreach service,$(or $(SERVICE),$(SERVICES)),$(call docker-commit,$(service)))
# target docker-commit-%: Call docker-commit with tag % for each SERVICES
.PHONY: docker-commit-%
docker-commit-%:
$(eval DRYRUN_IGNORE := true)
@ -26,6 +30,7 @@ docker-commit-%:
$(eval DRYRUN_IGNORE := false)
$(foreach service,$(or $(SERVICE),$(SERVICES)),$(call docker-commit,$(service),,,$*))
# target docker-compose-build: Fire docker-images-myos and call docker-compose build SERVICE
.PHONY: docker-compose-build
docker-compose-build: docker-images-myos
$(eval DRYRUN_IGNORE := true)
@ -33,15 +38,18 @@ docker-compose-build: docker-images-myos
$(eval DRYRUN_IGNORE := false)
$(call docker-compose,build $(if $(filter $(DOCKER_BUILD_NO_CACHE),true),--pull --no-cache) $(if $(filter $(SERVICE),$(SERVICES)),$(SERVICE)))
# target docker-compose-config: Call docker-compose config
.PHONY: docker-compose-config
docker-compose-config:
$(call docker-compose,config)
# target docker-compose-connect: Call docker-compose exec SERVICE DOCKER_SHELL
.PHONY: docker-compose-connect
docker-compose-connect: SERVICE ?= $(DOCKER_SERVICE)
docker-compose-connect:
$(call docker-compose,exec $(SERVICE) $(DOCKER_SHELL)) || true
# target docker-compose-down: Call docker-compose rm SERVICE or docker-compose down
.PHONY: docker-compose-down
docker-compose-down:
$(eval DRYRUN_IGNORE := true)
@ -49,11 +57,13 @@ docker-compose-down:
$(eval DRYRUN_IGNORE := false)
$(if $(filter $(SERVICE),$(SERVICES)),$(call docker-compose,rm -fs $(SERVICE)),$(call docker-compose,down $(DOCKER_COMPOSE_DOWN_OPTIONS)))
# target docker-compose-exec: Call docker-compose-exec SERVICE ARGS
.PHONY: docker-compose-exec
docker-compose-exec: SERVICE ?= $(DOCKER_SERVICE)
docker-compose-exec:
$(call docker-compose-exec,$(SERVICE),$(ARGS)) || true
# target docker-compose-logs: Call docker-compose logs SERVICE
.PHONY: docker-compose-logs
docker-compose-logs:
$(eval DRYRUN_IGNORE := true)
@ -61,17 +71,21 @@ docker-compose-logs:
$(eval DRYRUN_IGNORE := false)
$(call docker-compose,logs -f --tail=100 $(if $(filter $(SERVICE),$(SERVICES)),$(SERVICE))) || true
# target docker-compose-ps: Call docker-compose ps
.PHONY: docker-compose-ps
docker-compose-ps:
$(call docker-compose,ps)
# target docker-compose-rebuild: Call docker-compose-build target with DOCKER_BUILD_NO_CACHE=true
.PHONY: docker-compose-rebuild
docker-compose-rebuild: docker-images-myos
docker-compose-rebuild:
$(call make,docker-compose-build DOCKER_BUILD_NO_CACHE=true)
# target docker-compose-recreate: Fire docker-compose-rm docker-compose-up
.PHONY: docker-compose-recreate
docker-compose-recreate: docker-compose-rm docker-compose-up
# target docker-compose-restart: Call docker-compose restart SERVICE
.PHONY: docker-compose-restart
docker-compose-restart:
$(eval DRYRUN_IGNORE := true)
@ -79,6 +93,7 @@ docker-compose-restart:
$(eval DRYRUN_IGNORE := false)
$(call docker-compose,restart $(if $(filter $(SERVICE),$(SERVICES)),$(SERVICE)))
# target docker-compose-rm: Call docker-compose rm SERVICE
.PHONY: docker-compose-rm
docker-compose-rm:
$(eval DRYRUN_IGNORE := true)
@ -86,16 +101,19 @@ docker-compose-rm:
$(eval DRYRUN_IGNORE := false)
$(call docker-compose,rm -fs $(if $(filter $(SERVICE),$(SERVICES)),$(SERVICE)))
# target docker-compose-run: Call docker-compose run SERVICE ARGS
.PHONY: docker-compose-run
docker-compose-run: SERVICE ?= $(DOCKER_SERVICE)
docker-compose-run:
$(call docker-compose,run $(SERVICE) $(ARGS))
# target docker-compose-scale: Call docker-compose up --scale SERVICE=NUM
.PHONY: docker-compose-scale
docker-compose-scale: SERVICE ?= $(DOCKER_SERVICE)
docker-compose-scale:
$(call docker-compose,up $(DOCKER_COMPOSE_UP_OPTIONS) --scale $(SERVICE)=$(NUM))
# target docker-compose-start: Call docker-compose start SERVICE
.PHONY: docker-compose-start
docker-compose-start:
$(eval DRYRUN_IGNORE := true)
@ -103,6 +121,7 @@ docker-compose-start:
$(eval DRYRUN_IGNORE := false)
$(call docker-compose,start $(if $(filter $(SERVICE),$(SERVICES)),$(SERVICE)))
# target docker-compose-stop: Call docker-compose stop SERVICE
.PHONY: docker-compose-stop
docker-compose-stop:
$(eval DRYRUN_IGNORE := true)
@ -110,6 +129,7 @@ docker-compose-stop:
$(eval DRYRUN_IGNORE := false)
$(call docker-compose,stop $(if $(filter $(SERVICE),$(SERVICES)),$(SERVICE)))
# target docker-compose-up: Fire docker-image-myos and call docker-compose up SERVICE
.PHONY: docker-compose-up
docker-compose-up: docker-images-myos
$(eval DRYRUN_IGNORE := true)
@ -117,43 +137,53 @@ docker-compose-up: docker-images-myos
$(eval DRYRUN_IGNORE := false)
$(call docker-compose,up $(DOCKER_COMPOSE_UP_OPTIONS) $(if $(filter $(SERVICE),$(SERVICES)),$(SERVICE)))
# target docker-images-myos: Call myos-docker-build-% target for each DOCKER_IMAGES_MYOS
.PHONY: docker-images-myos
docker-images-myos:
$(foreach image,$(subst $(quote),,$(DOCKER_IMAGES_MYOS)),$(call make,myos-docker-build-$(image)))
# target docker-images-rm: Call docker-image-rm-% target for DOCKER_REPOSITORY
.PHONY: docker-images-rm
docker-images-rm:
$(call make,docker-images-rm-$(DOCKER_REPOSITORY)/)
# target docker-images-rm-%: Remove docker images matching %
.PHONY: docker-images-rm-%
docker-images-rm-%:
docker images |awk '$$1 ~ /^$(subst /,\/,$*)/ {print $$3}' |sort -u |while read image; do docker rmi -f $$image; done
# target docker-login: Exec docker login
.PHONY: docker-login
docker-login: myos-base
$(ECHO) docker login
# target docker-network-create: Fire docker-network-create-% for DOCKER_NETWORK
.PHONY: docker-network-create
docker-network-create: docker-network-create-$(DOCKER_NETWORK)
# target docker-network-create-%: Create docker network %
.PHONY: docker-network-create-%
docker-network-create-%:
[ -n "$(shell docker network ls -q --filter name='^$*$$' 2>/dev/null)" ] \
|| { echo -n "Creating docker network $* ... " && $(ECHO) docker network create $* >/dev/null 2>&1 && echo "done" || echo "ERROR"; }
# target docker-network-rm: Fire docker-network-rm-% for DOCKER_NETWORK
.PHONY: docker-network-rm
docker-network-rm: docker-network-rm-$(DOCKER_NETWORK)
# target docker-network-rm-%: Remove docker network %
.PHONY: docker-network-rm-%
docker-network-rm-%:
[ -z "$(shell docker network ls -q --filter name='^$*$$' 2>/dev/null)" ] \
|| { echo -n "Removing docker network $* ... " && $(ECHO) docker network rm $* >/dev/null 2>&1 && echo "done" || echo "ERROR"; }
# target docker-plugin-install: Install docker plugin DOCKER_PLUGIN with DOCKER_PLUGIN_OPTIONS
.PHONY: docker-plugin-install
docker-plugin-install:
$(eval docker_plugin_state := $(shell docker plugin ls | awk '$$2 == "$(DOCKER_PLUGIN)" {print $$NF}') )
$(if $(docker_plugin_state),$(if $(filter $(docker_plugin_state),false),echo -n "Enabling docker plugin $(DOCKER_PLUGIN) ... " && $(ECHO) docker plugin enable $(DOCKER_PLUGIN) >/dev/null 2>&1 && echo "done" || echo "ERROR"),echo -n "Installing docker plugin $(DOCKER_PLUGIN) ... " && $(ECHO) docker plugin install $(DOCKER_PLUGIN_OPTIONS) $(DOCKER_PLUGIN) $(DOCKER_PLUGIN_ARGS) >/dev/null 2>&1 && echo "done" || echo "ERROR")
# target docker-push: Call docker-push for each SERVICES
.PHONY: docker-push
docker-push:
ifneq ($(filter $(DEPLOY),true),)
@ -165,6 +195,7 @@ else
printf "${COLOR_BROWN}WARNING${COLOR_RESET}: ${COLOR_GREEN}target${COLOR_RESET} $@ ${COLOR_GREEN}not enabled in${COLOR_RESET} $(APP).\n" >&2
endif
# target docker-push-%: Call docker-push with tag % for each SERVICES
.PHONY: docker-push-%
docker-push-%:
ifneq ($(filter $(DEPLOY),true),)
@ -176,26 +207,32 @@ else
printf "${COLOR_BROWN}WARNING${COLOR_RESET}: ${COLOR_GREEN}target${COLOR_RESET} $@ ${COLOR_GREEN}not enabled in${COLOR_RESET} $(APP).\n" >&2
endif
# target docker-rebuild: Call docker-build target with DOCKER_BUILD_CAHE=false
.PHONY: docker-rebuild
docker-rebuild:
$(call make,docker-build DOCKER_BUILD_CACHE=false)
# target docker-rebuild-%: Call docker-build-% target with DOCKER_BUILD_CAHE=false
.PHONY: docker-rebuild-%
docker-rebuild-%:
$(call make,docker-build-$* DOCKER_BUILD_CACHE=false)
# target docker-rm: Fire docker-rm-% for COMPOSE_PROJECT_NAME
.PHONY: docker-rm
docker-rm: docker-rm-$(COMPOSE_PROJECT_NAME)
# target docker-rm-%: Remove dockers matching %
.PHONY: docker-rm-%
docker-rm-%:
docker ps -a |awk '$$NF ~ /^$*/ {print $$NF}' |while read docker; do docker rm -f $$docker; done
# target docker-run: Call docker-run-% target with ARGS for SERVICE
.PHONY: docker-run
docker-run: SERVICE ?= $(DOCKER_SERVICE)
docker-run:
$(call make,docker-run-$(SERVICE),,ARGS)
# target docker-run-%: Call docker-run with image % and command ARGS
.PHONY: docker-run-%
docker-run-%: docker-build-%
$(eval command := $(ARGS))
@ -204,6 +241,7 @@ docker-run-%: docker-build-%
$(eval image_id := $(shell docker images -q $(image) 2>/dev/null))
$(call docker-run,$(if $(image_id),$(image),$(path)),$(command))
# target docker-tag: Call docker-tag for each SERVICES
.PHONY: docker-tag
docker-tag:
ifneq ($(filter $(DEPLOY),true),)
@ -215,6 +253,7 @@ else
printf "${COLOR_BROWN}WARNING${COLOR_RESET}: ${COLOR_GREEN}target${COLOR_RESET} $@ ${COLOR_GREEN}not enabled in${COLOR_RESET} $(APP).\n" >&2
endif
# target docker-tag-%: Call docker-tag with target tag % for each SERVICES
.PHONY: docker-tag-%
docker-tag-%:
ifneq ($(filter $(DEPLOY),true),)
@ -226,9 +265,11 @@ else
printf "${COLOR_BROWN}WARNING${COLOR_RESET}: ${COLOR_GREEN}target${COLOR_RESET} $@ ${COLOR_GREEN}not enabled in${COLOR_RESET} $(APP).\n" >&2
endif
# target docker-volume-rm: Fire docker-volume-rm-% for COMPOSE_PROJECT_NAME
.PHONY: docker-volume-rm
docker-volume-rm: docker-volume-rm-$(COMPOSE_PROJECT_NAME)
# target docker-volume-rm-%: Remove docker volumes matching %
.PHONY: docker-volume-rm-%
docker-volume-rm-%:
docker volume ls |awk '$$2 ~ /^$*/ {print $$2}' |sort -u |while read volume; do docker volume rm $$volume; done

View File

@ -1,7 +1,7 @@
##
# GIT
# Create branch $(BRANCH) from upstream/$* branch
# target git-branch-create-upstream-%: Create git BRANCH from upstream/% branch
.PHONY: git-branch-create-upstream-%
git-branch-create-upstream-%: myos-base update-upstream
$(call exec,git fetch --prune upstream)
@ -9,13 +9,13 @@ git-branch-create-upstream-%: myos-base update-upstream
$(call exec,[ $$(git ls-remote --heads upstream $(BRANCH) |wc -l) -eq 0 ] && git push upstream $(BRANCH) || echo Unable to create branch $(BRANCH) on remote upstream.)
$(call exec,git checkout $(BRANCH))
# Delete branch $(BRANCH)
# target git-branch-delete: Delete git BRANCH
.PHONY: git-branch-delete
git-branch-delete: myos-base update-upstream
$(call exec,git rev-parse --verify $(BRANCH) >/dev/null 2>&1 && git branch -d $(BRANCH) || echo Unable to delete branch $(BRANCH).)
$(foreach remote,upstream, $(call exec,[ $$(git ls-remote --heads $(remote) $(BRANCH) |wc -l) -eq 1 ] && git push $(remote) :$(BRANCH) || echo Unable to delete branch $(BRANCH) on remote $(remote).) &&) true
# Merge branch $(BRANCH) into upstream/$* branch
# target git-branch-merge-upstream-%: Merge git BRANCH into upstream/% branch
.PHONY: git-branch-merge-upstream-%
git-branch-merge-upstream-%: myos-base update-upstream
$(call exec,git rev-parse --verify $(BRANCH) >/dev/null 2>&1)
@ -27,19 +27,21 @@ git-branch-merge-upstream-%: myos-base update-upstream
$(call exec,git merge --no-ff --no-edit $(BRANCH))
$(call exec,git push upstream $*)
# target git-stash: git stash
.PHONY: git-stash
git-stash: myos-base git-status
if [ ! $(STATUS) -eq 0 ]; then \
$(call exec,git stash); \
fi
# target git-status: Define STATUS with number of lines of git status
.PHONY: git-status
git-status: myos-base
$(eval DRYRUN_IGNORE := true)
$(eval STATUS := $(shell $(call exec,git status -uno --porcelain 2>/dev/null |wc -l)))
$(eval DRYRUN_IGNORE := false)
# Create $(TAG) tag to reference upstream/$* branch
# target git-tag-create-upstream-%: Create git TAG to reference upstream/% branch
.PHONY: git-tag-create-upstream-%
git-tag-create-upstream-%: myos-base update-upstream
ifneq ($(words $(TAG)),0)
@ -53,7 +55,7 @@ ifneq ($(words $(TAG)),0)
$(call exec,git push --tags upstream $*)
endif
# Merge tag $(TAG) into upstream/$* branch
# target git-tag-merge-upstream-%: Merge git TAG into upstream/% branch
.PHONY: git-tag-merge-upstream-%
git-tag-merge-upstream-%: myos-base update-upstream
ifneq ($(words $(TAG)),0)
@ -63,6 +65,7 @@ ifneq ($(words $(TAG)),0)
$(call exec,git push upstream $*)
endif
# target git-unstash: git stash pop
.PHONY: git-unstash
git-unstash: myos-base
$(eval STATUS ?= 0)

View File

@ -1,15 +1,22 @@
##
# INSTALL
.PHONY: install app-install
install: app-install ## Install application
# target install-mysql-database-%: Import %.mysql.gz to database %
# on local host
## it creates database %
## it creates user % with password % and all privileges on database %
## it imports %.mysql.gz file in database %
.PHONY: install-mysql-database-%
install-mysql-database-%: myos-base
$(call exec,mysql -h mysql -u root -proot $* -e "use $*" >/dev/null 2>&1 || mysql -h mysql -u root -proot mysql -e "create database $* character set utf8 collate utf8_unicode_ci;")
$(call exec,mysql -h mysql -u $* -p$* $* -e "use $*" >/dev/null 2>&1 || mysql -h mysql -u root -proot mysql -e "grant all privileges on $*.* to '\''$*'\''@'\''%'\'' identified by '\''$*'\''; flush privileges;")
$(call exec,[ $$(mysql -h mysql -u $* -p$* $* -e "show tables" 2>/dev/null |wc -l) -eq 0 ] && [ -f "${APP_DIR}/$*.mysql.gz" ] && gzip -cd "${APP_DIR}/$*.mysql.gz" |mysql -h mysql -u root -proot $* || true)
# target install-pgsql-database-%: Import %.pgsql.gz to database %
# on local host
## it creates database %
## it creates user % with password % and all privileges on database %
## it imports %.pgsql.gz file in database %
.PHONY: install-pgsql-database-%
install-pgsql-database-%: myos-base
$(call exec,PGPASSWORD=$* psql -h postgres -U $* template1 -c "\q" >/dev/null 2>&1 || PGPASSWORD=postgres psql -h postgres -U postgres -c "create user $* with createdb password '\''$*'\'';")
@ -17,14 +24,17 @@ install-pgsql-database-%: myos-base
$(call exec,[ $$(PGPASSWORD=$* psql -h postgres -U $* -d $* -c "\d" 2>/dev/null |wc -l) -eq 0 ] && [ -f "${APP_DIR}/$*.pgsql.gz" ] && gzip -cd "${APP_DIR}/$*.pgsql.gz" |PGPASSWORD="postgres" psql -h postgres -U postgres -d $* || true)
$(call exec,[ $$(PGPASSWORD=$* psql -h postgres -U $* -d $* -c "\d" 2>/dev/null |wc -l) -eq 0 ] && [ -f "${APP_DIR}/$*.pgsql" ] && PGPASSWORD="postgres" psql -h postgres -U postgres -c "ALTER ROLE $* WITH SUPERUSER" && PGPASSWORD="postgres" pg_restore -h postgres --no-owner --role=$* -U postgres -d $* ${APP_DIR}/$*.pgsql && PGPASSWORD="postgres" psql -h postgres -U postgres -c "ALTER ROLE $* WITH NOSUPERUSER" || true)
# target install-build-parameters: Call install-parameters with file * and dest build
.PHONY: install-build-parameters
install-build-parameters:
$(call install-parameters,,*,build)
# target install-parameters: Call install-parameters
.PHONY: install-parameters
install-parameters:
$(call install-parameters)
# target install-parameters-%: Call install-parameters with app %
.PHONY: install-parameters-%
install-parameters-%:
$(call install-parameters,$*)

View File

@ -1,9 +0,0 @@
##
# CLEAN
.PHONY: clean-js-app
clean-js-app: clean-js-assets-deps
.PHONY: clean-js-assets-deps
clean-js-assets-deps: bootstrap
$(call docker-compose-exec,$(DOCKER_SERVICE),rm -Rf node_modules/*)

View File

@ -1,21 +0,0 @@
##
# DEV
## Build assets
.PHONY: dev-assets
dev-assets: ## Build assets
$(call docker-compose-exec,$(DOCKER_SERVICE),yarn build:dev:watch)
.PHONY: dev-outdated
dev-outdated:
$(call docker-compose-exec,$(DOCKER_SERVICE),yarn outdated)
# compile webpack assets (REACT)
.PHONY: dev-webpack-compile
dev-webpack-compile: bootstrap ## Compile dev assets
$(call docker-compose-exec,$(DOCKER_SERVICE),yarn encore dev)
# watch webpack assets updates (REACT)
.PHONY: dev-webpack-watch
dev-webpack-watch: bootstrap ## Watch dev assets update
$(call docker-compose-exec,$(DOCKER_SERVICE),yarn encore dev --watch)

View File

@ -1,22 +0,0 @@
##
# INSTALL
.PHONY: install-bower
install-bower: bootstrap
$(call docker-compose-exec,$(DOCKER_SERVICE),npm install bower --allow-root)
$(call docker-compose-exec,$(DOCKER_SERVICE),./node_modules/bower/bin/bower install --allow-root)
.PHONY: install-npm
install-npm: bootstrap
$(call docker-compose-exec,$(DOCKER_SERVICE),npm install)
.PHONY: install-npm-run-build
install-npm-run-build: install-npm-run-build-$(SYMFONY_ENV)
.PHONY: install-npm-run-build-%
install-npm-run-build-%: bootstrap
$(call docker-compose-exec,$(DOCKER_SERVICE),npm run build:$*)
.PHONY: install-yarn
install-yarn: bootstrap
$(call docker-compose-exec,$(DOCKER_SERVICE),yarn install)

View File

@ -1,17 +0,0 @@
##
# TEST
.PHONY: test-assets
test-assets: bootstrap
$(call docker-compose-exec,$(DOCKER_SERVICE),yarn test)
## Run functional tests (make test-func TEST="S01-U1-find-product")
.PHONY: test-func-js
test-func-js: bootstrap ## Run functional tests (js)
ifdef TEST
$(call docker-compose-exec,$(DOCKER_SERVICE),yarn test:func -- --test tests/Functional/specs/$(TEST).js --env $(TESTENV))
else ifdef TESTSUITE
$(call docker-compose-exec,$(DOCKER_SERVICE),yarn test:func -- --tag $(TESTSUITE) --env $(TESTENV))
else
$(call docker-compose-exec,$(DOCKER_SERVICE),yarn test:func -- --env $(TESTENV))
endif

View File

@ -1,6 +0,0 @@
##
# UPDATE
.PHONY: update-npm
update-npm: bootstrap
$(call docker-compose-exec,$(DOCKER_SERVICE),npm upgrade)

View File

@ -7,6 +7,7 @@ SSH_PUBLIC_HOST_KEYS ?= $(SSH_REMOTE_HOSTS) $(SSH_BASTION_HOSTNAME)
SSH_PRIVATE_IP_RANGE ?= 10.10.*
SSH_REMOTE_HOSTS ?= github.com gitlab.com
# function ssh-connect: Exec command on remote hosts with tty
define ssh-connect
$(eval hosts := $(1))
$(eval command := $(2))
@ -15,6 +16,7 @@ define ssh-connect
$(foreach host,$(hosts),$(call exec,ssh -t -q -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no $(user)@$(host) "$(command)") ||) true
endef
# function ssh-exec: Exec command on remote hosts without tty
define ssh-exec
$(eval hosts := $(1))
$(eval command := $(2))

View File

@ -1,18 +1,22 @@
##
# SSH
# target ssh: Call ssh-connect with command SHELL
.PHONY: ssh
ssh: aws-ec2-get-PrivateIpAddress-$(SERVER_NAME)
ssh: aws-ec2-get-PrivateIpAddress-$(SERVER_NAME) ## Connect to first remote host
$(call ssh-connect,$(AWS_INSTANCE_IP),$(SHELL))
# target ssh-connect: Call ssh-connect with command make connect
.PHONY: ssh-connect
ssh-connect: aws-ec2-get-PrivateIpAddress-$(SERVER_NAME)
$(call ssh-connect,$(AWS_INSTANCE_IP),make connect $(if $(SERVICE),SERVICE=$(SERVICE)))
# target ssh-connect: Call ssh-connect with command make exec
.PHONY: ssh-exec
ssh-exec: aws-ec2-get-PrivateIpAddress-$(SERVER_NAME)
$(call ssh-exec,$(AWS_INSTANCE_IP),make exec $(if $(SERVICE),SERVICE=$(SERVICE)) $(if $(ARGS),ARGS='\''"$(ARGS)"'\''))
# target ssh-run: Call ssh-connect with command make run
.PHONY: ssh-run
ssh-run: aws-ec2-get-PrivateIpAddress-$(SERVER_NAME)
$(call ssh-exec,$(AWS_INSTANCE_IP),make run $(if $(SERVICE),SERVICE=$(SERVICE)) $(if $(ARGS),ARGS='\''"$(ARGS)"'\''))

View File

@ -1,17 +0,0 @@
##
# CACHE
## Clear symfony cache
.PHONY: cache-clear
cache-clear: cache-clear-$(SYMFONY_ENV)
.PHONY: cache-clear-%
cache-clear-%: bootstrap ## Clear symfony cache
$(call docker-compose-exec,$(DOCKER_SERVICE),app/console cache:clear --env=$*)
.PHONY: cache-warmup
cache-warmup: cache-warmup-$(SYMFONY_ENV)
.PHONY: cache-warmup-%
cache-warmup-%: bootstrap
$(call docker-compose-exec,$(DOCKER_SERVICE),app/console cache:warmup --env=$*)

View File

@ -1,11 +0,0 @@
##
# CLEAN
.PHONY: app-symfony-clean
app-symfony-clean: bootstrap
$(call docker-compose-exec,$(DOCKER_SERVICE),rm -rf app/bootstrap.php.cache)
$(call docker-compose-exec,$(DOCKER_SERVICE),rm -rf app/cache/* app/cach~)
$(call docker-compose-exec,$(DOCKER_SERVICE),rm -rf app/logs/*)
$(call docker-compose-exec,$(DOCKER_SERVICE),rm -rf var/cache/* var/cach~)
$(call docker-compose-exec,$(DOCKER_SERVICE),rm -rf var/logs/*)
$(call docker-compose-exec,$(DOCKER_SERVICE),rm -rf vendor/*)

View File

@ -1,24 +0,0 @@
COMPOSER_ARGS ?= --optimize-autoloader
COMPOSER_MEMORY_LIMIT ?= -1
CONTEXT += COMPOSER_ARGS
ifeq ($(SYMFONY_ENV), prod)
COMPOSER_ARGS += --classmap-authoritative --prefer-dist --no-dev --no-interaction
endif
ifeq ($(DRONE), true)
COMPOSER_ARGS += --no-progress
endif
define composer
$(call docker-compose-exec,$(DOCKER_SERVICE),COMPOSER_MEMORY_LIMIT=$(COMPOSER_MEMORY_LIMIT) SYMFONY_ENV=$(SYMFONY_ENV) composer $(1) $(COMPOSER_ARGS))
endef
define composer-require-vendor-binary
$(eval vendor:=$(1))
$(eval binary:=$(or $(2),$(lastword $(subst /, ,$(vendor)))))
$(eval version:=$(or $(addprefix :,$(3)),$(shell awk '/'$(subst /,\\/,$(vendor))'/ {gsub("[\",]","",$$2); print ":"$$2}' composer.json 2>/dev/null)))
$(eval DRYRUN_IGNORE := true)
$(eval COMPOSER_REQUIRE := $(shell $(call docker-compose-exec,$(DOCKER_SERVICE),[ -f vendor/$(vendor)/$(binary) ] || echo true)))
$(eval DRYRUN_IGNORE := false)
$(if $(COMPOSER_REQUIRE),$(call docker-compose-exec,$(DOCKER_SERVICE),mkdir -p vendor/$(vendor) && cd /tmp && COMPOSER_MEMORY_LIMIT=$(COMPOSER_MEMORY_LIMIT) SYMFONY_ENV=$(SYMFONY_ENV) composer require "$(vendor)$(version)" --prefer-source --no-interaction --dev && cd - && ln -s /tmp/vendor/$(vendor)/$(binary) vendor/$(vendor)/$(binary)))
endef

View File

@ -1,7 +0,0 @@
BUILD_ENV_VARS += SYMFONY_ENV
ifneq (,$(filter $(ENV),$(ENV_DEPLOY)))
SYMFONY_ENV ?= prod
else
SYMFONY_ENV ?= dev
endif

View File

@ -1,10 +0,0 @@
##
# DEV
.PHONY: dev-phpcs
dev-phpcs: bootstrap install-phpcs
$(call docker-compose-exec,$(DOCKER_SERVICE),bin/phpcs --standard=PSR2 --colors -p ./src)
.PHONY: dev-phpcbf
dev-phpcbf: bootstrap install-phpcbf
$(call docker-compose-exec,$(DOCKER_SERVICE),bin/phpcbf ./src/ --ignore=*.js)

View File

@ -1,42 +0,0 @@
##
# INSTALL
.PHONY: install-assets
install-assets: install-assets-$(SYMFONY_ENV)
.PHONY: install-assets-%
install-assets-%: bootstrap
$(call docker-compose-exec,$(DOCKER_SERVICE),app/console assetic:dump --env=$*)
$(call docker-compose-exec,$(DOCKER_SERVICE),app/console assets:install --env=$*)
.PHONY: install-codecept
install-codecept: bootstrap install-phpunit vendor/codeception/codeception/codecept
vendor/codeception/codeception/codecept:
$(call composer-require-vendor-binary,codeception/codeception,codecept)
.PHONY: install-composer
install-composer: bootstrap
$(call composer,install)
.PHONY: install-doctrine-schema-update
install-doctrine-schema-update: bootstrap
$(call docker-compose-exec,$(DOCKER_SERVICE),php app/console doctrine:schema:update --force)
.PHONY: install-phpcbf
install-phpcbf: bootstrap vendor/squizlabs/php_codesniffer/bin/phpcbf
vendor/squizlabs/php_codesniffer/bin/phpcbf:
$(call composer-require-vendor-binary,squizlabs/php_codesniffer,bin/phpcbf)
.PHONY: install-phpcs
install-phpcs: bootstrap vendor/squizlabs/php_codesniffer/bin/phpcs
vendor/squizlabs/php_codesniffer/bin/phpcs:
$(call composer-require-vendor-binary,squizlabs/php_codesniffer,bin/phpcs)
.PHONY: install-phpunit
install-phpunit: bootstrap vendor/phpunit/phpunit/phpunit
vendor/phpunit/phpunit/phpunit:
$(call composer-require-vendor-binary,phpunit/phpunit)

View File

@ -1,44 +0,0 @@
##
# TEST
## Run unit tests
.PHONY: test
test: test-unit ## Run unit tests
## Run codeception tests
.PHONY: test-codeception-%
test-codeception-%: bootstrap install-codecept ## Run codeception tests
$(call docker-compose-exec,$(DOCKER_SERVICE),bin/codecept run $*)
## Run old unit tests with code coverage
.PHONY: test-coverage
test-coverage: bootstrap install-phpunit ## Run code coverage
$(call docker-compose-exec,$(DOCKER_SERVICE),bin/phpunit --testsuite unit --coverage-text)
## Run codeception tests with coverage
.PHONY: test-coverage-codeception-%
test-coverage-codeception-%: bootstrap install-codecept ## Run codeception tests with coverage
$(call docker-compose-exec,$(DOCKER_SERVICE),bin/codecept run $* --coverage --coverage-html)
## Run phpunit functional tests
.PHONY: test-func
test-func: bootstrap install-phpunit ## Run functional tests
$(call docker-compose-exec,$(DOCKER_SERVICE),bin/phpunit --testsuite functional)
## Run search tests
.PHONY: test-search
test-search: bootstrap install-phpunit ## Run search tests
$(call docker-compose-exec,$(DOCKER_SERVICE),bin/phpunit --testsuite search)
.PHONY: test-templates
test-templates: bootstrap
$(call docker-compose-exec,$(DOCKER_SERVICE),php app/console lint:twig @UIBundle)
## Run old unit tests
.PHONY: test-unit
test-unit: bootstrap install-phpunit ## Run unit tests
ifdef FILTER
$(call docker-compose-exec,$(DOCKER_SERVICE),bin/phpunit --testsuite unit --filter $(FILTER))
else
$(call docker-compose-exec,$(DOCKER_SERVICE),bin/phpunit --testsuite unit)
endif

View File

@ -1,6 +0,0 @@
##
# UPDATE
.PHONY: update-database
update-database: bootstrap
$(call docker-compose-exec,$(DOCKER_SERVICE),app/console --no-interaction doctrine:migration:migrate)

46
make/apps/release.mk Normal file
View File

@ -0,0 +1,46 @@
##
# RELEASE
# target release-check: Define RELEASE_BRANCH and RELEASE_VERSION
.PHONY: release-check
release-check:
ifneq ($(words $(ARGS)),0)
$(eval RELEASE_VERSION := $(word 1, $(ARGS)))
$(eval RELEASE_BRANCH := release/$(RELEASE_VERSION))
else
ifneq ($(findstring $(firstword $(subst /, ,$(BRANCH))),release),)
$(eval RELEASE_BRANCH := $(BRANCH))
$(eval RELEASE_VERSION := $(word 2, $(subst /, ,$(BRANCH))))
endif
endif
$(if $(filter VERSION=%,$(MAKEFLAGS)), $(eval RELEASE_VERSION:=$(VERSION)) $(eval RELEASE_BRANCH := release/$(RELEASE_VERSION)))
$(if $(findstring $(firstword $(subst /, ,$(RELEASE_BRANCH))),release),,$(error Please provide a VERSION or a release BRANCH))
# target release-create: Create release VERSION from upstream/wip branch
.PHONY: release-create
release-create: release-check git-stash
$(call make,git-branch-create-upstream-wip BRANCH=$(RELEASE_BRANCH))
$(call make,git-unstash,,STATUS)
# target release-finish: Merge release VERSION in master branch
.PHONY: release-finish
release-finish: release-check git-stash
$(call make,git-branch-merge-upstream-master BRANCH=$(RELEASE_BRANCH))
$(call make,git-tag-create-upstream-master TAG=$(RELEASE_VERSION))
$(call make,git-tag-merge-upstream-wip TAG=$(RELEASE_VERSION))
$(call make,git-branch-delete BRANCH=$(RELEASE_BRANCH))
$(call make,git-unstash,,STATUS)
# target release-update: Update RELEASE with RELEASE_VERSION in .env
.PHONY: release-update
release-update:
$(ECHO) awk -v s=RELEASE=$(RELEASE_VERSION) '/^RELEASE=/{$$0=s;f=1} {a[++n]=$$0} END{if(!f)a[++n]=s;for(i=1;i<=n;i++)print a[i]>ARGV[1]}' .env
# target release-upgrade: Run migration targets to upgrade specific releases
.PHONY: release-upgrade
release-upgrade: $(patsubst %,release-upgrade-from-%,$(RELEASE_UPGRADE)) release-update ## Upgrade release
# target release-upgrade-from-%: Sample of catch-all release migration target
.PHONY: release-upgrade-from-%
release-upgrade-from-%:
echo "Upgrading from release: $*"

View File

@ -1,17 +1,21 @@
##
# SUBREPO
# target subrepo-branch-delete subrepo-branch-deletes: Call subrepo-branch-delete target in folder ..
.PHONY: subrepo-branch-delete subrepos-branch-delete
subrepo-branch-delete subrepos-branch-delete:
$(call make,subrepo-branch-delete,..,SUBREPO BRANCH)
# target subrepo-push subrepos-push: Call subrepo-push target in folder ..
.PHONY: subrepo-push subrepos-push
subrepo-push subrepos-push:
$(call make,subrepo-push,..,SUBREPO BRANCH)
# target subrepo-tag-create-% subrepos-tag-create-%: Call subrepo-tag-create-% target in folder ..
.PHONY: subrepo-tag-create-% subrepos-tag-create-%
subrepo-tag-create-% subrepos-tag-create-%:
$(call make,subrepo-tag-create-$*,..,SUBREPO TAG)
# target subrepo-update subrepos-update: Fire bootstrap-git git-stash subrepo-push git-unstash
.PHONY: subrepo-update subrepos-update
subrepo-update subrepos-update: bootstrap-git git-stash subrepo-push git-unstash

View File

@ -1,9 +1,11 @@
##
# DEBUG
# target debug: Print more informations
.PHONY: debug
debug:
$(MAKE) DEBUG=true
$(MAKE) doc help DEBUG=true
# target debug-%: Print value of %
.PHONY: debug-%
debug-%: context-% ;

View File

@ -36,18 +36,22 @@ ifeq ($(DOCKER), true)
DOCKER_SSH_AUTH := -e SSH_AUTH_SOCK=/tmp/ssh-agent/socket -v $(DOCKER_VOLUME_SSH):/tmp/ssh-agent
# function docker-run: Run new DOCKER_IMAGE:DOCKER_IMAGE_TAG docker with arg 2
define docker-run
$(call run,$(or $(1),$(DOCKER_IMAGE):$(DOCKER_IMAGE_TAG)) $(2))
endef
ifeq ($(DRONE), true)
# function exec: Run new DOCKER_IMAGE docker with arg 1
define exec
$(call run,$(DOCKER_SSH_AUTH) $(DOCKER_IMAGE) sh -c '$(or $(1),$(SHELL))')
endef
else
# function exec: Exec arg 1 in docker DOCKER_NAME
define exec
$(ECHO) docker exec $(DOCKER_EXEC_OPTIONS) $(DOCKER_ENV) $(DOCKER_RUN_WORKDIR) $(DOCKER_NAME) sh -c '$(or $(1),$(SHELL))'
endef
endif
# function run: Pass arg 1 to docker run
define run
$(ECHO) docker run $(DOCKER_RUN_OPTIONS) $(DOCKER_ENV) $(DOCKER_RUN_VOLUME) $(DOCKER_RUN_WORKDIR) $(1)
endef
@ -55,18 +59,22 @@ endef
else
SHELL := /bin/bash
# function docker-run: Run new DOCKER_IMAGE:DOCKER_IMAGE_TAG docker with arg 2
define docker-run
$(ECHO) docker run $(DOCKER_RUN_OPTIONS) $(DOCKER_ENV) $(DOCKER_RUN_VOLUME) $(DOCKER_RUN_WORKDIR) $(or $(1),$(DOCKER_IMAGE):$(DOCKER_IMAGE_TAG)) $(2)
endef
# function exec: Call run with arg 1
define exec
$(call run,sh -c '$(or $(1),$(SHELL))')
endef
# function run: Exec arg 1
define run
IFS=$$'\n'; env $(env_reset) $(env) $(1)
endef
endif
# function docker-volume-copy: Copy files from a docker volume to another
define docker-volume-copy
$(eval from := $(1))
$(eval to := $(2))

View File

@ -11,7 +11,7 @@ BRANCH ?= $(shell git rev-parse --abbrev-ref HEAD 2>/de
CMDS ?= exec exec:% exec@% run run:% run@%
COMMIT ?= $(shell git rev-parse $(BRANCH) 2>/dev/null)
CONTEXT ?= $(if $(APP),APP BRANCH VERSION) $(shell awk 'BEGIN {FS="="}; $$1 !~ /^(\#|$$)/ {print $$1}' .env.dist 2>/dev/null)
CONTEXT_DEBUG ?= APPS GIT_AUTHOR_EMAIL GIT_AUTHOR_NAME MAKEFILE_LIST MAKE_DIR MAKE_SUBDIRS MAKE_CMD_ARGS MAKE_ENV_ARGS MONOREPO_DIR UID USER env
CONTEXT_DEBUG ?= MAKEFILE_LIST env APPS GIT_AUTHOR_EMAIL GIT_AUTHOR_NAME LOG_LEVEL MAKE_DIR MAKE_SUBDIRS MAKE_CMD_ARGS MAKE_ENV_ARGS MONOREPO_DIR UID USER
DEBUG ?= false
DOCKER ?= true
DOMAIN ?= localhost
@ -32,6 +32,7 @@ GIT_REPOSITORY ?= $(if $(SUBREPO),$(shell awk -F ' = ' '$$1 ~ /
GIT_UPSTREAM_REPOSITORY ?= $(if $(findstring ://,$(GIT_REPOSITORY)),$(call pop,$(call pop,$(GIT_REPOSITORY)))/,$(call pop,$(GIT_REPOSITORY),:):)$(GIT_UPSTREAM_USER)/$(lastword $(subst /, ,$(GIT_REPOSITORY)))
GIT_UPSTREAM_USER ?= $(or $(MONOREPO),$(USER))
HOSTNAME ?= $(shell hostname 2>/dev/null |sed 's/\..*//')
LOG_LEVEL ?= $(if $(filter false,$(VERBOSE)),error,$(if $(filter true,$(DEBUG)),debug))
MAKE_ARGS ?= $(foreach var,$(MAKE_VARS),$(if $($(var)),$(var)='$($(var))'))
MAKE_SUBDIRS ?= $(if $(filter myos,$(MYOS)),monorepo,$(if $(APP),apps $(foreach type,$(APP_TYPE),$(if $(wildcard $(MAKE_DIR)/apps/$(type)),apps/$(type)))))
MAKE_CMD_ARGS ?= $(foreach var,$(MAKE_CMD_VARS),$(var)='$($(var))')
@ -55,7 +56,7 @@ SUBREPO ?= $(if $(wildcard .gitrepo),$(notdir $(CURDIR))
TAG ?= $(shell git tag -l --points-at $(BRANCH) 2>/dev/null)
UID ?= $(shell id -u 2>/dev/null)
USER ?= $(shell id -nu 2>/dev/null)
VERBOSE ?= true
VERBOSE ?= false
VERSION ?= $(shell git describe --tags $(BRANCH) 2>/dev/null || git rev-parse $(BRANCH) 2>/dev/null)
ifeq ($(DOCKER), true)
@ -100,6 +101,8 @@ SED_SUFFIX := '\'\''
endif
endif
# function conf: Extract variable=value line from configuration files
## it prints the line with variable 3 definition from block 2 in file 1
define conf
$(eval file := $(1))
$(eval block := $(2))
@ -126,13 +129,15 @@ define conf
done < "$(file)"
endef
# macro force: Run command sine die
# return never
## it starts command if it is not already running
force = $$(while true; do [ $$(ps x |awk 'BEGIN {nargs=split("'"$$*"'",args)} $$field == args[1] { matched=1; for (i=1;i<=NF-field;i++) { if ($$(i+field) == args[i+1]) {matched++} } if (matched == nargs) {found++} } END {print found+0}' field=4) -eq 0 ] && $(ECHO) $(command) || sleep 1; done)
# macro gid: Return GID of group 1
gid = $(shell grep '^$(1):' /etc/group 2>/dev/null |awk -F: '{print $$3}')
##
# function make
## call make with predefined options and variables
# function make: Call make with predefined options and variables
# 1st arg: make command line (targets and arguments)
# 2nd arg: directory to call make from
# 3rd arg: list of variables to pass to make (ENV by default)
@ -158,11 +163,14 @@ define make
$(if $(filter $(DRYRUN_RECURSIVE),true),$(MAKE) $(MAKE_DIR) $(patsubst %,-o %,$(MAKE_OLDFILE)) MAKE_OLDFILE="$(MAKE_OLDFILE)" DRYRUN=$(DRYRUN) RECURSIVE=$(RECURSIVE) $(MAKE_ARGS) $(cmd))
endef
# macro pop: Return last word of string 1 according to separator 2
pop = $(patsubst %$(or $(2),/)$(lastword $(subst $(or $(2),/), ,$(1))),%,$(1))
# macro sed: Exec sed script 1 on file 2
sed = $(call exec,sed -i $(SED_SUFFIX) '\''$(1)'\'' $(2))
# set ENV=$(env) for target ending with :$(env) and call $* target
# function TARGET:ENV: Create a new target ending with :env
## it sets ENV, ENV_FILE and calls original target
define TARGET:ENV
.PHONY: $(TARGET)
$(TARGET): $(ASSIGN_ENV)
@ -171,12 +179,14 @@ $(TARGET):
$$(call make,$$*,,ENV_FILE)
endef
# eval each target:$(env) targets
# override value of $(ENV) with $(env)
# override values of .env files with $(PARAMETERS)/$(env)/$(APP)/.env file
# set ENV=env for targets ending with :env
## for each env in ENV_LIST
## it overrides value of ENV with env
## it adds $(PARAMETERS)/$(env)/$(APP)/.env file to ENV_FILE
## it evals TARGET:ENV
$(foreach env,$(ENV_LIST),$(eval TARGET := %\:$(env)) $(eval ASSIGN_ENV := ENV:=$(env)) $(eval ASSIGN_ENV_FILE := ENV_FILE+=$(wildcard $(PARAMETERS)/$(env)/$(APP)/.env)) $(eval $(TARGET:ENV)))
# set ENV=$(env) for each target ending with @$(env)
# set ENV=env for targets ending with @env
$(foreach env,$(ENV_LIST),$(eval %@$(env): ENV:=$(env)))
# Accept arguments for CMDS targets and turn them into do-nothing targets

View File

@ -1,9 +1,12 @@
##
# target .env:
# update .env file when .env.dist file is newer
# ENV
# target .env: Update .env
## it updates .env file when .env.dist file is newer
.env: .env.dist
$(call .env,,,$(wildcard $(PARAMETERS)/$(ENV)/$(APP)/.env .env.$(ENV)))
# target .env-clean: Remove .env
.PHONY: .env-clean
.env-clean:
rm -f .env || true
@ -20,20 +23,19 @@ env.docker = $(env.docker.args) $(env.docker.dist) $(env.docker.file)
env.args = $(foreach var,$(ENV_VARS),$(if $($(var)),$(var)='$($(var))'))
env.dist = $(shell printenv |awk -F '=' 'NR == FNR { if($$1 !~ /^(\#|$$)/) { A[$$1]; next } } ($$1 in A)' .env.dist - 2>/dev/null)
env.file = $(shell cat $(wildcard $(ENV_FILE)) 2>/dev/null |sed '/^[ \t]*$$/d;/^[ \t]*\#/d;')
env.file = $(shell cat $(ENV_FILE) 2>/dev/null |sed '/^[ \t]*$$/d;/^[ \t]*\#/d;')
env.docker.args = $(foreach var,$(ENV_VARS),$(if $($(var)),-e $(var)='$($(var))'))
env.docker.dist = $(shell printenv |awk -F '=' 'NR == FNR { if($$1 !~ /^(\#|$$)/) { A[$$1]; next } } ($$1 in A) {print "-e "$$0}' .env.dist - 2>/dev/null)
env.docker.file = $(patsubst %,--env-file %,$(wildcard $(ENV_FILE)))
SHELL:=/bin/bash
##
# function .env
## set .env file path and call .env_update function if .env.dist file exists
# function .env: Call .env_update function
## it sets .env, .env.dist and .env.ENV files paths
## it calls .env_update function if .env.dist file exists
# 1st arg: path to .env file to update, default to .env
# 2nd arg: path to .env.dist file, default to .env.dist
# 3rd arg: path to .env override files, default to .env.$(ENV)
# if .env.dist exists then call .env_update function
define .env
$(eval env_file:=$(or $(1),.env))
$(eval env_dist:=$(or $(2),$(env_file).dist))
@ -41,9 +43,7 @@ define .env
$(if $(wildcard $(env_dist)), $(call .env_update))
endef
##
# function .env_update
## update .env file with vars from .env.dist not set in environment.
# function .env_update: Update .env file with values from .env.dist
## this function adds variables from the .env.dist to the .env file
## and does substitution to replace variables with their value when
## adding it to the .env. It reads variables first from environment,
@ -53,14 +53,13 @@ endef
# create the .env file
# read environment variables
# keep variables from .env.dist that does not exist in environment
# add variables definition from .env override files at the beginning of the list
# add variables definition from make command line at the beginning of the list
# add variables definition from .env override files at the beginning
# add variables definition from make command line at the beginning
# remove duplicate variables
# keep variables that exists in .env.dist
# keep variables that does not exist in .env
# read variables definition in a subshell with multiline support
# create a new environment (empty if $(ENV_RESET) is true) with
# $(env.args)
# create a new (empty if ENV_RESET is true) environment with env.args
# read environment variables and keep only those existing in .env.dist
# add .env overrides variables definition
# add .env.dist variables definition

View File

@ -1,3 +1,6 @@
##
# HELP
.DEFAULT_GOAL := help
COLOR_RESET ?= \033[0m
COLOR_GREEN ?= \033[32m
@ -5,36 +8,79 @@ COLOR_BROWN ?= \033[33m
COLOR_BLUE ?= \033[36m
.PHONY: FORCE
##
# HELP
# target blank1 blank2: Print new line
.PHONY: blank1 blank2
blank1 blank2:
printf "\n"
# target context: Call context-% for each CONTEXT
.PHONY: context
context:
printf "${COLOR_BROWN}Context:${COLOR_RESET}\n"
$(MAKE) $(foreach var,$(CONTEXT),$(if $($(var)),context-$(var))) FORCE
# target context-%: Print % value
.PHONY: context-%
context-%:
printf "${COLOR_BLUE}%-37s${COLOR_RESET}" $*
printf "${COLOR_GREEN}"
$(call PRINTF,$($*))
printf "${COLOR_RESET}"
# target doc: Fire functions macros target variables
doc: functions macros targets variables ;
# target doc: Fire functions-% macros-% target-% variables-%
doc-%: functions-% macros-% targets-% variables-%;
# target help: Fire usage blank1 target blank2 context
.PHONY: help
help: usage blank1 target blank2 context ## This help
# target functions: Fire functions-.
.PHONY: functions
functions: functions-.
# target functions-%: Print documented functions starting with %
.PHONY: functions-%
functions-%:
awk 'BEGIN {FS = ": "}; $$0 ~ /^# function $*.*:.*$$/ {printf "${COLOR_BLUE}%-39s${COLOR_RESET} %s\n", $$1, $$2}' $(MAKEFILE_LIST)
# target macros: Fire macros-.
.PHONY: macros
macros: macros-.
# target macros-%: Print documented macros starting with %
.PHONY: macros-%
macros-%:
awk 'BEGIN {FS = ": "}; $$0 ~ /^# macro $*.*:.*$$/ {printf "${COLOR_BLUE}%-39s${COLOR_RESET} %s\n", $$1, $$2}' $(MAKEFILE_LIST)
# target target: Show common targets
.PHONY: target
target:
printf "${COLOR_BROWN}Targets:${COLOR_RESET}\n"
awk 'BEGIN {FS = ":.*?## "}; $$0 ~ /^[a-zA-Z_-]+:.*?## .*$$/ {printf "${COLOR_BLUE}%-39s${COLOR_RESET} %s\n", $$1, $$2}' $(MAKEFILE_LIST)
# target targets: Fire targets-.
.PHONY: targets
targets: targets-.
# target targets-%: Print documented targets
.PHONY: targets-%
targets-%:
awk 'BEGIN {FS = ": "}; $$0 ~ /^# target $*.*:.*$$/ {printf "${COLOR_BLUE}%-39s${COLOR_RESET} %s\n", $$1, $$2}' $(MAKEFILE_LIST)
# target usage: Print Usage
.PHONY: usage
usage:
printf "${COLOR_BROWN}Usage:${COLOR_RESET}\n"
printf "make [target]\n"
.PHONY: blank1 blank2
blank1 blank2:
printf "\n"
# target variables: Fire variables-.
.PHONY: variables
variables: variables-.
.PHONY: target
## Show available targets
target:
printf "${COLOR_BROWN}Targets:${COLOR_RESET}\n"
awk 'BEGIN {FS = ":.*?## "}; $$0 ~ /^[a-zA-Z_-]+:.*?## .*$$/ {printf "${COLOR_BLUE}%-31s${COLOR_RESET} %s\n", $$1, $$2}' $(MAKEFILE_LIST)
.PHONY: context
## Show current context
context:
printf "${COLOR_BROWN}Context:${COLOR_RESET}\n"
$(MAKE) $(foreach var,$(CONTEXT),$(if $($(var)),context-$(var))) FORCE
.PHONY: context-%
context-%:
printf "${COLOR_BLUE}%-31s${COLOR_RESET}" $*
printf "${COLOR_GREEN}"
$(call PRINTF,$($*))
printf "${COLOR_RESET}"
# target variables-%: Show documented variables
.PHONY: variables-%
variables-%:
awk 'BEGIN {FS = ": "}; $$0 ~ /^# variable $*.*:.*$$/ {printf "${COLOR_BLUE}%-39s${COLOR_RESET} %s\n", $$1, $$2}' $(MAKEFILE_LIST)

View File

@ -1,11 +1,13 @@
# MAKE_DIR: directory path of this file
##
# INCLUDE
# variable MAKE_DIR: Directory path of this file
MAKE_DIR := $(patsubst %/,%,$(dir $(lastword $(MAKEFILE_LIST))))
# MAKE_FILES: list of first files to load
# variable MAKE_FILES: List of first files to load
MAKE_FILES := env.mk def.mk $(wildcard def.*.mk)
# include *.mk files
## $(MAKE_DIR)/$(MAKE_FILES) $(MAKE_DIR)/*.mk
## it includes $(MAKE_DIR)/$(MAKE_FILES) $(MAKE_DIR)/*.mk
include $(wildcard $(patsubst %,$(MAKE_DIR)/%,$(MAKE_FILES))) $(filter-out $(wildcard $(patsubst %,$(MAKE_DIR)/%,$(notdir $(lastword $(MAKEFILE_LIST))) $(MAKE_FILES))),$(wildcard $(MAKE_DIR)/*.mk))
## $(MAKE_DIR)/*/def.mk $(MAKE_DIR)/*/def.*.mk $(MAKE_DIR)/*/*.mk
## it includes $(MAKE_DIR)/*/def.mk $(MAKE_DIR)/*/def.*.mk $(MAKE_DIR)/*/*.mk
include $(foreach subdir,$(MAKE_SUBDIRS),$(wildcard $(MAKE_DIR)/$(subdir)/def.mk $(MAKE_DIR)/$(subdir)/def.*.mk) $(filter-out $(wildcard $(MAKE_DIR)/$(subdir)/def.mk $(MAKE_DIR)/$(subdir)/def.*.mk),$(wildcard $(MAKE_DIR)/$(subdir)/*.mk)))
## def.mk def.*.mk *.mk */def.mk */def.*.mk */*.mk
## it includes def.mk def.*.mk *.mk */def.mk */def.*.mk */*.mk
include $(wildcard def.mk def.*.mk) $(filter-out $(wildcard def.mk def.*.mk),$(wildcard *.mk)) $(filter-out $(wildcard $(MAKE_DIR)/*.mk),$(wildcard */def.mk */def.*.mk) $(filter-out $(wildcard */def.mk */def.*.mk),$(wildcard */*.mk)))

View File

@ -1,67 +1,102 @@
##
# COMMON
# target build: Fire APPS target
.PHONY: build
build: $(APPS) ## Build applications
# target build@%: Fire APPS target
.PHONY: build@%
build@%: $(APPS);
# target clean: Fire APPS target
.PHONY: clean
clean: $(APPS) ## Clean applications
# target clean@%: Fire APPS target
.PHONY: clean@%
clean@%: $(APPS);
# target config: Fire APPS target
.PHONY: config
config: $(APPS)
# target copy: Copy files and folders to all APPS
.PHONY: copy
copy:
$(foreach app,$(APPS),$(foreach file,$(ARGS),$(if $(wildcard $(file)),$(ECHO) $(if $(filter LINUX,$(HOST_SYSTEM)),cp -a --parents $(file) $(app)/,rsync -a $(file) $(app)/$(file)) &&)) true &&) true
# target deploy: Fire APPS target
.PHONY: deploy
deploy: $(APPS) ## Deploy applications
# target deploy@%: Fire APPS target
.PHONY: deploy@%
deploy@%: $(APPS);
# target down: Fire APPS target
.PHONY: down
down: $(APPS) ## Remove application dockers
down: $(APPS) ## Remove applications dockers
# target install: Fire APPS target
.PHONY: install
install: $(APPS) ## Install applications
# target ps: Fire APPS target
.PHONY: ps
ps: $(APPS)
# target rebuild: Fire APPS target
.PHONY: rebuild
rebuild: $(APPS) ## Rebuild applications
# target recreate: Fire APPS target
.PHONY: recreate
recreate: $(APPS) ## Recreate applications
# target reinstall: Fire APPS target
.PHONY: reinstall
reinstall: $(APPS) ## Reinstall applications
# target release: Fire release-create target
.PHONY: release
release: release-create ## Create release VERSION
# target restart: Fire APPS target
.PHONY: restart
restart: $(APPS) ## Restart applications
# target start: Fire APPS target
.PHONY: start
start: $(APPS) ## Start applications
# target stop: Fire APPS target
.PHONY: stop
stop: $(APPS) ## Stop applications
# target tests: Fire APPS target
.PHONY: tests
tests: $(APPS) ## Test applications
# target up: Fire APPS target
.PHONY: up
up: $(APPS) ## Create application dockers
up: $(APPS) ## Create applications dockers
# target update: Fire update-apps target
.PHONY: update
update: update-apps ## Update applications files
# target upgrade: Fire upgrade-apps and release-upgrade targets
.PHONY: upgrade
upgrade: upgrade-apps release-upgrade ## Upgrade applications
# target $(APPS): Call targets MAKECMDGOALS in folder $@
.PHONY: $(APPS)
$(APPS):
$(if $(wildcard $@/Makefile), \
$(call make,$(patsubst apps-%,%,$(MAKECMDGOALS)) STATUS=0,$(patsubst %/,%,$@),APP_PATH_PREFIX), \
printf "${COLOR_BROWN}WARNING${COLOR_RESET}: ${COLOR_GREEN}no app available in folder${COLOR_RESET} $@.\n" >&2)
# run targets in $(APPS)
# target apps-%: Fire $(APPS) target to call target % in $(APPS)
.PHONY: apps-%
apps-%: $(APPS) ; ## run % targets in $(APPS)
apps-%: $(APPS) ;

View File

@ -1,9 +1,7 @@
##
# RELEASE
.PHONY: release
release: release-create ## Create release [version]
# target release-check: Define RELEASE_BRANCH and RELEASE_VERSION
.PHONY: release-check
release-check:
ifneq ($(words $(ARGS)),0)
@ -18,13 +16,15 @@ endif
$(if $(filter VERSION=%,$(MAKEFLAGS)), $(eval RELEASE_VERSION:=$(VERSION)) $(eval RELEASE_BRANCH := release/$(RELEASE_VERSION)))
$(if $(findstring $(firstword $(subst /, ,$(RELEASE_BRANCH))),release),,$(error Please provide a VERSION or a release BRANCH))
# target release-create: Create release VERSION from upstream/develop branch
.PHONY: release-create
release-create: release-check git-stash ## Create release [version]
release-create: release-check git-stash
$(call make,git-branch-create-upstream-develop BRANCH=$(RELEASE_BRANCH))
$(call make,git-unstash,,STATUS)
# target release-finish: Merge release VERSION in master branch
.PHONY: release-finish
release-finish: release-check git-stash ## Finish release [version]
release-finish: release-check git-stash
$(call make,git-branch-merge-upstream-master BRANCH=$(RELEASE_BRANCH))
$(call make,subrepos-update)
$(call make,git-tag-create-upstream-master TAG=$(RELEASE_VERSION))
@ -34,16 +34,16 @@ release-finish: release-check git-stash ## Finish release [version]
$(call make,subrepos-branch-delete BRANCH=$(RELEASE_BRANCH))
$(call make,git-unstash,,STATUS)
## Update release version number in .env
# target release-update: Update RELEASE with RELEASE_VERSION in .env
.PHONY: release-update
release-update:
$(ECHO) awk -v s=RELEASE=$(RELEASE_VERSION) '/^RELEASE=/{$$0=s;f=1} {a[++n]=$$0} END{if(!f)a[++n]=s;for(i=1;i<=n;i++)print a[i]>ARGV[1]}' .env
## Run migration targets to upgrade specific releases
# target release-upgrade: Run migration targets to upgrade specific releases
.PHONY: release-upgrade
release-upgrade: $(patsubst %,release-upgrade-from-%,$(RELEASE_UPGRADE)) release-update ## Update monorepo version
release-upgrade: $(patsubst %,release-upgrade-from-%,$(RELEASE_UPGRADE)) release-update ## Upgrade release
## Sample of release migration target
# target release-upgrade-from-%: Sample of catch-all release migration target
.PHONY: release-upgrade-from-%
release-upgrade-from-%:
echo "Upgrading from release: $*"

View File

@ -1,13 +1,14 @@
##
# SUBREPO
## Delete branch $(BRANCH) on $(SUBREPO) remote
# target subrepo-branch-delete: Delete branch $(BRANCH) on remote $(SUBREPO)
.PHONY: subrepo-branch-delete
subrepo-branch-delete: myos-base subrepo-check
ifneq ($(words $(BRANCH)),0)
$(call exec,[ $$(git ls-remote --heads $(REMOTE) $(BRANCH) |wc -l) -eq 1 ] && git push $(REMOTE) :$(BRANCH) || echo Unable to delete branch $(BRANCH) on remote $(REMOTE).)
endif
# target subrepo-check: Define SUBREPO and REMOTE
.PHONY: subrepo-check
subrepo-check:
ifeq ($(words $(ARGS)), 0)
@ -18,28 +19,31 @@ endif
$(eval SUBREPO ?= $(word 1, $(ARGS)))
$(eval REMOTE := subrepo/$(SUBREPO))
## Check if monorepo is up to date with subrepo. subrepo-push saves the parent commit in file subrepo/.gitrepo
# target subrepo-git-diff: Check if monorepo is up to date with subrepo
# subrepo-push saves the parent commit in file subrepo/.gitrepo
## it gets parent commit in .gitrepo : awk '$1 == "parent" {print $3}' subrepo/.gitrepo
## it gets child of parent commit : git rev-list --ancestry-path parent..HEAD |tail -n 1
## it compares child commit with our tree : git diff --quiet child -- subrepo
.PHONY: subrepo-git-diff
subrepo-git-diff: myos-base subrepo-check
## Get parent commit in .gitrepo : awk '$1 == "parent" {print $3}' subrepo/.gitrepo
## Get child of parent commit : git rev-list --ancestry-path parent..HEAD |tail -n 1
## Compare child commit with our tree : git diff --quiet child -- subrepo
$(eval DRYRUN_IGNORE := true)
$(eval DIFF = $(shell $(call exec,git diff --quiet $(shell $(call exec,git rev-list --ancestry-path $(shell awk '$$1 == "parent" {print $$3}' $(SUBREPO)/.gitrepo)..HEAD |tail -n 1)) -- $(SUBREPO); echo $$?)) )
$(eval DRYRUN_IGNORE := false)
# target subrepo-git-fetch: Fetch git remote
.PHONY: subrepo-git-fetch
subrepo-git-fetch: myos-base subrepo-check
$(call exec,git fetch --prune $(REMOTE))
# target subrepo-tag-create-%: Create tag TAG to reference branch REMOTE/%
.PHONY: subrepo-tag-create-%
subrepo-tag-create-%: myos-base subrepo-check subrepo-git-fetch ## Create $(TAG) tag to reference $(REMOTE)/$* branch
subrepo-tag-create-%: myos-base subrepo-check subrepo-git-fetch
ifneq ($(words $(TAG)),0)
$(call exec,[ $$(git ls-remote --tags $(REMOTE) $(TAG) |wc -l) -eq 0 ] || git push $(REMOTE) :refs/tags/$(TAG))
$(call exec,git push $(REMOTE) refs/remotes/subrepo/$(SUBREPO)/$*:refs/tags/$(TAG))
endif
## Push to subrepo.
# target subrepo-push: Push to subrepo
.PHONY: subrepo-push
subrepo-push: myos-base subrepo-check subrepo-git-fetch subrepo-git-diff
# update .gitrepo only on master branch
@ -66,16 +70,20 @@ endif
$(call exec,git subrepo clean $(SUBREPO)); \
fi
# target subrepos-branch-delete: Fire APPS target
.PHONY: subrepos-branch-delete
subrepos-branch-delete: $(APPS) ;
# target subrepos-tag-create-%: Fire APPS target
.PHONY: subrepos-tag-create-%
subrepos-tag-create-%: $(APPS) ;
# target subrepos-update: Fire APPS target and push updates to upstream
.PHONY: subrepos-update
subrepos-update: myos-base git-stash $(APPS) git-unstash ## Update subrepos
$(call exec,git push upstream $(BRANCH))
# target subrepo-update-%: Call subrepo-update target in folder %
.PHONY: subrepo-update-%
subrepo-update-%:
$(if $(wildcard $*/Makefile),$(call make,subrepo-update,$*))

View File

@ -1,6 +1,7 @@
##
# MYOS
# target myos-%: call % target in MYOS folder
.PHONY: myos-%
myos-%: ;
ifeq ($(wildcard $(MYOS)),$(MYOS))

View File

@ -1,53 +1,68 @@
##
# UPDATE
# target update-apps: Call update-app target for each APPS
.PHONY: update-apps
update-apps:
$(foreach app,$(APPS),$(call make,update-app APP_NAME=$(app)))
# target update-app: Fire update-app-% for APP_NAME
.PHONY: update-app
update-app: update-app-$(APP_NAME) ; ## Update application source files
update-app: update-app-$(APP_NAME) ;
# target update-app-%: Fire % target
.PHONY: update-app-%
update-app-%: myos-base % ;
# target $(APP): Clone or pull application files
.PHONY: $(APP)
$(APP): APP_DIR := $(RELATIVE)$(APP)
$(APP):
$(call exec,[ -d $(APP_DIR) ] && cd $(APP_DIR) && git pull $(QUIET) origin $(BRANCH) || git clone $(QUIET) $(APP_REPOSITORY) $(APP_DIR))
## Update /etc/hosts
# target update-hosts: Update /etc/hosts
# on local host
## it reads .env files to extract applications hostnames and add it to /etc/hosts
.PHONY: update-hosts
update-hosts:
ifneq (,$(filter $(ENV),local))
cat */.env 2>/dev/null |grep -Eo 'urlprefix-[^/]+' |sed 's/urlprefix-//' |while read host; do grep $$host /etc/hosts >/dev/null 2>&1 || { echo "Adding $$host to /etc/hosts"; echo 127.0.0.1 $$host |$(ECHO) sudo tee -a /etc/hosts >/dev/null; }; done
endif
# target update-parameters: Fire PARAMETERS
.PHONY: update-parameters
update-parameters: $(PARAMETERS)
# target $(PARAMETERS): Clone or pull parameters files
.PHONY: $(PARAMETERS)
$(PARAMETERS): SSH_PUBLIC_HOST_KEYS := $(PARAMETERS_REMOTE_HOST) $(SSH_BASTION_HOSTNAME) $(SSH_REMOTE_HOSTS)
$(PARAMETERS): MAKE_VARS += SSH_BASTION_HOSTNAME SSH_BASTION_USERNAME SSH_PRIVATE_IP_RANGE SSH_PUBLIC_HOST_KEYS
$(PARAMETERS): myos-base
$(call exec,[ -d $(PARAMETERS) ] && cd $(PARAMETERS) && git pull --quiet || git clone --quiet $(APP_PARAMETERS_REPOSITORY))
# target update-remote-%: fetch git remote %
.PHONY: update-remote-%
update-remote-%: myos-base
$(call exec,git fetch --prune --tags $*)
# target update-remotes: fetch all git remotes
.PHONY: update-remotes
update-remotes: myos-base
$(call exec,git fetch --all --prune --tags)
# target update-upstream: fetch git remote upstream
.PHONY: update-upstream
update-upstream: myos-base .git/refs/remotes/upstream/master
$(call exec,git fetch --prune --tags upstream)
# target .git/refs/remotes/upstream/master: git add upstream APP_UPSTREAM_REPOSITORY
.git/refs/remotes/upstream/master: myos-base
$(call exec,git remote add upstream $(APP_UPSTREAM_REPOSITORY) 2>/dev/null ||:)
# target shared: Fire SHARED
.PHONY: update-shared
update-shared: $(SHARED)
# target $(SHARED): Create SHARED folder
$(SHARED):
$(ECHO) mkdir -p $(SHARED)