ci.yml 9.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343
  1. name: ci
  2. concurrency:
  3. group: ${{ github.workflow }}-${{ github.ref }}
  4. cancel-in-progress: true
  5. on:
  6. push:
  7. branches:
  8. - 'main'
  9. tags:
  10. - 'v*'
  11. pull_request:
  12. workflow_dispatch:
  13. inputs:
  14. debug_enabled:
  15. description: 'To run with tmate enter "debug_enabled"'
  16. required: false
  17. default: "false"
  18. permissions:
  19. contents: read # to fetch code (actions/checkout)
  20. jobs:
  21. prepare:
  22. runs-on: ubuntu-latest
  23. outputs:
  24. matrix: ${{ steps.platforms.outputs.matrix }}
  25. steps:
  26. -
  27. name: Checkout
  28. uses: actions/checkout@v4
  29. -
  30. name: Create matrix
  31. id: platforms
  32. run: |
  33. echo matrix=$(docker buildx bake binary-cross --print | jq -cr '.target."binary-cross".platforms') >> $GITHUB_OUTPUT
  34. -
  35. name: Show matrix
  36. run: |
  37. echo ${{ steps.platforms.outputs.matrix }}
  38. validate:
  39. runs-on: ubuntu-latest
  40. strategy:
  41. fail-fast: false
  42. matrix:
  43. target:
  44. - lint
  45. - validate-go-mod
  46. - validate-headers
  47. - validate-docs
  48. steps:
  49. -
  50. name: Checkout
  51. uses: actions/checkout@v4
  52. -
  53. name: Set up Docker Buildx
  54. uses: docker/setup-buildx-action@v3
  55. -
  56. name: Run
  57. run: |
  58. make ${{ matrix.target }}
  59. binary:
  60. runs-on: ubuntu-latest
  61. needs:
  62. - prepare
  63. strategy:
  64. fail-fast: false
  65. matrix:
  66. platform: ${{ fromJson(needs.prepare.outputs.matrix) }}
  67. steps:
  68. -
  69. name: Checkout
  70. uses: actions/checkout@v4
  71. -
  72. name: Prepare
  73. run: |
  74. platform=${MATRIX_PLATFORM}
  75. echo "PLATFORM_PAIR=${platform//\//-}" >> $GITHUB_ENV
  76. env:
  77. MATRIX_PLATFORM: ${{ matrix.platform }}
  78. -
  79. name: Set up QEMU
  80. uses: docker/setup-qemu-action@v3
  81. -
  82. name: Set up Docker Buildx
  83. uses: docker/setup-buildx-action@v3
  84. -
  85. name: Build
  86. uses: docker/bake-action@v6
  87. with:
  88. source: .
  89. targets: release
  90. provenance: mode=max
  91. sbom: true
  92. set: |
  93. *.platform=${{ matrix.platform }}
  94. *.cache-from=type=gha,scope=binary-${{ env.PLATFORM_PAIR }}
  95. *.cache-to=type=gha,scope=binary-${{ env.PLATFORM_PAIR }},mode=max
  96. -
  97. name: Rename provenance and sbom
  98. working-directory: ./bin/release
  99. run: |
  100. binname=$(find . -name 'docker-compose-*')
  101. filename=$(basename "$binname" | sed -E 's/\.exe$//')
  102. mv "provenance.json" "${filename}.provenance.json"
  103. mv "sbom-binary.spdx.json" "${filename}.sbom.json"
  104. find . -name 'sbom*.json' -exec rm {} \;
  105. -
  106. name: List artifacts
  107. run: |
  108. tree -nh ./bin/release
  109. -
  110. name: Upload artifacts
  111. uses: actions/upload-artifact@v4
  112. with:
  113. name: compose-${{ env.PLATFORM_PAIR }}
  114. path: ./bin/release
  115. if-no-files-found: error
  116. test:
  117. runs-on: ubuntu-latest
  118. steps:
  119. -
  120. name: Set up Docker Buildx
  121. uses: docker/setup-buildx-action@v3
  122. -
  123. name: Test
  124. uses: docker/bake-action@v6
  125. with:
  126. targets: test
  127. set: |
  128. *.cache-from=type=gha,scope=test
  129. *.cache-to=type=gha,scope=test
  130. -
  131. name: Gather coverage data
  132. uses: actions/upload-artifact@v4
  133. with:
  134. name: coverage-data-unit
  135. path: bin/coverage/unit/
  136. if-no-files-found: error
  137. -
  138. name: Unit Test Summary
  139. uses: test-summary/action@v2
  140. with:
  141. paths: bin/coverage/unit/report.xml
  142. if: always()
  143. e2e:
  144. runs-on: ubuntu-latest
  145. name: e2e (${{ matrix.mode }}, ${{ matrix.channel }})
  146. strategy:
  147. fail-fast: false
  148. matrix:
  149. include:
  150. # current stable
  151. - mode: plugin
  152. engine: 29
  153. channel: stable
  154. - mode: standalone
  155. engine: 29
  156. channel: stable
  157. # old stable (latest major - 1)
  158. - mode: plugin
  159. engine: 28
  160. channel: oldstable
  161. - mode: standalone
  162. engine: 28
  163. channel: oldstable
  164. steps:
  165. - name: Prepare
  166. run: |
  167. mode=${{ matrix.mode }}
  168. engine=${{ matrix.engine }}
  169. echo "MODE_ENGINE_PAIR=${mode}-${engine}" >> $GITHUB_ENV
  170. - name: Checkout
  171. uses: actions/checkout@v4
  172. - name: Install Docker ${{ matrix.engine }}
  173. run: |
  174. sudo systemctl stop docker.service
  175. sudo apt-get purge docker-ce docker-ce-cli containerd.io docker-compose-plugin docker-ce-rootless-extras docker-buildx-plugin
  176. sudo apt-get install curl
  177. curl -fsSL https://test.docker.com -o get-docker.sh
  178. sudo sh ./get-docker.sh --version ${{ matrix.engine }}
  179. - name: Check Docker Version
  180. run: docker --version
  181. - name: Set up Docker Buildx
  182. uses: docker/setup-buildx-action@v3
  183. - name: Set up Docker Model
  184. run: |
  185. sudo apt-get install docker-model-plugin
  186. docker model version
  187. - name: Set up Go
  188. uses: actions/setup-go@v5
  189. with:
  190. go-version-file: 'go.mod'
  191. check-latest: true
  192. cache: true
  193. - name: Build example provider
  194. run: make example-provider
  195. - name: Build
  196. uses: docker/bake-action@v6
  197. with:
  198. source: .
  199. targets: binary-with-coverage
  200. set: |
  201. *.cache-from=type=gha,scope=binary-linux-amd64
  202. *.cache-from=type=gha,scope=binary-e2e-${{ matrix.mode }}
  203. *.cache-to=type=gha,scope=binary-e2e-${{ matrix.mode }},mode=max
  204. env:
  205. BUILD_TAGS: e2e
  206. - name: Setup tmate session
  207. if: ${{ github.event_name == 'workflow_dispatch' && github.event.inputs.debug_enabled }}
  208. uses: mxschmitt/action-tmate@8b4e4ac71822ed7e0ad5fb3d1c33483e9e8fb270 # v3.11
  209. with:
  210. limit-access-to-actor: true
  211. github-token: ${{ secrets.GITHUB_TOKEN }}
  212. - name: Test plugin mode
  213. if: ${{ matrix.mode == 'plugin' }}
  214. run: |
  215. rm -rf ./bin/coverage/e2e
  216. mkdir -p ./bin/coverage/e2e
  217. make e2e-compose GOCOVERDIR=bin/coverage/e2e TEST_FLAGS="-v"
  218. - name: Gather coverage data
  219. if: ${{ matrix.mode == 'plugin' }}
  220. uses: actions/upload-artifact@v4
  221. with:
  222. name: coverage-data-e2e-${{ env.MODE_ENGINE_PAIR }}
  223. path: bin/coverage/e2e/
  224. if-no-files-found: error
  225. - name: Test standalone mode
  226. if: ${{ matrix.mode == 'standalone' }}
  227. run: |
  228. rm -f /usr/local/bin/docker-compose
  229. cp bin/build/docker-compose /usr/local/bin
  230. make e2e-compose-standalone
  231. - name: e2e Test Summary
  232. uses: test-summary/action@v2
  233. with:
  234. paths: /tmp/report/report.xml
  235. if: always()
  236. coverage:
  237. runs-on: ubuntu-latest
  238. needs:
  239. - test
  240. - e2e
  241. steps:
  242. # codecov won't process the report without the source code available
  243. - name: Checkout
  244. uses: actions/checkout@v4
  245. - name: Set up Go
  246. uses: actions/setup-go@v5
  247. with:
  248. go-version-file: 'go.mod'
  249. check-latest: true
  250. - name: Download unit test coverage
  251. uses: actions/download-artifact@v4
  252. with:
  253. name: coverage-data-unit
  254. path: coverage/unit
  255. merge-multiple: true
  256. - name: Download E2E test coverage
  257. uses: actions/download-artifact@v4
  258. with:
  259. pattern: coverage-data-e2e-*
  260. path: coverage/e2e
  261. merge-multiple: true
  262. - name: Merge coverage reports
  263. run: |
  264. go tool covdata textfmt -i=./coverage/unit,./coverage/e2e -o ./coverage.txt
  265. - name: Store coverage report in GitHub Actions
  266. uses: actions/upload-artifact@v4
  267. with:
  268. name: go-covdata-txt
  269. path: ./coverage.txt
  270. if-no-files-found: error
  271. - name: Upload coverage to Codecov
  272. uses: codecov/codecov-action@v3
  273. with:
  274. files: ./coverage.txt
  275. release:
  276. permissions:
  277. contents: write # to create a release (ncipollo/release-action)
  278. runs-on: ubuntu-latest
  279. needs:
  280. - binary
  281. steps:
  282. -
  283. name: Checkout
  284. uses: actions/checkout@v4
  285. -
  286. name: Download artifacts
  287. uses: actions/download-artifact@v4
  288. with:
  289. pattern: compose-*
  290. path: ./bin/release
  291. merge-multiple: true
  292. -
  293. name: Create checksums
  294. working-directory: ./bin/release
  295. run: |
  296. find . -type f -print0 | sort -z | xargs -r0 shasum -a 256 -b | sed 's# \*\./# *#' > $RUNNER_TEMP/checksums.txt
  297. shasum -a 256 -U -c $RUNNER_TEMP/checksums.txt
  298. mv $RUNNER_TEMP/checksums.txt .
  299. cat checksums.txt | while read sum file; do
  300. if [[ "${file#\*}" == docker-compose-* && "${file#\*}" != *.provenance.json && "${file#\*}" != *.sbom.json ]]; then
  301. echo "$sum $file" > ${file#\*}.sha256
  302. fi
  303. done
  304. -
  305. name: List artifacts
  306. run: |
  307. tree -nh ./bin/release
  308. -
  309. name: Check artifacts
  310. run: |
  311. find bin/release -type f -exec file -e ascii -- {} +
  312. -
  313. name: GitHub Release
  314. if: startsWith(github.ref, 'refs/tags/v')
  315. uses: ncipollo/release-action@58ae73b360456532aafd58ee170c045abbeaee37 # v1.10.0
  316. with:
  317. artifacts: ./bin/release/*
  318. generateReleaseNotes: true
  319. draft: true
  320. token: ${{ secrets.GITHUB_TOKEN }}