release.yml 9.0 KB

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