From 9f4af679a3b3cca412bf1bb8f2a881fe1fd1d501 Mon Sep 17 00:00:00 2001 From: link2xt Date: Sun, 10 Mar 2024 01:33:44 +0000 Subject: [PATCH] build: build deltachat-rpc-server wheels with nix --- .github/workflows/deltachat-rpc-server.yml | 27 ++++- flake.nix | 109 +++++++++++++++++++-- scripts/wheel-rpc-server.py | 91 +++++++---------- 3 files changed, 161 insertions(+), 66 deletions(-) diff --git a/.github/workflows/deltachat-rpc-server.yml b/.github/workflows/deltachat-rpc-server.yml index 089ed8f086..68325eccad 100644 --- a/.github/workflows/deltachat-rpc-server.yml +++ b/.github/workflows/deltachat-rpc-server.yml @@ -104,6 +104,8 @@ jobs: - uses: actions/checkout@v4 with: show-progress: false + - uses: DeterminateSystems/nix-installer-action@main + - uses: DeterminateSystems/magic-nix-cache-action@main - name: Download Linux aarch64 binary uses: actions/download-artifact@v4 @@ -182,9 +184,28 @@ jobs: run: pip install wheel - name: Build deltachat-rpc-server Python wheels and source package - run: scripts/wheel-rpc-server.py - - - name: List downloaded artifacts + run: | + nix build .#deltachat-rpc-server-x86_64-linux-wheel + cp result/*.whl dist/ + nix build .#deltachat-rpc-server-armv7l-linux-wheel + cp result/*.whl dist/ + nix build .#deltachat-rpc-server-armv6l-linux-wheel + cp result/*.whl dist/ + nix build .#deltachat-rpc-server-aarch64-linux-wheel + cp result/*.whl dist/ + nix build .#deltachat-rpc-server-i686-linux-wheel + cp result/*.whl dist/ + nix build .#deltachat-rpc-server-win64-wheel + cp result/*.whl dist/ + nix build .#deltachat-rpc-server-win32-wheel + cp result/*.whl dist/ + nix build .#deltachat-rpc-server-source + cp result/*.tar.gz dist/ + python3 scripts/wheel-rpc-server.py 1.136.3 x86_64-darwin dist/deltachat-rpc-server-x86_64-macos + python3 scripts/wheel-rpc-server.py 1.136.3 aarch64-darwin dist/deltachat-rpc-server-aarch64-macos + mv *.whl dist/ + + - name: List artifacts run: ls -l dist/ - name: Upload binaries to the GitHub release diff --git a/flake.nix b/flake.nix index d26115aed6..ad6ecbd0fb 100644 --- a/flake.nix +++ b/flake.nix @@ -251,10 +251,40 @@ LD = "${pkgsCross.stdenv.cc}/bin/${pkgsCross.stdenv.cc.targetPrefix}cc"; }; - mkRustPackages = arch: { - "deltachat-repl-${arch}" = mkCrossRustPackage arch "deltachat-repl"; - "deltachat-rpc-server-${arch}" = mkCrossRustPackage arch "deltachat-rpc-server"; - }; + mkRustPackages = arch: + let + rpc-server = mkCrossRustPackage arch "deltachat-rpc-server"; + in + { + "deltachat-repl-${arch}" = mkCrossRustPackage arch "deltachat-repl"; + "deltachat-rpc-server-${arch}" = rpc-server; + "deltachat-rpc-server-${arch}-wheel" = + pkgs.stdenv.mkDerivation { + pname = "deltachat-rpc-server-${arch}-wheel"; + version = manifest.version; + src = nix-filter.lib { + root = ./.; + include = [ + "scripts/wheel-rpc-server.py" + "deltachat-rpc-server/README.md" + "LICENSE" + ]; + }; + nativeBuildInputs = [ + pkgs.python3 + pkgs.python3Packages.wheel + ]; + buildInputs = [ + rpc-server + ]; + buildPhase = '' + mkdir tmp + cp ${rpc-server}/bin/deltachat-rpc-server tmp/deltachat-rpc-server + python3 scripts/wheel-rpc-server.py ${manifest.version} ${arch} tmp/deltachat-rpc-server + ''; + installPhase = ''mkdir -p $out; cp -av deltachat_rpc_server-*.whl $out''; + }; + }; in { formatter = pkgs.nixpkgs-fmt; @@ -271,12 +301,61 @@ deltachat-repl-win64 = mkWin64RustPackage "deltachat-repl"; deltachat-rpc-server-win64 = mkWin64RustPackage "deltachat-rpc-server"; + deltachat-rpc-server-win64-wheel = + pkgs.stdenv.mkDerivation { + pname = "deltachat-rpc-server-win64-wheel"; + version = manifest.version; + src = nix-filter.lib { + root = ./.; + include = [ + "scripts/wheel-rpc-server.py" + "deltachat-rpc-server/README.md" + "LICENSE" + ]; + }; + nativeBuildInputs = [ + pkgs.python3 + pkgs.python3Packages.wheel + ]; + buildInputs = [ + deltachat-rpc-server-win64 + ]; + buildPhase = '' + mkdir tmp + cp ${deltachat-rpc-server-win64}/bin/deltachat-rpc-server.exe tmp/deltachat-rpc-server.exe + python3 scripts/wheel-rpc-server.py ${manifest.version} win64 tmp/deltachat-rpc-server.exe + ''; + installPhase = ''mkdir -p $out; cp -av deltachat_rpc_server-*.whl $out''; + }; deltachat-repl-win32 = mkWin32RustPackage "deltachat-repl"; deltachat-rpc-server-win32 = mkWin32RustPackage "deltachat-rpc-server"; - - - + deltachat-rpc-server-win32-wheel = + pkgs.stdenv.mkDerivation { + pname = "deltachat-rpc-server-win32-wheel"; + version = manifest.version; + src = nix-filter.lib { + root = ./.; + include = [ + "scripts/wheel-rpc-server.py" + "deltachat-rpc-server/README.md" + "LICENSE" + ]; + }; + nativeBuildInputs = [ + pkgs.python3 + pkgs.python3Packages.wheel + ]; + buildInputs = [ + deltachat-rpc-server-win32 + ]; + buildPhase = '' + mkdir tmp + cp ${deltachat-rpc-server-win32}/bin/deltachat-rpc-server.exe tmp/deltachat-rpc-server.exe + python3 scripts/wheel-rpc-server.py ${manifest.version} win32 tmp/deltachat-rpc-server.exe + ''; + installPhase = ''mkdir -p $out; cp -av deltachat_rpc_server-*.whl $out''; + }; # Run `nix build .#docs` to get C docs generated in `./result/`. docs = pkgs.stdenv.mkDerivation { @@ -314,6 +393,22 @@ ''; }; + # Source package for deltachat-rpc-server. + # Fake package that downloads Linux version, + # needed to install deltachat-rpc-server on Android with `pip`. + deltachat-rpc-server-source = + pkgs.stdenv.mkDerivation { + pname = "deltachat-rpc-server-source"; + version = manifest.version; + src = pkgs.lib.cleanSource ./.; + nativeBuildInputs = [ + pkgs.python3 + pkgs.python3Packages.wheel + ]; + buildPhase = ''python3 scripts/wheel-rpc-server.py ${manifest.version} source deltachat-rpc-server-${manifest.version}.tar.gz''; + installPhase = ''mkdir -p $out; cp -av deltachat-rpc-server-${manifest.version}.tar.gz $out''; + }; + deltachat-rpc-client = pkgs.python3Packages.buildPythonPackage rec { pname = "deltachat-rpc-client"; diff --git a/scripts/wheel-rpc-server.py b/scripts/wheel-rpc-server.py index 43d3cfbad6..666ae34884 100755 --- a/scripts/wheel-rpc-server.py +++ b/scripts/wheel-rpc-server.py @@ -4,6 +4,7 @@ from wheel.wheelfile import WheelFile import tomllib import tarfile +import sys from io import BytesIO @@ -15,9 +16,7 @@ def metadata_contents(version): """ -def build_source_package(version): - filename = f"dist/deltachat-rpc-server-{version}.tar.gz" - +def build_source_package(version, filename): with tarfile.open(filename, "w:gz") as pkg: def pack(name, contents): @@ -98,7 +97,7 @@ def run(self): def build_wheel(version, binary, tag, windows=False): - filename = f"dist/deltachat_rpc_server-{version}-{tag}.whl" + filename = f"deltachat_rpc_server-{version}-{tag}.whl" with WheelFile(filename, "w") as wheel: wheel.write("LICENSE", "deltachat_rpc_server/LICENSE") @@ -143,59 +142,39 @@ def main(): ) -def main(): - with open("deltachat-rpc-server/Cargo.toml", "rb") as f: - cargo_toml = tomllib.load(f) - version = cargo_toml["package"]["version"] - Path("dist").mkdir(exist_ok=True) - build_source_package(version) - build_wheel( - version, - "dist/deltachat-rpc-server-x86_64-linux", - "py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.musllinux_1_1_x86_64", - ) - build_wheel( - version, - "dist/deltachat-rpc-server-armv7l-linux", - "py3-none-linux_armv7l.manylinux_2_17_armv7l.manylinux2014_armv7l.musllinux_1_1_armv7l", - ) - build_wheel( - version, - "dist/deltachat-rpc-server-armv6l-linux", - "py3-none-linux_armv6l", - ) - build_wheel( - version, - "dist/deltachat-rpc-server-aarch64-linux", - "py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.musllinux_1_1_aarch64", - ) - build_wheel( - version, - "dist/deltachat-rpc-server-i686-linux", - "py3-none-manylinux_2_12_i686.manylinux2010_i686.musllinux_1_1_i686", - ) - +arch2tags = { + "x86_64-linux": "manylinux_2_17_x86_64.manylinux2014_x86_64.musllinux_1_1_x86_64", + "armv7l-linux": "linux_armv7l.manylinux_2_17_armv7l.manylinux2014_armv7l.musllinux_1_1_armv7l", + "armv6l-linux": "linux_armv6l", + "aarch64-linux": "manylinux_2_17_aarch64.manylinux2014_aarch64.musllinux_1_1_aarch64", + "i686-linux": "manylinux_2_12_i686.manylinux2010_i686.musllinux_1_1_i686", + "win64": "win_amd64", + "win32": "win32", # macOS versions for platform compatibility tags are taken from https://doc.rust-lang.org/rustc/platform-support.html - build_wheel( - version, - "dist/deltachat-rpc-server-x86_64-macos", - "py3-none-macosx_10_7_x86_64", - ) - build_wheel( - version, - "dist/deltachat-rpc-server-aarch64-macos", - "py3-none-macosx_11_0_arm64", - ) - - build_wheel( - version, "dist/deltachat-rpc-server-win32.exe", "py3-none-win32", windows=True - ) - build_wheel( - version, - "dist/deltachat-rpc-server-win64.exe", - "py3-none-win_amd64", - windows=True, - ) + "x86_64-darwin": "macosx_10_7_x86_64", + "aarch64-darwin": "macosx_11_0_arm64", +} + + +def main(): + version = sys.argv[1] + if sys.argv[2] == "source": + filename = f"deltachat-rpc-server-{version}.tar.gz" + build_source_package(version, filename) + else: + arch = sys.argv[2] + executable = sys.argv[3] + tags = arch2tags[arch] + + if arch in ["win32", "win64"]: + build_wheel( + version, + executable, + f"py3-none-{tags}", + windows=True, + ) + else: + build_wheel(version, executable, f"py3-none-{tags}") main()