Skip to content

Commit f274f55

Browse files
Merge master into main with full project setup
2 parents 134524c + 79fde24 commit f274f55

21 files changed

Lines changed: 2240 additions & 1 deletion

.github/workflows/release.yml

Lines changed: 212 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,212 @@
1+
name: Build and Release
2+
3+
on:
4+
# Trigger from rgb-lib repository
5+
repository_dispatch:
6+
types: [rgb-lib-release]
7+
8+
# Manual trigger
9+
workflow_dispatch:
10+
inputs:
11+
rgb_lib_version:
12+
description: 'rgb-lib version to use (e.g., v0.3.0-beta.8)'
13+
required: true
14+
type: string
15+
16+
jobs:
17+
build:
18+
name: Build (${{ matrix.platform }})
19+
runs-on: ${{ matrix.runner }}
20+
strategy:
21+
fail-fast: false
22+
matrix:
23+
include:
24+
# Linux x64
25+
- runner: ubuntu-latest
26+
platform: linux-x86_64
27+
target: x86_64-unknown-linux-gnu
28+
# Linux ARM64
29+
- runner: ubuntu-24.04-arm
30+
platform: linux-aarch64
31+
target: aarch64-unknown-linux-gnu
32+
# macOS ARM64 (Apple Silicon)
33+
- runner: macos-latest
34+
platform: macosx-arm64
35+
target: aarch64-apple-darwin
36+
37+
steps:
38+
- name: Checkout repository
39+
uses: actions/checkout@v4
40+
with:
41+
submodules: recursive
42+
43+
- name: Get rgb-lib version
44+
id: rgb_lib_version
45+
run: |
46+
if [ "${{ github.event_name }}" == "repository_dispatch" ]; then
47+
echo "version=${{ github.event.client_payload.version }}" >> $GITHUB_OUTPUT
48+
elif [ "${{ github.event_name }}" == "workflow_dispatch" ]; then
49+
echo "version=${{ inputs.rgb_lib_version }}" >> $GITHUB_OUTPUT
50+
fi
51+
shell: bash
52+
53+
- name: Setup Python
54+
uses: actions/setup-python@v5
55+
with:
56+
python-version: '3.11'
57+
58+
- name: Setup Rust
59+
uses: actions-rust-lang/setup-rust-toolchain@v1
60+
with:
61+
toolchain: stable
62+
target: ${{ matrix.target }}
63+
64+
- name: Install Docker (Linux ARM64)
65+
if: matrix.platform == 'linux-aarch64'
66+
run: |
67+
sudo apt-get update
68+
sudo apt-get install -y docker.io
69+
sudo systemctl start docker
70+
71+
- name: Update rgb-lib submodule to target version
72+
run: |
73+
cd rgb-lib
74+
git fetch --all --tags
75+
git checkout ${{ steps.rgb_lib_version.outputs.version }}
76+
echo "Checked out rgb-lib version:"
77+
git log --oneline -1
78+
cd ..
79+
shell: bash
80+
81+
- name: Get version for Python package
82+
id: pyversion
83+
run: |
84+
VERSION="${{ steps.rgb_lib_version.outputs.version }}"
85+
# Remove 'v' prefix and convert to PEP 440 format
86+
# v0.3.0-beta.8 -> 0.3.0b8
87+
PY_VERSION=$(echo "$VERSION" | sed 's/^v//' | sed 's/-beta\./b/' | sed 's/-alpha\./a/' | sed 's/-rc\./rc/')
88+
echo "version=$PY_VERSION" >> $GITHUB_OUTPUT
89+
echo "Python version: $PY_VERSION"
90+
91+
- name: Update version in pyproject.toml
92+
run: |
93+
VERSION="${{ steps.pyversion.outputs.version }}"
94+
sed -i.bak "s/^version = .*/version = \"$VERSION\"/" pyproject.toml
95+
cat pyproject.toml | grep "^version"
96+
97+
- name: Install Python dependencies
98+
run: |
99+
python -m pip install --upgrade pip
100+
pip install poetry build wheel
101+
102+
- name: Build wheel
103+
run: |
104+
export PLATFORM="${{ matrix.platform }}"
105+
python -m build --wheel
106+
env:
107+
PLATFORM: ${{ matrix.platform }}
108+
109+
- name: List built wheels
110+
run: ls -la dist/
111+
112+
- name: Upload wheel artifact
113+
uses: actions/upload-artifact@v4
114+
with:
115+
name: wheel-${{ matrix.platform }}
116+
path: dist/*.whl
117+
retention-days: 5
118+
119+
publish:
120+
name: Publish to PyPI
121+
needs: build
122+
if: always() && !cancelled()
123+
runs-on: ubuntu-latest
124+
125+
steps:
126+
- name: Download all wheel artifacts
127+
uses: actions/download-artifact@v4
128+
with:
129+
path: wheels
130+
pattern: wheel-*
131+
merge-multiple: true
132+
133+
- name: List wheels
134+
run: ls -la wheels/
135+
136+
- name: Setup Python
137+
uses: actions/setup-python@v5
138+
with:
139+
python-version: '3.11'
140+
141+
- name: Install twine
142+
run: pip install twine
143+
144+
- name: Publish to PyPI
145+
run: |
146+
twine upload wheels/*.whl --skip-existing || echo "Some packages may already exist, continuing..."
147+
env:
148+
TWINE_USERNAME: __token__
149+
TWINE_PASSWORD: ${{ secrets.PYPI_TOKEN }}
150+
151+
release:
152+
name: Create GitHub Release
153+
needs: [build, publish]
154+
if: always() && !cancelled()
155+
runs-on: ubuntu-latest
156+
permissions:
157+
contents: write
158+
159+
steps:
160+
- name: Checkout repository
161+
uses: actions/checkout@v4
162+
163+
- name: Get version info
164+
id: version
165+
run: |
166+
if [ "${{ github.event_name }}" == "repository_dispatch" ]; then
167+
VERSION="${{ github.event.client_payload.version }}"
168+
else
169+
VERSION="${{ inputs.rgb_lib_version }}"
170+
fi
171+
echo "version=$VERSION" >> $GITHUB_OUTPUT
172+
173+
- name: Download all wheel artifacts
174+
uses: actions/download-artifact@v4
175+
with:
176+
path: wheels
177+
pattern: wheel-*
178+
merge-multiple: true
179+
180+
- name: Create Release
181+
uses: softprops/action-gh-release@v2
182+
with:
183+
tag_name: ${{ steps.version.outputs.version }}
184+
name: Release ${{ steps.version.outputs.version }}
185+
body: |
186+
## Python bindings for rgb-lib
187+
188+
Based on rgb-lib ${{ steps.version.outputs.version }}
189+
190+
### Installation via pip (recommended)
191+
192+
```bash
193+
pip install rgb-lib
194+
```
195+
196+
### Platforms
197+
198+
| Platform | Wheel |
199+
|----------|-------|
200+
| Linux x64 | `manylinux_2_34_x86_64` |
201+
| Linux ARM64 | `manylinux_2_34_aarch64` |
202+
| macOS ARM64 (Apple Silicon) | `macosx_12_0_arm64` |
203+
204+
### Changes
205+
206+
See [rgb-lib release notes](https://github.com/UTEXO-Protocol/rgb-lib/releases/tag/${{ steps.version.outputs.version }})
207+
draft: false
208+
prerelease: ${{ contains(steps.version.outputs.version, 'alpha') || contains(steps.version.outputs.version, 'beta') || contains(steps.version.outputs.version, 'rc') }}
209+
files: wheels/*.whl
210+
env:
211+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
212+

.gitignore

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
**/.vim/
2+
**/__pycache__/
3+
/dist/
4+
/poetry.lock
5+
/rgb_lib/*rgblibuniffi.*
6+
/rgb_lib/rgb_lib.py

.gitmodules

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
[submodule "rgb-lib"]
2+
path = rgb-lib
3+
url = https://github.com/UTEXO-Protocol/rgb-lib.git
4+
[submodule "cross"]
5+
path = cross
6+
url = https://github.com/nicbus/cross

CONTRIBUTING.md

Lines changed: 169 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,169 @@
1+
# RGB Lib Python bindings development
2+
3+
The goal of this project is to produce Python bindings for [rgb-lib], which is
4+
included as a submodule. The bindings are created by the [rgb-lib-uniffi]
5+
project, which is located inside the rgb-lib submodule.
6+
7+
## Build
8+
9+
In order to build the bindings package(s), clone the project (`git clone
10+
https://github.com/RGB-Tools/rgb-lib-python --recurse-submodules`), enter the
11+
project root (`cd rgb-lib-python`) and follow the next instructions.
12+
13+
Always make sure the submodules are up-to-date:
14+
15+
```sh
16+
git submodule update --init --recursive
17+
```
18+
19+
The builds of the native Rust library and of the python bindings are carried
20+
out in Docker, using [cross].
21+
22+
### Requirements
23+
24+
- [poetry] (version 2)
25+
- [docker]
26+
- [cargo]
27+
- [cross] (`cargo install cross`)
28+
- cc (`apt install gcc`)
29+
30+
### Local project
31+
32+
In order to build or install the project on the local machine, cross needs to
33+
be properly configured first. To do so, run:
34+
35+
```sh
36+
poetry run python -c 'import build_packages; build_packages.setup_cross()'
37+
```
38+
39+
or, if the project has already been installed (see below):
40+
41+
```sh
42+
poetry run setup-cross
43+
```
44+
45+
The package can then be built with:
46+
47+
```sh
48+
poetry build
49+
```
50+
51+
or installed with:
52+
53+
```sh
54+
poetry install
55+
```
56+
57+
Once the package has been installed, the following scripts are available to
58+
ease development:
59+
60+
- build-packages (builds all the packages, see the [packages] section)
61+
- setup-cross (configure cross to build project/packages)
62+
63+
### Packages
64+
65+
In order to build all the packages for the project, one wheel per supported
66+
platform plus the sdist, if the project has already been installed run:
67+
68+
```sh
69+
poetry run build-packages
70+
```
71+
72+
else run:
73+
74+
```sh
75+
poetry run python build_packages.py
76+
```
77+
78+
The package build script will build the required docker image and use it to
79+
build the wheels for all supported platforms, then builds the sdist. Once the
80+
build completes, the archives will be available in the `dist/` directory. The
81+
script will also cleanup the build artifacts and restore the submodules to
82+
their initial conditions.
83+
84+
### Wheel tags
85+
86+
The `build.py` script contains the wheel tags associated to the supported
87+
platforms. See Python's [platform compatibility tags] for details. You can use
88+
`sysconfig.get_platform()` and `platform.machine()` to get the data for the
89+
running system.
90+
91+
Special care is necessary for macosx wheels, as there
92+
`sysconfig.get_platform()` returns what the Python interpreter was built for
93+
(e.g. the system python reports `macosx-10.9-universal2`, while homebrew python
94+
3.12 might return `macosx-14.0-arm64`) and the operating system (e.g. version
95+
15.1.1) version is not used in a numerical comparison. To have wheels
96+
successfully install it's important to tag them with the correct major version
97+
but use `0` as the minor version (e.g. `macosx-12.0-arm64` will install on OSX
98+
12.7 but `macosx-12.3-arm64` won't).
99+
100+
## Format
101+
102+
To format the code of the build scripts, from the project root run:
103+
104+
```sh
105+
poetry run black *.py
106+
```
107+
108+
## Lint
109+
110+
To lint the code of the build scripts, from the project root run:
111+
112+
```sh
113+
poetry run flake8 *.py
114+
poetry run pylint *.py
115+
```
116+
117+
## Publish
118+
119+
Publishing to PyPI is handled with [poetry] (version 2.0 or later).
120+
121+
Make sure the `dist/` directory only contains the expected packages (e.g. using
122+
`poetry build` produces a wheel that's not meant to be published). The best way
123+
do to this is to empty the `dist/` directory and then build all the [packages].
124+
To check what would be published use `poetry publish --dry-run`.
125+
126+
To configure the access token, which only needs to be done once, run:
127+
128+
```sh
129+
poetry config pypi-token.pypi <token>
130+
```
131+
132+
To publish a new release run:
133+
134+
```sh
135+
poetry publish
136+
```
137+
138+
### Test PyPI
139+
140+
To use the test PyPI instance, the repository needs to be configured in poetry:
141+
142+
```sh
143+
poetry config repositories.test-pypi https://test.pypi.org/legacy/
144+
```
145+
146+
An access token then needs to also be set:
147+
148+
```sh
149+
poetry config pypi-token.test-pypi <token>
150+
```
151+
152+
Publishing needs to specify the registry:
153+
154+
```sh
155+
poetry publish -r test-pypi
156+
```
157+
158+
To install the package from test PyPI:
159+
160+
```sh
161+
pip install --index-url https://test.pypi.org/simple/ rgb-lib
162+
```
163+
164+
[cargo]: https://github.com/rust-lang/cargo
165+
[cross]: https://github.com/cross-rs/cross
166+
[docker]: https://docs.docker.com/engine/install/
167+
[packages]: #packages
168+
[platform compatibility tags]: https://packaging.python.org/en/latest/specifications/platform-compatibility-tags/
169+
[poetry]: https://github.com/python-poetry/poetry

0 commit comments

Comments
 (0)