packaging.yml 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262
  1. ---
  2. # Handles building of binary packages for the agent.
  3. name: Packages
  4. on:
  5. pull_request:
  6. branches:
  7. - master
  8. - develop
  9. push:
  10. branches:
  11. - master
  12. workflow_dispatch:
  13. inputs:
  14. type:
  15. description: Package build type
  16. default: devel
  17. required: true
  18. version:
  19. description: Package version
  20. required: false
  21. env:
  22. DISABLE_TELEMETRY: 1
  23. REPO_PREFIX: netdata/netdata
  24. concurrency:
  25. group: packages-${{ github.ref }}-${{ github.event_name }}
  26. cancel-in-progress: true
  27. jobs:
  28. matrix:
  29. name: Prepare Build Matrix
  30. runs-on: ubuntu-latest
  31. outputs:
  32. matrix: ${{ steps.set-matrix.outputs.matrix }}
  33. steps:
  34. - name: Checkout
  35. id: checkout
  36. uses: actions/checkout@v3
  37. - name: Prepare tools
  38. id: prepare
  39. run: |
  40. sudo apt-get update && sudo apt-get install -y python3-ruamel.yaml
  41. - name: Read build matrix
  42. id: set-matrix
  43. shell: python3 {0}
  44. run: |
  45. from ruamel.yaml import YAML
  46. import json
  47. import re
  48. FULL_CI_REGEX = '/actions run full ci'
  49. ALWAYS_RUN_ARCHES = ["amd64"]
  50. PR_BODY = """${{ github.event.pull_request.body }}"""
  51. yaml = YAML(typ='safe')
  52. entries = list()
  53. run_limited = False
  54. with open('.github/data/distros.yml') as f:
  55. data = yaml.load(f)
  56. if "${{ github.event_name }}" == "pull_request" and re.search(FULL_CI_REGEX, PR_BODY, re.I) is None:
  57. run_limited = True
  58. for i, v in enumerate(data['include']):
  59. if 'packages' in data['include'][i]:
  60. for arch in data['include'][i]['packages']['arches']:
  61. if arch in ALWAYS_RUN_ARCHES or not run_limited:
  62. entries.append({
  63. 'distro': data['include'][i]['distro'],
  64. 'version': data['include'][i]['version'],
  65. 'pkgclouddistro': data['include'][i]['packages']['repo_distro'],
  66. 'format': data['include'][i]['packages']['type'],
  67. 'base_image': data['include'][i]['base_image'] if 'base_image' in data['include'][i] else data['include'][i]['distro'],
  68. 'platform': data['platform_map'][arch],
  69. 'arch': arch
  70. })
  71. entries.sort(key=lambda k: (k['arch'], k['distro'], k['version']))
  72. matrix = json.dumps({'include': entries}, sort_keys=True)
  73. print('Generated Matrix: ' + matrix)
  74. print('::set-output name=matrix::' + matrix)
  75. - name: Failure Notification
  76. uses: rtCamp/action-slack-notify@v2
  77. env:
  78. SLACK_COLOR: 'danger'
  79. SLACK_ICON_EMOJI: ':github-actions:'
  80. SLACK_TITLE: 'Package Build matrix generation failed:'
  81. SLACK_USERNAME: 'GitHub Actions'
  82. SLACK_MESSAGE: |-
  83. ${{ github.repository }}: Failed to generate build matrix for package build.
  84. Checkout: ${{ steps.checkout.outcome }}
  85. Prepare Tools: ${{ steps.prepare.outcome }}
  86. Read Build Matrix: ${{ steps.set-matrix.outcome }}
  87. SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK_URL }}
  88. if: >-
  89. ${{
  90. failure()
  91. && github.event_name != 'pull_request'
  92. && startsWith(github.ref, 'refs/heads/master')
  93. }}
  94. version-check:
  95. name: Version check
  96. runs-on: ubuntu-latest
  97. outputs:
  98. repo: ${{ steps.check-version.outputs.repo }}
  99. version: ${{ steps.check-version.outputs.version }}
  100. retention: ${{ steps.check-version.outputs.retention }}
  101. steps:
  102. - name: Checkout
  103. id: checkout
  104. uses: actions/checkout@v3
  105. - name: Check Version
  106. id: check-version
  107. run: |
  108. if [ "${{ github.event_name }}" == "workflow_dispatch" ]; then
  109. case "${{ github.event.inputs.type }}" in
  110. "release")
  111. echo "::set-output name=repo::${REPO_PREFIX}"
  112. echo "::set-output name=version::${{ github.event.inputs.version }}"
  113. echo "::set-output name=retention::365"
  114. ;;
  115. "nightly")
  116. echo "::set-output name=repo::${REPO_PREFIX}-edge"
  117. echo "::set-output name=version::$(tr -d 'v' < packaging/version)"
  118. echo "::set-output name=retention::30"
  119. ;;
  120. *)
  121. echo "::set-output name=repo::${REPO_PREFIX}-devel"
  122. echo "::set-output name=version::0.${GITHUB_SHA}"
  123. echo "::set-output name=retention::30"
  124. ;;
  125. esac
  126. else
  127. echo "::set-output name=version::$(cut -d'-' -f 1 packaging/version | tr -d 'v')"
  128. echo "::set-output name=retention::0"
  129. fi
  130. - name: Failure Notification
  131. uses: rtCamp/action-slack-notify@v2
  132. env:
  133. SLACK_COLOR: 'danger'
  134. SLACK_ICON_EMOJI: ':github-actions:'
  135. SLACK_TITLE: 'Package Build version check failed:'
  136. SLACK_USERNAME: 'GitHub Actions'
  137. SLACK_MESSAGE: |-
  138. ${{ github.repository }}: Failed to generate version information for package build.
  139. Checkout: ${{ steps.checkout.outcome }}
  140. Check Version: ${{ steps.check-version.outcome }}
  141. SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK_URL }}
  142. if: >-
  143. ${{
  144. failure()
  145. && github.event_name != 'pull_request'
  146. && startsWith(github.ref, 'refs/heads/master')
  147. }}
  148. build:
  149. name: Build
  150. runs-on: ubuntu-latest
  151. env:
  152. DOCKER_CLI_EXPERIMENTAL: enabled
  153. needs:
  154. - matrix
  155. - version-check
  156. strategy:
  157. matrix: ${{ fromJson(needs.matrix.outputs.matrix) }}
  158. # We intentiaonally disable the fail-fast behavior so that a
  159. # build failure for one version doesn't prevent us from publishing
  160. # successfully built and tested packages for another version.
  161. fail-fast: false
  162. max-parallel: 8
  163. steps:
  164. - name: Checkout
  165. id: checkout
  166. uses: actions/checkout@v3
  167. with:
  168. fetch-depth: 0 # We need full history for versioning
  169. submodules: recursive
  170. - name: Setup QEMU
  171. id: qemu
  172. if: matrix.platform != 'linux/amd64' && matrix.platform != 'linux/i386'
  173. uses: docker/setup-qemu-action@v1
  174. - name: Prepare Docker Environment
  175. id: docker-config
  176. shell: bash
  177. run: |
  178. echo '{"cgroup-parent": "/actions_job", "experimental": true}' | sudo tee /etc/docker/daemon.json 2>/dev/null
  179. sudo service docker restart
  180. - name: Fetch images
  181. id: fetch-images
  182. uses: nick-invision/retry@v2
  183. with:
  184. max_attempts: 3
  185. retry_wait_seconds: 30
  186. timeout_seconds: 900
  187. command: |
  188. docker pull --platform ${{ matrix.platform }} ${{ matrix.base_image }}:${{ matrix.version }}
  189. docker pull --platform ${{ matrix.platform }} netdata/package-builders:${{ matrix.distro }}${{ matrix.version }}
  190. - name: Build Packages
  191. id: build
  192. shell: bash
  193. run: |
  194. docker run --security-opt seccomp=unconfined -e DISABLE_TELEMETRY=1 -e VERSION=${{ needs.version-check.outputs.version }} \
  195. --platform=${{ matrix.platform }} -v "$PWD":/netdata netdata/package-builders:${{ matrix.distro }}${{ matrix.version }}
  196. - name: Test Packages
  197. id: test
  198. shell: bash
  199. run: |
  200. docker run --security-opt seccomp=unconfined -e DISABLE_TELEMETRY=1 -e DISTRO=${{ matrix.distro }} \
  201. -e VERSION=${{ needs.version-check.outputs.version }} -e DISTRO_VERSION=${{ matrix.version }} \
  202. --platform=${{ matrix.platform }} -v "$PWD":/netdata ${{ matrix.base_image }}:${{ matrix.version }} \
  203. /netdata/.github/scripts/pkg-test.sh
  204. - name: Save Packages
  205. id: artifacts
  206. continue-on-error: true
  207. uses: actions/upload-artifact@v3
  208. with:
  209. name: ${{ matrix.distro }}-${{ matrix.version }}-${{ matrix.arch }}-packages
  210. path: ${{ github.workspace }}/artifacts/*
  211. - name: Upload to PackageCloud
  212. id: upload
  213. if: github.event_name == 'workflow_dispatch'
  214. shell: bash
  215. env:
  216. PKG_CLOUD_TOKEN: ${{ secrets.PACKAGE_CLOUD_API_KEY }}
  217. run: |
  218. printf "Packages to upload:\n%s" "$(ls artifacts/*.${{ matrix.format }})"
  219. for pkgfile in artifacts/*.${{ matrix.format }} ; do
  220. .github/scripts/package_cloud_wrapper.sh yank ${{ needs.version-check.outputs.repo }}/${{ matrix.pkgclouddistro }} \
  221. "$(basename "${pkgfile}")" || true
  222. .github/scripts/package_cloud_wrapper.sh push ${{ needs.version-check.outputs.repo }}/${{ matrix.pkgclouddistro }} "${pkgfile}"
  223. done
  224. - name: Clean
  225. id: cleanup
  226. if: github.event_name == 'workflow_dispatch'
  227. shell: bash
  228. env:
  229. REPO: ${{ needs.version-check.outputs.repo }}
  230. PKG_CLOUD_TOKEN: ${{ secrets.PACKAGE_CLOUD_API_KEY }}
  231. PACKAGE_CLOUD_RETENTION_DAYS: ${{ needs.version-check.outputs.retention }}
  232. run: .github/scripts/old_package_purging.sh
  233. - name: Failure Notification
  234. uses: rtCamp/action-slack-notify@v2
  235. env:
  236. SLACK_COLOR: 'danger'
  237. SLACK_ICON_EMOJI: ':github-actions:'
  238. SLACK_TITLE: 'Package Build failed:'
  239. SLACK_USERNAME: 'GitHub Actions'
  240. SLACK_MESSAGE: |-
  241. ${{ github.repository }}: ${{ matrix.pkgclouddistro }} ${{ matrix.version }} package build for ${{ matrix.arch }} failed.
  242. Checkout: ${{ steps.checkout.outcome }}
  243. Setup QEMU: ${{ steps.qemu.outcome }}
  244. Setup Docker: ${{ steps.docker-config.outcome }}
  245. Fetch images: ${{ steps.fetch-images.outcome }}
  246. Build: ${{ steps.build.outcome }}
  247. Test: ${{ steps.test.outcome }}
  248. Publish: ${{ steps.upload.outcome }}
  249. Cleanup: ${{ steps.cleanup.outcome }}
  250. SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK_URL }}
  251. if: >-
  252. ${{
  253. failure()
  254. && github.event_name != 'pull_request'
  255. && startsWith(github.ref, 'refs/heads/master')
  256. }}