From 2768548032f7e200cf1bafdda7c5fa26dd291fd4 Mon Sep 17 00:00:00 2001 From: Thomas Waldmann Date: Thu, 4 Jun 2026 18:22:11 +0200 Subject: [PATCH 1/2] build: add build-borg-using-pyinstaller.sh and use it in ci.yml --- .github/workflows/ci.yml | 9 +++------ scripts/build-borg-using-pyinstaller.sh | 22 ++++++++++++++++++++++ 2 files changed, 25 insertions(+), 6 deletions(-) create mode 100755 scripts/build-borg-using-pyinstaller.sh diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 5baec1f25..f7d449984 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -299,8 +299,7 @@ jobs: if: ${{ matrix.binary && startsWith(github.ref, 'refs/tags/') }} run: | pip install -r requirements.d/pyinstaller.txt - mkdir -p dist/binary - pyinstaller --clean --distpath=dist/binary scripts/borg.exe.spec + ./scripts/build-borg-using-pyinstaller.sh - name: Smoke-test the built binary (${{ matrix.binary }}) if: ${{ matrix.binary && startsWith(github.ref, 'refs/tags/') }} @@ -471,8 +470,7 @@ jobs: if [[ "${{ matrix.do_binaries }}" == "true" && "${{ startsWith(github.ref, 'refs/tags/') }}" == "true" ]]; then python -m pip install -r requirements.d/pyinstaller.txt - mkdir -p dist/binary - pyinstaller --clean --distpath=dist/binary scripts/borg.exe.spec + ./scripts/build-borg-using-pyinstaller.sh pushd dist/binary echo "single-file binary" chmod +x borg.exe @@ -665,8 +663,7 @@ jobs: # build borg.exe . env/bin/activate pip install -e ".[cockpit,s3,sftp,rclone]" - mkdir -p dist/binary - pyinstaller -y --clean --distpath=dist/binary scripts/borg.exe.spec + ./scripts/build-borg-using-pyinstaller.sh # build sdist and wheel in dist/... python -m build diff --git a/scripts/build-borg-using-pyinstaller.sh b/scripts/build-borg-using-pyinstaller.sh new file mode 100755 index 000000000..aa7d8970f --- /dev/null +++ b/scripts/build-borg-using-pyinstaller.sh @@ -0,0 +1,22 @@ +#!/bin/bash +# Generate a single-file binary of borgbackup using PyInstaller. + +set -euo pipefail + +OUTPUT_DIR="dist/binary" +SPEC_FILE="scripts/borg.exe.spec" + +echo "Building single-file binary of borgbackup using PyInstaller..." + +# Run PyInstaller compilation +# We use -y/--noconfirm to overwrite the output directory without asking. +# We use --clean to clean PyInstaller cache and temporary files before building. +mkdir -p $OUTPUT_DIR +pyinstaller \ + -y \ + --clean \ + --distpath="$OUTPUT_DIR" \ + "$SPEC_FILE" + +echo "Single-file binary generated at:" +echo "$OUTPUT_DIR/borg.exe" From fb53f44f0fbc05e342b85c9036beb0ae43d6ea39 Mon Sep 17 00:00:00 2001 From: Thomas Waldmann Date: Thu, 4 Jun 2026 18:31:57 +0200 Subject: [PATCH 2/2] nuitka build: also use dist/binary for output --- scripts/build-borg-using-nuitka.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/scripts/build-borg-using-nuitka.sh b/scripts/build-borg-using-nuitka.sh index 4ac177e05..37588bbcb 100755 --- a/scripts/build-borg-using-nuitka.sh +++ b/scripts/build-borg-using-nuitka.sh @@ -3,7 +3,7 @@ set -euo pipefail -OUTPUT_DIR="build" +OUTPUT_DIR="dist/binary" OUTPUT_FILENAME="borg-nuitka.exe" # .exe does NOT mean windows here SRC_DIR="src/borg" @@ -13,6 +13,7 @@ echo "Building single-file binary of borgbackup..." # We use --assume-yes-for-downloads to avoid interactive prompts in automated runs. # We set PYTHONPATH=src to ensure the local version of borg is used. # We include cffi to avoid runtime ModuleNotFoundError in argon2-cffi. +mkdir -p $OUTPUT_DIR PYTHONPATH=src python -m nuitka \ --mode=onefile \ --assume-yes-for-downloads \