1
0

Makefile 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297
  1. ###############################
  2. # Common defaults/definitions #
  3. ###############################
  4. comma := ,
  5. empty :=
  6. space := $(empty) $(empty)
  7. # Checks two given strings for equality.
  8. eq = $(if $(or $(1),$(2)),$(and $(findstring $(1),$(2)),\
  9. $(findstring $(2),$(1))),1)
  10. # Maps platform identifier to the one accepted by Docker CLI.
  11. dockerify = $(strip $(if $(call eq,$(1),linux/arm32v6),linux/arm/v6,\
  12. $(if $(call eq,$(1),linux/arm32v7),linux/arm/v7,\
  13. $(if $(call eq,$(1),linux/arm64v8),linux/arm64/v8,\
  14. $(if $(call eq,$(1),linux/i386), linux/386,\
  15. $(platform))))))
  16. ######################
  17. # Project parameters #
  18. ######################
  19. COTURN_VER ?= 4.7.0
  20. COTURN_MIN_VER = $(strip $(shell echo $(COTURN_VER) | cut -d '.' -f1,2))
  21. COTURN_MAJ_VER = $(strip $(shell echo $(COTURN_VER) | cut -d '.' -f1))
  22. ALPINE_VER := alpine$(strip $(shell grep -m1 'alpine_ver=' alpine/Dockerfile \
  23. | cut -d '=' -f2 \
  24. | cut -d '.' -f1,2))
  25. DEBIAN_VER := $(strip $(shell grep -m1 'debian_ver=' debian/Dockerfile \
  26. | cut -d '=' -f2))
  27. BUILD_REV ?= 4
  28. NAME := coturn
  29. OWNER := $(or $(GITHUB_REPOSITORY_OWNER),coturn)
  30. REGISTRIES := $(strip $(subst $(comma), ,\
  31. $(shell grep -m1 'registry: \["' ../../.github/workflows/docker.yml \
  32. | cut -d':' -f2 | tr -d '"][')))
  33. ALL_IMAGES := \
  34. debian:$(COTURN_VER)-r$(BUILD_REV)-debian,$(COTURN_VER)-debian,$(COTURN_MIN_VER)-debian,$(COTURN_MAJ_VER)-debian,debian,$(COTURN_VER)-$(DEBIAN_VER),$(COTURN_MIN_VER)-$(DEBIAN_VER),$(COTURN_MAJ_VER)-$(DEBIAN_VER),$(DEBIAN_VER),$(COTURN_VER)-r$(BUILD_REV),$(COTURN_VER),$(COTURN_MIN_VER),$(COTURN_MAJ_VER),latest \
  35. alpine:$(COTURN_VER)-r$(BUILD_REV)-alpine,$(COTURN_VER)-alpine,$(COTURN_MIN_VER)-alpine,$(COTURN_MAJ_VER)-alpine,alpine,$(COTURN_VER)-$(ALPINE_VER),$(COTURN_MIN_VER)-$(ALPINE_VER),$(COTURN_MAJ_VER)-$(ALPINE_VER),$(ALPINE_VER)
  36. # <Dockerfile>:<version>,<tag1>,<tag2>,...
  37. # Default is first image from ALL_IMAGES list.
  38. DOCKERFILE ?= $(word 1,$(subst :, ,$(word 1,$(ALL_IMAGES))))
  39. TAGS ?= $(word 1,$(subst |, ,\
  40. $(word 2,!$(subst $(DOCKERFILE):, ,$(subst $(space),|,$(ALL_IMAGES))))))
  41. VERSION ?= $(word 1,$(subst -, ,$(TAGS)))-$(word 2,$(strip \
  42. $(subst -, ,$(subst $(comma), ,$(TAGS)))))
  43. ###########
  44. # Aliases #
  45. ###########
  46. image: docker.image
  47. manifest: docker.manifest
  48. push: docker.push
  49. release: git.release
  50. tags: docker.tags
  51. test: test.docker
  52. ###################
  53. # Docker commands #
  54. ###################
  55. docker-registries = $(strip \
  56. $(or $(subst $(comma), ,$(registries)),$(REGISTRIES)))
  57. docker-tags = $(strip $(or $(subst $(comma), ,$(tags)),$(TAGS)))
  58. # Build single-platform Docker image with the given tag.
  59. #
  60. # Usage:
  61. # make docker.image [dockerfile=(debian|alpine)]
  62. # [tag=($(VERSION)|<docker-tag>)]] [no-cache=(no|yes)]
  63. # [platform=<os>/<arch>]
  64. # [ref=<git-ref>]
  65. github_url := $(strip $(or $(GITHUB_SERVER_URL),https://github.com))
  66. github_repo := $(strip $(or $(GITHUB_REPOSITORY),$(OWNER)/$(NAME)))
  67. docker.image:
  68. cd ../../ && \
  69. docker buildx build --force-rm \
  70. $(if $(call eq,$(platform),),,--platform $(call dockerify,$(platform)))\
  71. $(if $(call eq,$(no-cache),yes),--no-cache --pull,) \
  72. $(if $(call eq,$(ref),),,--build-arg coturn_git_ref=$(ref)) \
  73. --build-arg coturn_github_url=$(github_url) \
  74. --build-arg coturn_github_repo=$(github_repo) \
  75. --label org.opencontainers.image.source=$(github_url)/$(github_repo) \
  76. --label org.opencontainers.image.revision=$(strip \
  77. $(shell git show --pretty=format:%H --no-patch)) \
  78. --label org.opencontainers.image.version=$(subst docker/,,$(strip \
  79. $(shell git describe --tags --dirty --match='docker/*'))) \
  80. -f docker/coturn/$(or $(dockerfile),$(DOCKERFILE))/Dockerfile \
  81. --load -t $(OWNER)/$(NAME):$(or $(tag),$(VERSION)) ./
  82. # Unite multiple single-platform Docker images as a multi-platform Docker image.
  83. #
  84. # WARNING: All the single-platform Docker images should be present on their
  85. # remote registry. This is the limitation imposed by `docker manifest`
  86. # command.
  87. #
  88. # make docker.manifest [amend=(yes|no)] [push=(no|yes)]
  89. # [of=($(VERSION)|<docker-tag-1>[,<docker-tag-2>...])]
  90. # [tags=($(TAGS)|<docker-tag-1>[,<docker-tag-2>...])]
  91. # [registries=($(REGISTRIES)|<prefix-1>[,<prefix-2>...])]
  92. docker.manifest:
  93. $(foreach tag,$(subst $(comma), ,$(docker-tags)),\
  94. $(foreach registry,$(subst $(comma), ,$(docker-registries)),\
  95. $(call docker.manifest.create.do,$(or $(of),$(VERSION)),\
  96. $(registry),$(tag))))
  97. ifeq ($(push),yes)
  98. $(foreach tag,$(subst $(comma), ,$(docker-tags)),\
  99. $(foreach registry,$(subst $(comma), ,$(docker-registries)),\
  100. $(call docker.manifest.push.do,$(registry),$(tag))))
  101. endif
  102. define docker.manifest.create.do
  103. $(eval froms := $(strip $(1)))
  104. $(eval repo := $(strip $(2)))
  105. $(eval tag := $(strip $(3)))
  106. docker manifest create $(if $(call eq,$(amend),no),,--amend) \
  107. $(repo)/$(OWNER)/$(NAME):$(tag) \
  108. $(foreach from,$(subst $(comma), ,$(froms)),\
  109. $(repo)/$(OWNER)/$(NAME):$(from))
  110. endef
  111. define docker.manifest.push.do
  112. $(eval repo := $(strip $(1)))
  113. $(eval tag := $(strip $(2)))
  114. docker manifest push $(repo)/$(OWNER)/$(NAME):$(tag)
  115. endef
  116. # Manually push single-platform Docker images to container registries.
  117. #
  118. # Usage:
  119. # make docker.push [tags=($(TAGS)|<docker-tag-1>[,<docker-tag-2>...])]
  120. # [registries=($(REGISTRIES)|<prefix-1>[,<prefix-2>...])]
  121. docker.push:
  122. $(foreach tag,$(subst $(comma), ,$(docker-tags)),\
  123. $(foreach registry,$(subst $(comma), ,$(docker-registries)),\
  124. $(call docker.push.do,$(registry),$(tag))))
  125. define docker.push.do
  126. $(eval repo := $(strip $(1)))
  127. $(eval tag := $(strip $(2)))
  128. docker push $(repo)/$(OWNER)/$(NAME):$(tag)
  129. endef
  130. # Tag single-platform Docker image with the given tags.
  131. #
  132. # Usage:
  133. # make docker.tags [of=($(VERSION)|<docker-tag>)]
  134. # [tags=($(TAGS)|<docker-tag-1>[,<docker-tag-2>...])]
  135. # [registries=($(REGISTRIES)|<prefix-1>[,<prefix-2>...])]
  136. docker.tags:
  137. $(foreach tag,$(subst $(comma), ,$(docker-tags)),\
  138. $(foreach registry,$(subst $(comma), ,$(docker-registries)),\
  139. $(call docker.tags.do,$(or $(of),$(VERSION)),$(registry),$(tag))))
  140. define docker.tags.do
  141. $(eval from := $(strip $(1)))
  142. $(eval repo := $(strip $(2)))
  143. $(eval to := $(strip $(3)))
  144. docker tag $(OWNER)/$(NAME):$(from) $(repo)/$(OWNER)/$(NAME):$(to)
  145. endef
  146. # Save single-platform Docker images to a tarball file.
  147. #
  148. # Usage:
  149. # make docker.tar [to-file=(.cache/image.tar|<file-path>)]
  150. # [tags=($(VERSION)|<docker-tag-1>[,<docker-tag-2>...])]
  151. docker-tar-file = $(or $(to-file),.cache/image.tar)
  152. docker.tar:
  153. @mkdir -p $(dir $(docker-tar-file))
  154. docker save -o $(docker-tar-file) \
  155. $(foreach tag,$(subst $(comma), ,$(or $(tags),$(VERSION))),\
  156. $(OWNER)/$(NAME):$(tag))
  157. docker.test: test.docker
  158. # Load single-platform Docker images from a tarball file.
  159. #
  160. # Usage:
  161. # make docker.untar [from-file=(.cache/image.tar|<file-path>)]
  162. docker.untar:
  163. docker load -i $(or $(from-file),.cache/image.tar)
  164. ####################
  165. # Testing commands #
  166. ####################
  167. # Run Bats tests for Docker image.
  168. #
  169. # Documentation of Bats:
  170. # https://github.com/bats-core/bats-core
  171. #
  172. # Usage:
  173. # make test.docker [tag=($(VERSION)|<docker-tag>)]
  174. # [platform=(linux/amd64|<os>/<arch>)]
  175. # [with=ipv6]
  176. test.docker:
  177. ifeq ($(wildcard node_modules/.bin/bats),)
  178. @make npm.install
  179. endif
  180. IMAGE=$(OWNER)/$(NAME):$(or $(tag),$(VERSION)) \
  181. PLATFORM=$(or $(call dockerify,$(platform)),linux/amd64) \
  182. $(if $(call eq,$(with),ipv6),TEST_IPV6=1,) \
  183. node_modules/.bin/bats \
  184. --timing $(if $(call eq,$(CI),),--pretty,--formatter tap) \
  185. --print-output-on-failure \
  186. tests/main.bats
  187. ################
  188. # NPM commands #
  189. ################
  190. # Resolve project NPM dependencies.
  191. #
  192. # Usage:
  193. # make npm.install [dockerized=(no|yes)]
  194. npm.install:
  195. ifeq ($(dockerized),yes)
  196. docker run --rm --network=host -v "$(PWD)":/app/ -w /app/ \
  197. node \
  198. make npm.install dockerized=no
  199. else
  200. npm install
  201. endif
  202. ################
  203. # Git commands #
  204. ################
  205. # Release project version (apply version tag and push).
  206. #
  207. # Usage:
  208. # make git.release [ver=($(VERSION)|<proj-ver>)]
  209. git-release-tag = docker/$(strip $(or $(ver),$(VERSION)))
  210. git.release:
  211. ifeq ($(shell git rev-parse $(git-release-tag) >/dev/null 2>&1 && echo "ok"),ok)
  212. $(error "Git tag $(git-release-tag) already exists")
  213. endif
  214. git tag $(git-release-tag)
  215. git push origin refs/tags/$(git-release-tag)
  216. ##################
  217. # .PHONY section #
  218. ##################
  219. .PHONY: image manifest push release test \
  220. docker.image docker.manifest docker.push docker.tags docker.tar \
  221. docker.test docker.untar \
  222. git.release \
  223. npm.install \
  224. test.docker