build_and_push_docker_images.yaml 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209
  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. - docker-latest-*
  11. workflow_dispatch:
  12. inputs:
  13. branch_or_tag:
  14. required: false
  15. profile:
  16. required: false
  17. default: 'emqx'
  18. is_latest:
  19. required: false
  20. default: false
  21. jobs:
  22. prepare:
  23. runs-on: ubuntu-22.04
  24. # prepare source with any OTP version, no need for a matrix
  25. container: "ghcr.io/emqx/emqx-builder/5.1-3:1.14.5-25.3.2-1-ubuntu22.04"
  26. outputs:
  27. PROFILE: ${{ steps.get_profile.outputs.PROFILE }}
  28. EDITION: ${{ steps.get_profile.outputs.EDITION }}
  29. IS_LATEST: ${{ steps.get_profile.outputs.IS_LATEST }}
  30. IS_EXACT_TAG: ${{ steps.get_profile.outputs.IS_EXACT_TAG }}
  31. VERSION: ${{ steps.get_profile.outputs.VERSION }}
  32. steps:
  33. - uses: actions/checkout@v3
  34. with:
  35. ref: ${{ github.event.inputs.branch_or_tag }} # when input is not given, the event tag is used
  36. path: source
  37. fetch-depth: 0
  38. - name: Get profiles to build
  39. id: get_profile
  40. env:
  41. INPUTS_PROFILE: ${{ github.event.inputs.profile }}
  42. run: |
  43. cd source
  44. # tag docker-latest-ce or docker-latest-ee
  45. if git describe --tags --exact --match 'docker-latest-*' 2>/dev/null; then
  46. echo 'is_latest=true due to docker-latest-* tag'
  47. is_latest=true
  48. elif [ "${{ inputs.is_latest }}" = "true" ]; then
  49. echo 'is_latest=true due to manual input from workflow_dispatch'
  50. is_latest=true
  51. else
  52. echo 'is_latest=false'
  53. is_latest=false
  54. fi
  55. # resolve profile
  56. if git describe --tags --match "v*" --exact; then
  57. echo "This is an exact git tag, will publish images"
  58. is_exact='true'
  59. PROFILE=emqx
  60. elif git describe --tags --match "e*" --exact; then
  61. echo "This is an exact git tag, will publish images"
  62. is_exact='true'
  63. PROFILE=emqx-enterprise
  64. else
  65. echo "This is NOT an exact git tag, will not publish images"
  66. is_exact='false'
  67. fi
  68. case "${PROFILE:-$INPUTS_PROFILE}" in
  69. emqx)
  70. EDITION='Opensource'
  71. ;;
  72. emqx-enterprise)
  73. EDITION='Enterprise'
  74. ;;
  75. *)
  76. echo "ERROR: Failed to resolve build profile"
  77. exit 1
  78. ;;
  79. esac
  80. VSN="$(./pkg-vsn.sh "$PROFILE")"
  81. echo "Building emqx/$PROFILE:$VSN image (latest=$is_latest)"
  82. echo "Push = $is_exact"
  83. echo "IS_LATEST=$is_latest" >> $GITHUB_OUTPUT
  84. echo "IS_EXACT_TAG=$is_exact" >> $GITHUB_OUTPUT
  85. echo "PROFILE=$PROFILE" >> $GITHUB_OUTPUT
  86. echo "EDITION=$EDITION" >> $GITHUB_OUTPUT
  87. echo "VERSION=$VSN" >> $GITHUB_OUTPUT
  88. - name: get_all_deps
  89. env:
  90. PROFILE: ${{ steps.get_profile.outputs.PROFILE }}
  91. run: |
  92. zip -ryq source.zip source/* source/.[^.]*
  93. - uses: actions/upload-artifact@v3
  94. with:
  95. name: source
  96. path: source.zip
  97. docker:
  98. runs-on: ubuntu-22.04
  99. needs: prepare
  100. strategy:
  101. fail-fast: false
  102. matrix:
  103. profile:
  104. - "${{ needs.prepare.outputs.PROFILE }}"
  105. registry:
  106. - 'docker.io'
  107. - 'public.ecr.aws'
  108. os:
  109. - [debian11, "debian:11-slim", "deploy/docker/Dockerfile"]
  110. # NOTE: 'otp' and 'elixir' are to configure emqx-builder image
  111. # only support latest otp and elixir, not a matrix
  112. builder:
  113. - 5.1-3 # update to latest
  114. otp:
  115. - 25.3.2-1
  116. elixir:
  117. - 'no_elixir'
  118. - '1.14.5' # update to latest
  119. exclude: # TODO: publish enterprise to ecr too?
  120. - registry: 'public.ecr.aws'
  121. profile: emqx-enterprise
  122. steps:
  123. - uses: actions/download-artifact@v3
  124. with:
  125. name: source
  126. path: .
  127. - name: unzip source code
  128. run: unzip -q source.zip
  129. - uses: docker/setup-qemu-action@v2
  130. - uses: docker/setup-buildx-action@v2
  131. - name: Login to hub.docker.com
  132. uses: docker/login-action@v2
  133. if: matrix.registry == 'docker.io'
  134. with:
  135. username: ${{ secrets.DOCKER_HUB_USER }}
  136. password: ${{ secrets.DOCKER_HUB_TOKEN }}
  137. - name: Login to AWS ECR
  138. uses: docker/login-action@v2
  139. if: matrix.registry == 'public.ecr.aws'
  140. with:
  141. registry: public.ecr.aws
  142. username: ${{ secrets.AWS_ACCESS_KEY_ID }}
  143. password: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
  144. ecr: true
  145. - name: prepare for docker/metadata-action
  146. id: pre-meta
  147. shell: bash
  148. run: |
  149. extra_labels=
  150. img_suffix=
  151. if [ "${{ matrix.elixir }}" != 'no_elixir' ]; then
  152. img_suffix="-elixir"
  153. extra_labels="org.opencontainers.image.elixir.version=${{ matrix.elixir }}"
  154. fi
  155. extra_deps=
  156. if [[ "${{ matrix.profile }}" = *enterprise* ]]; then
  157. extra_deps='libsasl2-2,libsasl2-modules-gssapi-mit'
  158. fi
  159. echo "img_suffix=$img_suffix" >> $GITHUB_OUTPUT
  160. echo "extra_labels=$extra_labels" >> $GITHUB_OUTPUT
  161. echo "extra_deps=$extra_deps" >> $GITHUB_OUTPUT
  162. - uses: docker/metadata-action@v4
  163. id: meta
  164. with:
  165. images: |
  166. ${{ matrix.registry }}/${{ github.repository_owner }}/${{ matrix.profile }}
  167. flavor: |
  168. latest=${{ matrix.elixir == 'no_elixir' }}
  169. suffix=${{ steps.pre-meta.outputs.img_suffix }}
  170. tags: |
  171. type=semver,pattern={{major}}.{{minor}},value=${{ needs.prepare.outputs.VERSION }}
  172. type=semver,pattern={{version}},value=${{ needs.prepare.outputs.VERSION }}
  173. type=raw,value=${{ needs.prepare.outputs.VERSION }}
  174. type=raw,value=latest,enable=${{ needs.prepare.outputs.IS_LATEST }}
  175. labels: |
  176. org.opencontainers.image.otp.version=${{ matrix.otp }}
  177. org.opencontainers.image.edition=${{ needs.prepare.outputs.EDITION }}
  178. ${{ steps.pre-meta.outputs.extra_labels }}
  179. - uses: docker/build-push-action@v3
  180. with:
  181. push: ${{ needs.prepare.outputs.IS_EXACT_TAG == 'true' || github.repository_owner != 'emqx' }}
  182. pull: true
  183. no-cache: true
  184. platforms: linux/amd64,linux/arm64
  185. tags: ${{ steps.meta.outputs.tags }}
  186. labels: ${{ steps.meta.outputs.labels }}
  187. build-args: |
  188. EMQX_NAME=${{ matrix.profile }}${{ steps.pre-meta.outputs.img_suffix }}
  189. EXTRA_DEPS=${{ steps.pre-meta.outputs.extra_deps }}
  190. file: source/${{ matrix.os[2] }}
  191. context: source