feat: add optional builds for macOS x64, Linux ARM64, and Termux sour… #3
Workflow file for this run
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Release | |
| on: | |
| push: | |
| tags: | |
| - "v*" | |
| workflow_dispatch: | |
| inputs: | |
| release_tag: | |
| description: "Tag name to publish (example: v1.2.0). Leave empty for non-publishing build." | |
| required: false | |
| type: string | |
| publish: | |
| description: "Publish GitHub Release" | |
| required: false | |
| default: false | |
| type: boolean | |
| make_public: | |
| description: "Make release public immediately (false = hidden draft + prerelease)" | |
| required: false | |
| default: false | |
| type: boolean | |
| build_macos_x64: | |
| description: "Also build macOS x64 (intel). Optional and non-blocking." | |
| required: false | |
| default: false | |
| type: boolean | |
| build_linux_arm64: | |
| description: "Also build Linux ARM64. Optional and non-blocking." | |
| required: false | |
| default: false | |
| type: boolean | |
| build_termux_bundle: | |
| description: "Also publish Termux source bundle (supports arm64/armv7/x86_64 on-device)." | |
| required: false | |
| default: false | |
| type: boolean | |
| permissions: | |
| contents: write | |
| jobs: | |
| build-binaries: | |
| name: Build ${{ matrix.target }} | |
| runs-on: ${{ matrix.os }} | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| include: | |
| - os: windows-latest | |
| target: windows-x64 | |
| - os: ubuntu-latest | |
| target: linux-x64 | |
| - os: macos-14 | |
| target: macos-arm64 | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v4 | |
| - name: Setup Python | |
| uses: actions/setup-python@v5 | |
| with: | |
| python-version: "3.11" | |
| - name: Install build dependencies | |
| run: | | |
| python -m pip install --upgrade pip | |
| python -m pip install -r requirements.txt pyinstaller | |
| - name: Build standalone binary | |
| run: pyinstaller --noconfirm --clean --onefile --name MasterHttpRelayVPN --paths src main.py | |
| - name: Package release bundle | |
| env: | |
| TARGET: ${{ matrix.target }} | |
| run: python scripts/build_release_bundle.py | |
| - name: Upload build artifacts | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: release-${{ matrix.target }} | |
| path: release-assets/* | |
| build-macos-x64: | |
| name: Build macos-x64 (optional) | |
| if: github.event_name == 'workflow_dispatch' && github.event.inputs.build_macos_x64 == 'true' | |
| runs-on: macos-13 | |
| continue-on-error: true | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v4 | |
| - name: Setup Python | |
| uses: actions/setup-python@v5 | |
| with: | |
| python-version: "3.11" | |
| - name: Install build dependencies | |
| run: | | |
| python -m pip install --upgrade pip | |
| python -m pip install -r requirements.txt pyinstaller | |
| - name: Build standalone binary | |
| run: pyinstaller --noconfirm --clean --onefile --name MasterHttpRelayVPN --paths src main.py | |
| - name: Package release bundle | |
| env: | |
| TARGET: macos-x64 | |
| run: python scripts/build_release_bundle.py | |
| - name: Upload build artifacts | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: release-macos-x64 | |
| path: release-assets/* | |
| build-linux-arm64: | |
| name: Build linux-arm64 (optional) | |
| if: github.event_name == 'workflow_dispatch' && github.event.inputs.build_linux_arm64 == 'true' | |
| runs-on: ubuntu-24.04-arm | |
| continue-on-error: true | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v4 | |
| - name: Setup Python | |
| uses: actions/setup-python@v5 | |
| with: | |
| python-version: "3.11" | |
| - name: Install build dependencies | |
| run: | | |
| python -m pip install --upgrade pip | |
| python -m pip install -r requirements.txt pyinstaller | |
| - name: Build standalone binary | |
| run: pyinstaller --noconfirm --clean --onefile --name MasterHttpRelayVPN --paths src main.py | |
| - name: Package release bundle | |
| env: | |
| TARGET: linux-arm64 | |
| run: python scripts/build_release_bundle.py | |
| - name: Upload build artifacts | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: release-linux-arm64 | |
| path: release-assets/* | |
| build-termux-bundle: | |
| name: Build termux-source (optional) | |
| if: github.event_name == 'workflow_dispatch' && github.event.inputs.build_termux_bundle == 'true' | |
| runs-on: ubuntu-latest | |
| continue-on-error: true | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v4 | |
| - name: Create Termux source archive | |
| run: | | |
| python - <<'PY' | |
| import hashlib | |
| import re | |
| import tarfile | |
| from pathlib import Path | |
| root = Path('.').resolve() | |
| constants_py = (root / 'src' / 'constants.py').read_text(encoding='utf-8') | |
| m = re.search(r'__version__\s*=\s*"([^"]+)"', constants_py) | |
| version = m.group(1) if m else '0.0.0' | |
| release_dir = root / 'release-assets' | |
| release_dir.mkdir(parents=True, exist_ok=True) | |
| archive_name = f"MasterHttpRelayVPN-{version}-termux-source.tar.gz" | |
| archive_path = release_dir / archive_name | |
| include_items = [ | |
| 'main.py', | |
| 'setup.py', | |
| 'requirements.txt', | |
| 'config.example.json', | |
| 'README.md', | |
| 'README_FA.md', | |
| 'start.sh', | |
| 'apps_script', | |
| 'scripts', | |
| 'src', | |
| ] | |
| with tarfile.open(archive_path, 'w:gz') as tf: | |
| for item in include_items: | |
| p = root / item | |
| if p.exists(): | |
| tf.add(p, arcname=item) | |
| digest = hashlib.sha256(archive_path.read_bytes()).hexdigest() | |
| (release_dir / f"{archive_name}.sha256").write_text( | |
| f"{digest} {archive_name}\n", | |
| encoding='utf-8', | |
| ) | |
| install_script = release_dir / 'termux-install.sh' | |
| install_script.write_text( | |
| "#!/data/data/com.termux/files/usr/bin/bash\n" | |
| "set -euo pipefail\n" | |
| "pkg update -y\n" | |
| "pkg install -y python git clang libffi openssl\n" | |
| "python -m pip install --upgrade pip\n" | |
| "if [ ! -f requirements.txt ]; then\n" | |
| " echo 'Run this inside extracted MasterHttpRelayVPN source directory.' >&2\n" | |
| " exit 1\n" | |
| "fi\n" | |
| "pip install -r requirements.txt\n" | |
| "echo 'Done. Next: python setup.py and then python main.py'\n", | |
| encoding='utf-8', | |
| ) | |
| install_script.chmod(0o755) | |
| print(f"Created {archive_path}") | |
| PY | |
| - name: Upload build artifacts | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: release-termux-source | |
| path: release-assets/* | |
| publish-release: | |
| name: Publish GitHub Release | |
| needs: [build-binaries, build-macos-x64, build-linux-arm64, build-termux-bundle] | |
| runs-on: ubuntu-latest | |
| if: always() && !cancelled() && (startsWith(github.ref, 'refs/tags/v') || (github.event_name == 'workflow_dispatch' && github.event.inputs.publish == 'true' && startsWith(github.event.inputs.release_tag, 'v'))) | |
| steps: | |
| - name: Download all artifacts | |
| uses: actions/download-artifact@v4 | |
| with: | |
| path: release-assets | |
| - name: Flatten artifact directories | |
| run: | | |
| mkdir -p final-assets | |
| find release-assets -type f -exec cp {} final-assets/ \; | |
| ls -lah final-assets | |
| - name: Create GitHub release | |
| uses: softprops/action-gh-release@v2 | |
| with: | |
| tag_name: ${{ startsWith(github.ref, 'refs/tags/') && github.ref_name || github.event.inputs.release_tag }} | |
| files: final-assets/* | |
| generate_release_notes: true | |
| prerelease: ${{ github.event_name != 'workflow_dispatch' || github.event.inputs.make_public != 'true' }} | |
| draft: ${{ github.event_name != 'workflow_dispatch' || github.event.inputs.make_public != 'true' }} | |
| make_latest: ${{ (github.event_name == 'workflow_dispatch' && github.event.inputs.make_public == 'true') && 'true' || 'false' }} |