Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions .containerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# Exclude local build artifacts and any symlinks outside the context
build*

# Local documentation files (can be symlinks outside the context)
*.md

# Common Python / tooling artifacts
__pycache__/
*.pyc
.venv/
dist/
11 changes: 11 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# Exclude local build artifacts and any symlinks outside the context
build*

# Local documentation files (can be symlinks outside the context)
*.md

# Common Python / tooling artifacts
__pycache__/
*.pyc
.venv/
dist/
4 changes: 3 additions & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,9 @@ jobs:
git config --global --add safe.directory ${{ github.workspace }}
contrib/build_bin.sh
contrib/build_dist.sh
# Verify setup.py regeneration is stable after generating GUI artifacts.
contrib/generate_setup.sh
git diff --exit-code -- setup.py
find dist -type f -exec sha256sum {} \;
"

Expand Down Expand Up @@ -242,4 +245,3 @@ jobs:
with:
device: keepkey
runs-on: ubuntu-latest

2 changes: 1 addition & 1 deletion .github/workflows/device-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ jobs:
strategy:
fail-fast: false
matrix:
python-version: ['3.9', '3.10', '3.11', '3.12']
python-version: ['3.10', '3.11', '3.12']
device:
- ${{ inputs.device }}
test:
Expand Down
10 changes: 5 additions & 5 deletions .github/workflows/ledger-app-builder.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,14 @@ jobs:
build:
name: Build Bitcoin App
runs-on: ${{ inputs.runs-on }}
# Pin to 4.23.0 for SDK v25.9.0 compatibility with Speculos v0.25.10
container: ghcr.io/ledgerhq/ledger-app-builder/ledger-app-builder:4.23.0
# app-bitcoin v2.5.0 targets SDK v26.5.0, provided by builder 5.3.17.
container: ghcr.io/ledgerhq/ledger-app-builder/ledger-app-builder:5.3.17
steps:
- run: |
# Pin to v2.4.1 - last version that worked with HWI CI (PR #795 merged Sept 2025)
git clone --branch 2.4.1 --depth 1 https://github.com/LedgerHQ/app-bitcoin.git
# Pin to v2.5.0
git clone --branch 2.5.0 --depth 1 https://github.com/LedgerHQ/app-bitcoin.git
cd app-bitcoin
make DEBUG=1 BOLOS_SDK=$NANOX_SDK
make DEBUG=1 COIN=bitcoin_testnet BOLOS_SDK=$NANOX_SDK
- uses: actions/upload-artifact@v4
with:
name: ledger_app
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/ledger-legacy-app-builder.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ jobs:
build:
name: Build Bitcoin Legacy App
runs-on: ${{ inputs.runs-on }}
# Pin to 4.23.0 for SDK v25.9.0 compatibility with Speculos v0.25.10
# Pin to 4.23.0 for SDK v25.9.0 compatibility with Speculos v0.26.9
container: ghcr.io/ledgerhq/ledger-app-builder/ledger-app-builder:4.23.0
steps:
- run: |
Expand Down
2 changes: 1 addition & 1 deletion .python-version
Original file line number Diff line number Diff line change
@@ -1 +1 @@
3.9
3.10.20
23 changes: 0 additions & 23 deletions ci/py39.Dockerfile

This file was deleted.

2 changes: 0 additions & 2 deletions contrib/build-wine.Dockerfile
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
FROM debian:bookworm-slim

SHELL ["/bin/bash", "-c"]

ENV DEBIAN_FRONTEND=noninteractive
RUN apt-get update
RUN apt-get install -y \
Expand Down
6 changes: 2 additions & 4 deletions contrib/build.Dockerfile
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
FROM debian:bookworm-slim

SHELL ["/bin/bash", "-c"]

ENV DEBIAN_FRONTEND=noninteractive
RUN apt-get update
RUN apt-get install -y \
Expand Down Expand Up @@ -36,9 +34,9 @@ ENV PATH="$PYENV_ROOT/bin:$PATH"

COPY contrib/reproducible-python.diff /opt/reproducible-python.diff
ENV PYTHON_CONFIGURE_OPTS="--enable-shared"
ENV BUILD_DATE="Jan 1 2019"
ENV BUILD_DATE="Jan 1 2026"
ENV BUILD_TIME="00:00:00"
RUN eval "$(pyenv init --path)" && eval "$(pyenv virtualenv-init -)" && cat /opt/reproducible-python.diff | pyenv install -kp 3.9.19
RUN /bin/bash -c 'eval "$(pyenv init --path)" && eval "$(pyenv virtualenv-init -)" && cat /opt/reproducible-python.diff | pyenv install -kp 3.10.20'

ENV LC_ALL=C.UTF-8
ENV LANG=C.UTF-8
Expand Down
9 changes: 6 additions & 3 deletions contrib/build_bin.sh
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,11 @@ set -ex

