name: Release on: push: tags: - "v*" workflow_dispatch: permissions: contents: write jobs: build: name: Build ${{ matrix.os }} runs-on: ${{ matrix.os }} strategy: fail-fast: false matrix: os: [ubuntu-latest, macos-latest, windows-latest] steps: - name: Checkout uses: actions/checkout@v4 - name: Install Rust uses: dtolnay/rust-toolchain@stable - name: Cache Rust artifacts uses: Swatinem/rust-cache@v2 - name: Build release binaries run: cargo build --release --workspace - name: Package Linux artifacts if: runner.os == 'Linux' shell: bash run: | set -euo pipefail mkdir -p dist cp target/release/proxychains4 dist/ cp target/release/libproxychains.so dist/ cp proxychains.conf dist/ cp README.md dist/ tar -czf "proxychains-rs-${GITHUB_REF_NAME}-linux-x86_64.tar.gz" -C dist . - name: Build Linux deb package if: runner.os == 'Linux' shell: bash run: | set -euo pipefail VERSION="${GITHUB_REF_NAME#v}" PKG_ROOT="pkgroot" rm -rf "${PKG_ROOT}" mkdir -p "${PKG_ROOT}/DEBIAN" "${PKG_ROOT}/usr/bin" "${PKG_ROOT}/usr/lib" "${PKG_ROOT}/etc" cp target/release/proxychains4 "${PKG_ROOT}/usr/bin/proxychains4" cp target/release/libproxychains.so "${PKG_ROOT}/usr/lib/libproxychains.so" cp proxychains.conf "${PKG_ROOT}/etc/proxychains.conf" printf "Package: proxychains-rs\nVersion: %s\nSection: net\nPriority: optional\nArchitecture: amd64\nMaintainer: Proxychains Rust Team\nDescription: Cross-platform proxychains implementation in Rust\n" "${VERSION}" > "${PKG_ROOT}/DEBIAN/control" dpkg-deb --build "${PKG_ROOT}" "proxychains-rs-${GITHUB_REF_NAME}-linux-amd64.deb" - name: Package macOS artifacts if: runner.os == 'macOS' shell: bash run: | set -euo pipefail ARCH_RAW="$(uname -m)" if [ "${ARCH_RAW}" = "arm64" ] || [ "${ARCH_RAW}" = "aarch64" ]; then ARCH="arm64" else ARCH="x86_64" fi mkdir -p dist cp target/release/proxychains4 dist/ cp target/release/libproxychains.dylib dist/ cp proxychains.conf dist/ cp README.md dist/ tar -czf "proxychains-rs-${GITHUB_REF_NAME}-macos-${ARCH}.tar.gz" -C dist . PKG_DIR="proxychains-rs-${GITHUB_REF_NAME}-macos-${ARCH}" rm -rf "${PKG_DIR}" mkdir -p "${PKG_DIR}" cp -R dist/. "${PKG_DIR}/" hdiutil create \ -volname "proxychains-rs ${GITHUB_REF_NAME}" \ -srcfolder "${PKG_DIR}" \ -ov \ -format UDZO \ "proxychains-rs-${GITHUB_REF_NAME}-macos-${ARCH}.dmg" - name: Package Windows artifacts if: runner.os == 'Windows' shell: pwsh run: | New-Item -ItemType Directory -Path dist -Force | Out-Null Copy-Item target\release\proxychains4.exe dist\ Copy-Item target\release\proxychains.dll dist\ Copy-Item proxychains.conf dist\ Copy-Item README.md dist\ Compress-Archive -Path dist\* -DestinationPath "proxychains-rs-$env:GITHUB_REF_NAME-windows-x86_64.zip" -Force - name: Upload packaged artifact uses: actions/upload-artifact@v4 with: name: release-${{ matrix.os }} path: | proxychains-rs-*.tar.gz proxychains-rs-*.zip proxychains-rs-*.deb proxychains-rs-*.dmg build-linux-arm64: name: Build ubuntu arm64 runs-on: ubuntu-latest steps: - name: Checkout uses: actions/checkout@v4 - name: Install Rust (with arm64 target) uses: dtolnay/rust-toolchain@stable with: targets: aarch64-unknown-linux-gnu - name: Install cross toolchain shell: bash run: | set -euo pipefail sudo apt-get update sudo apt-get install -y gcc-aarch64-linux-gnu libc6-dev-arm64-cross - name: Cache Rust artifacts uses: Swatinem/rust-cache@v2 - name: Build linux arm64 release binaries shell: bash env: CARGO_TARGET_AARCH64_UNKNOWN_LINUX_GNU_LINKER: aarch64-linux-gnu-gcc run: | set -euo pipefail cargo build --release --workspace --target aarch64-unknown-linux-gnu - name: Package Linux arm64 artifacts shell: bash run: | set -euo pipefail mkdir -p dist cp target/aarch64-unknown-linux-gnu/release/proxychains4 dist/ cp target/aarch64-unknown-linux-gnu/release/libproxychains.so dist/ cp proxychains.conf dist/ cp README.md dist/ tar -czf "proxychains-rs-${GITHUB_REF_NAME}-linux-arm64.tar.gz" -C dist . - name: Build Linux arm64 deb package shell: bash run: | set -euo pipefail VERSION="${GITHUB_REF_NAME#v}" PKG_ROOT="pkgroot-arm64" rm -rf "${PKG_ROOT}" mkdir -p "${PKG_ROOT}/DEBIAN" "${PKG_ROOT}/usr/bin" "${PKG_ROOT}/usr/lib" "${PKG_ROOT}/etc" cp target/aarch64-unknown-linux-gnu/release/proxychains4 "${PKG_ROOT}/usr/bin/proxychains4" cp target/aarch64-unknown-linux-gnu/release/libproxychains.so "${PKG_ROOT}/usr/lib/libproxychains.so" cp proxychains.conf "${PKG_ROOT}/etc/proxychains.conf" printf "Package: proxychains-rs\nVersion: %s\nSection: net\nPriority: optional\nArchitecture: arm64\nMaintainer: Proxychains Rust Team\nDescription: Cross-platform proxychains implementation in Rust\n" "${VERSION}" > "${PKG_ROOT}/DEBIAN/control" dpkg-deb --build "${PKG_ROOT}" "proxychains-rs-${GITHUB_REF_NAME}-linux-arm64.deb" - name: Upload packaged artifact uses: actions/upload-artifact@v4 with: name: release-linux-arm64 path: | proxychains-rs-*-linux-arm64.tar.gz proxychains-rs-*-linux-arm64.deb publish: name: Publish GitHub Release needs: [build, build-linux-arm64] runs-on: ubuntu-latest if: startsWith(github.ref, 'refs/tags/') steps: - name: Checkout (for changelog generation) uses: actions/checkout@v4 with: fetch-depth: 0 - name: Download artifacts uses: actions/download-artifact@v4 with: path: release-assets - name: Generate checksums shell: bash run: | set -euo pipefail find release-assets -type f \( -name '*.tar.gz' -o -name '*.zip' -o -name '*.deb' -o -name '*.dmg' \) -print0 \ | sort -z \ | xargs -0 sha256sum > SHA256SUMS.txt - name: Generate release notes and changelog shell: bash run: | set -euo pipefail TAG="${GITHUB_REF_NAME}" PREV_TAG="$(git tag --sort=-creatordate | grep -v "^${TAG}$" | head -n1 || true)" if [ -n "${PREV_TAG}" ]; then RANGE="${PREV_TAG}..${TAG}" else RANGE="${TAG}" fi mapfile -t COMMITS < <(git log --no-merges --pretty=format:'%s' ${RANGE}) section() { local name="$1" shift echo "### ${name}" >> CHANGELOG_AUTO.md local found=0 for c in "${COMMITS[@]}"; do for prefix in "$@"; do if [[ "${c}" == ${prefix}* ]]; then echo "- ${c}" >> CHANGELOG_AUTO.md found=1 break fi done done if [ "${found}" -eq 0 ]; then echo "- (none)" >> CHANGELOG_AUTO.md fi echo "" >> CHANGELOG_AUTO.md } { echo "## Changelog (${TAG})" echo "" } > CHANGELOG_AUTO.md section "Features" "feat:" "feature:" section "Fixes" "fix:" section "Docs" "docs:" section "CI/Build" "ci:" "build:" "chore:" echo "### Other" >> CHANGELOG_AUTO.md OTHER_FOUND=0 for c in "${COMMITS[@]}"; do if [[ "${c}" != feat:* && "${c}" != feature:* && "${c}" != fix:* && "${c}" != docs:* && "${c}" != ci:* && "${c}" != build:* && "${c}" != chore:* ]]; then echo "- ${c}" >> CHANGELOG_AUTO.md OTHER_FOUND=1 fi done if [ "${OTHER_FOUND}" -eq 0 ]; then echo "- (none)" >> CHANGELOG_AUTO.md fi echo "" >> CHANGELOG_AUTO.md cat > RELEASE_NOTES.md <> RELEASE_NOTES.md - name: Publish release assets uses: softprops/action-gh-release@v2 with: body_path: RELEASE_NOTES.md files: | release-assets/**/*.tar.gz release-assets/**/*.zip release-assets/**/*.deb release-assets/**/*.dmg SHA256SUMS.txt