diff --git a/.github/workflows/cleanup_caches.yml b/.github/workflows/cleanup_caches.yml deleted file mode 100644 index dcf50fce..00000000 --- a/.github/workflows/cleanup_caches.yml +++ /dev/null @@ -1,31 +0,0 @@ -name: Cleanup Caches -on: - schedule: - - cron: '0 3 * * 0' # every Sunday - workflow_dispatch: - -jobs: - cleanup: - runs-on: ubuntu-latest - permissions: - actions: write - steps: - - name: Delete caches older than 3 days - env: - GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} - run: | - CUTOFF_DATE=$(date -d "3 days ago" -Ins --utc | sed 's/+0000/Z/') - echo "Deleting caches older than: $CUTOFF_DATE" - - CACHE_IDS=$(gh api --paginate repos/${{ github.repository }}/actions/caches \ - --jq ".actions_caches[] | select(.last_accessed_at < \"$CUTOFF_DATE\") | .id" 2>/dev/null) - - if [ -z "$CACHE_IDS" ]; then - echo "No old caches found to delete." - else - echo "$CACHE_IDS" | while read CACHE_ID; do - echo "Deleting cache: $CACHE_ID" - gh api -X DELETE repos/${{ github.repository }}/actions/caches/$CACHE_ID - done - echo "Old caches deleted successfully." - fi \ No newline at end of file diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml deleted file mode 100644 index 0dd4847d..00000000 --- a/.github/workflows/docker.yml +++ /dev/null @@ -1,62 +0,0 @@ -name: Release 3X-UI for Docker - -permissions: - contents: read - packages: write - -on: - workflow_dispatch: - push: - tags: - - "v*.*.*" - -jobs: - build: - runs-on: ubuntu-latest - - steps: - - uses: actions/checkout@v6 - with: - submodules: true - - - name: Docker meta - id: meta - uses: docker/metadata-action@v6 - with: - images: | - hsanaeii/3x-ui - ghcr.io/mhsanaei/3x-ui - tags: | - type=ref,event=branch - type=ref,event=tag - type=semver,pattern={{version}} - - - name: Set up QEMU - uses: docker/setup-qemu-action@v4 - - - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v4 - with: - install: true - - - name: Login to Docker Hub - uses: docker/login-action@v4 - with: - username: ${{ secrets.DOCKER_HUB_USERNAME }} - password: ${{ secrets.DOCKER_HUB_TOKEN }} - - - name: Login to GHCR - uses: docker/login-action@v4 - with: - registry: ghcr.io - username: ${{ github.actor }} - password: ${{ secrets.GITHUB_TOKEN }} - - - name: Build and push Docker image - uses: docker/build-push-action@v7 - with: - context: . - push: true - platforms: linux/amd64,linux/arm64/v8,linux/arm/v7,linux/arm/v6,linux/386 - tags: ${{ steps.meta.outputs.tags }} - labels: ${{ steps.meta.outputs.labels }} diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml deleted file mode 100644 index ed9417c9..00000000 --- a/.github/workflows/release.yml +++ /dev/null @@ -1,283 +0,0 @@ -name: Release 3X-UI - -on: - workflow_dispatch: - push: - branches: - - '**' - tags: - - "v*.*.*" - paths: - - '**.js' - - '**.css' - - '**.html' - - '**.sh' - - '**.go' - - 'go.mod' - - 'go.sum' - - 'x-ui.service.debian' - - 'x-ui.service.arch' - - 'x-ui.service.rhel' - pull_request: - -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: Upload files to GH release - uses: svenstaro/upload-release-action@v2 - if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/') - with: - repo_token: ${{ secrets.GITHUB_TOKEN }} - tag: ${{ github.ref_name }} - file: x-ui-linux-${{ matrix.platform }}.tar.gz - asset_name: x-ui-linux-${{ matrix.platform }}.tar.gz - overwrite: true - prerelease: true - - # ================================= - # Windows Build - # ================================= - 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 == 'push' && startsWith(github.ref, 'refs/tags/') - 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