1
0

release.yml 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228
  1. name: Release 3X-UI
  2. on:
  3. workflow_dispatch:
  4. release:
  5. types: [published]
  6. push:
  7. branches:
  8. - main
  9. tags:
  10. - "v*.*.*"
  11. paths:
  12. - '**.js'
  13. - '**.css'
  14. - '**.html'
  15. - '**.sh'
  16. - '**.go'
  17. - 'go.mod'
  18. - 'go.sum'
  19. - 'x-ui.service.debian'
  20. - 'x-ui.service.arch'
  21. - 'x-ui.service.rhel'
  22. jobs:
  23. build:
  24. permissions:
  25. contents: write
  26. strategy:
  27. matrix:
  28. platform:
  29. - amd64
  30. - arm64
  31. - armv7
  32. - armv6
  33. - 386
  34. - armv5
  35. - s390x
  36. runs-on: ubuntu-latest
  37. steps:
  38. - name: Checkout repository
  39. uses: actions/checkout@v5
  40. - name: Setup Go
  41. uses: actions/setup-go@v6
  42. with:
  43. go-version-file: go.mod
  44. check-latest: true
  45. - name: Build 3X-UI
  46. run: |
  47. export CGO_ENABLED=1
  48. export GOOS=linux
  49. export GOARCH=${{ matrix.platform }}
  50. # Use Bootlin prebuilt cross-toolchains (musl 1.2.5 in stable series)
  51. case "${{ matrix.platform }}" in
  52. amd64) BOOTLIN_ARCH="x86-64" ;;
  53. arm64) BOOTLIN_ARCH="aarch64" ;;
  54. armv7) BOOTLIN_ARCH="armv7-eabihf"; export GOARCH=arm GOARM=7 ;;
  55. armv6) BOOTLIN_ARCH="armv6-eabihf"; export GOARCH=arm GOARM=6 ;;
  56. armv5) BOOTLIN_ARCH="armv5-eabi"; export GOARCH=arm GOARM=5 ;;
  57. 386) BOOTLIN_ARCH="x86-i686" ;;
  58. s390x) BOOTLIN_ARCH="s390x-z13" ;;
  59. esac
  60. echo "Resolving Bootlin musl toolchain for arch=$BOOTLIN_ARCH (platform=${{ matrix.platform }})"
  61. TARBALL_BASE="https://toolchains.bootlin.com/downloads/releases/toolchains/$BOOTLIN_ARCH/tarballs/"
  62. TARBALL_URL=$(curl -fsSL "$TARBALL_BASE" | grep -oE "${BOOTLIN_ARCH}--musl--stable-[^\"]+\\.tar\\.xz" | sort -r | head -n1)
  63. [ -z "$TARBALL_URL" ] && { echo "Failed to locate Bootlin musl toolchain for arch=$BOOTLIN_ARCH" >&2; exit 1; }
  64. echo "Downloading: $TARBALL_URL"
  65. cd /tmp
  66. curl -fL -sS -o "$(basename "$TARBALL_URL")" "$TARBALL_BASE/$TARBALL_URL"
  67. tar -xf "$(basename "$TARBALL_URL")"
  68. TOOLCHAIN_DIR=$(find . -maxdepth 1 -type d -name "${BOOTLIN_ARCH}--musl--stable-*" | head -n1)
  69. export PATH="$(realpath "$TOOLCHAIN_DIR")/bin:$PATH"
  70. export CC=$(realpath "$(find "$TOOLCHAIN_DIR/bin" -name '*-gcc.br_real' -type f -executable | head -n1)")
  71. [ -z "$CC" ] && { echo "No gcc.br_real found in $TOOLCHAIN_DIR/bin" >&2; exit 1; }
  72. cd -
  73. go build -ldflags "-w -s -linkmode external -extldflags '-static'" -o xui-release -v main.go
  74. file xui-release
  75. ldd xui-release || echo "Static binary confirmed"
  76. mkdir x-ui
  77. cp xui-release x-ui/
  78. cp x-ui.service.debian x-ui/
  79. cp x-ui.service.arch x-ui/
  80. cp x-ui.service.rhel x-ui/
  81. cp x-ui.sh x-ui/
  82. mv x-ui/xui-release x-ui/x-ui
  83. mkdir x-ui/bin
  84. cd x-ui/bin
  85. # Download dependencies
  86. Xray_URL="https://github.com/XTLS/Xray-core/releases/download/v25.12.8/"
  87. if [ "${{ matrix.platform }}" == "amd64" ]; then
  88. wget -q ${Xray_URL}Xray-linux-64.zip
  89. unzip Xray-linux-64.zip
  90. rm -f Xray-linux-64.zip
  91. elif [ "${{ matrix.platform }}" == "arm64" ]; then
  92. wget -q ${Xray_URL}Xray-linux-arm64-v8a.zip
  93. unzip Xray-linux-arm64-v8a.zip
  94. rm -f Xray-linux-arm64-v8a.zip
  95. elif [ "${{ matrix.platform }}" == "armv7" ]; then
  96. wget -q ${Xray_URL}Xray-linux-arm32-v7a.zip
  97. unzip Xray-linux-arm32-v7a.zip
  98. rm -f Xray-linux-arm32-v7a.zip
  99. elif [ "${{ matrix.platform }}" == "armv6" ]; then
  100. wget -q ${Xray_URL}Xray-linux-arm32-v6.zip
  101. unzip Xray-linux-arm32-v6.zip
  102. rm -f Xray-linux-arm32-v6.zip
  103. elif [ "${{ matrix.platform }}" == "386" ]; then
  104. wget -q ${Xray_URL}Xray-linux-32.zip
  105. unzip Xray-linux-32.zip
  106. rm -f Xray-linux-32.zip
  107. elif [ "${{ matrix.platform }}" == "armv5" ]; then
  108. wget -q ${Xray_URL}Xray-linux-arm32-v5.zip
  109. unzip Xray-linux-arm32-v5.zip
  110. rm -f Xray-linux-arm32-v5.zip
  111. elif [ "${{ matrix.platform }}" == "s390x" ]; then
  112. wget -q ${Xray_URL}Xray-linux-s390x.zip
  113. unzip Xray-linux-s390x.zip
  114. rm -f Xray-linux-s390x.zip
  115. fi
  116. rm -f geoip.dat geosite.dat
  117. wget -q https://github.com/Loyalsoldier/v2ray-rules-dat/releases/latest/download/geoip.dat
  118. wget -q https://github.com/Loyalsoldier/v2ray-rules-dat/releases/latest/download/geosite.dat
  119. wget -q -O geoip_IR.dat https://github.com/chocolate4u/Iran-v2ray-rules/releases/latest/download/geoip.dat
  120. wget -q -O geosite_IR.dat https://github.com/chocolate4u/Iran-v2ray-rules/releases/latest/download/geosite.dat
  121. wget -q -O geoip_RU.dat https://github.com/runetfreedom/russia-v2ray-rules-dat/releases/latest/download/geoip.dat
  122. wget -q -O geosite_RU.dat https://github.com/runetfreedom/russia-v2ray-rules-dat/releases/latest/download/geosite.dat
  123. mv xray xray-linux-${{ matrix.platform }}
  124. cd ../..
  125. - name: Package
  126. run: tar -zcvf x-ui-linux-${{ matrix.platform }}.tar.gz x-ui
  127. - name: Upload files to Artifacts
  128. uses: actions/upload-artifact@v4
  129. with:
  130. name: x-ui-linux-${{ matrix.platform }}
  131. path: ./x-ui-linux-${{ matrix.platform }}.tar.gz
  132. - name: Upload files to GH release
  133. uses: svenstaro/upload-release-action@v2
  134. if: |
  135. (github.event_name == 'release' && github.event.action == 'published') ||
  136. (github.event_name == 'push' && startsWith(github.ref, 'refs/tags/'))
  137. with:
  138. repo_token: ${{ secrets.GITHUB_TOKEN }}
  139. tag: ${{ github.ref }}
  140. file: x-ui-linux-${{ matrix.platform }}.tar.gz
  141. asset_name: x-ui-linux-${{ matrix.platform }}.tar.gz
  142. overwrite: true
  143. prerelease: true
  144. # =================================
  145. # Windows Build
  146. # =================================
  147. build-windows:
  148. name: Build for Windows
  149. permissions:
  150. contents: write
  151. strategy:
  152. matrix:
  153. platform:
  154. - amd64
  155. runs-on: windows-latest
  156. steps:
  157. - name: Checkout repository
  158. uses: actions/checkout@v5
  159. - name: Setup Go
  160. uses: actions/setup-go@v6
  161. with:
  162. go-version-file: go.mod
  163. check-latest: true
  164. - name: Build 3X-UI for Windows
  165. shell: pwsh
  166. run: |
  167. $env:CGO_ENABLED="1"
  168. $env:GOOS="windows"
  169. $env:GOARCH="amd64"
  170. go build -ldflags "-w -s" -o xui-release.exe -v main.go
  171. mkdir x-ui
  172. Copy-Item xui-release.exe x-ui\
  173. mkdir x-ui\bin
  174. cd x-ui\bin
  175. # Download Xray for Windows
  176. $Xray_URL = "https://github.com/XTLS/Xray-core/releases/download/v25.12.8/"
  177. Invoke-WebRequest -Uri "${Xray_URL}Xray-windows-64.zip" -OutFile "Xray-windows-64.zip"
  178. Expand-Archive -Path "Xray-windows-64.zip" -DestinationPath .
  179. Remove-Item "Xray-windows-64.zip"
  180. Remove-Item geoip.dat, geosite.dat -ErrorAction SilentlyContinue
  181. Invoke-WebRequest -Uri "https://github.com/Loyalsoldier/v2ray-rules-dat/releases/latest/download/geoip.dat" -OutFile "geoip.dat"
  182. Invoke-WebRequest -Uri "https://github.com/Loyalsoldier/v2ray-rules-dat/releases/latest/download/geosite.dat" -OutFile "geosite.dat"
  183. Invoke-WebRequest -Uri "https://github.com/chocolate4u/Iran-v2ray-rules/releases/latest/download/geoip.dat" -OutFile "geoip_IR.dat"
  184. Invoke-WebRequest -Uri "https://github.com/chocolate4u/Iran-v2ray-rules/releases/latest/download/geosite.dat" -OutFile "geosite_IR.dat"
  185. Invoke-WebRequest -Uri "https://github.com/runetfreedom/russia-v2ray-rules-dat/releases/latest/download/geoip.dat" -OutFile "geoip_RU.dat"
  186. Invoke-WebRequest -Uri "https://github.com/runetfreedom/russia-v2ray-rules-dat/releases/latest/download/geosite.dat" -OutFile "geosite_RU.dat"
  187. Rename-Item xray.exe xray-windows-amd64.exe
  188. cd ..
  189. Copy-Item -Path ..\windows_files\* -Destination . -Recurse
  190. cd ..
  191. - name: Package to Zip
  192. shell: pwsh
  193. run: |
  194. Compress-Archive -Path .\x-ui -DestinationPath "x-ui-windows-amd64.zip"
  195. - name: Upload files to Artifacts
  196. uses: actions/upload-artifact@v4
  197. with:
  198. name: x-ui-windows-amd64
  199. path: ./x-ui-windows-amd64.zip
  200. - name: Upload files to GH release
  201. uses: svenstaro/upload-release-action@v2
  202. if: |
  203. (github.event_name == 'release' && github.event.action == 'published') ||
  204. (github.event_name == 'push' && startsWith(github.ref, 'refs/tags/'))
  205. with:
  206. repo_token: ${{ secrets.GITHUB_TOKEN }}
  207. tag: ${{ github.ref }}
  208. file: x-ui-windows-amd64.zip
  209. asset_name: x-ui-windows-amd64.zip
  210. overwrite: true
  211. prerelease: true