build.yml 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313
  1. name: Build
  2. on:
  3. push:
  4. branches-ignore:
  5. - 'weblate'
  6. paths:
  7. - "app/**/*.js"
  8. - "app/**/*.vue"
  9. - "app/src/language/**/*.po"
  10. - "app/i18n.json"
  11. - "app/package.json"
  12. - "app/.env*"
  13. - "**/*.go"
  14. - "go.mod"
  15. - "go.sum"
  16. - ".github/workflows/build*.yml"
  17. - "resources/docker/docker/*"
  18. - "resources/development/*"
  19. - "resources/demo/*"
  20. - "Dockerfile"
  21. - "demo.Dockerfile"
  22. pull_request:
  23. types: [ opened, synchronize, reopened ]
  24. paths:
  25. - "**/*.js"
  26. - "**/*.vue"
  27. - "app/package.json"
  28. - "app/.env*"
  29. - "**/*.go"
  30. - "go.mod"
  31. - "go.sum"
  32. - ".github/workflows/*.yml"
  33. - "resources/docker/docker/*"
  34. - "resources/development/*"
  35. - "resources/demo/*"
  36. release:
  37. types:
  38. - published
  39. jobs:
  40. build_app:
  41. runs-on: macos-14
  42. steps:
  43. - name: Checkout
  44. uses: actions/checkout@v4
  45. - name: Set up nodejs
  46. uses: actions/setup-node@v4
  47. with:
  48. node-version: current
  49. - name: Install dependencies
  50. run: |
  51. corepack enable
  52. corepack prepare pnpm@latest --activate
  53. pnpm install
  54. working-directory: app
  55. - name: Check frontend code style
  56. run: |
  57. pnpm run lint
  58. working-directory: app
  59. - name: Check frontend types
  60. run: |
  61. pnpm run typecheck
  62. working-directory: app
  63. - name: Build
  64. run: |
  65. npx browserslist@latest --update-db
  66. pnpm build
  67. working-directory: app
  68. - name: Archive app artifacts
  69. uses: actions/upload-artifact@v4
  70. with:
  71. name: app-dist
  72. path: app/dist
  73. - name: Prepare publish
  74. if: github.event_name == 'release'
  75. run: |
  76. cp README*.md app/dist
  77. find app/dist -printf '%P\n' | tar -C app/dist --no-recursion -zcvf app-dist.tar.gz -T -
  78. - name: Publish
  79. uses: softprops/action-gh-release@v2
  80. if: github.event_name == 'release'
  81. with:
  82. files: app-dist.tar.gz
  83. build:
  84. runs-on: ubuntu-latest
  85. needs: build_app
  86. strategy:
  87. matrix:
  88. goos: [ linux, darwin ]
  89. goarch: [ amd64, 386, arm64 ]
  90. exclude:
  91. # Exclude i386 on darwin.
  92. - goarch: 386
  93. goos: darwin
  94. include:
  95. # BEGIN Linux ARM 5 6 7
  96. - goos: linux
  97. goarch: arm
  98. goarm: 7
  99. - goos: linux
  100. goarch: arm
  101. goarm: 6
  102. - goos: linux
  103. goarch: arm
  104. goarm: 5
  105. # END Linux ARM 5 6 7
  106. - goos: linux
  107. goarch: riscv64
  108. - goos: linux
  109. goarch: loong64
  110. # BEGIN MIPS
  111. - goos: linux
  112. goarch: mips64
  113. - goos: linux
  114. goarch: mips64le
  115. - goos: linux
  116. goarch: mipsle
  117. - goos: linux
  118. goarch: mips
  119. # END MIPS
  120. env:
  121. CGO_ENABLED: 1
  122. GOOS: ${{ matrix.goos }}
  123. GOARCH: ${{ matrix.goarch }}
  124. GOARM: ${{ matrix.goarm }}
  125. steps:
  126. - name: Checkout
  127. uses: actions/checkout@v4
  128. - name: Set up Go
  129. uses: actions/setup-go@v5
  130. with:
  131. go-version: ^1.24.2
  132. cache: false
  133. - name: Setup environment
  134. id: info
  135. run: |
  136. export _NAME=$(jq ".$GOOS[\"$GOARCH$GOARM\"].name" -r < .github/build/build_info.json)
  137. export _ARCH=$(jq ".$GOOS[\"$GOARCH$GOARM\"].arch" -r < .github/build/build_info.json)
  138. export _ABI=$(jq ".$GOOS[\"$GOARCH$GOARM\"].abi // \"\"" -r < .github/build/build_info.json)
  139. export _ARTIFACT=nginx-ui-$GOOS-$GOARCH$(if [[ "$GOARM" ]]; then echo "v$GOARM"; fi)
  140. echo "GOOS: $GOOS, GOARCH: $GOARCH, GOARM: $GOARM, ABI: $_ABI, RELEASE_NAME: $_NAME, ARTIFACT_NAME: $_ARTIFACT"
  141. echo "CACHE_NAME=$_NAME" >> $GITHUB_ENV
  142. echo "ARCH_NAME=$_ARCH" >> $GITHUB_ENV
  143. echo "ABI=$_ABI" >> $GITHUB_ENV
  144. echo "DIST=nginx-ui-$_NAME" >> $GITHUB_ENV
  145. echo "ARTIFACT=$_ARTIFACT" >> $GITHUB_ENV
  146. - name: Setup Go modules cache
  147. uses: actions/cache@v4
  148. with:
  149. path: |
  150. ~/go/pkg/mod
  151. key: go-${{ runner.os }}-${{ runner.arch }}-mod-${{ hashFiles('go.mod') }}
  152. restore-keys: |
  153. go-${{ runner.os }}-${{ runner.arch }}-mod-
  154. - name: Setup Go build cache
  155. uses: actions/cache@v4
  156. with:
  157. path: |
  158. ~/.cache/go-build
  159. key: go-${{ runner.os }}-${{ runner.arch }}-${{ env.CACHE_NAME }}-${{ hashFiles('go.mod') }}
  160. restore-keys: |
  161. go-${{ runner.os }}-${{ runner.arch }}-${{ env.CACHE_NAME }}-
  162. - name: Download app artifacts
  163. uses: actions/download-artifact@v4
  164. with:
  165. name: app-dist
  166. path: app/dist
  167. - name: Generate files
  168. env:
  169. GOOS: linux
  170. GOARCH: amd64
  171. run: go generate
  172. - name: Install musl cross compiler
  173. if: env.GOOS == 'linux'
  174. uses: nginxui/musl-cross-compilers@v1
  175. id: musl
  176. with:
  177. target: ${{ env.ARCH_NAME }}-linux-musl${{ env.ABI }}
  178. variant: ${{ env.GOARCH == 'loong64' && 'userdocs/qbt-musl-cross-make' || 'richfelker/musl-cross-make' }}
  179. - name: Post install musl cross compiler
  180. if: env.GOOS == 'linux'
  181. run: |
  182. echo "PATH=${{ steps.musl.outputs.path }}:$PATH" >> $GITHUB_ENV
  183. echo "CC=${{ env.ARCH_NAME }}-linux-musl${{ env.ABI }}-gcc" >> $GITHUB_ENV
  184. echo "CXX=${{ env.ARCH_NAME }}-linux-musl${{ env.ABI }}-g++" >> $GITHUB_ENV
  185. echo "LD_FLAGS=-w --extldflags '-static'" >> $GITHUB_ENV
  186. - name: Install darwin cross compiler
  187. if: env.GOOS == 'darwin'
  188. run: |
  189. curl -L https://github.com/Hintay/crossosx/releases/latest/download/crossosx.tar.zst -o crossosx.tar.zst
  190. tar xvaf crossosx.tar.zst
  191. echo "LD_LIBRARY_PATH=$(pwd)/crossosx/lib/" >> $GITHUB_ENV
  192. echo "PATH=$(pwd)/crossosx/bin/:$PATH" >> $GITHUB_ENV
  193. echo "CC=${{ env.ARCH_NAME }}-clang" >> $GITHUB_ENV
  194. echo "CXX=${{ env.ARCH_NAME }}-clang++" >> $GITHUB_ENV
  195. echo "LD_FLAGS=-w" >> $GITHUB_ENV
  196. - name: Build
  197. run: |
  198. mkdir -p dist
  199. go build -tags=jsoniter -ldflags "$LD_FLAGS -X 'github.com/0xJacky/Nginx-UI/settings.buildTime=$(date +%s)'" -o dist/nginx-ui -v main.go
  200. - name: Archive backend artifacts
  201. uses: actions/upload-artifact@v4
  202. with:
  203. name: ${{ env.ARTIFACT }}
  204. path: dist/nginx-ui
  205. - name: Prepare publish
  206. if: github.event_name == 'release'
  207. run: |
  208. cp README*.md ./dist
  209. find dist -printf '%P\n' | tar -C dist --no-recursion -zcvf ${{ env.DIST }}.tar.gz -T -
  210. openssl dgst -sha512 ${{ env.DIST }}.tar.gz | sed 's/([^)]*)//g' | awk '{print $NF}' >> ${{ env.DIST }}.tar.gz.digest
  211. - name: Publish
  212. uses: softprops/action-gh-release@v2
  213. if: github.event_name == 'release'
  214. with:
  215. files: |
  216. ${{ env.DIST }}.tar.gz
  217. ${{ env.DIST }}.tar.gz.digest
  218. docker-build:
  219. if: github.event_name != 'pull_request'
  220. runs-on: ubuntu-latest
  221. needs: build
  222. env:
  223. PLATFORMS: linux/amd64,linux/arm64,linux/arm/v7,linux/arm/v6,linux/arm/v5
  224. steps:
  225. - name: Checkout
  226. uses: actions/checkout@v4
  227. - name: Docker meta
  228. id: meta
  229. uses: docker/metadata-action@v5
  230. with:
  231. images: |
  232. uozi/nginx-ui
  233. tags: |
  234. type=schedule
  235. type=ref,event=branch
  236. type=semver,pattern={{version}}
  237. type=sha
  238. type=raw,value=latest,enable=${{ github.event_name == 'release' && !github.event.release.prerelease }}
  239. - name: Download artifacts
  240. uses: actions/download-artifact@v4
  241. with:
  242. path: ./dist
  243. - name: Prepare Artifacts
  244. run: chmod +x ./dist/nginx-ui-*/nginx-ui
  245. - name: Set up Docker Buildx
  246. id: buildx
  247. uses: docker/setup-buildx-action@v3
  248. - name: Login to DockerHub
  249. uses: docker/login-action@v3
  250. with:
  251. username: ${{ secrets.DOCKERHUB_USER }}
  252. password: ${{ secrets.DOCKERHUB_TOKEN }}
  253. - name: Prepare Dockerfile
  254. run: |
  255. cp ./Dockerfile ./dist
  256. cp -rp ./resources ./dist
  257. - name: Build and push
  258. uses: docker/build-push-action@v6
  259. with:
  260. context: ./dist
  261. file: ./dist/Dockerfile
  262. platforms: ${{ env.PLATFORMS }}
  263. push: ${{ github.event_name != 'pull_request' }}
  264. tags: ${{ steps.meta.outputs.tags }}
  265. labels: ${{ steps.meta.outputs.labels }}
  266. - name: Prepare Demo Dockerfile
  267. run: |
  268. cp ./demo.Dockerfile ./dist
  269. cp -rp ./resources ./dist
  270. - name: Build and push demo
  271. uses: docker/build-push-action@v6
  272. if: github.ref == 'refs/heads/dev'
  273. with:
  274. context: ./dist
  275. file: ./dist/demo.Dockerfile
  276. platforms: ${{ env.PLATFORMS }}
  277. push: 'true'
  278. tags: |
  279. uozi/nginx-ui-demo:latest