packaging.yml 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311
  1. ---
  2. # Handles building of binary packages for the agent.
  3. name: Packages
  4. on:
  5. pull_request:
  6. types:
  7. - opened
  8. - reopened
  9. - labeled
  10. - synchronize
  11. push:
  12. branches:
  13. - master
  14. workflow_dispatch:
  15. inputs:
  16. type:
  17. description: Package build type
  18. default: devel
  19. required: true
  20. version:
  21. description: Package version
  22. required: false
  23. env:
  24. DISABLE_TELEMETRY: 1
  25. REPO_PREFIX: netdata/netdata
  26. concurrency:
  27. group: packages-${{ github.ref }}-${{ github.event_name }}
  28. cancel-in-progress: true
  29. jobs:
  30. file-check: # Check what files changed if we’re being run in a PR or on a push.
  31. name: Check Modified Files
  32. runs-on: ubuntu-latest
  33. outputs:
  34. run: ${{ steps.check-run.outputs.run }}
  35. steps:
  36. - name: Checkout
  37. id: checkout
  38. uses: actions/checkout@v4
  39. with:
  40. fetch-depth: 0
  41. submodules: recursive
  42. - name: Check files
  43. id: file-check
  44. uses: tj-actions/changed-files@v41
  45. with:
  46. since_last_remote_commit: ${{ github.event_name != 'pull_request' }}
  47. files: |
  48. **.c
  49. **.cc
  50. **.h
  51. **.hh
  52. **.in
  53. netdata.spec.in
  54. CMakeLists.txt
  55. .github/data/distros.yml
  56. .github/workflows/packaging.yml
  57. .github/scripts/gen-matrix-packaging.py
  58. .github/scripts/pkg-test.sh
  59. build/**
  60. packaging/*.sh
  61. packaging/*.checksums
  62. packaging/*.version
  63. contrib/debian/**
  64. aclk/aclk-schemas/
  65. ml/dlib/
  66. mqtt_websockets
  67. web/server/h2o/libh2o
  68. files_ignore: |
  69. **.md
  70. - name: Check Run
  71. id: check-run
  72. run: |
  73. if [ "${{ steps.file-check.outputs.any_modified }}" == "true" ] || [ "${{ github.event_name }}" == "workflow_dispatch" ]; then
  74. echo 'run=true' >> "${GITHUB_OUTPUT}"
  75. else
  76. echo 'run=false' >> "${GITHUB_OUTPUT}"
  77. fi
  78. matrix:
  79. name: Prepare Build Matrix
  80. runs-on: ubuntu-latest
  81. outputs:
  82. matrix: ${{ steps.set-matrix.outputs.matrix }}
  83. steps:
  84. - name: Checkout
  85. id: checkout
  86. uses: actions/checkout@v4
  87. - name: Prepare tools
  88. id: prepare
  89. run: |
  90. sudo apt-get update && sudo apt-get install -y python3-ruamel.yaml
  91. - name: Read build matrix
  92. id: set-matrix
  93. run: |
  94. if [ "${{ github.event_name }}" = "pull_request" ] && \
  95. [ "${{ !contains(github.event.pull_request.labels.*.name, 'run-ci/packaging') }}" = "true" ]; then
  96. matrix="$(.github/scripts/gen-matrix-packaging.py 1)"
  97. else
  98. matrix="$(.github/scripts/gen-matrix-packaging.py 0)"
  99. fi
  100. echo "Generated matrix: ${matrix}"
  101. echo "matrix=${matrix}" >> "${GITHUB_OUTPUT}"
  102. - name: Failure Notification
  103. uses: rtCamp/action-slack-notify@v2
  104. env:
  105. SLACK_COLOR: 'danger'
  106. SLACK_ICON_EMOJI: ':github-actions:'
  107. SLACK_TITLE: 'Package Build matrix generation failed:'
  108. SLACK_USERNAME: 'GitHub Actions'
  109. SLACK_MESSAGE: |-
  110. ${{ github.repository }}: Failed to generate build matrix for package build.
  111. Checkout: ${{ steps.checkout.outcome }}
  112. Prepare Tools: ${{ steps.prepare.outcome }}
  113. Read Build Matrix: ${{ steps.set-matrix.outcome }}
  114. SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK_URL }}
  115. if: >-
  116. ${{
  117. failure()
  118. && github.event_name != 'pull_request'
  119. && startsWith(github.ref, 'refs/heads/master')
  120. && github.repository == 'netdata/netdata'
  121. }}
  122. version-check:
  123. name: Version check
  124. runs-on: ubuntu-latest
  125. outputs:
  126. repo: ${{ steps.check-version.outputs.repo }}
  127. version: ${{ steps.check-version.outputs.version }}
  128. retention: ${{ steps.check-version.outputs.retention }}
  129. steps:
  130. - name: Checkout
  131. id: checkout
  132. uses: actions/checkout@v4
  133. - name: Check Version
  134. id: check-version
  135. run: |
  136. if [ "${{ github.event_name }}" == "workflow_dispatch" ]; then
  137. case "${{ github.event.inputs.type }}" in
  138. "release")
  139. echo "repo=${REPO_PREFIX}" >> "${GITHUB_OUTPUT}"
  140. echo "version=${{ github.event.inputs.version }}" >> "${GITHUB_OUTPUT}"
  141. echo "retention=365" >> "${GITHUB_OUTPUT}"
  142. ;;
  143. "nightly")
  144. echo "repo=${REPO_PREFIX}-edge" >> "${GITHUB_OUTPUT}"
  145. echo "version=$(tr -d 'v' < packaging/version)" >> "${GITHUB_OUTPUT}"
  146. echo "retention=30" >> "${GITHUB_OUTPUT}"
  147. ;;
  148. *)
  149. echo "repo=${REPO_PREFIX}-devel" >> "${GITHUB_OUTPUT}"
  150. echo "version=0.${GITHUB_SHA}" >> "${GITHUB_OUTPUT}"
  151. echo "retention=30" >> "${GITHUB_OUTPUT}"
  152. ;;
  153. esac
  154. else
  155. echo "version=$(cut -d'-' -f 1 packaging/version | tr -d 'v')" >> "${GITHUB_OUTPUT}"
  156. echo "retention=0" >> "${GITHUB_OUTPUT}"
  157. fi
  158. - name: Failure Notification
  159. uses: rtCamp/action-slack-notify@v2
  160. env:
  161. SLACK_COLOR: 'danger'
  162. SLACK_ICON_EMOJI: ':github-actions:'
  163. SLACK_TITLE: 'Package Build version check failed:'
  164. SLACK_USERNAME: 'GitHub Actions'
  165. SLACK_MESSAGE: |-
  166. ${{ github.repository }}: Failed to generate version information for package build.
  167. Checkout: ${{ steps.checkout.outcome }}
  168. Check Version: ${{ steps.check-version.outcome }}
  169. SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK_URL }}
  170. if: >-
  171. ${{
  172. failure()
  173. && github.event_name != 'pull_request'
  174. && startsWith(github.ref, 'refs/heads/master')
  175. && github.repository == 'netdata/netdata'
  176. }}
  177. build:
  178. name: Build
  179. runs-on: ubuntu-latest
  180. env:
  181. DOCKER_CLI_EXPERIMENTAL: enabled
  182. needs:
  183. - matrix
  184. - version-check
  185. - file-check
  186. strategy:
  187. matrix: ${{ fromJson(needs.matrix.outputs.matrix) }}
  188. # We intentiaonally disable the fail-fast behavior so that a
  189. # build failure for one version doesn't prevent us from publishing
  190. # successfully built and tested packages for another version.
  191. fail-fast: false
  192. max-parallel: 8
  193. steps:
  194. - name: Skip Check
  195. id: skip
  196. if: needs.file-check.outputs.run != 'true'
  197. run: echo "SKIPPED"
  198. - name: Checkout
  199. id: checkout
  200. if: needs.file-check.outputs.run == 'true'
  201. uses: actions/checkout@v4
  202. with:
  203. fetch-depth: 0 # We need full history for versioning
  204. submodules: recursive
  205. - name: Setup QEMU
  206. id: qemu
  207. if: matrix.platform != 'linux/amd64' && matrix.platform != 'linux/i386' && needs.file-check.outputs.run == 'true'
  208. uses: docker/setup-qemu-action@v3
  209. - name: Prepare Docker Environment
  210. id: docker-config
  211. if: needs.file-check.outputs.run == 'true'
  212. shell: bash
  213. run: |
  214. echo '{"cgroup-parent": "actions-job.slice", "experimental": true}' | sudo tee /etc/docker/daemon.json 2>/dev/null
  215. sudo service docker restart
  216. - name: Fetch images
  217. id: fetch-images
  218. if: needs.file-check.outputs.run == 'true'
  219. uses: nick-invision/retry@v2
  220. with:
  221. max_attempts: 3
  222. retry_wait_seconds: 30
  223. timeout_seconds: 900
  224. command: |
  225. docker pull --platform ${{ matrix.platform }} ${{ matrix.base_image }}
  226. docker pull --platform ${{ matrix.platform }} netdata/package-builders:${{ matrix.distro }}${{ matrix.version }}-v1
  227. - name: Build Packages
  228. id: build
  229. if: needs.file-check.outputs.run == 'true'
  230. shell: bash
  231. run: |
  232. docker run --security-opt seccomp=unconfined -e DISABLE_TELEMETRY=1 -e VERSION=${{ needs.version-check.outputs.version }} \
  233. --platform=${{ matrix.platform }} -v "$PWD":/netdata netdata/package-builders:${{ matrix.distro }}${{ matrix.version }}-v1
  234. - name: Save Packages
  235. id: artifacts
  236. if: needs.file-check.outputs.run == 'true'
  237. continue-on-error: true
  238. uses: actions/upload-artifact@v3
  239. with:
  240. name: ${{ matrix.distro }}-${{ matrix.version }}-${{ matrix.arch }}-packages
  241. path: ${{ github.workspace }}/artifacts/*
  242. - name: Test Packages
  243. id: test
  244. if: needs.file-check.outputs.run == 'true'
  245. shell: bash
  246. run: |
  247. docker run --security-opt seccomp=unconfined -e DISABLE_TELEMETRY=1 -e DISTRO=${{ matrix.distro }} \
  248. -e VERSION=${{ needs.version-check.outputs.version }} -e DISTRO_VERSION=${{ matrix.version }} \
  249. --platform=${{ matrix.platform }} -v "$PWD":/netdata ${{ matrix.base_image }} \
  250. /netdata/.github/scripts/pkg-test.sh
  251. - name: Upload to PackageCloud
  252. id: upload
  253. if: github.event_name == 'workflow_dispatch' && github.repository == 'netdata/netdata' && needs.file-check.outputs.run == 'true'
  254. continue-on-error: true
  255. shell: bash
  256. env:
  257. PKG_CLOUD_TOKEN: ${{ secrets.PACKAGE_CLOUD_API_KEY }}
  258. run: |
  259. printf "Packages to upload:\n%s" "$(ls artifacts/*.${{ matrix.format }})"
  260. for pkgfile in artifacts/*.${{ matrix.format }} ; do
  261. .github/scripts/package_cloud_wrapper.sh yank ${{ needs.version-check.outputs.repo }}/${{ matrix.repo_distro }} \
  262. "$(basename "${pkgfile}")" || true
  263. .github/scripts/package_cloud_wrapper.sh push ${{ needs.version-check.outputs.repo }}/${{ matrix.repo_distro }} "${pkgfile}"
  264. done
  265. - name: SSH setup
  266. id: ssh-setup
  267. if: github.event_name == 'workflow_dispatch' && github.repository == 'netdata/netdata' && needs.file-check.outputs.run == 'true'
  268. uses: shimataro/ssh-key-action@v2
  269. with:
  270. key: ${{ secrets.NETDATABOT_PACKAGES_SSH_KEY }}
  271. name: id_ecdsa
  272. known_hosts: ${{ secrets.PACKAGES_KNOWN_HOSTS }}
  273. - name: Upload to packages.netdata.cloud
  274. id: package-upload
  275. if: github.event_name == 'workflow_dispatch' && github.repository == 'netdata/netdata' && needs.file-check.outputs.run == 'true'
  276. run: |
  277. .github/scripts/package-upload.sh \
  278. ${{ matrix.repo_distro }} \
  279. ${{ matrix.arch }} \
  280. ${{ matrix.format }} \
  281. ${{ needs.version-check.outputs.repo }}
  282. - name: Failure Notification
  283. uses: rtCamp/action-slack-notify@v2
  284. env:
  285. SLACK_COLOR: 'danger'
  286. SLACK_ICON_EMOJI: ':github-actions:'
  287. SLACK_TITLE: 'Package Build failed:'
  288. SLACK_USERNAME: 'GitHub Actions'
  289. SLACK_MESSAGE: |-
  290. ${{ github.repository }}: ${{ matrix.repo_distro }} ${{ matrix.version }} package build for ${{ matrix.arch }} failed.
  291. Checkout: ${{ steps.checkout.outcome }}
  292. Setup QEMU: ${{ steps.qemu.outcome }}
  293. Setup Docker: ${{ steps.docker-config.outcome }}
  294. Fetch images: ${{ steps.fetch-images.outcome }}
  295. Build: ${{ steps.build.outcome }}
  296. Test: ${{ steps.test.outcome }}
  297. Publish to PackageCloud: ${{ steps.upload.outcome }}
  298. Import SSH Key: ${{ steps.ssh-setup.outcome }}
  299. Publish to packages.netdata.cloud: ${{ steps.package-upload.outcome }}
  300. SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK_URL }}
  301. if: >-
  302. ${{
  303. failure()
  304. && github.event_name != 'pull_request'
  305. && startsWith(github.ref, 'refs/heads/master')
  306. && github.repository == 'netdata/netdata'
  307. && needs.file-check.outputs.run == 'true'
  308. }}