From 85ffdb7096b994094d89d14e5b9c950902d55fc3 Mon Sep 17 00:00:00 2001 From: "aynic.os" Date: Wed, 2 Jun 2021 00:54:33 +0200 Subject: [PATCH] doc --- ansible/roles/aws-cli/tasks/main.yml | 4 +- make/apps/build.mk | 56 ++++++------- make/apps/clean.mk | 10 --- make/apps/common.mk | 150 ++++++++++++++++++++++++++++++----- make/apps/def.docker.mk | 12 ++- make/apps/def.install.mk | 5 +- make/apps/deploy.mk | 33 ++++---- make/apps/docker.mk | 43 +++++++++- make/apps/git.mk | 13 +-- make/apps/install.mk | 16 +++- make/apps/js/clean.mk | 9 --- make/apps/js/dev.mk | 21 ----- make/apps/js/install.mk | 22 ----- make/apps/js/test.mk | 17 ---- make/apps/js/update.mk | 6 -- make/apps/myos/def.ssh.mk | 2 + make/apps/myos/ssh.mk | 6 +- make/apps/php/cache.mk | 17 ---- make/apps/php/clean.mk | 11 --- make/apps/php/def.composer.mk | 24 ------ make/apps/php/def.mk | 7 -- make/apps/php/dev.mk | 10 --- make/apps/php/install.mk | 42 ---------- make/apps/php/test.mk | 44 ---------- make/apps/php/update.mk | 6 -- make/apps/release.mk | 46 +++++++++++ make/apps/subrepo/subrepo.mk | 4 + make/debug.mk | 4 +- make/def.docker.mk | 8 ++ make/def.mk | 30 ++++--- make/env.mk | 27 +++---- make/help.mk | 92 +++++++++++++++------ make/include.mk | 14 ++-- make/monorepo/common.mk | 43 +++++++++- make/monorepo/release.mk | 18 ++--- make/monorepo/subrepo.mk | 22 +++-- make/myos.mk | 1 + make/update.mk | 19 ++++- 38 files changed, 509 insertions(+), 405 deletions(-) delete mode 100644 make/apps/clean.mk delete mode 100644 make/apps/js/clean.mk delete mode 100644 make/apps/js/dev.mk delete mode 100644 make/apps/js/install.mk delete mode 100644 make/apps/js/test.mk delete mode 100644 make/apps/js/update.mk delete mode 100644 make/apps/php/cache.mk delete mode 100644 make/apps/php/clean.mk delete mode 100644 make/apps/php/def.composer.mk delete mode 100644 make/apps/php/def.mk delete mode 100644 make/apps/php/dev.mk delete mode 100644 make/apps/php/install.mk delete mode 100644 make/apps/php/test.mk delete mode 100644 make/apps/php/update.mk create mode 100644 make/apps/release.mk diff --git a/ansible/roles/aws-cli/tasks/main.yml b/ansible/roles/aws-cli/tasks/main.yml index 4a1ffbd..44b519c 100644 --- a/ansible/roles/aws-cli/tasks/main.yml +++ b/ansible/roles/aws-cli/tasks/main.yml @@ -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 diff --git a/make/apps/build.mk b/make/apps/build.mk index 1ec13cc..5f5ff45 100644 --- a/make/apps/build.mk +++ b/make/apps/build.mk @@ -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 \ + ) diff --git a/make/apps/clean.mk b/make/apps/clean.mk deleted file mode 100644 index 3d4ec3c..0000000 --- a/make/apps/clean.mk +++ /dev/null @@ -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') diff --git a/make/apps/common.mk b/make/apps/common.mk index 5a5ff82..f5e5d45 100644 --- a/make/apps/common.mk +++ b/make/apps/common.mk @@ -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)) diff --git a/make/apps/def.docker.mk b/make/apps/def.docker.mk index aaf88bd..1473909 100644 --- a/make/apps/def.docker.mk +++ b/make/apps/def.docker.mk @@ -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))) diff --git a/make/apps/def.install.mk b/make/apps/def.install.mk index a2d49f2..549de60 100644 --- a/make/apps/def.install.mk +++ b/make/apps/def.install.mk @@ -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 diff --git a/make/apps/deploy.mk b/make/apps/deploy.mk index 6b71f9d..0a82558 100644 --- a/make/apps/deploy.mk +++ b/make/apps/deploy.mk @@ -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) \ + ||: ) diff --git a/make/apps/docker.mk b/make/apps/docker.mk index 01924d9..df1685a 100644 --- a/make/apps/docker.mk +++ b/make/apps/docker.mk @@ -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 diff --git a/make/apps/git.mk b/make/apps/git.mk index 5ee4a33..b44c228 100644 --- a/make/apps/git.mk +++ b/make/apps/git.mk @@ -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) diff --git a/make/apps/install.mk b/make/apps/install.mk index d69f9c8..c6e0fd1 100644 --- a/make/apps/install.mk +++ b/make/apps/install.mk @@ -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,$*) diff --git a/make/apps/js/clean.mk b/make/apps/js/clean.mk deleted file mode 100644 index 9bc6292..0000000 --- a/make/apps/js/clean.mk +++ /dev/null @@ -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/*) diff --git a/make/apps/js/dev.mk b/make/apps/js/dev.mk deleted file mode 100644 index c9310d1..0000000 --- a/make/apps/js/dev.mk +++ /dev/null @@ -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) diff --git a/make/apps/js/install.mk b/make/apps/js/install.mk deleted file mode 100644 index e190add..0000000 --- a/make/apps/js/install.mk +++ /dev/null @@ -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) diff --git a/make/apps/js/test.mk b/make/apps/js/test.mk deleted file mode 100644 index 1f79b2b..0000000 --- a/make/apps/js/test.mk +++ /dev/null @@ -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 diff --git a/make/apps/js/update.mk b/make/apps/js/update.mk deleted file mode 100644 index f34ed57..0000000 --- a/make/apps/js/update.mk +++ /dev/null @@ -1,6 +0,0 @@ -## -# UPDATE - -.PHONY: update-npm -update-npm: bootstrap - $(call docker-compose-exec,$(DOCKER_SERVICE),npm upgrade) diff --git a/make/apps/myos/def.ssh.mk b/make/apps/myos/def.ssh.mk index ae4b57f..f20f2a9 100644 --- a/make/apps/myos/def.ssh.mk +++ b/make/apps/myos/def.ssh.mk @@ -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)) diff --git a/make/apps/myos/ssh.mk b/make/apps/myos/ssh.mk index f1c2814..5c058d2 100644 --- a/make/apps/myos/ssh.mk +++ b/make/apps/myos/ssh.mk @@ -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)"'\'')) diff --git a/make/apps/php/cache.mk b/make/apps/php/cache.mk deleted file mode 100644 index 3ae3be8..0000000 --- a/make/apps/php/cache.mk +++ /dev/null @@ -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=$*) diff --git a/make/apps/php/clean.mk b/make/apps/php/clean.mk deleted file mode 100644 index dc54188..0000000 --- a/make/apps/php/clean.mk +++ /dev/null @@ -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/*) diff --git a/make/apps/php/def.composer.mk b/make/apps/php/def.composer.mk deleted file mode 100644 index 7e4c1f6..0000000 --- a/make/apps/php/def.composer.mk +++ /dev/null @@ -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 diff --git a/make/apps/php/def.mk b/make/apps/php/def.mk deleted file mode 100644 index ee81efc..0000000 --- a/make/apps/php/def.mk +++ /dev/null @@ -1,7 +0,0 @@ -BUILD_ENV_VARS += SYMFONY_ENV - -ifneq (,$(filter $(ENV),$(ENV_DEPLOY))) -SYMFONY_ENV ?= prod -else -SYMFONY_ENV ?= dev -endif diff --git a/make/apps/php/dev.mk b/make/apps/php/dev.mk deleted file mode 100644 index c133630..0000000 --- a/make/apps/php/dev.mk +++ /dev/null @@ -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) diff --git a/make/apps/php/install.mk b/make/apps/php/install.mk deleted file mode 100644 index 7fffa3b..0000000 --- a/make/apps/php/install.mk +++ /dev/null @@ -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) diff --git a/make/apps/php/test.mk b/make/apps/php/test.mk deleted file mode 100644 index b55bcb2..0000000 --- a/make/apps/php/test.mk +++ /dev/null @@ -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 diff --git a/make/apps/php/update.mk b/make/apps/php/update.mk deleted file mode 100644 index 522f1b6..0000000 --- a/make/apps/php/update.mk +++ /dev/null @@ -1,6 +0,0 @@ -## -# UPDATE - -.PHONY: update-database -update-database: bootstrap - $(call docker-compose-exec,$(DOCKER_SERVICE),app/console --no-interaction doctrine:migration:migrate) diff --git a/make/apps/release.mk b/make/apps/release.mk new file mode 100644 index 0000000..a0b61a6 --- /dev/null +++ b/make/apps/release.mk @@ -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: $*" diff --git a/make/apps/subrepo/subrepo.mk b/make/apps/subrepo/subrepo.mk index acb43a8..e3ba219 100644 --- a/make/apps/subrepo/subrepo.mk +++ b/make/apps/subrepo/subrepo.mk @@ -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 diff --git a/make/debug.mk b/make/debug.mk index d547481..6462379 100644 --- a/make/debug.mk +++ b/make/debug.mk @@ -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-% ; diff --git a/make/def.docker.mk b/make/def.docker.mk index 1cd3419..b6c316b 100644 --- a/make/def.docker.mk +++ b/make/def.docker.mk @@ -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)) diff --git a/make/def.mk b/make/def.mk index 4df3978..89d6a1f 100644 --- a/make/def.mk +++ b/make/def.mk @@ -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 diff --git a/make/env.mk b/make/env.mk index a5f2ea8..99e759e 100644 --- a/make/env.mk +++ b/make/env.mk @@ -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 diff --git a/make/help.mk b/make/help.mk index 1a5ecf4..ca34746 100644 --- a/make/help.mk +++ b/make/help.mk @@ -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) diff --git a/make/include.mk b/make/include.mk index 83e9fbc..1b3ff42 100644 --- a/make/include.mk +++ b/make/include.mk @@ -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))) diff --git a/make/monorepo/common.mk b/make/monorepo/common.mk index 9178ab1..6bb20fa 100644 --- a/make/monorepo/common.mk +++ b/make/monorepo/common.mk @@ -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) ; diff --git a/make/monorepo/release.mk b/make/monorepo/release.mk index e7cdf2a..3525c91 100644 --- a/make/monorepo/release.mk +++ b/make/monorepo/release.mk @@ -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: $*" diff --git a/make/monorepo/subrepo.mk b/make/monorepo/subrepo.mk index d894b90..f9746fa 100644 --- a/make/monorepo/subrepo.mk +++ b/make/monorepo/subrepo.mk @@ -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,$*)) diff --git a/make/myos.mk b/make/myos.mk index 70d3a46..9c8dea7 100644 --- a/make/myos.mk +++ b/make/myos.mk @@ -1,6 +1,7 @@ ## # MYOS +# target myos-%: call % target in MYOS folder .PHONY: myos-% myos-%: ; ifeq ($(wildcard $(MYOS)),$(MYOS)) diff --git a/make/update.mk b/make/update.mk index c4c3ddd..4e44dac 100644 --- a/make/update.mk +++ b/make/update.mk @@ -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)