static.yaml 10 KB

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