diff --git a/.github/workflows/build-appimage-test.yml b/.github/workflows/build-appimage.yml similarity index 88% rename from .github/workflows/build-appimage-test.yml rename to .github/workflows/build-appimage.yml index 9be3350..2d15bb5 100644 --- a/.github/workflows/build-appimage-test.yml +++ b/.github/workflows/build-appimage.yml @@ -1,13 +1,20 @@ name: Build Test AppImage + + on: workflow_dispatch: inputs: - tags: + commitHash: + description: 'Enter the commit hash to build (leave empty to use the default branch or the branch that triggered the workflow)' + required: false + type: string + buildDMG: description: 'Test Build AppImage' required: false type: boolean + jobs: build: runs-on: ubuntu-latest @@ -16,6 +23,7 @@ jobs: uses: actions/checkout@v3 with: fetch-depth: 0 # Fetch all history for all branches and tags + ref: ${{ github.event.inputs.commitHash || github.sha }} - name: Set up Python environment @@ -67,6 +75,12 @@ jobs: fi + - name: Upload AppImage Files from dist/ + uses: actions/upload-artifact@v4 + with: + name: appimages + path: dist/*.appimage + # - name: Install Dependencies for gui test # run: | # sudo apt-get update diff --git a/.github/workflows/build-mac-test.yml b/.github/workflows/build-mac-arm.yml similarity index 66% rename from .github/workflows/build-mac-test.yml rename to .github/workflows/build-mac-arm.yml index 2a2d04c..9bbeb67 100644 --- a/.github/workflows/build-mac-test.yml +++ b/.github/workflows/build-mac-arm.yml @@ -1,13 +1,21 @@ name: Build Test DMG - on: workflow_dispatch: inputs: - tags: - description: 'Test Build DMG' + commitHash: + description: 'Enter the commit hash to build (leave empty to use the default branch or the branch that triggered the workflow)' + required: false + type: string + buildDMG: + description: 'Test Build DMG (Arm64)' required: false type: boolean + # push: + # branches: [ "main" ] + # pull_request: + # branches: [ "main" ] + jobs: build: runs-on: macos-14 # see available: https://github.com/actions/runner-images?tab=readme-ov-file#available-images @@ -16,7 +24,7 @@ jobs: uses: actions/checkout@v3 with: fetch-depth: 0 # Fetch all history for all branches and tags - + ref: ${{ github.event.inputs.commitHash || github.sha }} - name: Run build script diff --git a/.github/workflows/build-windows-test.yml b/.github/workflows/build-windows.yml similarity index 83% rename from .github/workflows/build-windows-test.yml rename to .github/workflows/build-windows.yml index 9171bd5..85d646c 100644 --- a/.github/workflows/build-windows-test.yml +++ b/.github/workflows/build-windows.yml @@ -3,8 +3,12 @@ name: Build Test Windows on: workflow_dispatch: inputs: - tags: - description: 'Test Build AppImage' + commitHash: + description: 'Enter the commit hash to build (leave empty to use the default branch or the branch that triggered the workflow)' + required: false + type: string + buildDMG: + description: 'Test Build Exe' required: false type: boolean @@ -16,6 +20,7 @@ jobs: uses: actions/checkout@v3 with: fetch-depth: 0 # Fetch all history for all branches and tags + ref: ${{ github.event.inputs.commitHash || github.sha }} - name: Set up Python environment @@ -72,3 +77,9 @@ jobs: echo "Setup EXE file is missing" exit 1 fi + + - name: Upload EXE Files from dist/ + uses: actions/upload-artifact@v4 + with: + name: exes + path: dist/*.exe \ No newline at end of file diff --git a/.github/workflows/python-tests.yml b/.github/workflows/python-tests.yml index 9e634c9..2006eca 100644 --- a/.github/workflows/python-tests.yml +++ b/.github/workflows/python-tests.yml @@ -79,3 +79,12 @@ jobs: - name: Run Tests for marker_qt_2 run: | poetry run pytest -m 'marker_qt_2' -vvv --log-cli-level=DEBUG --setup-show --maxfail=1 + + + + + - name: Upload output Files from tests/output + uses: actions/upload-artifact@v4 + with: + name: test-output + path: tests/output \ No newline at end of file diff --git a/.vscode/launch.json b/.vscode/launch.json index c6c3394..c62b083 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -138,6 +138,16 @@ ], "console": "integratedTerminal", "preLaunchTask": "Poetry Install" // label of the task +},{ + "name": "Build mac", + "type": "python", + "request": "launch", + "program": "tools/build.py", + "args": [ + "--targets", "mac", +], + "console": "integratedTerminal", + "preLaunchTask": "Poetry Install" // label of the task },{ "name": "Build Linux (Current Files)", "type": "python", @@ -149,6 +159,17 @@ ], "console": "integratedTerminal", "preLaunchTask": "Poetry Install" // label of the task +},{ + "name": "Build Mac (Current Files)", + "type": "python", + "request": "launch", + "program": "tools/build.py", + "args": [ + "--targets", "mac", + "--commit", "None", +], + "console": "integratedTerminal", + "preLaunchTask": "Poetry Install" // label of the task },{ "name": "Build Windows (Current Files)", "type": "python", diff --git a/tests/gui/qt/test_setup_wallet.py b/tests/gui/qt/test_setup_wallet.py index 48eb3a4..6fb5199 100644 --- a/tests/gui/qt/test_setup_wallet.py +++ b/tests/gui/qt/test_setup_wallet.py @@ -101,7 +101,7 @@ def enter_text(text: str, widget: QWidget) -> None: QTest.keyClick(widget, char) -@pytest.mark.marker_qt_1 +@pytest.mark.marker_qt_1 # repeated gui tests let the RAM usage increase (unclear why the memory isnt freed), and to stay under the github VM limit, we split the tests def test_wizard( qapp: QApplication, qtbot: QtBot, diff --git a/tools/build-mac/make_osx.sh b/tools/build-mac/make_osx.sh index b8fe394..05c92ae 100755 --- a/tools/build-mac/make_osx.sh +++ b/tools/build-mac/make_osx.sh @@ -95,7 +95,7 @@ $python3 -m pip install --no-build-isolation --no-dependencies --no-binary :all: || fail "Could not install build dependencies (mac)" info "Installing some build-time deps for compilation..." -brew install autoconf automake libtool gettext coreutils pkgconfig libiconv +brew install autoconf automake libtool gettext coreutils pkgconfig info "Building PyInstaller." PYINSTALLER_REPO="https://github.com/pyinstaller/pyinstaller.git" @@ -195,7 +195,7 @@ $python3 -m pip uninstall -y pip info "Faking timestamps..." -find . -exec touch -t '200101220000' {} + || true +find . -exec sudo touch -t '200101220000' {} + || true VERSION=$(git describe --tags --dirty --always) diff --git a/tools/build-mac/osx.spec b/tools/build-mac/osx.spec index f448c9f..579ca92 100644 --- a/tools/build-mac/osx.spec +++ b/tools/build-mac/osx.spec @@ -1,5 +1,6 @@ # -*- mode: python -*- +import platform from PyInstaller.utils.hooks import collect_data_files, collect_submodules, collect_dynamic_libs from PyInstaller.building.api import COLLECT, EXE, PYZ from PyInstaller.building.build_main import Analysis @@ -7,6 +8,21 @@ from PyInstaller.building.osx import BUNDLE import sys, os + + +# Function to determine target architecture based on Python's running architecture +def get_target_arch(): + arch = platform.machine() + if arch == 'x86_64': + return 'x86_64' + elif arch in ('arm', 'arm64', 'aarch64'): + return 'arm64' + else: + return 'universal2' # Defaulting to universal for other cases (as a fallback) +target_arch = get_target_arch() +print(f"Building for {target_arch=}") + + PACKAGE_NAME='Bitcoin_Safe.app' PYPKG='bitcoin_safe' PROJECT_ROOT = os.path.abspath(".") @@ -112,7 +128,7 @@ exe = EXE( upx=True, icon=ICONS_FILE, console=False, - target_arch='x86_64', # TODO investigate building 'universal2' + target_arch=target_arch, # TODO investigate building 'universal2' ) app = BUNDLE( diff --git a/tools/build.py b/tools/build.py index 5679198..0d52ccf 100644 --- a/tools/build.py +++ b/tools/build.py @@ -243,9 +243,60 @@ def build_in_docker( def build_dmg( self, + build_commit: None | str | Literal["current_commit"] = "current_commit", ): - PROJECT_ROOT = Path(".").resolve().absolute() - run_local(PROJECT_ROOT / "tools" / "build-mac" / "make_osx.sh") + PROJECT_ROOT_OR_FRESHCLONE_ROOT = PROJECT_ROOT = Path(".").resolve().absolute() + DISTDIR = PROJECT_ROOT / "dist" + + if build_commit == "current_commit": + # Get the current git HEAD commit + result = subprocess.run( + ["git", "rev-parse", "HEAD"], stdout=subprocess.PIPE, check=True, text=True + ) + build_commit = result.stdout.strip() + + if not build_commit: + # Local development build + logger.info(f"Building within current project") + + # Possibly do a fresh clone + FRESH_CLONE = False + if build_commit: + logger.info(f"BITCOINSAFE_BUILD_COMMIT={build_commit}. Doing fresh clone and git checkout.") + FRESH_CLONE = Path(f"/tmp/{build_commit.replace(' ','')}/fresh_clone/bitcoin_safe") + try: + run_local(f'rm -rf "{FRESH_CLONE}"') + except subprocess.CalledProcessError: + logger.info("We need sudo to remove previous FRESH_CLONE.") + run_local(f'sudo rm -rf "{FRESH_CLONE}"') + os.umask(0o022) + run_local(f'git clone "{PROJECT_ROOT}" "{FRESH_CLONE}"') + os.chdir(str(FRESH_CLONE)) + run_local(f'git checkout "{build_commit}"') + PROJECT_ROOT_OR_FRESHCLONE_ROOT = FRESH_CLONE + else: + logger.info("Not doing fresh clone.") + + Source_Dist_dir = PROJECT_ROOT_OR_FRESHCLONE_ROOT / "dist" + + os.chdir(str(PROJECT_ROOT_OR_FRESHCLONE_ROOT)) + run_local(f'bash {PROJECT_ROOT_OR_FRESHCLONE_ROOT / "tools" / "build-mac" / "make_osx.sh"}') + + os.chdir(str(PROJECT_ROOT)) + + # Ensure the resulting binary location is independent of fresh_clone + if Source_Dist_dir != DISTDIR: + os.makedirs(DISTDIR, exist_ok=True) + for file in Source_Dist_dir.iterdir(): + # only move the .app directory (no need for the unsigned dmg) + if file.is_dir() and file.name.endswith(".app"): + logger.info(f"Moving {file} --> {DISTDIR / file.name}") + # Replace module name with formatted app name in the directory name + new_dir_name = file.name.replace( + self.module_name, self.app_name_formatter(self.module_name) + ) + # Perform the move + shutil.move(str(file), str(DISTDIR / new_dir_name)) def briefcase_appimage(self, **kwargs): # briefcase appimage building works on some systems, but not on others... unknown why. diff --git a/tools/make_libusb.sh b/tools/make_libusb.sh index 092e0e2..fc6ee9c 100755 --- a/tools/make_libusb.sh +++ b/tools/make_libusb.sh @@ -44,6 +44,7 @@ info "Building $pkgname..." LDFLAGS="" fi LDFLAGS="$LDFLAGS" ./configure \ + --prefix="$HOME/local" \ $AUTOCONF_FLAGS \ || fail "Could not configure $pkgname. Please make sure you have a C compiler installed and try again." fi diff --git a/tools/make_zbar.sh b/tools/make_zbar.sh index eb77b9e..4fb5204 100755 --- a/tools/make_zbar.sh +++ b/tools/make_zbar.sh @@ -41,6 +41,7 @@ info "Building $pkgname..." if [ "$BUILD_TYPE" = "wine" ] ; then echo "libzbar_la_LDFLAGS += -Wc,-static" >> zbar/Makefile.am echo "LDFLAGS += -Wc,-static" >> Makefile.am + LDFLAGS="-L/usr/local/lib -liconv" # Example for adding libiconv fi if ! [ -x configure ] ; then autoreconf -vfi || fail "Could not run autoreconf for $pkgname. Please make sure you have automake and libtool installed, and try again." @@ -56,17 +57,20 @@ info "Building $pkgname..." --disable-dependency-tracking" elif [ $(uname) == "Darwin" ]; then # macos target + LDFLAGS="-L/opt/local/lib -liconv" # Adjust for macOS specific libiconv path if needed AUTOCONF_FLAGS="$AUTOCONF_FLAGS \ --with-x=no \ --enable-video=no \ --with-jpeg=no" else # linux target + LDFLAGS="-L/usr/lib/x86_64-linux-gnu -liconv" # Adjust based on your distro AUTOCONF_FLAGS="$AUTOCONF_FLAGS \ --with-x=yes \ --enable-video=yes \ --with-jpeg=yes" fi + export LDFLAGS ./configure \ $AUTOCONF_FLAGS \ --prefix="$here/$pkgname/dist" \