Skip to content

Commit c5fbd2c

Browse files
clementb49claude
andauthored
ci: build for windows arm64 (#1084)
* ci: add Windows ARM64 build to GitHub Actions matrix Add arm64 architecture to the build matrix using the windows-11-arm hosted runner, and fix Inno Setup installer to use arm64 install mode instead of x64compatible for ARM64 builds. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * fix(ci): fix ARM64 Windows build for cryptography dependency Add OPENSSL_VENDORED=1 for ARM64 builds since cryptography 46.x has no win_arm64 wheel on PyPI and must be compiled from source. Also declare uv environments to include win_arm64 in lock file resolution, removing macOS/Linux-only packages from the lock. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * fix(ci): install ARM64 OpenSSL via vcpkg to build cryptography Replace ineffective OPENSSL_VENDORED approach (blocked by cargo --locked in maturin) with a vcpkg-based OpenSSL installation. The compiled output is cached under a stable key to avoid recompiling on every run. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * feat: restrict accessible_output3 to x86/x86_64 Windows Add platform marker to exclude accessible-output3 on ARM64 Windows. Guard the import with try/except so the app runs gracefully when the package is absent; use_accessible_output now returns False when accessible_output3 is not installed. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * fix(ci): fix invalid arm64compatible in Inno Setup script Inno Setup does not support the arm64compatible identifier. Use a preprocessor conditional to set ArchitecturesAllowed=arm64 for ARM64 and {arch}compatible for x86/x64 builds. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * ci: use actions/checkout to fetch vcpkg instead of git clone Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * fix(updater): detect ARM64 architecture for update download platform.architecture() returns '64bit' on ARM64, causing the updater to download the x64 installer. Check platform.machine() first to correctly identify ARM64 Windows. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * fix: remove uv environment restriction * fix: correct vcpkg build path * feat: use vcpkg action * fix: add missing github token * fix: change vcpkg subdir * fix: move repository checkout * fix: use a a subdir for repo checkout * fix: correct path for installer * fix: correct path for windows installer spec * fix: change GITHUB_WORKSPACE env var * fix: sppecify innosetup script as relative path * fix: use the correct sub path to upload setup * fix: remove archive for pot file * feat: disable workflow when only .pre-commit config file is updated * fix: prevent crash in handle when accessible_output3 is unavailable Introduce _NullAccessibleOutput with no-op speak/braille methods and assign it instead of None when _AO3_AVAILABLE is False, so handle(..., force=True) can never crash with AttributeError on unsupported platforms. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
1 parent 2e7de49 commit c5fbd2c

8 files changed

Lines changed: 150 additions & 2479 deletions

File tree

.github/workflows/build_app.yml

Lines changed: 41 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -6,68 +6,96 @@ permissions:
66

77
jobs:
88
build_windows:
9-
runs-on: windows-2025
9+
runs-on: ${{ matrix.runner }}
10+
env:
11+
UV_NO_DEV: true
1012
strategy:
1113
fail-fast: false
1214
matrix:
13-
arch:
14-
- x86_64
15-
- x86
15+
include:
16+
- arch: x86_64
17+
runner: windows-2025
18+
- arch: x86
19+
runner: windows-2025
20+
- arch: arm64
21+
runner: windows-11-arm
1622

1723
steps:
18-
- name: checkout repository
19-
uses: actions/checkout@v6
20-
with:
21-
fetch-depth: 0
2224
- name: setup uv
2325
uses: astral-sh/setup-uv@v7
2426
with:
2527
python-version: 'cpython-3.14-windows-${{ matrix.arch }}-none'
28+
- name: install OpenSSL via vcpkg (arm64)
29+
if: matrix.arch == 'arm64'
30+
id: vcpkg
31+
uses: johnwason/vcpkg-action@v7
32+
with:
33+
pkgs: openssl
34+
triplet: arm64-windows
35+
token: ${{ github.token }}
36+
- name: set OpenSSL env (arm64)
37+
if: matrix.arch == 'arm64'
38+
run: |
39+
$installed = "${{ github.workspace }}\vcpkg\installed\arm64-windows"
40+
echo "OPENSSL_DIR=$installed" >> $env:GITHUB_ENV
41+
- name: checkout repository
42+
uses: actions/checkout@v6
43+
with:
44+
fetch-depth: 0
45+
path: ${{ github.workspace }}/repo
2646
- name: Install dependencies
27-
run: uv sync --frozen --no-dev --group build --group test
47+
working-directory: ${{ github.workspace }}/repo
48+
run: uv sync --frozen --compile --group build --group test
2849
- name: run tests
50+
working-directory: ${{ github.workspace }}/repo
2951
run: uv run -m pytest --cov
3052
- name: compile translations
53+
working-directory: ${{ github.workspace }}/repo
3154
run: uv run setup.py compile_catalog
3255
- name: Build executable
56+
working-directory: ${{ github.workspace }}/repo
3357
run: uv run -m cx_Freeze build_exe
3458
- name: get variables
3559
id: get_variables
60+
working-directory: ${{ github.workspace }}/repo
3661
run: |
3762
$version = (uv run -m setuptools_scm)
3863
echo version_number=$version >> $env:GITHUB_OUTPUT
3964
if ("${{ matrix.arch }}" -eq "x86_64") {
4065
echo arch="x64" >> $env:GITHUB_OUTPUT
66+
} elseif ("${{ matrix.arch }}" -eq "arm64") {
67+
echo arch="arm64" >> $env:GITHUB_OUTPUT
4168
} else {
4269
echo arch="x86" >> $env:GITHUB_OUTPUT
4370
}
4471
- name: build windows installer
4572
uses: Minionguyjpro/Inno-Setup-Action@v1.2.7
4673
with:
47-
path: .\win_installer.iss
74+
path: repo\win_installer.iss
4875
options: |
4976
/O+
5077
/DAppArch=${{ steps.get_variables.outputs.arch }}
5178
/DMyAppVersion=${{ steps.get_variables.outputs.version_number }}
79+
5280
- name: create user config file for portable version
81+
working-directory: ${{ github.workspace }}/repo
5382
run: |
5483
New-Item -Path dist -Name user_data -ItemType directory
5584
New-Item -Path dist\user_data -Name config.yml -ItemType file
5685
echo "general:" >> dist\user_data\config.yml
5786
echo " language: auto" >> dist\user_data\config.yml
5887
echo " log_level: info" >> dist\user_data\config.yml
59-
6088
- name: create and upload portable zip
6189
uses: actions/upload-artifact@v7
6290
with:
6391
name: portable_basiliskLLM_${{ steps.get_variables.outputs.version_number }}_${{ runner.os }}_${{ steps.get_variables.outputs.arch }}
64-
path: dist/*
92+
path: ${{ github.workspace }}/repo/dist/*
6593
if-no-files-found: error
6694
retention-days: 30
6795
- name: upload installer
6896
uses: actions/upload-artifact@v7
6997
with:
7098
name: setup_basiliskLLM_${{ steps.get_variables.outputs.version_number }}_${{ runner.os }}_${{ steps.get_variables.outputs.arch }}
71-
path: output_setup/*
99+
path: ${{ github.workspace }}/repo/output_setup/*
72100
if-no-files-found: error
73101
retention-days: 30

.github/workflows/ci.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,13 @@ on:
66
- CI*
77
tags:
88
- v*
9+
paths-ignore:
10+
- ".pre-commit-config.yaml"
911
pull_request:
1012
branches:
1113
- master
14+
paths-ignore:
15+
- ".pre-commit-config.yaml"
1216

1317
permissions:
1418
contents: write

.github/workflows/localization.yml

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ on:
1717
jobs:
1818
generate_pot:
1919
runs-on: windows-latest
20+
env:
21+
UV_NO_DEV: true
2022
permissions:
2123
contents: read
2224
steps:
@@ -25,7 +27,7 @@ jobs:
2527
- name: setup uv
2628
uses: astral-sh/setup-uv@v7
2729
- name: Install dependencies
28-
run: uv sync --frozen --no-dev --group build
30+
run: uv sync --frozen --group build
2931
- name: build POT file
3032
run: uv run setup.py extract_messages
3133
- name: upload POT file
@@ -35,6 +37,7 @@ jobs:
3537
path: basiliskLLM.pot
3638
if-no-files-found: error
3739
retention-days: 30
40+
archive: false
3841

3942
upload_on_crowdin:
4043
runs-on: ubuntu-latest

basilisk/accessible_output.py

Lines changed: 33 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,21 @@
11
"""Functions for interacting with the Accessible Output library."""
22

3+
from __future__ import annotations
4+
35
import logging
46
import re
57
from functools import cached_property
8+
from typing import TYPE_CHECKING
9+
10+
try:
11+
import accessible_output3.outputs.auto
12+
13+
_AO3_AVAILABLE = True
14+
except ImportError:
15+
_AO3_AVAILABLE = False
616

7-
import accessible_output3.outputs.auto
17+
if TYPE_CHECKING:
18+
import accessible_output3.outputs.auto
819

920
import basilisk.config as config
1021
from basilisk.completion_handler import COMMON_PATTERN
@@ -14,6 +25,16 @@
1425
RE_SPEECH_STREAM_BUFFER = re.compile(rf"{COMMON_PATTERN}")
1526

1627

28+
class _NullAccessibleOutput:
29+
"""No-op fallback used when accessible_output3 is unavailable."""
30+
31+
def speak(self, text: str) -> None:
32+
pass
33+
34+
def braille(self, text: str) -> None:
35+
pass
36+
37+
1738
class AccessibleOutputHandler:
1839
"""Handles accessible output and streaming for screen readers.
1940
@@ -55,12 +76,21 @@ def clean_steps(self) -> list[tuple[re.Pattern | str]]:
5576

5677
@property
5778
def use_accessible_output(self) -> bool:
58-
"""Check if accessible output is enabled in the configuration."""
59-
return config.conf().conversation.use_accessible_output
79+
"""Check if accessible output is enabled and available."""
80+
return (
81+
_AO3_AVAILABLE and config.conf().conversation.use_accessible_output
82+
)
6083

6184
@measure_time
6285
def _init_accessible_output(self, display_log: bool) -> None:
6386
"""Initialize the Accessible Output library."""
87+
if not _AO3_AVAILABLE:
88+
if display_log:
89+
log.debug(
90+
"accessible_output3 is not available on this platform."
91+
)
92+
self._accessible_output = _NullAccessibleOutput()
93+
return
6494
if not self.use_accessible_output:
6595
if display_log:
6696
log.warning(

basilisk/updater.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -145,8 +145,11 @@ def get_app_architecture(self) -> str:
145145
"""Get the architecture of the application.
146146
147147
Returns:
148-
The architecture of the application as a string (e.g., 'x64' or 'x86').
148+
The architecture of the application as a string (e.g., 'x64', 'x86' or 'arm64').
149149
"""
150+
machine = platform.machine()
151+
if machine == "ARM64":
152+
return "arm64"
150153
arch = platform.architecture()[0]
151154
if arch == "64bit":
152155
return "x64"

pyproject.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ readme = "README.md"
1010
license = "GPL-2.0-only"
1111
requires-python = ">=3.14,<3.15"
1212
dependencies = [
13-
"accessible-output3 @ git+https://github.com/SigmaNight/accessible_output3.git",
13+
"accessible-output3 @ git+https://github.com/SigmaNight/accessible_output3.git ; sys_platform == 'win32' and platform_machine != 'ARM64'",
1414
"alembic>=1.18,<1.19",
1515
"anthropic>=0.94.0,<0.95",
1616
"babel>=2.17,<2.19",
@@ -79,6 +79,7 @@ fallback_version = "0.0.0"
7979
[tool.uv]
8080
package = false
8181

82+
8283
[tool.coverage.run]
8384
branch = true
8485
source = ["basilisk"]

0 commit comments

Comments
 (0)