static.yaml 9.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257
  1. ---
  2. name: Build binary releases
  3. on:
  4. pull_request:
  5. branches:
  6. - main
  7. push:
  8. branches:
  9. - main
  10. tags:
  11. - v*.*.*
  12. workflow_dispatch:
  13. inputs:
  14. version:
  15. description: 'FrankenPHP version'
  16. required: false
  17. type: string
  18. schedule:
  19. - cron: '0 0 * * *'
  20. env:
  21. IMAGE_NAME: ${{ (github.event_name == 'schedule' || (github.event_name == 'workflow_dispatch' && inputs.version) || startsWith(github.ref, 'refs/tags/')) && 'dunglas/frankenphp' || 'dunglas/frankenphp-dev' }}
  22. jobs:
  23. prepare:
  24. runs-on: ubuntu-latest
  25. outputs:
  26. push: ${{ toJson((steps.check.outputs.ref || (github.event_name == 'workflow_dispatch' && inputs.version) || startsWith(github.ref, 'refs/tags/') || (github.ref == 'refs/heads/main' && github.event_name != 'pull_request')) && true || false) }}
  27. platforms: ${{ steps.matrix.outputs.platforms }}
  28. metadata: ${{ steps.matrix.outputs.metadata }}
  29. ref: ${{ steps.check.outputs.ref }}
  30. steps:
  31. -
  32. name: Get version
  33. id: check
  34. if: github.event_name == 'schedule'
  35. run: |
  36. ref="${{ (github.ref_type == 'tag' && github.ref_name) || (github.event_name == 'workflow_dispatch' && inputs.version) || '' }}"
  37. if [[ -z "${ref}" ]]; then
  38. ref="$(gh release view --repo dunglas/frankenphp --json tagName --jq '.tagName')"
  39. fi
  40. echo "ref=${ref}" >> "${GITHUB_OUTPUT}"
  41. env:
  42. GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
  43. -
  44. uses: actions/checkout@v4
  45. with:
  46. ref: ${{ steps.check.outputs.ref }}
  47. -
  48. name: Set up Docker Buildx
  49. uses: docker/setup-buildx-action@v3
  50. with:
  51. version: latest
  52. -
  53. name: Create platforms matrix
  54. id: matrix
  55. run: |
  56. METADATA="$(docker buildx bake --print static-builder | jq -c)"
  57. {
  58. echo metadata="${METADATA}"
  59. echo platforms="$(jq -c 'first(.target[]) | .platforms' <<< "${METADATA}")"
  60. } >> "${GITHUB_OUTPUT}"
  61. env:
  62. SHA: ${{ github.sha }}
  63. VERSION: ${{ steps.check.outputs.ref || github.sha }}
  64. build-linux:
  65. strategy:
  66. fail-fast: false
  67. matrix:
  68. platform: ${{ fromJson(needs.prepare.outputs.platforms) }}
  69. include:
  70. - race: ""
  71. qemu: true
  72. - platform: linux/amd64
  73. qemu: false
  74. name: Build ${{ matrix.platform }} static binary
  75. runs-on: ubuntu-latest
  76. needs: [ prepare ]
  77. steps:
  78. -
  79. uses: actions/checkout@v4
  80. with:
  81. ref: ${{ needs.prepare.outputs.ref }}
  82. -
  83. name: Set up QEMU
  84. if: matrix.qemu
  85. uses: docker/setup-qemu-action@v3
  86. with:
  87. platforms: ${{ matrix.platform }}
  88. -
  89. name: Set up Docker Buildx
  90. uses: docker/setup-buildx-action@v3
  91. with:
  92. platforms: ${{ matrix.platform }}
  93. version: latest
  94. -
  95. name: Login to DockerHub
  96. if: ${{ fromJson(needs.prepare.outputs.push) }}
  97. uses: docker/login-action@v3
  98. with:
  99. username: ${{ secrets.REGISTRY_USERNAME }}
  100. password: ${{ secrets.REGISTRY_PASSWORD }}
  101. -
  102. name: Build
  103. id: build
  104. uses: docker/bake-action@v4
  105. with:
  106. pull: true
  107. load: ${{ !fromJson(needs.prepare.outputs.push) }}
  108. targets: static-builder
  109. set: |
  110. *.tags=
  111. *.platform=${{ matrix.platform }}
  112. *.cache-from=type=gha,scope=${{ needs.prepare.outputs.ref || github.ref }}-static-builder
  113. *.cache-from=type=gha,scope=refs/heads/main-static-builder
  114. *.cache-to=type=gha,scope=${{ needs.prepare.outputs.ref || github.ref }}-static-builder,ignore-error=true
  115. ${{ fromJson(needs.prepare.outputs.push) && '*.output=type=image,name=dunglas/frankenphp,push-by-digest=true,name-canonical=true,push=true' || '' }}
  116. env:
  117. SHA: ${{ github.sha }}
  118. VERSION: ${{ (github.ref_type == 'tag' && github.ref_name) || needs.prepare.outputs.ref || github.sha}}
  119. GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
  120. -
  121. # Workaround for https://github.com/actions/runner/pull/2477#issuecomment-1501003600
  122. name: Export metadata
  123. if: fromJson(needs.prepare.outputs.push)
  124. run: |
  125. mkdir -p /tmp/metadata
  126. # shellcheck disable=SC2086
  127. digest=$(jq -r '."static-builder"."containerimage.digest"' <<< ${METADATA})
  128. touch "/tmp/metadata/${digest#sha256:}"
  129. env:
  130. METADATA: ${{ steps.build.outputs.metadata }}
  131. -
  132. name: Upload metadata
  133. if: fromJson(needs.prepare.outputs.push)
  134. uses: actions/upload-artifact@v3
  135. with:
  136. name: metadata-static-builder
  137. path: /tmp/metadata/*
  138. if-no-files-found: error
  139. retention-days: 1
  140. -
  141. name: Copy binary
  142. if: ${{ !fromJson(needs.prepare.outputs.push) }}
  143. run: |
  144. digest=$(jq -r '."static-builder"."containerimage.config.digest"' <<< "${METADATA}")
  145. docker create --platform=${{ matrix.platform }} --name static-builder "${digest}"
  146. docker cp "static-builder:/go/src/app/dist/${BINARY}" "${BINARY}"
  147. env:
  148. METADATA: ${{ steps.build.outputs.metadata }}
  149. BINARY: frankenphp-linux-${{ matrix.platform == 'linux/amd64' && 'x86_64' || 'aarch64' }}
  150. -
  151. name: Upload artifact
  152. if: ${{ !fromJson(needs.prepare.outputs.push) }}
  153. uses: actions/upload-artifact@v3
  154. with:
  155. name: frankenphp-linux-${{ matrix.platform == 'linux/amd64' && 'x86_64' || 'aarch64' }}
  156. path: frankenphp-linux-${{ matrix.platform == 'linux/amd64' && 'x86_64' || 'aarch64' }}
  157. # Adapted from https://docs.docker.com/build/ci/github-actions/multi-platform/
  158. push:
  159. runs-on: ubuntu-latest
  160. needs:
  161. - prepare
  162. - build-linux
  163. if: fromJson(needs.prepare.outputs.push)
  164. #if: fromJson(needs.prepare.outputs.push) && (needs.prepare.outputs.ref || github.ref_type == 'tag')
  165. steps:
  166. -
  167. name: Download metadata
  168. uses: actions/download-artifact@v3
  169. with:
  170. name: metadata-static-builder
  171. path: /tmp/metadata
  172. -
  173. name: Set up Docker Buildx
  174. uses: docker/setup-buildx-action@v3
  175. with:
  176. version: latest
  177. -
  178. name: Login to DockerHub
  179. uses: docker/login-action@v3
  180. with:
  181. username: ${{ secrets.REGISTRY_USERNAME }}
  182. password: ${{ secrets.REGISTRY_PASSWORD }}
  183. -
  184. name: Create manifest list and push
  185. working-directory: /tmp/metadata
  186. run: |
  187. # shellcheck disable=SC2046,SC2086
  188. docker buildx imagetools create $(jq -cr '.target."static-builder".tags | map("-t " + .) | join(" ")' <<< "${METADATA}") \
  189. $(printf 'dunglas/frankenphp@sha256:%s ' *)
  190. env:
  191. METADATA: ${{ needs.prepare.outputs.metadata }}
  192. -
  193. name: Inspect image
  194. run: |
  195. # shellcheck disable=SC2046,SC2086
  196. docker buildx imagetools inspect "$(jq -cr '.target."static-builder".tags | first' <<< "${METADATA}")"
  197. env:
  198. METADATA: ${{ needs.prepare.outputs.metadata }}
  199. -
  200. name: Copy binary
  201. run: |
  202. tag=$(jq -cr '.target."static-builder".tags | first' <<< "${METADATA}")
  203. docker cp "$(docker create --platform=linux/amd64 --name static-builder "${tag}"):/go/src/app/dist/frankenphp-linux-x86_64" frankenphp-linux-x86_64 ; docker rm static-builder
  204. docker cp "$(docker create --platform=linux/arm64 --name static-builder "${tag}"):/go/src/app/dist/frankenphp-linux-aarch64" frankenphp-linux-aarch64 ; docker rm static-builder
  205. env:
  206. METADATA: ${{ needs.prepare.outputs.metadata }}
  207. -
  208. name: Upload asset
  209. if: needs.prepare.outputs.ref || github.ref_type == 'tag'
  210. run: gh release upload "${{ (github.ref_type == 'tag' && github.ref_name) || needs.prepare.outputs.ref }}" frankenphp-linux-x86_64 frankenphp-linux-aarch64 --repo dunglas/frankenphp --clobber
  211. env:
  212. GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
  213. build-mac:
  214. name: Build macOS x86_64 binaries
  215. runs-on: macos-latest
  216. needs: [ prepare ]
  217. env:
  218. HOMEBREW_NO_AUTO_UPDATE: 1
  219. steps:
  220. -
  221. uses: actions/checkout@v4
  222. with:
  223. ref: ${{ needs.prepare.outputs.ref }}
  224. -
  225. uses: actions/setup-go@v5
  226. with:
  227. go-version: '1.21'
  228. cache-dependency-path: |
  229. go.sum
  230. caddy/go.sum
  231. -
  232. name: Set FRANKENPHP_VERSION
  233. run: |
  234. if [ "${GITHUB_REF_TYPE}" == "tag" ]; then
  235. export FRANKENPHP_VERSION=${GITHUB_REF_NAME:1}
  236. elif [ "${GITHUB_EVENT_NAME}" == "schedule" ]; then
  237. export FRANKENPHP_VERSION="${{ needs.prepare.outputs.ref }}"
  238. else
  239. export FRANKENPHP_VERSION=${GITHUB_SHA}
  240. fi
  241. echo "FRANKENPHP_VERSION=${FRANKENPHP_VERSION}" >> "${GITHUB_ENV}"
  242. -
  243. name: Build FrankenPHP
  244. run: ./build-static.sh
  245. env:
  246. GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
  247. RELEASE: ${{ (needs.prepare.outputs.ref || github.ref_type == 'tag') && '1' || '' }}
  248. -
  249. name: Upload artifact
  250. if: github.ref_type == 'branch'
  251. uses: actions/upload-artifact@v3
  252. with:
  253. name: frankenphp-mac-x86_64
  254. path: dist/frankenphp-mac-x86_64