Fix Koharu enum ABI in release builds #4
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: | |
| - "*" | |
| workflow_dispatch: | |
| inputs: | |
| tag: | |
| description: "Release tag to upload files to" | |
| required: true | |
| type: string | |
| permissions: | |
| contents: write | |
| concurrency: | |
| group: release-${{ github.ref }} | |
| cancel-in-progress: false | |
| env: | |
| CARGO_TERM_COLOR: always | |
| CARGO_TARGET_DIR: target | |
| jobs: | |
| build-runner: | |
| name: Build Flint runner (${{ matrix.platform }}) | |
| runs-on: ${{ matrix.os }} | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| include: | |
| - os: ubuntu-latest | |
| platform: linux-x86_64 | |
| exe_suffix: "" | |
| - os: windows-latest | |
| platform: windows-x86_64 | |
| exe_suffix: ".exe" | |
| - os: macos-14 | |
| platform: macos-arm64 | |
| exe_suffix: "" | |
| steps: | |
| - name: Checkout Flint | |
| uses: actions/checkout@v4 | |
| with: | |
| path: flint | |
| - name: Checkout RustScript / pd-vm | |
| uses: actions/checkout@v4 | |
| with: | |
| repository: rustscript-lang/rustscript | |
| path: rustscript | |
| - name: Install Rust toolchain | |
| uses: dtolnay/rust-toolchain@stable | |
| - name: Patch Koharu C enum ABI compatibility | |
| working-directory: flint | |
| run: python .github/scripts/patch-koharu-diffusion.py | |
| - name: Preload Unix LibTorch | |
| if: runner.os != 'Windows' | |
| working-directory: flint | |
| shell: python | |
| env: | |
| RUNNER_OS: ${{ runner.os }} | |
| run: | | |
| import os | |
| import pathlib | |
| import shutil | |
| import tempfile | |
| import urllib.request | |
| import zipfile | |
| version = "2.12.1" | |
| runner_os = os.environ["RUNNER_OS"] | |
| if runner_os == "Linux": | |
| archive_name = f"libtorch-shared-with-deps-{version}%2Bcpu.zip" | |
| required = ("libc10.so", "libtorch_cpu.so", "libtorch.so") | |
| elif runner_os == "macOS": | |
| archive_name = f"libtorch-macos-arm64-{version}.zip" | |
| required = ("libomp.dylib", "libc10.dylib", "libtorch_cpu.dylib", "libtorch.dylib") | |
| else: | |
| raise RuntimeError(f"unsupported runner OS: {runner_os}") | |
| url = f"https://download.pytorch.org/libtorch/cpu/{archive_name}" | |
| target_dir = pathlib.Path(os.environ.get("CARGO_TARGET_DIR", "target")) | |
| package_dir = target_dir / "store" / "libtorch" / version / "cpu" | |
| lib_dir = package_dir / "libtorch" / "lib" | |
| if all((lib_dir / name).is_file() for name in required): | |
| raise SystemExit(0) | |
| package_dir.parent.mkdir(parents=True, exist_ok=True) | |
| staging_dir = package_dir.with_name(f"{package_dir.name}.tmp") | |
| shutil.rmtree(staging_dir, ignore_errors=True) | |
| archive_path = None | |
| try: | |
| with tempfile.NamedTemporaryFile( | |
| dir=package_dir.parent, suffix=".zip", delete=False | |
| ) as archive: | |
| archive_path = pathlib.Path(archive.name) | |
| request = urllib.request.Request( | |
| url, headers={"User-Agent": "flint-release-ci"} | |
| ) | |
| with urllib.request.urlopen(request, timeout=300) as response: | |
| shutil.copyfileobj(response, archive, length=1024 * 1024) | |
| with zipfile.ZipFile(archive_path) as zip_file: | |
| damaged = zip_file.testzip() | |
| if damaged is not None: | |
| raise RuntimeError(f"damaged LibTorch member: {damaged}") | |
| zip_file.extractall(staging_dir) | |
| if not all( | |
| (staging_dir / "libtorch" / "lib" / name).is_file() | |
| for name in required | |
| ): | |
| raise RuntimeError("LibTorch archive is missing required libraries") | |
| shutil.rmtree(package_dir, ignore_errors=True) | |
| staging_dir.replace(package_dir) | |
| finally: | |
| if archive_path is not None: | |
| archive_path.unlink(missing_ok=True) | |
| shutil.rmtree(staging_dir, ignore_errors=True) | |
| - name: Build release runner | |
| working-directory: flint | |
| run: cargo build --release --locked --bin flint | |
| - name: Package runner | |
| id: package | |
| shell: python | |
| env: | |
| PLATFORM: ${{ matrix.platform }} | |
| EXE_SUFFIX: ${{ matrix.exe_suffix }} | |
| run: | | |
| import os | |
| import pathlib | |
| import shutil | |
| import zipfile | |
| root = pathlib.Path("flint") | |
| cargo_target_dir = pathlib.Path(os.environ.get("CARGO_TARGET_DIR", "target")) | |
| if not cargo_target_dir.is_absolute(): | |
| cargo_target_dir = root / cargo_target_dir | |
| release_dir = cargo_target_dir / "release" | |
| package_name = f"flint-{os.environ['PLATFORM']}" | |
| package_dir = root / "dist" / package_name | |
| archive = root / "dist" / f"{package_name}.zip" | |
| exe_suffix = os.environ.get("EXE_SUFFIX", "") | |
| if package_dir.exists(): | |
| shutil.rmtree(package_dir) | |
| package_dir.mkdir(parents=True, exist_ok=True) | |
| binary = release_dir / f"flint{exe_suffix}" | |
| if not binary.exists(): | |
| raise FileNotFoundError(f"missing built runner binary: {binary}") | |
| shutil.copy2(binary, package_dir / binary.name) | |
| for extra in ("README.md", "LICENSE"): | |
| source = root / extra | |
| if source.exists(): | |
| shutil.copy2(source, package_dir / extra) | |
| with zipfile.ZipFile(archive, "w", compression=zipfile.ZIP_DEFLATED) as zf: | |
| for path in package_dir.rglob("*"): | |
| zf.write(path, path.relative_to(package_dir.parent)) | |
| with open(os.environ["GITHUB_OUTPUT"], "a", encoding="utf-8") as output: | |
| output.write(f"archive={archive.as_posix()}\n") | |
| - name: Upload release asset | |
| uses: softprops/action-gh-release@v2 | |
| with: | |
| tag_name: ${{ github.event_name == 'workflow_dispatch' && inputs.tag || github.ref_name }} | |
| files: ${{ steps.package.outputs.archive }} | |
| fail_on_unmatched_files: true |