diff --git a/.github/workflows/publish-all-platforms.yml b/.github/workflows/publish-all-platforms.yml index a6f956496..735160cf9 100644 --- a/.github/workflows/publish-all-platforms.yml +++ b/.github/workflows/publish-all-platforms.yml @@ -6,34 +6,19 @@ on: description: 'commit/tag/branch reference' required: true type: string - csharp-package-version: - description: 'version for the C# nuget package (MAJOR.MINOR.BUILD)' - required: false + package-version: + description: 'version for the published package(s) (MAJOR.MINOR.BUILD)' + required: true + type: string + packages-to-publish: + description: 'array of packages to publish (remove what you do not want)' + required: true type: string + default: '["csharp", "golang", "maven", "kotlin-mpp", "flutter", "react-native", "python"]' csharp-ref: description: 'optional commit/tag/branch reference for the C# project. Defaults to ref.' required: false type: string - golang-package-version: - description: 'version for the golang package (MAJOR.MINOR.BUILD) (no v prefix)' - required: false - type: string - maven-package-version: - description: 'version for the android package (MAJOR.MINOR.BUILD)' - required: false - type: string - kotlin-mpp-package-version: - description: 'version for the kotlin multiplatform package (MAJOR.MINOR.BUILD)' - required: false - type: string - flutter-package-version: - description: 'version for the flutter package (MAJOR.MINOR.BUILD) (no v prefix)' - required: false - type: string - react-native-package-version: - description: 'version for the react native package (MAJOR.MINOR.BUILD)' - required: false - type: string use-dummy-binaries: description: 'boolean indicating whether to use dummies for the sdk binaries. Default = false.' required: false @@ -82,6 +67,10 @@ on: description: 'version for the react native package (MAJOR.MINOR.BUILD)' required: false type: string + python-package-version: + description: 'version for the python package (MAJOR.MINOR.BUILD)' + required: false + type: string use-dummy-binaries: description: 'boolean indicating whether to use dummies for the sdk binaries. Default = false.' required: false @@ -100,13 +89,14 @@ jobs: # certain inputs. repository: ${{ inputs.repository || github.repository }} ref: ${{ inputs.ref || github.sha }} - csharp-package-version: ${{ inputs.csharp-package-version }} + csharp-package-version: ${{ (contains(fromJSON(inputs.packages-to-publish), 'csharp') && inputs.package-version) || '' }} csharp-ref: ${{ inputs.csharp-ref || inputs.ref || github.sha }} - golang-package-version: ${{ inputs.golang-package-version }} - maven-package-version: ${{ inputs.maven-package-version }} - kotlin-mpp-package-version: ${{ inputs.kotlin-mpp-package-version }} - flutter-package-version: ${{ inputs.flutter-package-version }} - react-native-package-version: ${{ inputs.react-native-package-version }} + golang-package-version: ${{ (contains(fromJSON(inputs.packages-to-publish), 'golang') && inputs.package-version) || '' }} + maven-package-version: ${{ (contains(fromJSON(inputs.packages-to-publish), 'maven') && inputs.package-version) || ''}} + kotlin-mpp-package-version: ${{ (contains(fromJSON(inputs.packages-to-publish), 'kotlin-mpp') && inputs.package-version) || '' }} + flutter-package-version: ${{ (contains(fromJSON(inputs.packages-to-publish), 'flutter') && inputs.package-version) || '' }} + react-native-package-version: ${{ (contains(fromJSON(inputs.packages-to-publish), 'react-native') && inputs.package-version) || '' }} + python-package-version: ${{ (contains(fromJSON(inputs.packages-to-publish), 'python') && inputs.package-version) || '' }} use-dummy-binaries: ${{ inputs.use-dummy-binaries }} publish: ${{ inputs.publish }} steps: @@ -124,13 +114,13 @@ jobs: # (e.g. bindings-windows: true) if you want to test something. repository: ${{ needs.pre-setup.outputs.repository }} bindings-windows: ${{ !!needs.pre-setup.outputs.csharp-package-version || !!needs.pre-setup.outputs.golang-package-version }} - bindings-darwin: ${{ !!needs.pre-setup.outputs.csharp-package-version || !!needs.pre-setup.outputs.golang-package-version }} - bindings-linux: ${{ !!needs.pre-setup.outputs.csharp-package-version || !!needs.pre-setup.outputs.golang-package-version }} + bindings-darwin: ${{ !!needs.pre-setup.outputs.csharp-package-version || !!needs.pre-setup.outputs.golang-package-version || !!needs.pre-setup.outputs.python-package-version }} + bindings-linux: ${{ !!needs.pre-setup.outputs.csharp-package-version || !!needs.pre-setup.outputs.golang-package-version || !!needs.pre-setup.outputs.python-package-version}} bindings-android: ${{ !!needs.pre-setup.outputs.kotlin-mpp-package-version || !!needs.pre-setup.outputs.maven-package-version || !!needs.pre-setup.outputs.golang-package-version || !!needs.pre-setup.outputs.flutter-package-version }} bindings-ios: ${{ !!needs.pre-setup.outputs.kotlin-mpp-package-version || !!needs.pre-setup.outputs.maven-package-version }} kotlin: ${{ !!needs.pre-setup.outputs.kotlin-mpp-package-version || !!needs.pre-setup.outputs.maven-package-version }} swift: false - python: false + python: ${{ !!needs.pre-setup.outputs.python-package-version }} csharp: ${{ !!needs.pre-setup.outputs.csharp-package-version }} golang: ${{ !!needs.pre-setup.outputs.golang-package-version }} maven: ${{ !!needs.pre-setup.outputs.maven-package-version }} @@ -145,6 +135,7 @@ jobs: kotlin-mpp-package-version: ${{ needs.pre-setup.outputs.kotlin-mpp-package-version || '0.0.2' }} flutter-package-version: ${{ needs.pre-setup.outputs.flutter-package-version || '0.0.2' }} react-native-package-version: ${{ needs.pre-setup.outputs.react-native-package-version || '0.0.2' }} + python-package-version: ${{ needs.pre-setup.outputs.python-package-version || '0.0.2' }} publish: ${{ needs.pre-setup.outputs.publish }} use-dummy-binaries: ${{ needs.pre-setup.outputs.use-dummy-binaries }} steps: @@ -204,7 +195,7 @@ jobs: swift: ${{ needs.setup.outputs.swift == 'true'}} publish-csharp: - needs: + needs: - setup - build-bindings-windows - build-bindings-darwin @@ -222,7 +213,7 @@ jobs: NUGET_API_KEY: ${{ secrets.NUGET_API_KEY }} publish-golang: - needs: + needs: - setup - build-bindings-android - build-bindings-windows @@ -239,7 +230,7 @@ jobs: REPO_SSH_KEY: ${{ secrets.REPO_SSH_KEY }} publish-maven: - needs: + needs: - setup - build-bindings-android - build-language-bindings @@ -255,7 +246,7 @@ jobs: BREEZ_MVN_PASSWORD: ${{ secrets.BREEZ_MVN_PASSWORD }} publish-kotlin-mpp: - needs: + needs: - setup - build-bindings-android - build-bindings-ios @@ -272,9 +263,9 @@ jobs: BREEZ_MVN_PASSWORD: ${{ secrets.BREEZ_MVN_PASSWORD }} publish-flutter: - needs: + needs: - setup - - build-bindings-android + - build-bindings-android if: ${{ needs.setup.outputs.flutter == 'true' }} uses: ./.github/workflows/publish-flutter.yml with: @@ -299,3 +290,18 @@ jobs: publish: ${{ needs.setup.outputs.publish == 'true' }} secrets: NPM_TOKEN: ${{ secrets.NPM_TOKEN }} + + publish-python: + needs: + - setup + - build-bindings-darwin + - build-bindings-linux + - build-language-bindings + if: ${{ needs.setup.outputs.python == 'true' }} + uses: ./.github/workflows/publish-python.yml + with: + ref: ${{ needs.setup.outputs.ref }} + package-version: ${{ needs.setup.outputs.python-package-version }} + publish: ${{ needs.setup.outputs.publish == 'true' }} + secrets: + PYPI_API_TOKEN: ${{ secrets.PYPI_API_TOKEN }} diff --git a/.github/workflows/publish-python.yml b/.github/workflows/publish-python.yml new file mode 100644 index 000000000..04315ed65 --- /dev/null +++ b/.github/workflows/publish-python.yml @@ -0,0 +1,158 @@ +name: Publish Python Bindings +on: + workflow_call: + inputs: + ref: + description: 'commit/tag/branch reference' + required: true + type: string + package-version: + description: 'version for the python package (MAJOR.MINOR.BUILD)' + required: true + type: string + publish: + description: 'value indicating whether to publish to pypi.' + required: true + type: boolean + default: false + secrets: + PYPI_API_TOKEN: + description: 'api token to authenticate to pypi' + required: true + +jobs: + build-macos-wheels: + runs-on: macos-latest + strategy: + matrix: + python: ["3.8", "3.9", "3.10"] + steps: + - name: Checkout breez-sdk repo + uses: actions/checkout@v3 + with: + ref: ${{ inputs.ref || github.sha }} + + - name: "Install Python" + uses: actions/setup-python@v4 + with: + python-version: ${{ matrix.python }} + + - uses: actions/download-artifact@v3 + with: + name: sdk-bindings-darwin-universal + path: libs/sdk-bindings/bindings-python/src/breez_sdk + + - uses: actions/download-artifact@v3 + with: + name: bindings-python + path: libs/sdk-bindings/bindings-python/src/breez_sdk + + - name: Clean up downloaded files + run: | + rm -f libs/sdk-bindings/bindings-python/src/breez_sdk/*.a + ls -R libs/sdk-bindings/bindings-python + + - name: Update package version + if: ${{ inputs.package-version }} + working-directory: libs/sdk-bindings/bindings-python + run: sed -i.bak -e 's/ version=".*",/ version="${{ inputs.package-version }}",/' setup.py + + - name: Install dependencies + working-directory: libs/sdk-bindings/bindings-python + run: pip3 install wheel setuptools + + - name: Build wheel + working-directory: libs/sdk-bindings/bindings-python + run: python3 setup.py bdist_wheel --plat-name macosx_11_0_universal2 --verbose + + - name: List wheel contents + working-directory: libs/sdk-bindings/bindings-python/dist + run: python3 -m zipfile --list *.whl || true + + - name: Archive the wheel + uses: actions/upload-artifact@v3 + with: + name: python-wheel-${{ matrix.python }}-macos + path: libs/sdk-bindings/bindings-python/dist/*.whl + + build-linux-wheels: + runs-on: ubuntu-20.04 + strategy: + matrix: + arch: [x86_64, aarch64] + python: ["3.8", "3.9", "3.10"] + steps: + - name: "Checkout" + uses: actions/checkout@v3 + + - name: "Setup Python" + uses: actions/setup-python@v4 + with: + python-version: ${{ matrix.python }} + + - uses: actions/download-artifact@v3 + with: + name: sdk-bindings-${{ matrix.arch }}-unknown-linux-gnu + path: libs/sdk-bindings/bindings-python/src/breez_sdk + + - uses: actions/download-artifact@v3 + with: + name: bindings-python + path: libs/sdk-bindings/bindings-python/src/breez_sdk + + - name: Update package version + if: ${{ inputs.package-version }} + working-directory: libs/sdk-bindings/bindings-python + run: sed -i.bak -e 's/ version=".*",/ version="${{ inputs.package-version }}",/' setup.py + + - name: Install dependencies + working-directory: libs/sdk-bindings/bindings-python + run: pip3 install wheel setuptools + + - name: "Build wheel" + working-directory: libs/sdk-bindings/bindings-python + run: python3 setup.py bdist_wheel --plat-name manylinux_2_31_${{ matrix.arch }} --verbose + + - uses: actions/upload-artifact@v3 + with: + name: python-wheel-${{ matrix.python }}-manylinux_2_31_${{ matrix.arch }} + path: libs/sdk-bindings/bindings-python/dist/*.whl + + publish-package: + runs-on: ubuntu-latest + needs: [build-macos-wheels, build-linux-wheels] + steps: + - name: Checkout breez-sdk repo + uses: actions/checkout@v3 + with: + ref: ${{ inputs.ref || github.sha }} + + - name: Download wheels + uses: actions/download-artifact@v3 + with: + path: libs/sdk-bindings/bindings-python/dist/ + + - name: Clean downloaded contents + working-directory: libs/sdk-bindings/bindings-python + run: | + find dist -maxdepth 1 ! -path dist ! -name "python-wheel-*" -exec rm -rf {} \; + ls -laR dist + + # for developing, testing, and experimenting + # - name: "Publish on test PyPI" + # uses: pypa/gh-action-pypi-publish@release/v1 + # with: + # verbose: true + # user: __token__ + # password: ${{ secrets.PYPI_API_TOKEN }} + # repository_url: https://test.pypi.org/legacy/ + # packages_dir: libs/sdk-bindings/bindings-python/dist/*/ + + - name: "Publish on PyPI" + if: ${{ inputs.publish }} + uses: pypa/gh-action-pypi-publish@release/v1 + with: + verbose: true + user: __token__ + password: ${{ secrets.PYPI_API_TOKEN }} + packages_dir: libs/sdk-bindings/bindings-python/dist/*/ diff --git a/libs/sdk-bindings/bindings-python/.gitignore b/libs/sdk-bindings/bindings-python/.gitignore new file mode 100644 index 000000000..41a367527 --- /dev/null +++ b/libs/sdk-bindings/bindings-python/.gitignore @@ -0,0 +1,5 @@ +src/breez_sdk/breez_sdk.py +src/breez_sdk/*.dylib +*.egg-info +build +dist diff --git a/libs/sdk-bindings/bindings-python/README.md b/libs/sdk-bindings/bindings-python/README.md new file mode 100644 index 000000000..a2621699f --- /dev/null +++ b/libs/sdk-bindings/bindings-python/README.md @@ -0,0 +1,37 @@ +# SDK bindings for Python + +## Usage + +``` +pip install breez_sdk +``` + +``` python +import breez_sdk + +# see https://sdk-doc.breez.technology +``` + +## Python Package + +Run the GitHub workflow 'Publish Python Bindings' when creating a new release of Breez SDK. +It will create wheels for the following Python versions and Platforms and upload them to [PyPi.org](https://pypi.org/project/breez-sdk/). + +### Supported Wheels + +| | GNU/Linux amd64 | GNU/Linux arm64v8 | macOS x86_64 | macos aarch64 | +|-----------------|-----------------|-------------------|--------------|---------------| +| **Python 3.8** | ✅ | ✅ | ✅ | ✅ | +| **Python 3.9** | ✅ | ✅ | ✅ | ✅ | +| **Python 3.10** | ✅ | ✅ | ✅ | ✅ | + +## Building Manually + +To build the package manually inside this directory use the supplied `makefile`: + +``` shell +make darwin # builds the package for macos +make linux # builds the package for linux +``` + +The artifacts will be placed in `src/breez_sdk/`. diff --git a/libs/sdk-bindings/bindings-python/makefile b/libs/sdk-bindings/bindings-python/makefile new file mode 100644 index 000000000..f17739fa0 --- /dev/null +++ b/libs/sdk-bindings/bindings-python/makefile @@ -0,0 +1,13 @@ +.PHONY: init +init: + make -C ../ init + +darwin: + make -C ../ python-darwin + cp ../ffi/python/breez_sdk.py src/breez_sdk + cp ../ffi/python/libbreez_sdk_bindings.dylib src/breez_sdk + +linux: + make -C ../ python-linux + cp ../ffi/python/breez_sdk.py src/breez_sdk + cp ../ffi/python/libbreez_sdk_bindings.dylib src/breez_sdk diff --git a/libs/sdk-bindings/bindings-python/pyproject.toml b/libs/sdk-bindings/bindings-python/pyproject.toml new file mode 100644 index 000000000..fed528d4a --- /dev/null +++ b/libs/sdk-bindings/bindings-python/pyproject.toml @@ -0,0 +1,3 @@ +[build-system] +requires = ["setuptools"] +build-backend = "setuptools.build_meta" diff --git a/libs/sdk-bindings/bindings-python/setup.py b/libs/sdk-bindings/bindings-python/setup.py new file mode 100644 index 000000000..40d906071 --- /dev/null +++ b/libs/sdk-bindings/bindings-python/setup.py @@ -0,0 +1,33 @@ +#!/usr/bin/env python + +from setuptools import setup + +LONG_DESCRIPTION = """# Breez SDK +Python language bindings for the [Breez SDK](https://github.com/breez/breez-sdk). + +## Installing + +```shell +pip install breez_sdk +``` + +## Docs + +See [sdk-doc.breez.technology](https://sdk-doc.breez.technology). +""" + +setup( + name="breez_sdk", + version="0.2.7.dev9", + description="Python language bindings for the Breez SDK", + long_description=LONG_DESCRIPTION, + long_description_content_type="text/markdown", + packages=["breez_sdk"], + package_dir={"breez_sdk": "./src/breez_sdk"}, + include_package_data=True, + package_data={"breez_sdk": ["*.dylib", "*.so"]}, + url="https://github.com/breez/breez-sdk", + author="Breez ", + license="MIT", + has_ext_modules=lambda: True, +) diff --git a/libs/sdk-bindings/bindings-python/src/breez_sdk/__init__.py b/libs/sdk-bindings/bindings-python/src/breez_sdk/__init__.py new file mode 100644 index 000000000..054d9d339 --- /dev/null +++ b/libs/sdk-bindings/bindings-python/src/breez_sdk/__init__.py @@ -0,0 +1 @@ +from breez_sdk.breez_sdk import *