3x-ui/.github/workflows/release.yml
Sora39831 e40f73cc1c ci: remove release trigger, auto-create release on tag push
Remove the duplicate release trigger. Now pushing a tag like v*.*.*
automatically creates a prerelease (if not exists) and uploads the
build artifacts via gh CLI, eliminating the duplicate build issue.
2026-04-02 17:20:33 +08:00

287 lines
11 KiB
YAML

name: Release 3X-UI
on:
workflow_dispatch:
push:
tags:
- "v*.*.*"
pull_request:
paths:
- '**.js'
- '**.css'
- '**.html'
- '**.sh'
- '**.go'
- 'go.mod'
- 'go.sum'
- 'x-ui.service.debian'
- 'x-ui.service.arch'
- 'x-ui.service.rhel'
jobs:
analyze:
name: Analyze Go code
permissions:
contents: read
runs-on: ubuntu-latest
timeout-minutes: 20
steps:
- name: Checkout repository
uses: actions/checkout@v6
- name: Set up Go
uses: actions/setup-go@v6
with:
go-version-file: go.mod
cache: true
- name: Check formatting
run: |
unformatted=$(gofmt -l .)
if [ -n "$unformatted" ]; then
echo "These files are not gofmt-formatted:"
echo "$unformatted"
exit 1
fi
- name: Run go vet
run: go vet ./...
- name: Run staticcheck
uses: dominikh/staticcheck-action@v1
with:
version: "latest"
install-go: false
- name: Run tests
run: go test -race -shuffle=on ./...
build:
needs: analyze
permissions:
contents: write
strategy:
matrix:
platform:
- amd64
# 手动注释,请勿更改
# - arm64
# 手动注释,请勿更改
# - armv7
# 手动注释,请勿更改
# - armv6
# 手动注释,请勿更改
# - 386
# 手动注释,请勿更改
# - armv5
# 手动注释,请勿更改
# - s390x
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v6
- name: Setup Go
uses: actions/setup-go@v6
with:
go-version-file: go.mod
check-latest: true
- name: Build 3X-UI
run: |
export CGO_ENABLED=1
export GOOS=linux
export GOARCH=${{ matrix.platform }}
# Use Bootlin prebuilt cross-toolchains (musl 1.2.5 in stable series)
case "${{ matrix.platform }}" in
amd64) BOOTLIN_ARCH="x86-64" ;;
arm64) BOOTLIN_ARCH="aarch64" ;;
armv7) BOOTLIN_ARCH="armv7-eabihf"; export GOARCH=arm GOARM=7 ;;
armv6) BOOTLIN_ARCH="armv6-eabihf"; export GOARCH=arm GOARM=6 ;;
armv5) BOOTLIN_ARCH="armv5-eabi"; export GOARCH=arm GOARM=5 ;;
386) BOOTLIN_ARCH="x86-i686" ;;
s390x) BOOTLIN_ARCH="s390x-z13" ;;
esac
echo "Resolving Bootlin musl toolchain for arch=$BOOTLIN_ARCH (platform=${{ matrix.platform }})"
TARBALL_BASE="https://toolchains.bootlin.com/downloads/releases/toolchains/$BOOTLIN_ARCH/tarballs/"
TARBALL_URL=$(curl -fsSL "$TARBALL_BASE" | grep -oE "${BOOTLIN_ARCH}--musl--stable-[^\"]+\\.tar\\.xz" | sort -r | head -n1)
[ -z "$TARBALL_URL" ] && { echo "Failed to locate Bootlin musl toolchain for arch=$BOOTLIN_ARCH" >&2; exit 1; }
echo "Downloading: $TARBALL_URL"
cd /tmp
curl -fL -sS -o "$(basename "$TARBALL_URL")" "$TARBALL_BASE/$TARBALL_URL"
tar -xf "$(basename "$TARBALL_URL")"
TOOLCHAIN_DIR=$(find . -maxdepth 1 -type d -name "${BOOTLIN_ARCH}--musl--stable-*" | head -n1)
export PATH="$(realpath "$TOOLCHAIN_DIR")/bin:$PATH"
export CC=$(realpath "$(find "$TOOLCHAIN_DIR/bin" -name '*-gcc.br_real' -type f -executable | head -n1)")
[ -z "$CC" ] && { echo "No gcc.br_real found in $TOOLCHAIN_DIR/bin" >&2; exit 1; }
cd -
go build -ldflags "-w -s -linkmode external -extldflags '-static'" -o xui-release -v main.go
file xui-release
ldd xui-release || echo "Static binary confirmed"
mkdir x-ui
cp xui-release x-ui/
cp x-ui.service.debian x-ui/
cp x-ui.service.arch x-ui/
cp x-ui.service.rhel x-ui/
cp x-ui.sh x-ui/
mv x-ui/xui-release x-ui/x-ui
mkdir x-ui/bin
cd x-ui/bin
# Download dependencies
Xray_URL="https://github.com/XTLS/Xray-core/releases/download/v26.2.6/"
if [ "${{ matrix.platform }}" == "amd64" ]; then
wget -q ${Xray_URL}Xray-linux-64.zip
unzip Xray-linux-64.zip
rm -f Xray-linux-64.zip
elif [ "${{ matrix.platform }}" == "arm64" ]; then
wget -q ${Xray_URL}Xray-linux-arm64-v8a.zip
unzip Xray-linux-arm64-v8a.zip
rm -f Xray-linux-arm64-v8a.zip
elif [ "${{ matrix.platform }}" == "armv7" ]; then
wget -q ${Xray_URL}Xray-linux-arm32-v7a.zip
unzip Xray-linux-arm32-v7a.zip
rm -f Xray-linux-arm32-v7a.zip
elif [ "${{ matrix.platform }}" == "armv6" ]; then
wget -q ${Xray_URL}Xray-linux-arm32-v6.zip
unzip Xray-linux-arm32-v6.zip
rm -f Xray-linux-arm32-v6.zip
elif [ "${{ matrix.platform }}" == "386" ]; then
wget -q ${Xray_URL}Xray-linux-32.zip
unzip Xray-linux-32.zip
rm -f Xray-linux-32.zip
elif [ "${{ matrix.platform }}" == "armv5" ]; then
wget -q ${Xray_URL}Xray-linux-arm32-v5.zip
unzip Xray-linux-arm32-v5.zip
rm -f Xray-linux-arm32-v5.zip
elif [ "${{ matrix.platform }}" == "s390x" ]; then
wget -q ${Xray_URL}Xray-linux-s390x.zip
unzip Xray-linux-s390x.zip
rm -f Xray-linux-s390x.zip
fi
rm -f geoip.dat geosite.dat
wget -q https://github.com/Loyalsoldier/v2ray-rules-dat/releases/latest/download/geoip.dat
wget -q https://github.com/Loyalsoldier/v2ray-rules-dat/releases/latest/download/geosite.dat
wget -q -O geoip_IR.dat https://github.com/chocolate4u/Iran-v2ray-rules/releases/latest/download/geoip.dat
wget -q -O geosite_IR.dat https://github.com/chocolate4u/Iran-v2ray-rules/releases/latest/download/geosite.dat
wget -q -O geoip_RU.dat https://github.com/runetfreedom/russia-v2ray-rules-dat/releases/latest/download/geoip.dat
wget -q -O geosite_RU.dat https://github.com/runetfreedom/russia-v2ray-rules-dat/releases/latest/download/geosite.dat
mv xray xray-linux-${{ matrix.platform }}
cd ../..
- name: Package
run: tar -zcvf x-ui-linux-${{ matrix.platform }}.tar.gz x-ui
- name: Upload files to Artifacts
uses: actions/upload-artifact@v7
with:
name: x-ui-linux-${{ matrix.platform }}
path: ./x-ui-linux-${{ matrix.platform }}.tar.gz
- name: Create release and upload assets
if: startsWith(github.ref, 'refs/tags/')
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
TAG="${{ github.ref_name }}"
if ! gh release view "$TAG" > /dev/null 2>&1; then
gh release create "$TAG" --prerelease --title "$TAG" --generate-notes
fi
gh release upload "$TAG" x-ui-linux-${{ matrix.platform }}.tar.gz --clobber
# =================================
# Windows Build (disabled)
# =================================
# build-windows:
# name: Build for Windows
# needs: analyze
# permissions:
# contents: write
# strategy:
# matrix:
# platform:
# - amd64
# runs-on: windows-latest
# steps:
# - name: Checkout repository
# uses: actions/checkout@v6
#
# - name: Setup Go
# uses: actions/setup-go@v6
# with:
# go-version-file: go.mod
# check-latest: true
#
# - name: Install MSYS2
# uses: msys2/setup-msys2@v2
# with:
# msystem: MINGW64
# update: true
# install: >-
# mingw-w64-x86_64-gcc
# mingw-w64-x86_64-sqlite3
# mingw-w64-x86_64-pkg-config
#
# - name: Build 3X-UI for Windows (CGO)
# shell: msys2 {0}
# run: |
# export PATH="/c/hostedtoolcache/windows/go/$(ls /c/hostedtoolcache/windows/go | sort -V | tail -n1)/x64/bin:$PATH"
#
# export CGO_ENABLED=1
# export GOOS=windows
# export GOARCH=amd64
# export CC=x86_64-w64-mingw32-gcc
#
# which go
# go version
# gcc --version
#
# go build -ldflags "-w -s" -o xui-release.exe -v main.go
#
# - name: Copy and download resources
# shell: pwsh
# run: |
# mkdir x-ui
# Copy-Item xui-release.exe x-ui\x-ui.exe
# mkdir x-ui\bin
# cd x-ui\bin
#
# # Download Xray for Windows
# $Xray_URL = "https://github.com/XTLS/Xray-core/releases/download/v26.2.6/"
# Invoke-WebRequest -Uri "${Xray_URL}Xray-windows-64.zip" -OutFile "Xray-windows-64.zip"
# Expand-Archive -Path "Xray-windows-64.zip" -DestinationPath .
# Remove-Item "Xray-windows-64.zip"
# Remove-Item geoip.dat, geosite.dat -ErrorAction SilentlyContinue
# Invoke-WebRequest -Uri "https://github.com/Loyalsoldier/v2ray-rules-dat/releases/latest/download/geoip.dat" -OutFile "geoip.dat"
# Invoke-WebRequest -Uri "https://github.com/Loyalsoldier/v2ray-rules-dat/releases/latest/download/geosite.dat" -OutFile "geosite.dat"
# Invoke-WebRequest -Uri "https://github.com/chocolate4u/Iran-v2ray-rules/releases/latest/download/geoip.dat" -OutFile "geoip_IR.dat"
# Invoke-WebRequest -Uri "https://github.com/chocolate4u/Iran-v2ray-rules/releases/latest/download/geosite.dat" -OutFile "geosite_IR.dat"
# Invoke-WebRequest -Uri "https://github.com/runetfreedom/russia-v2ray-rules-dat/releases/latest/download/geoip.dat" -OutFile "geoip_RU.dat"
# Invoke-WebRequest -Uri "https://github.com/runetfreedom/russia-v2ray-rules-dat/releases/latest/download/geosite.dat" -OutFile "geosite_RU.dat"
# Rename-Item xray.exe xray-windows-amd64.exe
# cd ..
# Copy-Item -Path ..\windows_files\* -Destination . -Recurse
# cd ..
#
# - name: Package to Zip
# shell: pwsh
# run: |
# Compress-Archive -Path .\x-ui -DestinationPath "x-ui-windows-amd64.zip"
#
# - name: Upload files to Artifacts
# uses: actions/upload-artifact@v7
# with:
# name: x-ui-windows-amd64
# path: ./x-ui-windows-amd64.zip
#
# - name: Upload files to GH release
# uses: svenstaro/upload-release-action@v2
# if: github.event_name == 'release'
# with:
# repo_token: ${{ secrets.GITHUB_TOKEN }}
# tag: ${{ github.ref_name }}
# file: x-ui-windows-amd64.zip
# asset_name: x-ui-windows-amd64.zip
# overwrite: true
# prerelease: true