docker.yml 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188
  1. name: Build Docker images
  2. on:
  3. pull_request:
  4. branches:
  5. - main
  6. push:
  7. branches:
  8. - main
  9. tags:
  10. - v*.*.*
  11. workflow_dispatch:
  12. inputs: {}
  13. jobs:
  14. prepare:
  15. runs-on: ubuntu-latest
  16. outputs:
  17. # Push only if it's a tag or if we're committing in the main branch
  18. push: ${{toJson(startsWith(github.ref, 'refs/tags/') || (github.ref == 'refs/heads/main' && github.event_name != 'pull_request'))}}
  19. variants: ${{ steps.matrix.outputs.variants }}
  20. platforms: ${{ steps.matrix.outputs.platforms }}
  21. metadata: ${{ steps.matrix.outputs.metadata }}
  22. steps:
  23. - uses: actions/checkout@v4
  24. - name: Set up Docker Buildx
  25. uses: docker/setup-buildx-action@v2
  26. with:
  27. version: latest
  28. - name: Create variants matrix
  29. id: matrix
  30. run: |
  31. METADATA=$(docker buildx bake --print | jq -c)
  32. echo "metadata=$METADATA" >> "$GITHUB_OUTPUT"
  33. echo "variants=$(jq -c '.group.default.targets|map(sub("runner-|builder-"; ""))|unique' <<< $METADATA)" >> "$GITHUB_OUTPUT"
  34. echo "platforms=$(jq -c 'first(.target[]) | .platforms' <<< $METADATA)" >> "$GITHUB_OUTPUT"
  35. env:
  36. LATEST: '1' # TODO: unset this variable when releasing the first stable version
  37. SHA: ${{github.sha}}
  38. VERSION: ${{github.ref_type == 'tag' && github.ref_name || github.sha}}
  39. build:
  40. runs-on: ubuntu-latest
  41. needs:
  42. - prepare
  43. strategy:
  44. fail-fast: false
  45. matrix:
  46. variant: ${{ fromJson(needs.prepare.outputs.variants) }}
  47. platform: ${{ fromJson(needs.prepare.outputs.platforms) }}
  48. include:
  49. - race: ""
  50. qemu: true
  51. - platform: linux/amd64
  52. qemu: false
  53. race: "-race" # The Go race detector is only supported on amd64
  54. - platform: linux/386
  55. qemu: false
  56. steps:
  57. - uses: actions/checkout@v4
  58. - name: Set up QEMU
  59. if: matrix.qemu
  60. uses: docker/setup-qemu-action@v2
  61. with:
  62. platforms: ${{matrix.platform}}
  63. - name: Set up Docker Buildx
  64. uses: docker/setup-buildx-action@v2
  65. with:
  66. platforms: ${{matrix.platform}}
  67. version: latest
  68. - name: Login to DockerHub
  69. if: fromJson(needs.prepare.outputs.push)
  70. uses: docker/login-action@v2
  71. with:
  72. username: ${{secrets.REGISTRY_USERNAME}}
  73. password: ${{secrets.REGISTRY_PASSWORD}}
  74. - name: Build
  75. id: build
  76. uses: docker/bake-action@v3
  77. with:
  78. pull: true
  79. load: ${{!fromJson(needs.prepare.outputs.push)}}
  80. targets: |
  81. builder-${{matrix.variant}}
  82. runner-${{matrix.variant}}
  83. # Remove tags to prevent "can't push tagged ref [...] by digest" error
  84. set: |
  85. *.tags=
  86. *.platform=${{matrix.platform}}
  87. *.cache-from=type=gha,scope=${{github.ref}}-${{matrix.platform}}
  88. *.cache-from=type=gha,scope=refs/heads/main-${{matrix.platform}}
  89. *.cache-to=type=gha,scope=${{github.ref}}-${{matrix.platform}}
  90. ${{fromJson(needs.prepare.outputs.push) && '*.output=type=image,name=dunglas/frankenphp,push-by-digest=true,name-canonical=true,push=true' || ''}}
  91. env:
  92. LATEST: '1' # TODO: unset this variable when releasing the first stable version
  93. SHA: ${{github.sha}}
  94. VERSION: ${{github.ref_type == 'tag' && github.ref_name || github.sha}}
  95. # Workaround for https://github.com/actions/runner/pull/2477#issuecomment-1501003600
  96. - name: Export metadata
  97. if: fromJson(needs.prepare.outputs.push)
  98. run: |
  99. mkdir -p /tmp/metadata/builder /tmp/metadata/runner
  100. builderDigest=$(jq -r '."builder-${{matrix.variant}}"."containerimage.digest"' <<< $METADATA)
  101. touch "/tmp/metadata/builder/${builderDigest#sha256:}"
  102. runnerDigest=$(jq -r '."runner-${{matrix.variant}}"."containerimage.digest"' <<< $METADATA)
  103. touch "/tmp/metadata/runner/${runnerDigest#sha256:}"
  104. env:
  105. METADATA: ${{steps.build.outputs.metadata}}
  106. - name: Upload runner metadata
  107. if: fromJson(needs.prepare.outputs.push)
  108. uses: actions/upload-artifact@v3
  109. with:
  110. name: metadata-builder-${{matrix.variant}}
  111. path: /tmp/metadata/builder/*
  112. if-no-files-found: error
  113. retention-days: 1
  114. - name: Upload runner metadata
  115. if: fromJson(needs.prepare.outputs.push)
  116. uses: actions/upload-artifact@v3
  117. with:
  118. name: metadata-runner-${{matrix.variant}}
  119. path: /tmp/metadata/runner/*
  120. if-no-files-found: error
  121. retention-days: 1
  122. - name: Run tests
  123. if: '!matrix.qemu'
  124. continue-on-error: ${{fromJson(needs.prepare.outputs.push)}}
  125. run: |
  126. docker run --platform=${{matrix.platform}} --rm \
  127. $(jq -r '."builder-${{matrix.variant}}"."containerimage.config.digest"' <<< $METADATA) \
  128. sh -c 'go test ${{matrix.race}} -v ./... && cd caddy && go test ${{matrix.race}} -v ./...'
  129. env:
  130. METADATA: ${{steps.build.outputs.metadata}}
  131. # Adapted from https://docs.docker.com/build/ci/github-actions/multi-platform/
  132. push:
  133. runs-on: ubuntu-latest
  134. needs:
  135. - prepare
  136. - build
  137. if: fromJson(needs.prepare.outputs.push)
  138. strategy:
  139. fail-fast: false
  140. matrix:
  141. variant: ${{ fromJson(needs.prepare.outputs.variants) }}
  142. target: ['builder', 'runner']
  143. steps:
  144. - name: Download metadata
  145. uses: actions/download-artifact@v3
  146. with:
  147. name: metadata-${{matrix.target}}-${{matrix.variant}}
  148. path: /tmp/metadata
  149. - name: Set up Docker Buildx
  150. uses: docker/setup-buildx-action@v2
  151. with:
  152. version: latest
  153. - name: Login to DockerHub
  154. uses: docker/login-action@v2
  155. with:
  156. username: ${{secrets.REGISTRY_USERNAME}}
  157. password: ${{secrets.REGISTRY_PASSWORD}}
  158. - name: Create manifest list and push
  159. working-directory: /tmp/metadata
  160. run: |
  161. docker buildx imagetools create $(jq -cr '.target."${{matrix.target}}-${{matrix.variant}}".tags | map("-t " + .) | join(" ")' <<< $METADATA) \
  162. $(printf 'dunglas/frankenphp@sha256:%s ' *)
  163. env:
  164. METADATA: ${{needs.prepare.outputs.metadata}}
  165. - name: Inspect image
  166. run: |
  167. docker buildx imagetools inspect $(jq -cr '.target."${{matrix.target}}-${{matrix.variant}}".tags | first' <<< $METADATA)
  168. env:
  169. METADATA: ${{needs.prepare.outputs.metadata}}