ci.yml 9.5 KB

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