ARCH=$(uname -m | tr '[:upper:]' '[:lower:]')

PYTHON_VERSION=3.10.20

eval "$(pyenv init --path)"
eval "$(pyenv virtualenv-init -)"
export PYENV_VERSION="$PYTHON_VERSION"
pip install -U pip
pip install poetry

Expand All @@ -21,8 +24,8 @@ else
fi

# We also need to change the timestamps of all of the base library files
lib_dir=$(pyenv prefix)/lib/python3.9
TZ=UTC find ${lib_dir} -name '*.py' -type f -execdir touch -t "201901010000.00" '{}' \;
lib_dir=$(pyenv prefix)/lib/python3.10
TZ=UTC find ${lib_dir} -name '*.py' -type f -execdir touch -t "202601010000.00" '{}' \;

# Make the standalone binary
export PYTHONHASHSEED=42
Expand All @@ -45,7 +48,7 @@ fi

target_tarfile="hwi-${VERSION}-${OS}-${ARCH}.tar.gz"

if [[ $gui_support == "--with-gui" ]]; then
if [[ $gui_support == "--with-gui" && $ARCH == "x86_64" ]]; then
tar -czf $target_tarfile hwi hwi-qt
else
tar -czf $target_tarfile hwi
Expand Down
8 changes: 6 additions & 2 deletions contrib/build_dist.sh
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,11 @@

set -ex

PYTHON_VERSION=3.10.20

eval "$(pyenv init --path)"
eval "$(pyenv virtualenv-init -)"
export PYENV_VERSION="$PYTHON_VERSION"
pip install -U pip
pip install poetry

Expand All @@ -14,11 +17,12 @@ gui_support="${1:---with-gui}";
# Setup poetry and install the dependencies
if [[ $gui_support == "--with-gui" ]]; then
poetry install -E qt
poetry run contrib/generate-ui.sh
else
poetry install
fi

# Make the distribution archives for pypi
poetry build -f wheel
# faketime is needed to make sdist detereministic
TZ=UTC faketime -f "2019-01-01 00:00:00" poetry build -f sdist
# faketime is needed to make sdist deterministic
TZ=UTC faketime -f "2026-01-01 00:00:00" poetry build -f sdist
33 changes: 16 additions & 17 deletions contrib/build_wine.sh
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,11 @@

set -ex

PYTHON_VERSION=3.9.13
# Note: Python MSIs/EXEs are no longer hosted for 3.10.x on python.org.
# The NuGet python package currently only goes up to 3.10.11, so Windows builds use that.
PYTHON_VERSION=3.10.11
PYTHON_NUGET_URL="https://api.nuget.org/v3-flatcontainer/python/${PYTHON_VERSION}/python.${PYTHON_VERSION}.nupkg"
PYTHON_NUGET_HASH="7c6f99b160a36a7e09492dfcff2b0a3a60bb5229ca44cdcc3ecb32871a6144d0"

PYTHON_FOLDER="python3"
PYHOME="c:/$PYTHON_FOLDER"
Expand All @@ -19,28 +23,23 @@ WINDOWS_SDK_VERSION=10.0.17763.0

wine 'wineboot'

# Install Python
# Get the PGP keys
wget -O pubkeys.txt -N -c "https://keybase.io/stevedower/pgp_keys.asc?fingerprint=7ed10b6531d7c8e1bc296021fc624643487034e5"
gpg --import pubkeys.txt
rm pubkeys.txt

