build_packages.yaml 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458
  1. name: Cross build packages
  2. on:
  3. schedule:
  4. - cron: '0 */6 * * *'
  5. push:
  6. tags:
  7. - v*
  8. release:
  9. types:
  10. - published
  11. jobs:
  12. prepare:
  13. runs-on: ubuntu-20.04
  14. container: emqx/build-env:erl23.2.7-ubuntu20.04
  15. outputs:
  16. profiles: ${{ steps.set_profile.outputs.profiles}}
  17. steps:
  18. - uses: actions/checkout@v2
  19. with:
  20. path: source
  21. - name: set profile
  22. id: set_profile
  23. shell: bash
  24. run: |
  25. if make -C source emqx-ee --dry-run > /dev/null 2>&1; then
  26. echo "::set-output name=profiles::[\"emqx-ee\"]"
  27. else
  28. echo "::set-output name=profiles::[\"emqx\", \"emqx-edge\"]"
  29. fi
  30. - name: get_all_deps
  31. if: endsWith(github.repository, 'emqx')
  32. run: |
  33. make -C source deps-all
  34. zip -ryq source.zip source
  35. - name: get_all_deps
  36. if: endsWith(github.repository, 'enterprise')
  37. run: |
  38. echo "https://ci%40emqx.io:${{ secrets.CI_GIT_TOKEN }}@github.com" > $HOME/.git-credentials
  39. git config --global credential.helper store
  40. echo "${{ secrets.CI_GIT_TOKEN }}" >> source/scripts/git-token
  41. make -C source deps-all
  42. zip -ryq source.zip source
  43. - uses: actions/upload-artifact@v2
  44. with:
  45. name: source
  46. path: source.zip
  47. windows:
  48. runs-on: windows-2019
  49. needs: prepare
  50. strategy:
  51. matrix:
  52. profile: ${{fromJSON(needs.prepare.outputs.profiles)}}
  53. exclude:
  54. - profile: emqx-edge
  55. steps:
  56. - uses: actions/download-artifact@v2
  57. with:
  58. name: source
  59. path: .
  60. - name: unzip source code
  61. run: Expand-Archive -Path source.zip -DestinationPath ./
  62. - uses: ilammy/msvc-dev-cmd@v1
  63. - uses: gleam-lang/setup-erlang@v1.1.0
  64. id: install_erlang
  65. with:
  66. otp-version: 23.2
  67. - name: build
  68. env:
  69. PYTHON: python
  70. DIAGNOSTIC: 1
  71. run: |
  72. $env:PATH = "${{ steps.install_erlang.outputs.erlpath }}\bin;$env:PATH"
  73. $version = $( "${{ github.ref }}" -replace "^(.*)/(.*)/" )
  74. if ($version -match "^v[0-9]+\.[0-9]+(\.[0-9]+)?") {
  75. $regex = "[0-9]+\.[0-9]+(-alpha|-beta|-rc)?\.[0-9]"
  76. $pkg_name = "${{ matrix.profile }}-windows-$([regex]::matches($version, $regex).value).zip"
  77. }
  78. else {
  79. $pkg_name = "${{ matrix.profile }}-windows-$($version -replace '/').zip"
  80. }
  81. cd source
  82. make ${{ matrix.profile }}
  83. mkdir -p _packages/${{ matrix.profile }}
  84. Compress-Archive -Path _build/${{ matrix.profile }}/rel/emqx -DestinationPath _build/${{ matrix.profile }}/rel/$pkg_name
  85. mv _build/${{ matrix.profile }}/rel/$pkg_name _packages/${{ matrix.profile }}
  86. Get-FileHash -Path "_packages/${{ matrix.profile }}/$pkg_name" | Format-List | grep 'Hash' | awk '{print $3}' > _packages/${{ matrix.profile }}/$pkg_name.sha256
  87. - name: run emqx
  88. run: |
  89. cd source
  90. ./_build/${{ matrix.profile }}/rel/emqx/bin/emqx start
  91. ./_build/${{ matrix.profile }}/rel/emqx/bin/emqx stop
  92. ./_build/${{ matrix.profile }}/rel/emqx/bin/emqx install
  93. ./_build/${{ matrix.profile }}/rel/emqx/bin/emqx uninstall
  94. - uses: actions/upload-artifact@v1
  95. if: startsWith(github.ref, 'refs/tags/')
  96. with:
  97. name: ${{ matrix.profile }}
  98. path: source/_packages/${{ matrix.profile }}/.
  99. mac:
  100. runs-on: macos-10.15
  101. needs: prepare
  102. strategy:
  103. matrix:
  104. profile: ${{fromJSON(needs.prepare.outputs.profiles)}}
  105. exclude:
  106. - profile: emqx-edge
  107. steps:
  108. - uses: actions/download-artifact@v2
  109. with:
  110. name: source
  111. path: .
  112. - name: unzip source code
  113. run: unzip -q source.zip
  114. - name: prepare
  115. run: |
  116. brew install curl zip unzip gnu-sed kerl unixodbc freetds
  117. echo "/usr/local/bin" >> $GITHUB_PATH
  118. git config --global credential.helper store
  119. - name: build erlang
  120. timeout-minutes: 60
  121. run: |
  122. kerl build 23.2.7
  123. kerl install 23.2.7 $HOME/.kerl/23.2.7
  124. - name: build
  125. run: |
  126. . $HOME/.kerl/23.2.7/activate
  127. make -C source ${{ matrix.profile }}-pkg
  128. - name: test
  129. run: |
  130. cd source
  131. pkg_name=$(basename _packages/${{ matrix.profile }}/${{ matrix.profile }}-*.zip)
  132. unzip _packages/${{ matrix.profile }}/$pkg_name
  133. gsed -i '/emqx_telemetry/d' ./emqx/data/loaded_plugins
  134. ./emqx/bin/emqx start || cat emqx/log/erlang.log.1
  135. ready='no'
  136. for i in {1..10}; do
  137. if curl -fs 127.0.0.1:18083 > /dev/null; then
  138. ready='yes'
  139. break
  140. fi
  141. sleep 1
  142. done
  143. if [ "$ready" != "yes" ]; then
  144. echo "Timed out waiting for emqx to be ready"
  145. cat emqx/log/erlang.log.1
  146. exit 1
  147. fi
  148. ./emqx/bin/emqx_ctl status
  149. ./emqx/bin/emqx stop
  150. rm -rf emqx
  151. openssl dgst -sha256 ./_packages/${{ matrix.profile }}/$pkg_name | awk '{print $2}' > ./_packages/${{ matrix.profile }}/$pkg_name.sha256
  152. - uses: actions/upload-artifact@v1
  153. if: startsWith(github.ref, 'refs/tags/')
  154. with:
  155. name: ${{ matrix.profile }}
  156. path: source/_packages/${{ matrix.profile }}/.
  157. linux:
  158. runs-on: ubuntu-20.04
  159. needs: prepare
  160. strategy:
  161. matrix:
  162. profile: ${{fromJSON(needs.prepare.outputs.profiles)}}
  163. arch:
  164. - amd64
  165. - arm64
  166. os:
  167. - ubuntu20.04
  168. - ubuntu18.04
  169. - ubuntu16.04
  170. - debian10
  171. - debian9
  172. # - opensuse
  173. - centos8
  174. - centos7
  175. - centos6
  176. - raspbian10
  177. - raspbian9
  178. exclude:
  179. - os: centos6
  180. arch: arm64
  181. - os: raspbian9
  182. arch: amd64
  183. - os: raspbian10
  184. arch: amd64
  185. - os: raspbian9
  186. profile: emqx
  187. - os: raspbian10
  188. profile: emqx
  189. - os: raspbian9
  190. profile: emqx-ee
  191. - os: raspbian10
  192. profile: emqx-ee
  193. defaults:
  194. run:
  195. shell: bash
  196. steps:
  197. - name: prepare docker
  198. run: |
  199. mkdir -p $HOME/.docker
  200. echo '{ "experimental": "enabled" }' | tee $HOME/.docker/config.json
  201. echo '{ "experimental": true, "storage-driver": "overlay2", "max-concurrent-downloads": 50, "max-concurrent-uploads": 50}' | sudo tee /etc/docker/daemon.json
  202. sudo systemctl restart docker
  203. docker info
  204. docker buildx create --use --name mybuild
  205. docker run --rm --privileged tonistiigi/binfmt --install all
  206. - uses: actions/download-artifact@v2
  207. with:
  208. name: source
  209. path: .
  210. - name: unzip source code
  211. run: unzip -q source.zip
  212. - name: downloads emqx zip packages
  213. env:
  214. PROFILE: ${{ matrix.profile }}
  215. ARCH: ${{ matrix.arch }}
  216. SYSTEM: ${{ matrix.os }}
  217. run: |
  218. set -e -u -x
  219. cd source
  220. if [ $ARCH = "arm64" ];then arch="aarch64"; else arch="x86_64"; fi
  221. if [ $PROFILE = "emqx" ];then broker="emqx-ce"; else broker="$PROFILE"; fi
  222. if [ $PROFILE = "emqx-ee" ];then edition='enterprise'; else edition='opensource'; fi
  223. vsn="$(grep -E "define.+EMQX_RELEASE.+${edition}" include/emqx_release.hrl | cut -d '"' -f2)"
  224. pre_vsn="$(echo $vsn | grep -oE '^[0-9]+.[0-9]')"
  225. if [ $PROFILE = "emqx-ee" ]; then
  226. old_vsns=($(git tag -l "e$pre_vsn.[0-9]" | sed "s/e$vsn//"))
  227. else
  228. old_vsns=($(git tag -l "v$pre_vsn.[0-9]" | sed "s/v$vsn//"))
  229. fi
  230. mkdir -p tmp/relup_packages/$PROFILE
  231. cd tmp/relup_packages/$PROFILE
  232. for tag in ${old_vsns[@]};do
  233. if [ ! -z "$(echo $(curl -I -m 10 -o /dev/null -s -w %{http_code} https://s3-${{ secrets.AWS_DEFAULT_REGION }}.amazonaws.com/${{ secrets.AWS_S3_BUCKET }}/$broker/$tag/$PROFILE-$SYSTEM-${tag#[e|v]}-$arch.zip) | grep -oE "^[23]+")" ];then
  234. wget https://s3-${{ secrets.AWS_DEFAULT_REGION }}.amazonaws.com/${{ secrets.AWS_S3_BUCKET }}/$broker/$tag/$PROFILE-$SYSTEM-${tag#[e|v]}-$arch.zip
  235. wget https://s3-${{ secrets.AWS_DEFAULT_REGION }}.amazonaws.com/${{ secrets.AWS_S3_BUCKET }}/$broker/$tag/$PROFILE-$SYSTEM-${tag#[e|v]}-$arch.zip.sha256
  236. echo "$(cat $PROFILE-$SYSTEM-${tag#[e|v]}-$arch.zip.sha256) $PROFILE-$SYSTEM-${tag#[e|v]}-$arch.zip" | sha256sum -c || exit 1
  237. fi
  238. done
  239. cd -
  240. - name: build emqx packages
  241. env:
  242. ERL_OTP: erl23.2.7
  243. PROFILE: ${{ matrix.profile }}
  244. ARCH: ${{ matrix.arch }}
  245. SYSTEM: ${{ matrix.os }}
  246. run: |
  247. set -e -u
  248. cd source
  249. docker buildx build --no-cache \
  250. --platform=linux/$ARCH \
  251. -t cross_build_emqx_for_$SYSTEM \
  252. -f .ci/build_packages/Dockerfile \
  253. --build-arg BUILD_FROM=emqx/build-env:$ERL_OTP-$SYSTEM \
  254. --build-arg EMQX_NAME=$PROFILE \
  255. --output type=tar,dest=/tmp/cross-build-$PROFILE-for-$SYSTEM.tar .
  256. mkdir -p /tmp/packages/$PROFILE
  257. tar -xvf /tmp/cross-build-$PROFILE-for-$SYSTEM.tar --wildcards emqx/_packages/$PROFILE/*
  258. mv emqx/_packages/$PROFILE/* /tmp/packages/$PROFILE/
  259. rm -rf /tmp/cross-build-$PROFILE-for-$SYSTEM.tar
  260. docker rm -f $(docker ps -a -q)
  261. docker volume prune -f
  262. - name: create sha256
  263. env:
  264. PROFILE: ${{ matrix.profile}}
  265. run: |
  266. if [ -d /tmp/packages/$PROFILE ]; then
  267. cd /tmp/packages/$PROFILE
  268. for var in $(ls emqx-* ); do
  269. bash -c "echo $(sha256sum $var | awk '{print $1}') > $var.sha256"
  270. done
  271. cd -
  272. fi
  273. - uses: actions/upload-artifact@v1
  274. if: startsWith(github.ref, 'refs/tags/')
  275. with:
  276. name: ${{ matrix.profile }}
  277. path: /tmp/packages/${{ matrix.profile }}/.
  278. docker:
  279. runs-on: ubuntu-20.04
  280. needs: prepare
  281. strategy:
  282. matrix:
  283. profile: ${{fromJSON(needs.prepare.outputs.profiles)}}
  284. arch:
  285. - [amd64, x86_64]
  286. - [arm64v8, aarch64]
  287. - [arm32v7, arm]
  288. - [i386, i386]
  289. - [s390x, s390x]
  290. exclude:
  291. - profile: emqx-ee
  292. arch: [i386, i386]
  293. - profile: emqx-ee
  294. arch: [s390x, s390x]
  295. steps:
  296. - uses: actions/download-artifact@v2
  297. with:
  298. name: source
  299. path: .
  300. - name: unzip source code
  301. run: unzip -q source.zip
  302. - name: build emqx docker image
  303. env:
  304. PROFILE: ${{ matrix.profile }}
  305. ARCH: ${{ matrix.arch[0] }}
  306. QEMU_ARCH: ${{ matrix.arch[1] }}
  307. run: |
  308. sudo docker run --rm --privileged multiarch/qemu-user-static --reset -p yes
  309. cd source
  310. sudo TARGET=emqx/$PROFILE ARCH=$ARCH QEMU_ARCH=$QEMU_ARCH make docker
  311. cd _packages/$PROFILE && for var in $(ls ${PROFILE}-docker-* ); do sudo bash -c "echo $(sha256sum $var | awk '{print $1}') > $var.sha256"; done && cd -
  312. - uses: actions/upload-artifact@v1
  313. if: startsWith(github.ref, 'refs/tags/')
  314. with:
  315. name: ${{ matrix.profile }}
  316. path: source/_packages/${{ matrix.profile }}/.
  317. delete-artifact:
  318. runs-on: ubuntu-20.04
  319. needs: [prepare, windows, mac, linux, docker]
  320. steps:
  321. - uses: geekyeggo/delete-artifact@v1
  322. with:
  323. name: source
  324. upload:
  325. runs-on: ubuntu-20.04
  326. if: startsWith(github.ref, 'refs/tags/')
  327. needs: [prepare, windows, mac, linux, docker]
  328. strategy:
  329. matrix:
  330. profile: ${{fromJSON(needs.prepare.outputs.profiles)}}
  331. steps:
  332. - uses: actions/checkout@v2
  333. - name: get_version
  334. run: |
  335. echo 'version<<EOF' >> $GITHUB_ENV
  336. echo ${{ github.ref }} | sed -r "s ^refs/heads/|^refs/tags/(.*) \1 g" >> $GITHUB_ENV
  337. echo 'EOF' >> $GITHUB_ENV
  338. - uses: actions/download-artifact@v2
  339. with:
  340. name: ${{ matrix.profile }}
  341. path: ./_packages/${{ matrix.profile }}
  342. - name: install dos2unix
  343. run: sudo apt-get update && sudo apt install -y dos2unix
  344. - name: get packages
  345. run: |
  346. set -e -u
  347. cd _packages/${{ matrix.profile }}
  348. for var in $( ls |grep emqx |grep -v sha256); do
  349. dos2unix $var.sha256
  350. echo "$(cat $var.sha256) $var" | sha256sum -c || exit 1
  351. done
  352. cd -
  353. - name: upload aws s3
  354. run: |
  355. set -e -u
  356. if [ "${{ matrix.profile }}" == "emqx" ];then
  357. broker="emqx-ce"
  358. else
  359. broker=${{ matrix.profile }}
  360. fi
  361. aws configure set aws_access_key_id ${{ secrets.AWS_ACCESS_KEY_ID }}
  362. aws configure set aws_secret_access_key ${{ secrets.AWS_SECRET_ACCESS_KEY }}
  363. aws configure set default.region ${{ secrets.AWS_DEFAULT_REGION }}
  364. aws s3 cp --recursive _packages/${{ matrix.profile }} s3://${{ secrets.AWS_S3_BUCKET }}/$broker/${{ env.version }}
  365. aws cloudfront create-invalidation --distribution-id ${{ secrets.AWS_CLOUDFRONT_ID }} --paths "/$broker/${{ env.version }}/*"
  366. - uses: Rory-Z/upload-release-asset@v1
  367. if: github.event_name == 'release'
  368. with:
  369. repo: emqx
  370. path: "_packages/${{ matrix.profile }}/emqx-*"
  371. token: ${{ github.token }}
  372. - name: update to emqx.io
  373. if: github.event_name == 'release'
  374. run: |
  375. set -e -x -u
  376. curl -w %{http_code} \
  377. --insecure \
  378. -H "Content-Type: application/json" \
  379. -H "token: ${{ secrets.EMQX_IO_TOKEN }}" \
  380. -X POST \
  381. -d "{\"repo\":\"emqx/emqx\", \"tag\": \"${{ env.version }}\" }" \
  382. ${{ secrets.EMQX_IO_RELEASE_API }}
  383. - name: push docker image to docker hub
  384. if: github.event_name == 'release'
  385. run: |
  386. set -e -x -u
  387. sudo make docker-prepare
  388. cd _packages/${{ matrix.profile }} && for var in $(ls |grep docker |grep -v sha256); do unzip $var; sudo docker load < ${var%.*}; rm -f ${var%.*}; done && cd -
  389. echo ${{ secrets.DOCKER_HUB_TOKEN }} |sudo docker login -u ${{ secrets.DOCKER_HUB_USER }} --password-stdin
  390. sudo TARGET=emqx/${{ matrix.profile }} make docker-push
  391. sudo TARGET=emqx/${{ matrix.profile }} make docker-manifest-list
  392. - name: update repo.emqx.io
  393. if: github.event_name == 'release' && endsWith(github.repository, 'enterprise') && matrix.profile == 'emqx-ee'
  394. run: |
  395. curl --silent --show-error \
  396. -H "Authorization: token ${{ secrets.CI_GIT_TOKEN }}" \
  397. -H "Accept: application/vnd.github.v3+json" \
  398. -X POST \
  399. -d "{\"ref\":\"v1.0.1\",\"inputs\":{\"version\": \"${{ env.version }}\", \"emqx_ee\": \"true\"}}" \
  400. "https://api.github.com/repos/emqx/emqx-ci-helper/actions/workflows/update_emqx_repos.yaml/dispatches"
  401. - name: update repo.emqx.io
  402. if: github.event_name == 'release' && endsWith(github.repository, 'emqx') && matrix.profile == 'emqx'
  403. run: |
  404. curl --silent --show-error \
  405. -H "Authorization: token ${{ secrets.CI_GIT_TOKEN }}" \
  406. -H "Accept: application/vnd.github.v3+json" \
  407. -X POST \
  408. -d "{\"ref\":\"v1.0.1\",\"inputs\":{\"version\": \"${{ env.version }}\", \"emqx_ce\": \"true\"}}" \
  409. "https://api.github.com/repos/emqx/emqx-ci-helper/actions/workflows/update_emqx_repos.yaml/dispatches"
  410. - name: update homebrew packages
  411. if: github.event_name == 'release' && endsWith(github.repository, 'emqx') && matrix.profile == 'emqx'
  412. run: |
  413. if [ -z $(echo $version | grep -oE "(alpha|beta|rc)\.[0-9]") ]; then
  414. curl --silent --show-error \
  415. -H "Authorization: token ${{ secrets.CI_GIT_TOKEN }}" \
  416. -H "Accept: application/vnd.github.v3+json" \
  417. -X POST \
  418. -d "{\"ref\":\"v1.0.1\",\"inputs\":{\"version\": \"${{ env.version }}\"}}" \
  419. "https://api.github.com/repos/emqx/emqx-ci-helper/actions/workflows/update_emqx_homebrew.yaml/dispatches"
  420. fi
  421. - uses: geekyeggo/delete-artifact@v1
  422. with:
  423. name: ${{ matrix.profile }}