static.yaml 11 KB

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