# Install python components
for msifile in core dev exe lib pip tools; do
wget -N -c "https://www.python.org/ftp/python/$PYTHON_VERSION/amd64/${msifile}.msi"
wget -N -c "https://www.python.org/ftp/python/$PYTHON_VERSION/amd64/${msifile}.msi.asc"
gpg --verify "${msifile}.msi.asc" "${msifile}.msi"
wine msiexec /i "${msifile}.msi" /qb TARGETDIR=$PYHOME
rm $msifile.msi*
done
# Install Python from NuGet package
wget -O python.nupkg -N -c "$PYTHON_NUGET_URL"
echo "$PYTHON_NUGET_HASH python.nupkg" | sha256sum -c
rm -rf python-nupkg
7z x python.nupkg -opython-nupkg >/dev/null
rm -rf ~/.wine/drive_c/python3
mkdir -p ~/.wine/drive_c/python3
cp -a python-nupkg/tools/* ~/.wine/drive_c/python3/
rm -rf python.nupkg python-nupkg

# Get and build libusb
wget -N -c -O libusb.tar.bz2 "$LIBUSB_URL"
echo "$LIBUSB_HASH libusb.tar.bz2" | sha256sum -c
tar -xf libusb.tar.bz2
pushd "libusb-$LIBUSB_VERSION"
./configure --host=x86_64-w64-mingw32
faketime -f "2019-01-01 00:00:00" make
faketime -f "2026-01-01 00:00:00" make
cp libusb/.libs/libusb-1.0.dll ~/.wine/drive_c/python3/
popd
rm -r libusb*
Expand All @@ -62,7 +61,7 @@ $PYTHON -m pip install poetry

# We also need to change the timestamps of all of the base library files
lib_dir=~/.wine/drive_c/python3/Lib
TZ=UTC find ${lib_dir} -name '*.py' -type f -execdir touch -t "201901010000.00" '{}' \;
TZ=UTC find ${lib_dir} -name '*.py' -type f -execdir touch -t "202601010000.00" '{}' \;

# Install python dependencies
POETRY="wine $PYHOME/Scripts/poetry.exe"
Expand Down
1 change: 1 addition & 0 deletions contrib/generate-ui.sh
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
set -ex

pushd hwilib/ui
rm -f ui_*.py
for file in *.ui
do
gen_file=ui_`echo $file| cut -d. -f1`.py
Expand Down
2 changes: 2 additions & 0 deletions contrib/generate_setup.sh
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ set -ex

# Setup poetry and install the dependencies
poetry install -E qt
# Generate the Python modules so Poetry consistently detects hwilib.ui as a package.
poetry run contrib/generate-ui.sh

# Build the source distribution
poetry build -f sdist
Expand Down
12 changes: 6 additions & 6 deletions docs/development/release-process.rst
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ Release Process
1. Bump version number in ``pyproject.toml`` and ``hwilib/__init__.py``, generate the setup.py file, and git tag release
2. Build distribution archives for PyPi with ``contrib/build_dist.sh``
3. For MacOS and Linux, use ``contrib/build_bin.sh``. This needs to be run on a macOS machine for the macOS binary and on a Linux machine for the linux one.
4. For Windows, use ``contrib/build_wine.sh`` to build the Windows binary using wine
4. For Windows, use ``contrib/build_wine.sh`` to build the Windows binary using wine. Note that this uses Python 3.10.11 via the NuGet package because python.org no longer hosts the MSIs for newer 3.10.x releases.
5. Make ``SHA256SUMS.txt`` using ``contrib/make_shasums.sh``.
6. Make ``SHA256SUMS.txt.asc`` using ``gpg --clearsign SHA256SUMS.txt``
7. Upload distribution archives to PyPi
Expand All @@ -26,7 +26,7 @@ Build everything::

docker run -it --name hwi-builder -v $PWD:/opt/hwi --rm --workdir /opt/hwi hwi-builder /bin/bash -c "contrib/build_bin.sh && contrib/build_dist.sh"
docker run -it --name hwi-wine-builder -v $PWD:/opt/hwi --rm --workdir /opt/hwi hwi-wine-builder /bin/bash -c "contrib/build_wine.sh"
docker run --platform linux/arm64 -it --rm --name hwi-builder-arm64 -v $PWD:/opt/hwi --workdir /opt/hwi hwi-builder-arm64 /bin/bash -c "contrib/build_bin.sh --without-gui && contrib/build_dist.sh --without-gui"
docker run --platform linux/arm64 -it --rm --name hwi-builder-arm64 -v $PWD:/opt/hwi --workdir /opt/hwi hwi-builder-arm64 /bin/bash -c "contrib/build_bin.sh --without-gui && contrib/build_dist.sh --without-gui"

Building macOS binary
=====================
Expand All @@ -35,14 +35,14 @@ Note that the macOS build is non-deterministic.

First install `pyenv <https://github.com/pyenv/pyenv>`_ using whichever method you prefer.

Then a deterministic build of Python 3.9.19 needs to be installed. This can be done with the patch in ``contrib/reproducible-python.diff``. First ``cd`` into HWI's source tree. Then use::
Then a deterministic build of Python 3.10.20 needs to be installed. This can be done with the patch in ``contrib/reproducible-python.diff``. First ``cd`` into HWI's source tree. Then use::

cat contrib/reproducible-python.diff | PYTHON_CONFIGURE_OPTS="--enable-framework" BUILD_DATE="Jan 1 2019" BUILD_TIME="00:00:00" pyenv install -kp 3.9.19
cat contrib/reproducible-python.diff | PYTHON_CONFIGURE_OPTS="--enable-framework" BUILD_DATE="Jan 1 2026" BUILD_TIME="00:00:00" pyenv install -kp 3.10.20

Make sure that python 3.9.19 is active::
Make sure that python 3.10.20 is active::

$ python --version
Python 3.9.19
Python 3.10.20

Now install `Poetry <https://github.com/sdispater/poetry>`_ with ``pip install poetry``

Expand Down
Loading
Loading