release.yml 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148
  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'
  20. jobs:
  21. build:
  22. permissions:
  23. contents: write
  24. strategy:
  25. matrix:
  26. platform:
  27. - amd64
  28. - arm64
  29. - armv7
  30. - armv6
  31. - 386
  32. - armv5
  33. - s390x
  34. runs-on: ubuntu-latest
  35. steps:
  36. - name: Checkout repository
  37. uses: actions/checkout@v5
  38. - name: Setup Go
  39. uses: actions/setup-go@v5
  40. with:
  41. go-version-file: go.mod
  42. check-latest: true
  43. - name: Build 3X-UI
  44. run: |
  45. export CGO_ENABLED=1
  46. export GOOS=linux
  47. export GOARCH=${{ matrix.platform }}
  48. # Use Bootlin prebuilt cross-toolchains (musl 1.2.5 in stable series)
  49. case "${{ matrix.platform }}" in
  50. amd64) BOOTLIN_ARCH="x86-64" ;;
  51. arm64) BOOTLIN_ARCH="aarch64" ;;
  52. armv7) BOOTLIN_ARCH="armv7-eabihf"; export GOARCH=arm GOARM=7 ;;
  53. armv6) BOOTLIN_ARCH="armv6-eabihf"; export GOARCH=arm GOARM=6 ;;
  54. armv5) BOOTLIN_ARCH="armv5-eabi"; export GOARCH=arm GOARM=5 ;;
  55. 386) BOOTLIN_ARCH="x86-i686" ;;
  56. s390x) BOOTLIN_ARCH="s390x-z13" ;;
  57. esac
  58. echo "Resolving Bootlin musl toolchain for arch=$BOOTLIN_ARCH (platform=${{ matrix.platform }})"
  59. TARBALL_BASE="https://toolchains.bootlin.com/downloads/releases/toolchains/$BOOTLIN_ARCH/tarballs/"
  60. TARBALL_URL=$(curl -fsSL "$TARBALL_BASE" | grep -oE "${BOOTLIN_ARCH}--musl--stable-[^\"]+\\.tar\\.xz" | sort -r | head -n1)
  61. [ -z "$TARBALL_URL" ] && { echo "Failed to locate Bootlin musl toolchain for arch=$BOOTLIN_ARCH" >&2; exit 1; }
  62. echo "Downloading: $TARBALL_URL"
  63. cd /tmp
  64. curl -fL -sS -o "$(basename "$TARBALL_URL")" "$TARBALL_BASE/$TARBALL_URL"
  65. tar -xf "$(basename "$TARBALL_URL")"
  66. TOOLCHAIN_DIR=$(find . -maxdepth 1 -type d -name "${BOOTLIN_ARCH}--musl--stable-*" | head -n1)
  67. export PATH="$(realpath "$TOOLCHAIN_DIR")/bin:$PATH"
  68. export CC=$(realpath "$(find "$TOOLCHAIN_DIR/bin" -name '*-gcc.br_real' -type f -executable | head -n1)")
  69. [ -z "$CC" ] && { echo "No gcc.br_real found in $TOOLCHAIN_DIR/bin" >&2; exit 1; }
  70. cd -
  71. go build -ldflags "-w -s -linkmode external -extldflags '-static'" -o xui-release -v main.go
  72. file xui-release
  73. ldd xui-release || echo "Static binary confirmed"
  74. mkdir x-ui
  75. cp xui-release x-ui/
  76. cp x-ui.service x-ui/
  77. cp x-ui.sh x-ui/
  78. mv x-ui/xui-release x-ui/x-ui
  79. mkdir x-ui/bin
  80. cd x-ui/bin
  81. # Download dependencies
  82. Xray_URL="https://github.com/XTLS/Xray-core/releases/download/v25.9.5/"
  83. if [ "${{ matrix.platform }}" == "amd64" ]; then
  84. wget -q ${Xray_URL}Xray-linux-64.zip
  85. unzip Xray-linux-64.zip
  86. rm -f Xray-linux-64.zip
  87. elif [ "${{ matrix.platform }}" == "arm64" ]; then
  88. wget -q ${Xray_URL}Xray-linux-arm64-v8a.zip
  89. unzip Xray-linux-arm64-v8a.zip
  90. rm -f Xray-linux-arm64-v8a.zip
  91. elif [ "${{ matrix.platform }}" == "armv7" ]; then
  92. wget -q ${Xray_URL}Xray-linux-arm32-v7a.zip
  93. unzip Xray-linux-arm32-v7a.zip
  94. rm -f Xray-linux-arm32-v7a.zip
  95. elif [ "${{ matrix.platform }}" == "armv6" ]; then
  96. wget -q ${Xray_URL}Xray-linux-arm32-v6.zip
  97. unzip Xray-linux-arm32-v6.zip
  98. rm -f Xray-linux-arm32-v6.zip
  99. elif [ "${{ matrix.platform }}" == "386" ]; then
  100. wget -q ${Xray_URL}Xray-linux-32.zip
  101. unzip Xray-linux-32.zip
  102. rm -f Xray-linux-32.zip
  103. elif [ "${{ matrix.platform }}" == "armv5" ]; then
  104. wget -q ${Xray_URL}Xray-linux-arm32-v5.zip
  105. unzip Xray-linux-arm32-v5.zip
  106. rm -f Xray-linux-arm32-v5.zip
  107. elif [ "${{ matrix.platform }}" == "s390x" ]; then
  108. wget -q ${Xray_URL}Xray-linux-s390x.zip
  109. unzip Xray-linux-s390x.zip
  110. rm -f Xray-linux-s390x.zip
  111. fi
  112. rm -f geoip.dat geosite.dat
  113. wget -q https://github.com/Loyalsoldier/v2ray-rules-dat/releases/latest/download/geoip.dat
  114. wget -q https://github.com/Loyalsoldier/v2ray-rules-dat/releases/latest/download/geosite.dat
  115. wget -q -O geoip_IR.dat https://github.com/chocolate4u/Iran-v2ray-rules/releases/latest/download/geoip.dat
  116. wget -q -O geosite_IR.dat https://github.com/chocolate4u/Iran-v2ray-rules/releases/latest/download/geosite.dat
  117. wget -q -O geoip_RU.dat https://github.com/runetfreedom/russia-v2ray-rules-dat/releases/latest/download/geoip.dat
  118. wget -q -O geosite_RU.dat https://github.com/runetfreedom/russia-v2ray-rules-dat/releases/latest/download/geosite.dat
  119. mv xray xray-linux-${{ matrix.platform }}
  120. cd ../..
  121. - name: Package
  122. run: tar -zcvf x-ui-linux-${{ matrix.platform }}.tar.gz x-ui
  123. - name: Upload files to Artifacts
  124. uses: actions/upload-artifact@v4
  125. with:
  126. name: x-ui-linux-${{ matrix.platform }}
  127. path: ./x-ui-linux-${{ matrix.platform }}.tar.gz
  128. - name: Upload files to GH release
  129. uses: svenstaro/upload-release-action@v2
  130. if: |
  131. (github.event_name == 'release' && github.event.action == 'published') ||
  132. (github.event_name == 'push' && startsWith(github.ref, 'refs/tags/'))
  133. with:
  134. repo_token: ${{ secrets.GITHUB_TOKEN }}
  135. tag: ${{ github.ref }}
  136. file: x-ui-linux-${{ matrix.platform }}.tar.gz
  137. asset_name: x-ui-linux-${{ matrix.platform }}.tar.gz
  138. overwrite: true
  139. prerelease: true