name: release Linux on: workflow_dispatch: inputs: release_tag: required: false type: string push: branches: - master permissions: contents: write actions: read jobs: build: uses: ./.github/workflows/build.yml with: target: linux release-zip: if: inputs.release_tag != '' needs: build uses: ./.github/workflows/package-zip.yml with: target: linux release_tag: ${{ inputs.release_tag }} secrets: inherit build-aot: uses: ./.github/workflows/build.yml with: target: linux isAot: true release-aot-zip: if: inputs.release_tag != '' needs: build-aot uses: ./.github/workflows/package-zip.yml with: target: linux release_tag: ${{ inputs.release_tag }} isAot: true secrets: inherit deb: name: build and release deb x64 & arm64 & riscv64 & ppc64le & loong64 if: (github.event_name == 'workflow_dispatch' && inputs.release_tag != '') || (github.event_name == 'push' && startsWith(github.ref, 'refs/tags/')) runs-on: ubuntu-26.04 container: debian:13 env: { RELEASE_TAG: "${{ case(inputs.release_tag != '', inputs.release_tag, github.ref_name) }}" } steps: - name: Prepare tools (Debian) shell: bash run: | set -euo pipefail export DEBIAN_FRONTEND=noninteractive apt-get update apt-get install -y sudo git rsync findutils tar gzip unzip which curl jq wget file ca-certificates desktop-file-utils xdg-utils fakeroot dpkg-dev libc6 libgcc-s1 libstdc++6 zlib1g libicu-dev libssl-dev - name: Checkout repo (for scripts) uses: actions/checkout@v7 with: { submodules: 'recursive', fetch-depth: '0' } - name: Ensure script permissions run: chmod 755 package-debian.sh - name: Package DEB (Debian-family) run: ./package-debian.sh "${RELEASE_TAG}" --arch all - name: Collect DEBs into workspace run: | mkdir -p "$GITHUB_WORKSPACE/dist/deb" rsync -av "$HOME/debbuild/" "$GITHUB_WORKSPACE/dist/deb/" || true find "$GITHUB_WORKSPACE/dist/deb" -name "v2rayn_*_amd64.deb" -exec mv {} "$GITHUB_WORKSPACE/dist/deb/v2rayN-linux-64.deb" \; || true find "$GITHUB_WORKSPACE/dist/deb" -name "v2rayn_*_arm64.deb" -exec mv {} "$GITHUB_WORKSPACE/dist/deb/v2rayN-linux-arm64.deb" \; || true find "$GITHUB_WORKSPACE/dist/deb" -name "v2rayn_*_riscv64.deb" -exec mv {} "$GITHUB_WORKSPACE/dist/deb/v2rayN-linux-riscv64.deb" \; || true find "$GITHUB_WORKSPACE/dist/deb" -name "v2rayn_*_ppc64el.deb" -exec mv {} "$GITHUB_WORKSPACE/dist/deb/v2rayN-linux-ppc64le.deb" \; || true find "$GITHUB_WORKSPACE/dist/deb" -name "v2rayn_*_loong64.deb" -exec mv {} "$GITHUB_WORKSPACE/dist/deb/v2rayN-linux-loong64.deb" \; || true echo "==== Dist tree ====" ls -R "$GITHUB_WORKSPACE/dist/deb" || true - name: Upload DEB artifact uses: actions/upload-artifact@v7 with: { name: release-deb, path: "dist/deb/**/*.deb", if-no-files-found: error } rpm: name: build and release rpm x64 & arm64 & riscv64 & ppc64le & loong64 if: (github.event_name == 'workflow_dispatch' && inputs.release_tag != '') || (github.event_name == 'push' && startsWith(github.ref, 'refs/tags/')) runs-on: ubuntu-26.04 container: registry.access.redhat.com/ubi10/ubi env: { RELEASE_TAG: "${{ case(inputs.release_tag != '', inputs.release_tag, github.ref_name) }}" } steps: - name: Prepare tools (Red Hat) shell: bash run: | set -euo pipefail . /etc/os-release EL_MAJOR="${VERSION_ID%%.*}" echo "EL_MAJOR=${EL_MAJOR}" dnf -y makecache || true command -v curl >/dev/null || dnf -y install curl ca-certificates ARCH="$(uname -m)" case "$ARCH" in x86_64|aarch64) ;; *) echo "Unsupported arch: $ARCH"; exit 1 ;; esac install_epel_from_dir() { local base="$1" rpm echo "Try: $base" rpm="$({ curl -fsSL "$base/Packages/" 2>/dev/null; curl -fsSL "$base/Packages/e/" 2>/dev/null | sed 's|href="|href="e/|'; } | sed -n 's/.*href="\([^"]*epel-release-[^"]*\.noarch\.rpm\)".*/\1/p' | sort -V | tail -n1)" || true [[ -n "$rpm" ]] || return 1 dnf -y install "$base/Packages/$rpm" } FEDORA="https://dl.fedoraproject.org/pub/epel/epel-release-latest-${EL_MAJOR}.noarch.rpm" ROCKY="https://dl.rockylinux.org/pub/rocky/${EL_MAJOR}/extras/${ARCH}/os" ALMA="https://repo.almalinux.org/almalinux/${EL_MAJOR}/extras/${ARCH}/os" echo "Try Fedora: $FEDORA" curl -fsSLI "$FEDORA" >/dev/null && dnf -y install "$FEDORA" || install_epel_from_dir "$ROCKY" || install_epel_from_dir "$ALMA" || { echo "EPEL bootstrap failed (Fedora/Rocky/Alma)"; exit 1; } dnf -y install sudo git rpm-build rpmdevtools dnf-plugins-core rsync findutils tar gzip unzip which dnf repolist | grep -i epel || true - name: Checkout repo (for scripts) uses: actions/checkout@v7 with: { submodules: 'recursive', fetch-depth: '0' } - name: Ensure script permissions run: chmod 755 package-rhel.sh - name: Package RPM (RHEL-family) run: ./package-rhel.sh "${RELEASE_TAG}" --arch all - name: Collect RPMs into workspace run: | mkdir -p "$GITHUB_WORKSPACE/dist/rpm" rsync -av "$HOME/rpmbuild/RPMS/" "$GITHUB_WORKSPACE/dist/rpm/" || true find "$GITHUB_WORKSPACE/dist/rpm" -name "v2rayN-*-1*.x86_64.rpm" -exec mv {} "$GITHUB_WORKSPACE/dist/rpm/v2rayN-linux-rhel-64.rpm" \; || true find "$GITHUB_WORKSPACE/dist/rpm" -name "v2rayN-*-1*.aarch64.rpm" -exec mv {} "$GITHUB_WORKSPACE/dist/rpm/v2rayN-linux-rhel-arm64.rpm" \; || true find "$GITHUB_WORKSPACE/dist/rpm" -name "v2rayN-*-1*.riscv64.rpm" -exec mv {} "$GITHUB_WORKSPACE/dist/rpm/v2rayN-linux-rhel-riscv64.rpm" \; || true find "$GITHUB_WORKSPACE/dist/rpm" -name "v2rayN-*-1*.ppc64le.rpm" -exec mv {} "$GITHUB_WORKSPACE/dist/rpm/v2rayN-linux-rhel-ppc64le.rpm" \; || true find "$GITHUB_WORKSPACE/dist/rpm" -name "v2rayN-*-1*.loongarch64.rpm" -exec mv {} "$GITHUB_WORKSPACE/dist/rpm/v2rayN-linux-rhel-loong64.rpm" \; || true echo "==== Dist tree ====" ls -R "$GITHUB_WORKSPACE/dist/rpm" || true - name: Upload RPM artifact uses: actions/upload-artifact@v7 with: { name: release-rpm, path: "dist/rpm/**/*.rpm", if-no-files-found: error } deb-x86: name: build and release deb x86 if: (github.event_name == 'workflow_dispatch' && inputs.release_tag != '') || (github.event_name == 'push' && startsWith(github.ref, 'refs/tags/')) runs-on: ubuntu-26.04 container: debian:13 env: { RELEASE_TAG: "${{ case(inputs.release_tag != '', inputs.release_tag, github.ref_name) }}" } steps: - name: Prepare tools (Debian) shell: bash run: | set -euo pipefail export DEBIAN_FRONTEND=noninteractive apt-get update apt-get install -y sudo git rsync findutils tar gzip unzip which curl jq wget file ca-certificates desktop-file-utils xdg-utils fakeroot dpkg-dev libc6 libgcc-s1 libstdc++6 zlib1g libicu-dev libssl-dev - name: Checkout repo (for scripts) uses: actions/checkout@v7 with: { submodules: 'recursive', fetch-depth: '0' } - name: Ensure script permissions run: chmod 755 package-debian-x86.sh - name: Package DEB x86 (Debian-family) run: ./package-debian-x86.sh "${RELEASE_TAG}" - name: Collect x86 DEB into workspace run: | mkdir -p "$GITHUB_WORKSPACE/dist/deb-x86" rsync -av "$HOME/debbuild/" "$GITHUB_WORKSPACE/dist/deb-x86/" || true find "$GITHUB_WORKSPACE/dist/deb-x86" -name "v2rayn_*_i386.deb" \ -exec mv {} "$GITHUB_WORKSPACE/dist/deb-x86/v2rayN-linux-86.deb" \; || true echo "==== Dist tree ====" ls -R "$GITHUB_WORKSPACE/dist/deb-x86" || true - name: Upload x86 DEB artifact uses: actions/upload-artifact@v7 with: { name: release-deb-x86, path: "dist/deb-x86/**/*.deb", if-no-files-found: error } rpm-x86: name: build and release rpm x86 if: (github.event_name == 'workflow_dispatch' && inputs.release_tag != '') || (github.event_name == 'push' && startsWith(github.ref, 'refs/tags/')) runs-on: ubuntu-26.04 container: registry.access.redhat.com/ubi10/ubi env: { RELEASE_TAG: "${{ case(inputs.release_tag != '', inputs.release_tag, github.ref_name) }}" } steps: - name: Prepare tools (Red Hat) shell: bash run: | set -euo pipefail . /etc/os-release EL_MAJOR="${VERSION_ID%%.*}" echo "EL_MAJOR=${EL_MAJOR}" dnf -y makecache || true command -v curl >/dev/null || dnf -y install curl ca-certificates ARCH="$(uname -m)" case "$ARCH" in x86_64|aarch64) ;; *) echo "Unsupported arch: $ARCH"; exit 1 ;; esac install_epel_from_dir() { local base="$1" rpm echo "Try: $base" rpm="$({ curl -fsSL "$base/Packages/" 2>/dev/null; curl -fsSL "$base/Packages/e/" 2>/dev/null | sed 's|href="|href="e/|'; } | sed -n 's/.*href="\([^"]*epel-release-[^"]*\.noarch\.rpm\)".*/\1/p' | sort -V | tail -n1)" || true [[ -n "$rpm" ]] || return 1 dnf -y install "$base/Packages/$rpm" } FEDORA="https://dl.fedoraproject.org/pub/epel/epel-release-latest-${EL_MAJOR}.noarch.rpm" ROCKY="https://dl.rockylinux.org/pub/rocky/${EL_MAJOR}/extras/${ARCH}/os" ALMA="https://repo.almalinux.org/almalinux/${EL_MAJOR}/extras/${ARCH}/os" echo "Try Fedora: $FEDORA" curl -fsSLI "$FEDORA" >/dev/null && dnf -y install "$FEDORA" || install_epel_from_dir "$ROCKY" || install_epel_from_dir "$ALMA" || { echo "EPEL bootstrap failed (Fedora/Rocky/Alma)"; exit 1; } dnf -y install sudo git rpm-build rpmdevtools dnf-plugins-core rsync findutils tar gzip unzip which python3 dnf repolist | grep -i epel || true - name: Checkout repo (for scripts) uses: actions/checkout@v7 with: { submodules: 'recursive', fetch-depth: '0' } - name: Ensure script permissions run: chmod 755 package-rhel-x86.sh - name: Package RPM x86 (RHEL-family) run: ./package-rhel-x86.sh "${RELEASE_TAG}" - name: Collect x86 RPM into workspace run: | mkdir -p "$GITHUB_WORKSPACE/dist/rpm-x86" rsync -av "$HOME/rpmbuild/RPMS/" "$GITHUB_WORKSPACE/dist/rpm-x86/" || true find "$GITHUB_WORKSPACE/dist/rpm-x86" -name "v2rayN-*-1*.i686.rpm" \ -exec mv {} "$GITHUB_WORKSPACE/dist/rpm-x86/v2rayN-linux-rhel-86.rpm" \; || true echo "==== Dist tree ====" ls -R "$GITHUB_WORKSPACE/dist/rpm-x86" || true - name: Upload x86 RPM artifact uses: actions/upload-artifact@v7 with: { name: release-rpm-x86, path: "dist/rpm-x86/**/*.rpm", if-no-files-found: error } release-deb: name: sign and upload deb x64 arm64 riscv64 ppc64le loong64 needs: deb uses: ./.github/workflows/upload-sign.yml with: { release_tag: "${{ inputs.release_tag || github.ref_name }}", artifact_name: release-deb, file_pattern: "*.deb" } secrets: { GPG_PRIVATE_KEY: "${{ secrets.GPG_PRIVATE_KEY }}" } release-rpm: name: sign and upload rpm x64 arm64 riscv64 ppc64le loong64 needs: rpm uses: ./.github/workflows/upload-sign.yml with: { release_tag: "${{ inputs.release_tag || github.ref_name }}", artifact_name: release-rpm, file_pattern: "*.rpm" } secrets: { GPG_PRIVATE_KEY: "${{ secrets.GPG_PRIVATE_KEY }}" } release-deb-x86: name: sign and upload deb x86 needs: deb-x86 uses: ./.github/workflows/upload-sign.yml with: { release_tag: "${{ inputs.release_tag || github.ref_name }}", artifact_name: release-deb-x86, file_pattern: "*.deb" } secrets: { GPG_PRIVATE_KEY: "${{ secrets.GPG_PRIVATE_KEY }}" } release-rpm-x86: name: sign and upload rpm x86 needs: rpm-x86 uses: ./.github/workflows/upload-sign.yml with: { release_tag: "${{ inputs.release_tag || github.ref_name }}", artifact_name: release-rpm-x86, file_pattern: "*.rpm" } secrets: { GPG_PRIVATE_KEY: "${{ secrets.GPG_PRIVATE_KEY }}" }