@@ -149,33 +149,33 @@ jobs:
149149 include :
150150 - arch : x86_64
151151 runner : macos-15-intel
152+ platform : x86_64-apple-darwin
152153 - arch : arm64
153154 runner : macos-15
155+ platform : aarch64-apple-darwin
154156 env :
155- HOMEBREW_NO_AUTO_UPDATE : 1
156- # the runners come with Homebrew's Python, which is built for the runner's own macOS version and would
157- # make the app require it too; uv's own builds target much older macOS versions
157+ # Oldest macOS the app has to run on. The runners are newer, and by default everything gets picked
158+ # or built for the runner's own version: uv chooses wheels for it, Homebrew's libraries are built for
159+ # it, and so is anything compiled here. The build fails if any bundled binary needs a newer one.
160+ MACOSX_DEPLOYMENT_TARGET : ' 12.0'
161+ # the runners come with Homebrew's Python, which is built for the runner's macOS; uv's own builds
162+ # target much older versions
158163 UV_PYTHON_PREFERENCE : only-managed
159164 steps :
160165 - uses : actions/checkout@v7
161166 with :
162167 fetch-depth : 0
163168 filter : blob:none
164169
165- - name : Install OpenSSL
166- # cryptography stopped publishing Intel macOS wheels, so here it gets compiled against Homebrew's OpenSSL
167- if : matrix.arch == 'x86_64'
168- run : |
169- brew install openssl@3
170- echo "OPENSSL_DIR=$(brew --prefix openssl@3)" >> "$GITHUB_ENV"
171-
172170 - uses : astral-sh/setup-uv@v10.2.0
173171 with :
174172 enable-cache : true
175173 cache-dependency-glob : uv.lock
176174
177175 - name : Install dependencies
178- run : uv sync --frozen --no-default-groups --group packaging --group wx-binary
176+ # naming the platform makes uv choose wheels for MACOSX_DEPLOYMENT_TARGET instead of the runner's
177+ # macOS (numpy, for one, has separate wheels for macOS 14 and newer)
178+ run : uv sync --frozen --no-default-groups --group packaging --group wx-binary --python-platform ${{ matrix.platform }}
179179
180180 - name : Prepare pyfa data
181181 run : |
@@ -193,10 +193,9 @@ jobs:
193193 echo "::error::expected a ${{ matrix.arch }} build, got: $built"
194194 exit 1
195195 fi
196- (cd dist && zip -yr "pyfa-$PYFA_VERSION-mac-${{ matrix.arch }}.zip" pyfa.app)
197196
198- - name : Report the oldest macOS the app runs on
199- # informational: the bundled binaries needing the newest macOS decide it for the whole app
197+ - name : Check the oldest macOS the app runs on
198+ # the bundled binaries needing the newest macOS decide it for the whole app
200199 run : |
201200 find dist/pyfa.app -type f \( -name '*.dylib' -o -name '*.so' -o -perm -u+x \) -print0 |
202201 while IFS= read -r -d '' file; do
@@ -206,12 +205,26 @@ jobs:
206205 /LC_VERSION_MIN_MACOSX/ { legacy = 1 }
207206 legacy && $1 == "version" { print $2; exit }')
208207 if [ -n "$minos" ]; then echo "$minos ${file#dist/}"; fi
209- done | sort -t. -k1,1n -k2,2n > minos.txt
208+ done | sort -t. -k1,1n -k2,2n -k3,3n > minos.txt
210209 newest=$(tail -n 1 minos.txt | cut -d' ' -f1)
211- echo "The app needs macOS $newest or newer, because of:"
212- grep "^$newest " minos.txt | head -n 15
213- echo "Binaries per minimum version:"
210+ echo "Binaries per minimum macOS version:"
214211 cut -d' ' -f1 minos.txt | uniq -c
212+ echo "The app needs macOS $newest or newer, because of:"
213+ awk -v version="$newest" '$1 == version' minos.txt | head -n 15
214+ too_new=$(awk -v needed="$newest" -v target="$MACOSX_DEPLOYMENT_TARGET" 'BEGIN {
215+ split(needed, n, "."); split(target, t, ".")
216+ for (i = 1; i <= 3; i++) {
217+ if (n[i] + 0 > t[i] + 0) { print "yes"; exit }
218+ if (n[i] + 0 < t[i] + 0) { exit }
219+ }
220+ }')
221+ if [ -n "$too_new" ]; then
222+ echo "::error::the app needs macOS $newest, but has to run on macOS $MACOSX_DEPLOYMENT_TARGET (binaries listed above)"
223+ exit 1
224+ fi
225+
226+ - name : Package app
227+ run : (cd dist && zip -yr "pyfa-$PYFA_VERSION-mac-${{ matrix.arch }}.zip" pyfa.app)
215228
216229 - uses : actions/upload-artifact@v7
217230 with :
0 commit comments