build_and_push_docker_images.yaml 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357
  1. name: Build and push docker images
  2. concurrency:
  3. group: docker-build-${{ github.event_name }}-${{ github.ref }}
  4. cancel-in-progress: true
  5. on:
  6. push:
  7. tags:
  8. - v*
  9. - e*
  10. workflow_dispatch:
  11. inputs:
  12. branch_or_tag:
  13. required: false
  14. profile:
  15. required: false
  16. jobs:
  17. prepare:
  18. runs-on: ubuntu-20.04
  19. # prepare source with any OTP version, no need for a matrix
  20. container: "ghcr.io/emqx/emqx-builder/5.0-17:1.13.4-24.2.1-1-ubuntu20.04"
  21. outputs:
  22. BUILD_PROFILE: ${{ steps.get_profile.outputs.BUILD_PROFILE }}
  23. IS_DOCKER_LATEST: ${{ steps.get_profile.outputs.IS_DOCKER_LATEST }}
  24. IS_EXACT_TAG: ${{ steps.get_profile.outputs.IS_EXACT_TAG }}
  25. DOCKER_TAG_VERSION: ${{ steps.get_profile.outputs.DOCKER_TAG_VERSION }}
  26. steps:
  27. - uses: actions/checkout@v3
  28. with:
  29. ref: ${{ github.event.inputs.branch_or_tag }} # when input is not given, the event tag is used
  30. path: source
  31. fetch-depth: 0
  32. - name: Get profiles to build
  33. id: get_profile
  34. run: |
  35. cd source
  36. tag=${{ github.ref }}
  37. # tag docker-latest-ce or docker-latest-ee
  38. if git describe --tags --exact --match 'docker-latest-*'; then
  39. docker_latest=true
  40. else
  41. docker_latest=false
  42. fi
  43. if git describe --tags --match "[v|e]*" --exact; then
  44. echo "This is an exact git tag, will publish images"
  45. is_exact='true'
  46. else
  47. echo "This is NOT an exact git tag, will not publish images"
  48. is_exact='false'
  49. fi
  50. case $tag in
  51. refs/tags/v*)
  52. PROFILE='emqx'
  53. ;;
  54. refs/tags/e*)
  55. PROFILE=emqx-enterprise
  56. ;;
  57. *)
  58. PROFILE=${{ github.event.inputs.profile }}
  59. case "$PROFILE" in
  60. emqx)
  61. true
  62. ;;
  63. emqx-enterprise)
  64. true
  65. ;;
  66. *)
  67. echo "ERROR: Failed to resolve build profile"
  68. exit 1
  69. ;;
  70. esac
  71. ;;
  72. esac
  73. VSN="$(./pkg-vsn.sh "$PROFILE")"
  74. echo "Building $PROFILE image with tag $VSN (latest=$docker_latest)"
  75. echo "IS_DOCKER_LATEST=$docker_latest" >> $GITHUB_OUTPUT
  76. echo "IS_EXACT_TAG=$is_exact" >> $GITHUB_OUTPUT
  77. echo "BUILD_PROFILE=$PROFILE" >> $GITHUB_OUTPUT
  78. echo "DOCKER_TAG_VERSION=$VSN" >> $GITHUB_OUTPUT
  79. - name: get_all_deps
  80. run: |
  81. make -C source deps-all
  82. zip -ryq source.zip source/* source/.[^.]*
  83. - uses: actions/upload-artifact@v3
  84. with:
  85. name: source
  86. path: source.zip
  87. docker:
  88. runs-on: ${{ matrix.arch[1] }}
  89. needs: prepare
  90. strategy:
  91. fail-fast: false
  92. matrix:
  93. arch:
  94. - [amd64, ubuntu-20.04]
  95. - [arm64, aws-arm64]
  96. profile:
  97. - ${{ needs.prepare.outputs.BUILD_PROFILE }}
  98. registry:
  99. - 'docker.io'
  100. - 'public.ecr.aws'
  101. os:
  102. - [alpine3.15.1, "alpine:3.15.1", "deploy/docker/Dockerfile.alpine"]
  103. - [debian11, "debian:11-slim", "deploy/docker/Dockerfile"]
  104. # NOTE: 'otp' and 'elixir' are to configure emqx-builder image
  105. # only support latest otp and elixir, not a matrix
  106. otp:
  107. - 24.2.1-1 # update to latest
  108. elixir:
  109. - 1.13.4 # update to latest
  110. steps:
  111. - uses: AutoModality/action-clean@v1
  112. if: matrix.arch[1] == 'aws-arm64'
  113. - uses: actions/download-artifact@v3
  114. with:
  115. name: source
  116. path: .
  117. - name: unzip source code
  118. run: unzip -q source.zip
  119. - uses: docker/setup-buildx-action@v2
  120. - name: Login for docker.
  121. uses: docker/login-action@v2
  122. if: matrix.registry == 'docker.io'
  123. with:
  124. username: ${{ secrets.DOCKER_HUB_USER }}
  125. password: ${{ secrets.DOCKER_HUB_TOKEN }}
  126. - name: Login for AWS ECR
  127. uses: docker/login-action@v2
  128. if: matrix.registry == 'public.ecr.aws'
  129. with:
  130. registry: public.ecr.aws
  131. username: ${{ secrets.AWS_ACCESS_KEY_ID }}
  132. password: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
  133. ecr: true
  134. - uses: ./source/.github/actions/docker-meta
  135. id: meta
  136. with:
  137. profile: ${{ matrix.profile }}
  138. registry: ${{ matrix.registry }}
  139. arch: ${{ matrix.arch[0] }}
  140. otp: ${{ matrix.otp }}
  141. builder_base: ${{ matrix.os[0] }}
  142. owner: ${{ github.repository_owner }}
  143. docker_tags: ${{ needs.prepare.outputs.DOCKER_TAG_VERSION }}
  144. - uses: docker/build-push-action@v3
  145. with:
  146. push: ${{ needs.prepare.outputs.IS_EXACT_TAG }}
  147. pull: true
  148. no-cache: true
  149. platforms: linux/${{ matrix.arch[0] }}
  150. tags: ${{ steps.meta.outputs.tags }}
  151. labels: ${{ steps.meta.outputs.labels }}
  152. build-args: |
  153. BUILD_FROM=ghcr.io/emqx/emqx-builder/5.0-17:${{ matrix.elixir }}-${{ matrix.otp }}-${{ matrix.os[0] }}
  154. RUN_FROM=${{ matrix.os[1] }}
  155. EMQX_NAME=${{ steps.meta.outputs.emqx_name }}
  156. file: source/${{ matrix.os[2] }}
  157. context: source
  158. docker-elixir:
  159. runs-on: ${{ matrix.arch[1] }}
  160. needs: prepare
  161. # do not build elixir images for ee for now
  162. if: needs.prepare.outputs.BUILD_PROFILE == 'emqx'
  163. strategy:
  164. fail-fast: false
  165. matrix:
  166. arch:
  167. - [amd64, ubuntu-20.04]
  168. - [arm64, aws-arm64]
  169. profile:
  170. - ${{ needs.prepare.outputs.BUILD_PROFILE }}
  171. registry:
  172. - 'docker.io'
  173. os:
  174. - [debian11, "debian:11-slim", "deploy/docker/Dockerfile"]
  175. otp:
  176. - 24.2.1-1 # update to latest
  177. elixir:
  178. - 1.13.4 # update to latest
  179. steps:
  180. - uses: AutoModality/action-clean@v1
  181. if: matrix.arch[1] == 'aws-arm64'
  182. - uses: actions/download-artifact@v3
  183. with:
  184. name: source
  185. path: .
  186. - name: unzip source code
  187. run: unzip -q source.zip
  188. - uses: docker/setup-buildx-action@v2
  189. - name: Login for docker.
  190. uses: docker/login-action@v2
  191. with:
  192. username: ${{ secrets.DOCKER_HUB_USER }}
  193. password: ${{ secrets.DOCKER_HUB_TOKEN }}
  194. - uses: ./source/.github/actions/docker-meta
  195. id: meta
  196. with:
  197. profile: ${{ matrix.profile }}
  198. registry: ${{ matrix.registry }}
  199. arch: ${{ matrix.arch[0] }}
  200. otp: ${{ matrix.otp }}
  201. elixir: ${{ matrix.elixir }}
  202. builder_base: ${{ matrix.os[0] }}
  203. owner: ${{ github.repository_owner }}
  204. docker_tags: ${{ needs.prepare.outputs.DOCKER_TAG_VERSION }}
  205. - uses: docker/build-push-action@v3
  206. with:
  207. push: ${{ needs.prepare.outputs.IS_EXACT_TAG }}
  208. pull: true
  209. no-cache: true
  210. platforms: linux/${{ matrix.arch[0] }}
  211. tags: ${{ steps.meta.outputs.tags }}
  212. labels: ${{ steps.meta.outputs.labels }}
  213. build-args: |
  214. BUILD_FROM=ghcr.io/emqx/emqx-builder/5.0-17:${{ matrix.elixir }}-${{ matrix.otp }}-${{ matrix.os[0] }}
  215. RUN_FROM=${{ matrix.os[1] }}
  216. EMQX_NAME=${{ steps.meta.outputs.emqx_name }}
  217. file: source/${{ matrix.os[2] }}
  218. context: source
  219. docker-push-multi-arch-manifest:
  220. # note, we only run on amd64
  221. if: needs.prepare.outputs.IS_EXACT_TAG
  222. needs:
  223. - prepare
  224. - docker
  225. runs-on: ${{ matrix.arch[1] }}
  226. strategy:
  227. fail-fast: false
  228. matrix:
  229. arch:
  230. - [amd64, ubuntu-20.04]
  231. profile:
  232. - ${{ needs.prepare.outputs.BUILD_PROFILE }}
  233. os:
  234. - [alpine3.15.1, "alpine:3.15.1", "deploy/docker/Dockerfile.alpine"]
  235. - [debian11, "debian:11-slim", "deploy/docker/Dockerfile"]
  236. # NOTE: only support latest otp version, not a matrix
  237. otp:
  238. - 24.2.1-1 # update to latest
  239. registry:
  240. - 'docker.io'
  241. - 'public.ecr.aws'
  242. steps:
  243. - uses: actions/download-artifact@v3
  244. with:
  245. name: source
  246. path: .
  247. - name: unzip source code
  248. run: unzip -q source.zip
  249. - uses: docker/login-action@v2
  250. if: matrix.registry == 'docker.io'
  251. with:
  252. username: ${{ secrets.DOCKER_HUB_USER }}
  253. password: ${{ secrets.DOCKER_HUB_TOKEN }}
  254. - uses: docker/login-action@v2
  255. if: matrix.registry == 'public.ecr.aws'
  256. with:
  257. registry: public.ecr.aws
  258. username: ${{ secrets.AWS_ACCESS_KEY_ID }}
  259. password: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
  260. ecr: true
  261. - uses: ./source/.github/actions/docker-meta
  262. id: meta
  263. with:
  264. profile: ${{ matrix.profile }}
  265. registry: ${{ matrix.registry }}
  266. arch: ${{ matrix.arch[0] }}
  267. otp: ${{ matrix.otp }}
  268. builder_base: ${{ matrix.os[0] }}
  269. owner: ${{ github.repository_owner }}
  270. docker_tags: ${{ needs.prepare.outputs.DOCKER_TAG_VERSION }}
  271. - name: update manifest for multiarch image
  272. working-directory: source
  273. run: |
  274. is_latest="${{ needs.prepare.outputs.IS_DOCKER_LATEST }}"
  275. scripts/docker-create-push-manifests.sh "${{ steps.meta.outputs.tags }}" "$is_latest"
  276. docker-elixir-push-multi-arch-manifest:
  277. # note, we only run on amd64
  278. # do not build enterprise elixir images for now
  279. if: needs.prepare.outputs.IS_EXACT_TAG && needs.prepare.outputs.BUILD_PROFILE == 'emqx'
  280. needs:
  281. - prepare
  282. - docker-elixir
  283. runs-on: ${{ matrix.arch[1] }}
  284. strategy:
  285. fail-fast: false
  286. matrix:
  287. arch:
  288. - [amd64, ubuntu-20.04]
  289. profile:
  290. - ${{ needs.prepare.outputs.BUILD_PROFILE }}
  291. # NOTE: for docker, only support latest otp version, not a matrix
  292. otp:
  293. - 24.2.1-1 # update to latest
  294. elixir:
  295. - 1.13.4 # update to latest
  296. registry:
  297. - 'docker.io'
  298. steps:
  299. - uses: actions/download-artifact@v3
  300. with:
  301. name: source
  302. path: .
  303. - name: unzip source code
  304. run: unzip -q source.zip
  305. - uses: docker/login-action@v2
  306. with:
  307. username: ${{ secrets.DOCKER_HUB_USER }}
  308. password: ${{ secrets.DOCKER_HUB_TOKEN }}
  309. - uses: ./source/.github/actions/docker-meta
  310. id: meta
  311. with:
  312. profile: ${{ matrix.profile }}
  313. registry: ${{ matrix.registry }}
  314. arch: ${{ matrix.arch[0] }}
  315. otp: ${{ matrix.otp }}
  316. elixir: ${{ matrix.elixir }}
  317. builder_base: ${{ matrix.os[0] }}
  318. owner: ${{ github.repository_owner }}
  319. docker_tags: ${{ needs.prepare.outputs.DOCKER_TAG_VERSION }}
  320. - name: update manifest for multiarch image
  321. working-directory: source
  322. run: |
  323. scripts/docker-create-push-manifests.sh "${{ steps.meta.outputs.tags }}" false