From bfa0858c470a29c1a64d2a98b680f10f5917c540 Mon Sep 17 00:00:00 2001 From: Jaison Reis Date: Tue, 21 Apr 2026 22:53:47 -0300 Subject: [PATCH 01/10] fix: retract v0.1.1 and v0.1.2 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Both bundles were compiled without an explicit Swift target, so the helper Mach-O is pinned to macOS 15.0 minimum and refuses to launch on macOS 13 or 14 — directly contradicting the README's macOS 13+ promise. v0.1.3 was the first tag built with `-target arm64-apple-macos13.0` in scripts/build-wifi-scanner-app.sh. Extending the retract block steers `go get` and Dependabot away from both broken versions in addition to v0.1.0 (which was already retracted). --- go.mod | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/go.mod b/go.mod index 305dd1a..540378a 100644 --- a/go.mod +++ b/go.mod @@ -2,7 +2,14 @@ module github.com/jaisonerick/macwifi go 1.26.1 -// v0.1.0 was tagged from an off-branch local snapshot that never landed on -// main and is missing the CI, tests, and Swift-target pin that shipped in -// v0.1.1 onward. Use v0.1.1 or later. -retract v0.1.0 +// v0.1.0 was tagged from an off-branch local snapshot that never landed +// on main. v0.1.1 and v0.1.2 shipped a helper compiled without an +// explicit Swift target; the resulting bundle's Mach-O LC_BUILD_VERSION +// pins macOS 15.0 minimum, so the helper refuses to launch on macOS 13 +// and 14 even though the README and Info.plist advertise macOS 13+. Use +// v0.1.3 or later. +retract ( + v0.1.2 + v0.1.1 + v0.1.0 +) From 4df05a07aeb3b3e1afb116385f8b2548e95c5b4d Mon Sep 17 00:00:00 2001 From: Jaison Reis Date: Tue, 21 Apr 2026 22:53:54 -0300 Subject: [PATCH 02/10] ci: matrix-test against macOS 13, 14, and latest The Go module advertises macOS 13+ as the support floor, but CI was only exercising `macos-latest`, so 13/14 compatibility was unverified and could regress silently between releases. Run the helper job across `macos-13`, `macos-14`, and `macos-latest` and add a `macos-helper` aggregator that keeps the existing required status check name ("macOS helper") intact, so branch protection doesn't need re-pinning every time the matrix changes. --- .github/workflows/ci.yml | 30 ++++++++++++++++++++++++++++-- 1 file changed, 28 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 93bd2cb..bdc2639 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -11,8 +11,16 @@ permissions: jobs: macos: - name: macOS helper - runs-on: macos-latest + name: macOS helper (${{ matrix.os }}) + runs-on: ${{ matrix.os }} + + strategy: + fail-fast: false + matrix: + # Cover the documented support floor (macOS 13) plus the two + # currently-supported newer majors so regressions on any of the + # three OS versions block merge. + os: [macos-13, macos-14, macos-latest] steps: - name: Check out repository @@ -48,3 +56,21 @@ jobs: - name: Build ad-hoc signed helper run: make scanner-ci + + # Aggregator job pinned in branch protection. Its name stays stable + # ("macOS helper") even as the matrix expands, so adding new OS rows + # doesn't require editing the required-status-checks contract. + macos-helper: + name: macOS helper + runs-on: ubuntu-latest + needs: macos + if: always() + steps: + - name: Require macOS matrix to pass + env: + MATRIX_RESULT: ${{ needs.macos.result }} + run: | + if [ "$MATRIX_RESULT" != "success" ]; then + echo "macOS matrix concluded with: $MATRIX_RESULT" >&2 + exit 1 + fi From fded06e45379e629d461b19c3b8e46c901baea86 Mon Sep 17 00:00:00 2001 From: Jaison Reis Date: Tue, 21 Apr 2026 22:54:01 -0300 Subject: [PATCH 03/10] test: add Client lifecycle smoke test Wire-protocol decoding is well-covered in protocol_test.go, but the exec/socket path in macwifi.go (extract embedded bundle, launch via `open -W`, accept loopback callback, send close_request, wait for process exit) had no test coverage. A regression there would only surface in downstream consumers. The new test runs `New` then `Close` (twice, to cover Close idempotency) without ever calling Scan or Password, so it never trips Location Services or Keychain prompts on interactive machines. Skipped under -short for the same reason `make ci-go` skips the full helper bring-up. --- client_smoke_test.go | 42 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) create mode 100644 client_smoke_test.go diff --git a/client_smoke_test.go b/client_smoke_test.go new file mode 100644 index 0000000..d9f0c44 --- /dev/null +++ b/client_smoke_test.go @@ -0,0 +1,42 @@ +//go:build darwin + +package macwifi_test + +import ( + "context" + "testing" + "time" + + "github.com/jaisonerick/macwifi" +) + +// TestClientLifecycle exercises the Go↔helper launch path end-to-end: +// extract the embedded bundle, launch it via `open -W`, accept the +// helper's loopback callback, send a close_request, and wait for a +// clean process exit. +// +// Deliberately avoids Scan/Password so no Location Services or +// Keychain prompt can appear on interactive machines. Skipped in +// -short mode because it spawns a real GUI app and round-trips through +// macOS launch services. +func TestClientLifecycle(t *testing.T) { + if testing.Short() { + t.Skip("launches the signed helper app; skipped under -short") + } + + ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second) + defer cancel() + + c, err := macwifi.New(ctx) + if err != nil { + t.Fatalf("New: %v", err) + } + if err := c.Close(); err != nil { + t.Fatalf("Close: %v", err) + } + + // Close is documented as idempotent; a second call must not error. + if err := c.Close(); err != nil { + t.Fatalf("second Close: %v", err) + } +} From 0f732460efc2e8e2de3dabe5fe491ec6a14d8603 Mon Sep 17 00:00:00 2001 From: Jaison Reis Date: Tue, 21 Apr 2026 22:54:09 -0300 Subject: [PATCH 04/10] build: bump helper bundle version to 1.0.0 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Align CFBundleVersion and CFBundleShortVersionString with the upcoming module version. The bundle version surfaces in System Settings → Location Services and was a stale placeholder ("1" / "1.0") that didn't track the module. The signed companion will rebuild and re-sign the embedded helper for this PR because Info.plist is one of its trigger paths. --- scanner/Info.plist | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scanner/Info.plist b/scanner/Info.plist index 95c28c3..3c01da5 100644 --- a/scanner/Info.plist +++ b/scanner/Info.plist @@ -11,9 +11,9 @@ CFBundleExecutable wifi-scanner CFBundleVersion - 1 + 1.0.0 CFBundleShortVersionString - 1.0 + 1.0.0 CFBundlePackageType APPL CFBundleInfoDictionaryVersion From c53846ae06ec9a1527381682a9700f8e78c49a53 Mon Sep 17 00:00:00 2001 From: Jaison Reis Date: Tue, 21 Apr 2026 22:54:21 -0300 Subject: [PATCH 05/10] docs: declare v1 API stability and refresh release docs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adds a "Versioning" section to the README committing the exported `macwifi` Go API to backward compatibility under semver across the v1.x line, with the helper wire protocol explicitly excluded. Replaces the manual "Releasing the Helper" section, which described a local Developer-ID + notarytool workflow that consumers will never need. The reality is now end-to-end automated: conventional commits → Release Please PR → signed companion rebuild → merge → tag + GitHub Release + signed bundle zip attached. The local helper rebuild snippet is preserved as a "development only" note for Swift iteration via `MACWIFI_APP`. Release-As: 1.0.0 --- README.md | 69 +++++++++++++++++++++++++++++++++---------------------- 1 file changed, 42 insertions(+), 27 deletions(-) diff --git a/README.md b/README.md index 92c615f..09f1944 100644 --- a/README.md +++ b/README.md @@ -93,6 +93,19 @@ Permissions requested: - Location Services for WiFi discovery. - macOS Keychain for password retrieval. +### Versioning + +`macwifi` follows [Semantic Versioning](https://semver.org/). The exported +Go API of the `macwifi` package — types, functions, and option helpers — +is stable across the v1.x line: no breaking changes will land without a +major-version bump. The wire protocol between the Go client and the +embedded helper is an internal implementation detail and is not covered +by this commitment. + +Versions before v1.0.0 are retracted in `go.mod` when they cannot meet +the macOS support floor; `go get` and tooling like Dependabot will steer +you to the latest non-retracted release. + ### Reuse One Helper Session When scanning for networks and then fetching a password in one run, create a @@ -163,39 +176,41 @@ MACWIFI_APP=$PWD/WifiScanner.app go run ./examples/scan `MACWIFI_APP` tells the Go package to use a local helper bundle instead of the embedded one. -## Releasing the Helper - -The embedded helper is part of the Go module via `go:embed`. To cut a release -with an updated helper: - -```sh -make release -# commit, tag, and push -``` - -`make release` builds, signs with Developer ID, notarizes, staples, and copies -the bundle into `embedded/WifiScanner.app`. - -Release prerequisites: +## Releases + +Releases are fully automated. Day-to-day: + +1. Land changes on `main` using [Conventional Commits](https://www.conventionalcommits.org/). +2. [Release Please](https://github.com/googleapis/release-please) keeps a + rolling Release PR open with the next `CHANGELOG.md` entry, the + `go.mod`-aware version bump, and the `embeddedVersion` constant in + `embed.go`. +3. Merging the Release PR tags the version, publishes a GitHub Release, + primes `proxy.golang.org`, and attaches the signed `WifiScanner.app` + zip to the release. + +The signed companion workflow handles the helper bundle. Pull requests +that touch `scanner/Sources/`, `scanner/Info.plist`, +`scanner/entitlements.plist`, or the helper build scripts trigger a +macOS runner that builds, codesigns with Developer ID, notarizes, +staples, and commits the regenerated `embedded/WifiScanner.app` back to +the PR branch before merge. The workflow expects the environment +secrets documented in +[`.github/SIGNING_SECRETS.md`](.github/SIGNING_SECRETS.md). -- A **Developer ID Application** certificate in your login keychain. -- A `xcrun notarytool` credential profile named `macwifi-notary`, or another - profile set through `$NOTARY_PROFILE`. +### Local helper rebuild (development only) -Set up the default notary profile once: +When iterating on Swift code, you don't need notarization — just an +ad-hoc signed bundle pointed at via `MACWIFI_APP`: ```sh -xcrun notarytool store-credentials macwifi-notary \ - --apple-id YOUR_APPLE_ID \ - --team-id YOUR_TEAM_ID \ - --password YOUR_APP_SPECIFIC_PASSWORD +make scanner +MACWIFI_APP=$PWD/WifiScanner.app go run ./examples/scan ``` -On GitHub, pull requests to `main` that touch the Swift companion run the -signed companion workflow. The workflow signs, notarizes, staples, and commits -the updated `embedded/WifiScanner.app` back to the pull request branch before -merge. The workflow expects the environment secrets documented in -[`.github/SIGNING_SECRETS.md`](.github/SIGNING_SECRETS.md). +A full Developer ID + notarized release build can be produced locally +with `make release`, but it is not required to ship — CI handles that +end-to-end. ## Contributing From d52b53420c19efd3fc9e6f497c26727cff29e21b Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 22 Apr 2026 01:55:55 +0000 Subject: [PATCH 06/10] chore: update signed WifiScanner.app for PR #25 [skip companion] --- .../WifiScanner.app/Contents/CodeResources | Bin 1653 -> 1653 bytes embedded/WifiScanner.app/Contents/Info.plist | 4 ++-- .../Contents/MacOS/wifi-scanner | Bin 159024 -> 159024 bytes .../Contents/Resources/macwifi-build.json | 2 +- .../Contents/_CodeSignature/CodeResources | 4 ++-- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/embedded/WifiScanner.app/Contents/CodeResources b/embedded/WifiScanner.app/Contents/CodeResources index 26f364fd39c159449625ad9fcd1382602a8bba37..74f591669bc3ec68dfac7a0a064939fce60cb433 100644 GIT binary patch delta 109 zcmV-z0FwXp4D}4K5C&zUD(Gnd00002Oy~4Hs@1H}7?r|58Nlf}USr90Fhv3(0RNcn zTlp~B#r|&f=)6{D^20PO=m;JLWIkK)@z`qJc>*9qQ9=cJbJ_*Xdrdj|z;t^3`Mo)3 PtRSjW>hh=`*ze!~;l(wX delta 109 zcmV-z0FwXp4D}4K5C&z29_VQR00002OyGUpHjWb`cbVS$Bj!S*5hWy0Fhl|%Ps>(H z1O@oy=jAxw{DGnu4@+8?qVh19RJLgJYw@140w6C-cfRV3M$$HR$Tf|msm7T&qzx#P Pjvo#0auMw@6J-DZ)!{DF diff --git a/embedded/WifiScanner.app/Contents/Info.plist b/embedded/WifiScanner.app/Contents/Info.plist index 95c28c3..3c01da5 100644 --- a/embedded/WifiScanner.app/Contents/Info.plist +++ b/embedded/WifiScanner.app/Contents/Info.plist @@ -11,9 +11,9 @@ CFBundleExecutable wifi-scanner CFBundleVersion - 1 + 1.0.0 CFBundleShortVersionString - 1.0 + 1.0.0 CFBundlePackageType APPL CFBundleInfoDictionaryVersion diff --git a/embedded/WifiScanner.app/Contents/MacOS/wifi-scanner b/embedded/WifiScanner.app/Contents/MacOS/wifi-scanner index 0ef8d4c6f448b1cf497f129ab9b4e28b10759442..492cb7043d803ec737e4d6e26ba4e940cbbf0afd 100755 GIT binary patch delta 1553 zcmah}dohzBua1d)RFN$aW$6Lt7;7sl3yTo^9z~={wnz3d3W|gi^x=Bm;|rv6X=Sfge!G+Q z&lC2cv=<4B$;H&3i@dZGHZBnU7i$2A`#+J94KS_E!25;82gUn12Qz60_PEo?vA#^J zsAP&if441Q4@R)qZQVDaYPAy-u$rZy+}shchpYwj)I?XiTMMGk<&z{qYePKWEzR~yiMlA>Aj-kYJn@dzV}pL|?uthT4+>N2G{3@c zy${UsnV!^=2|i*B0}j=cWy`g<|SR8^$nZ~ z2R{1q8FoNC! zhyXKq;;G9o%zWmd(7Q$#!{sU8KopSac#w;$!cCaxq zSkii$Y2fFmpag0ME;#QB!5T52q83MCvxd4lH|F75abAo&=N=?KQ8ZP*ep=;uLwMRM z@2lPQ^@yzvp-r{MS9QUoF@R>h(;T*^sWrzxvX+)%QGQ%aPMMyP?Yv^54`B&N3Quw^ zu`A-1Ja4kfNy8wsd$D`Rgxppn+Y9<>Bz?0^O|o<-0HAe?{2YLLQ1$k9ThILax$=-X zD@RoY6kQOFzQk8{1Ps9}nakL5gznq*>Q~PCJhbqta{bDBTBjLI7MfH~#R^9Z6|WG^ zr{FS@BA4#yZl5wUaJMN7x^zDwjKycjX^cgc;{huwi$2wFoqsSakm=f zD9!uISBMw8j60Y6^LBg;i~J-ea>^}p+*j9cI%$)=Yk9@!=pE*i8{2gJ=E_K z+WKBwP$7GOS2H4WCxC+dcVJgN09TX0XKC=?Q^CO1tJfybGhVDqE54~U=E{n*oW-&TO}>8Wn{L=E9~bnEbnJZ*rmf&<`D~BMq#VD?MlOB>L zp-4qW8eMs0Hm+CFEss1(u5<4>_ul{RpWpc&|9s#1YKIZE!-%Bw(0Txm!4wqSG~2K& zz0g~fzKVB8kG4grk&$~u#iv3_6!kFR{lTHej{LhueFK3yPu0)th0V-fDzGA%gcrqWB1Ep zdn@(Gx+tF}=VMxegBFPmxODeVl3y-}!x z?sY8&iboxt5pDi}xSY7*(_=^DN3(GJK)^V!da$T>h#NbwlYg>a^`u3FPcv@`SGDIZ zo|b{#^e#BPH*Ng(+dbNOM^swXL9|)e6^{tDDdvIFeIBo;#g@8FKs8$RQJBl8+_%&K z@Lg7IwBoxjyDFr-FV4*_>ITg$d|Hlg9GBc2)}Ej55rm^!?+hhdw--C$jW+t_d>czr zQ&*ER*IbYvV#wW*X_o2f)azW$jG!8tR-AcYbc(8e1sq*$S#sN;z?*Ww!wIyJJ%h9_ z0~lj$stIt0s$}xQ+f5~;Fv>egIDuPmw6u^GJXza)Y%Fhbf5!dZ1prQ|w|U5Q_LV?M z=@ImZ1Oq)i0=U(lo)-ZIK%oEv!u9<19NEswlf#na6IkLf0t+_B+2Q~Ie#HDzwH3(P z#x^GbIr0P$ByJfEz2qggf($|Zzn}s80|`)uIeQ#oBh>+0=JScDN{Ji1%%h4!8Du6~ON?)t)H{OiyzG_$+3OC_M) zZBbO;QhS%_sAhZR+T6UzZB2^9L1CiHr1^ zZ9a}dx8F&O4>dCJGfq968P2ZVup?IymOc<AMtLo^EX-MHk9m^&*}J%fb0-t$lSc~ zNoL5I-qb|NMz&27_f3#1 zt6^wRm1?`cgY@+@Z_Hd-#FD7qaZ4#m4~LjNfWz# z$)641c!`KMZq@RH?3hKJw!Me=_`o_+)cx3_KCzx?Yh-Dslh)6ge>&!GJ~AY;s>mXUcg>_|6inmddPw{;-c|0wt3hFd;T;ck z))VBO#A$gCS8@~wb;m32Ut1+lN{pPeiX7yfHQPPXtJqzEE6*5^|L$CSSwgAaF-$Qi zrk2>O;ZO))m8!WYrHp4x?ViKkV#=?(d1b{pOW+UHJOYPJ`xO#b@TyU3xq3@aeX>8A zw(RikF=@t{rJ=(b4S_-zjj}IMyLf)j#l`F5P}WPM2RV;1iVgvJ+AhPR8<7;)bk#n8 z`TV) Resources/macwifi-build.json - ZhY/eeOnXMNmm2MrPMmgYCdEmAg= + 3m2HbuFHiMqJk1CcU2yPCHUgIdY= files2 @@ -15,7 +15,7 @@ hash2 - UNqC9tSATdJqoAMeZu5mlwn/kDC8aW8yN2VoXFfGKxk= + YlNJU3xcq6I/9ZQQ9xnh4m/qo3bt8HUbTaUunXvrVIQ= From 846cd902633ff4591a2a61a8e244c56fd0fba101 Mon Sep 17 00:00:00 2001 From: Jaison Reis Date: Tue, 21 Apr 2026 23:01:24 -0300 Subject: [PATCH 07/10] fix: drop Swift 6.1 trailing commas for Swift 5.9/5.10 compat MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `scanner/Sources/WifiScanner.swift` and the helper tests had trailing commas in function arg lists, which is a Swift 6.1 feature (SE-0439). The macOS 13 (Swift 5.9) and macOS 14 (Swift 5.10) CI matrix runners fail typecheck because of this — the bug was hidden until the matrix expansion forced compilation on older Swift toolchains. Drop the trailing commas. The remaining code is portable across Swift 5.9 → 6.x. --- scanner/Sources/WifiScanner.swift | 2 +- scanner/Tests/WifiScannerTests.swift | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/scanner/Sources/WifiScanner.swift b/scanner/Sources/WifiScanner.swift index 21632b1..f58d911 100644 --- a/scanner/Sources/WifiScanner.swift +++ b/scanner/Sources/WifiScanner.swift @@ -357,7 +357,7 @@ func watchParentPID(_ pid: pid_t) { let source = DispatchSource.makeProcessSource( identifier: pid, eventMask: .exit, - queue: .global(qos: .utility), + queue: .global(qos: .utility) ) source.setEventHandler { exit(0) } source.resume() diff --git a/scanner/Tests/WifiScannerTests.swift b/scanner/Tests/WifiScannerTests.swift index 423e3c5..b3ea3ff 100644 --- a/scanner/Tests/WifiScannerTests.swift +++ b/scanner/Tests/WifiScannerTests.swift @@ -50,7 +50,7 @@ func testBinaryWriterUsesLittleEndianAndLengthPrefixes() throws { 0x04, 0x00, 0x77, 0x69, 0x66, 0x69, 0x02, 0xAA, 0xBB, ], - "BinaryWriter should encode values in the helper wire format", + "BinaryWriter should encode values in the helper wire format" ) } @@ -97,7 +97,7 @@ func testParseBSSIDAcceptsHexOctets() throws { try expectEqual( parseBSSID("01:23:45:ab:CD:ef"), Data([0x01, 0x23, 0x45, 0xAB, 0xCD, 0xEF]), - "parseBSSID should accept six hex octets", + "parseBSSID should accept six hex octets" ) } @@ -119,7 +119,7 @@ func testEncodePasswordResponseMatchesWireFormat() throws { 0x06, 0x00, 0x64, 0x65, 0x6E, 0x69, 0x65, 0x64, 0x06, 0x00, 0x73, 0x65, 0x63, 0x72, 0x65, 0x74, ], - "password response should match the Go protocol wire format", + "password response should match the Go protocol wire format" ) } @@ -136,7 +136,7 @@ func testEncodeScanResponseMatchesWireFormat() throws { phyMode: "ax", password: "pw", current: true, - saved: true, + saved: true ) let response = encodeScanResponse(networks: [network], error: "") @@ -161,7 +161,7 @@ func testEncodeScanResponseMatchesWireFormat() throws { 0x02, 0x00, 0x70, 0x77, 0x03, ], - "scan response should match the Go protocol wire format", + "scan response should match the Go protocol wire format" ) } From 3f3dc4e5ff191779c75581bcbebbfc071f44659e Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 22 Apr 2026 02:02:28 +0000 Subject: [PATCH 08/10] chore: update signed WifiScanner.app for PR #25 [skip companion] --- .../WifiScanner.app/Contents/CodeResources | Bin 1653 -> 1653 bytes .../Contents/MacOS/wifi-scanner | Bin 159024 -> 159024 bytes .../Contents/Resources/macwifi-build.json | 2 +- .../Contents/_CodeSignature/CodeResources | 4 ++-- 4 files changed, 3 insertions(+), 3 deletions(-) diff --git a/embedded/WifiScanner.app/Contents/CodeResources b/embedded/WifiScanner.app/Contents/CodeResources index 74f591669bc3ec68dfac7a0a064939fce60cb433..3efc0180f12297d03da65222d0fc58a712bfbd96 100644 GIT binary patch delta 109 zcmV-z0FwXp4D}4K5C&x`Ea+(f00002xBf2=ZXVS@pxbW4!_!#OJt@{8Fhv3&2#x;I z+Guz#$1B+JCg~cJ7R|!c36Dz*ph)de9PEqR0wDnVYCT=kv5f`0dz*wBV@@Ty_#RFb PJ3RI4*UhZx`q*9qQ9=cJbJ_*Xdrdj|z;t^3`Mo)3 PtRSjW>hh=`*ze!~;l(wX diff --git a/embedded/WifiScanner.app/Contents/MacOS/wifi-scanner b/embedded/WifiScanner.app/Contents/MacOS/wifi-scanner index 492cb7043d803ec737e4d6e26ba4e940cbbf0afd..ed901424508961ad9650eb467df805449e0ab41b 100755 GIT binary patch delta 963 zcmdmRi*v&*&W0AoElkhl7!$U?kYlo8R0x@HSbpxt8Je-o^W?5NEV!L_`0(Y3OSYQV6efLaVeb=q%4PIg`2X}5 zW=wK~RjHXXy_PP~Hz{*5GD$TIbxt=jGIuGr^oumeGAJ<2beyhZ!DLmhC?#Y2L+-;= z+lLA~{a1g^vwK}oRQ3Gd@xP*T8nTuxQOq_-$jdRBYV!SK|FfvXerC=V-Zi@qy?r4a z-IH}}>pa%LPamu9mzsP}-*(#3V}s8wjmr(w8E5Mk7G6uXa{ijD`}f#SmXqOg-Tk*( zWzKwQ`b+=1_U%WTCS-rHng86Z$EyCjyC2h0eb!S~jP}aKmNaB#EI3yYAM*TCtWebP z$fo7Do~uqx{%ta;@9O)l?-vW6-q_!F@>Z(V($3BGFW&CwyB(R^!nK+^xIK#Nqjcuf z?v;i<3p_=B-}@2g-n#K$Vr;C3ZL;xO3#a>WdsG^OK4=#6UVg165EEg3Xs_#*ol6S1 z!fQS+Y!bL&&?In%jT;sV0!(~{O#-`tg4^Ly!_KszNniy~XbBS|vmv(uCmX9aA2X8_ zD}zB5l1@gJ1=%c_2I8QP0pu@GweCp~wdyefnmUDi3`}5QG7WW^|{p*o` z?%qx&4o#)TH%XkYr%3Pv6N8z7i4iDG7#SEw888D=3lj(1IWN!4-a!W2m93c8@@Yfm zl;O?-rWi36ktxTo-~Q31cbLcE&(`kRjdLe$`FeQzZx1HN`r275@K(yZw#IroeI?bKb-nXGWU&GPyK{Ws3#%w~D`TdLE*G6Bgo4Q8nDb64#D zBdEQGd&$&D1Kq<%>$|3XuU9$0jK6G?$z{XSi)3H6wEy_YoTt_vdt0;koA&$Ow)TVh zuM*3btxVqZU82tV)W`g;gDqvxT3$R+H&_*$F`_c(p?~+;mzcCpUy30Oy7L* H;x{D#&^fTw delta 966 zcmdmRi*v&*&W0AoElkhl7!$X@kYlo8RM=*F*~hJ1bd}4i1)3&HV-{!Z4=82WUN(R4 z&zKz%wo*>pT@;uWvN0xaf2PL7#n0ts&?Mr<#K>q+G~L&LDPek)8B@5qp{c2{ag>2R z8>d#AN85K^Motz(B^Cvr=U;4BU0riQV(KA#$pbH~;*w96e65@xf39O))OSyIDe%uR&8mzDoUUWRWL2M0R=)r23`U`i zFC*&Lm$7o~IvS+!BEjs{`qkvJfX#VW!*7 zxAA-X;x+O%w{GwDGoPNz|Kd*W(`_x!4y7|68u)U4HKzfBjtd2v?Qq2ota9bK;1 zRQEoIxi&dFWqYI1t6(m%yFEkW&UI2`hNjyBeDC`#}f85o%vm>3xufKr7?lmRm^wJ>oq9KY&WU7jhhYrB#a(^@`l zsH8I7UBDzG#v-!**Gqx--esLX{A)Mpaj|{$y7hed^j{uKj`d}=J}s+*SM8n3X_*+m zz-v8gy;V_<+QTB1qaTznpW$4zJp0#j$*t3OJ-68XQ_YoSZvD)Z?O~f``i87p~!BcUB9;d+dC7UvgD;LQeK+xSHPC=-t+{& zkdJ(Ps(S0&h%F{g7q&i??r*+!ac(dBteg< Resources/macwifi-build.json - 3m2HbuFHiMqJk1CcU2yPCHUgIdY= + qkQqjLkwtpbFQkhZy2/mZg17G5E= files2 @@ -15,7 +15,7 @@ hash2 - YlNJU3xcq6I/9ZQQ9xnh4m/qo3bt8HUbTaUunXvrVIQ= + 0fQ/3mmE2Q94bir6m6DHI38yMOBig+/RBuDrEeMmGLA= From e0d7568694df9dea2158f0c9189800bdc6f2f4b4 Mon Sep 17 00:00:00 2001 From: Jaison Reis Date: Tue, 21 Apr 2026 23:17:42 -0300 Subject: [PATCH 09/10] ci: drop macos-13 from matrix (runner label retired Dec 2025) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit GitHub Actions retired the `macos-13` hosted runner label in December 2025 (actions/runner-images#13402, #13413). Jobs scheduled on it queue indefinitely without ever picking up a runner — confirmed on PR #25 where macos-13 sat queued for 14+ minutes while macos-14 and macos-latest finished in under a minute each. Drop macos-13 from the CI matrix so PRs are not blocked on a runner pool that no longer exists. The shipped helper is still pinned to `-target arm64-apple-macos13.0` in scripts/build-wifi-scanner-app.sh, which means the Mach-O LC_BUILD_VERSION pins macOS 13 minimum and the binary runs on macOS 13 (we just can't verify that on a runner). The macos-14 row preserves coverage of the Swift 5.10 toolchain, which was the row that caught the trailing-comma regression earlier today. --- .github/workflows/ci.yml | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index bdc2639..2ec0080 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -17,10 +17,14 @@ jobs: strategy: fail-fast: false matrix: - # Cover the documented support floor (macOS 13) plus the two - # currently-supported newer majors so regressions on any of the - # three OS versions block merge. - os: [macos-13, macos-14, macos-latest] + # GitHub retired the macos-13 runner label in December 2025, so + # we can't continuously verify the documented macOS 13 support + # floor on CI. The Swift helper is still pinned to + # `-target arm64-apple-macos13.0` in the build script, which + # makes the shipped Mach-O run on macOS 13. macos-14 covers the + # older Swift 5.10 toolchain (catches Swift 6.x-only syntax); + # macos-latest covers the current SDK + Swift toolchain. + os: [macos-14, macos-latest] steps: - name: Check out repository From 9caf0db3e81a114cef7f2986812dd9d2bbc67298 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 22 Apr 2026 02:18:39 +0000 Subject: [PATCH 10/10] chore: update signed WifiScanner.app for PR #25 [skip companion] --- .../WifiScanner.app/Contents/CodeResources | Bin 1653 -> 1653 bytes .../Contents/MacOS/wifi-scanner | Bin 159024 -> 159024 bytes 2 files changed, 0 insertions(+), 0 deletions(-) diff --git a/embedded/WifiScanner.app/Contents/CodeResources b/embedded/WifiScanner.app/Contents/CodeResources index 3efc0180f12297d03da65222d0fc58a712bfbd96..06a7dbd685afbb49c15bbed775f0809d20407eb6 100644 GIT binary patch delta 109 zcmV-z0FwXp4D}4K5C&!XFX(9i00002xBf2=ZXVS@pxbW4!_!#OJt@{8Fhl|%ZOqbg zyyXHvD%d7AeLs6*pb>3)brw&U8d691U7IMy0w8uUhneV0vqs^6%8bd7?oiuoG?xAT Pgd8xMmMs}I7vcZ_{QEC# delta 109 zcmV-z0FwXp4D}4K5C&x`Ea+(f00002xBf2=ZXVS@pxbW4!_!#OJt@{8Fhv3&2#x;I z+Guz#$1B+JCg~cJ7R|!c36Dz*ph)de9PEqR0wDnVYCT=kv5f`0dz*wBV@@Ty_#RFb PJ3RI4*UhZx`qTk%2Z1wmPdq?`;|y_zEG8bPhmzIbA8e>vY_D0J!-kde zridaPR#bbn3Bi#qOqk|}Si3yBN9I{-46DX1J?+O&6Po0{PdaYQMKwr6{G>LyNpyL7J54XZo#IciM!r<2}ObnQY88XL^RWE($+2L6NBBL*)Pzh7$pi0thWJ7$Ap$fC)ccLg9=scnBCoXBz?7 zbL}pG|1(K)vec)zu;t`3p?rMa!vN$dbtn2)`El(s6F|r^I#9*!I|MH)t^?}eK|LLQ z;j3fh3BvfI0Z2$)s*yZz%2$y=5#@i0fPoa)5`#Yj03n>$&gP-m?@4r1V<2BvR~HBB z=;3iXo-(3*CVd>AiQnSri^hO5T~Y%ekU0#c&y3GwD^I2FneG?IcWe8sRgQ;ylsi4l z-Ei-Fx;W`RHQv>^kQ^ns38Oh+oYw9g*}Cv1Pf(6ofBD%*VYFeAl`# zD9(l3ZspnG*&3BJ5n1->Tb+}t!kaAKe*7ZZ#Kg?A>vx6Slf!9AOuxk2i>@y1WGU_e z-|Yt|7RyffTU>W>8$oPWCfatO`()Cw{3vfH**T92R(Ab_GK3`awCH;_hM0R7q5M{-Fb7oqQbrs{KUp#z=fGsqma>oAd9q?vNfnZ+=|EF{9?%~&V3LrGe> zWjw*D>2ubs%%Q~E`sxCfMscJqCivD1PLJ<%+1qzW+g_E&ewFdW_8OZ_cWtogU z3yLXZCe70H?RTFIt(f5yKX;F;LRaF&*<5!X!n*SHT*+LXvEG{!gzGwM?Kp(s5GbJN zrK2}AjhZ=#UT?7zRU6r4ZuaiNouxUn-$sI^nhm3$5i($^L0AV_pVzL(Pv{bl=15F{ ziEaus;#u9pe!hvNPlypaV|tUb^FDhnvk1O|v_D+7*)tUFr@}=OEG| nuxtJaqP-bJPGOc-xuLyB>-LI+zpmA25vH9Q`mvGAT~+=Ec-ox= delta 1475 zcmV;!1w8t&+6l1Q34nwFv;yZI0bsZ29s>Ob0b;l2CISi%3P~`66h#670WflxO)vsr zms&OgSOhRKFfg~aHUh8#e<2ziJ@_8*l|A7g43E|Mo<8eva(d_f$Nd$YfNG|sA!{&T zZfr7@H23k3=2~Ho0||r;th>VP=o?#%YR0vm1ySdD0>v){%G5Hw z9$j>RYG|O&cwbcK(p?f-$611>+UF&eWBW9cj@9qA@1qgRv5$_)+GRSWiL-y`?Y|D& zS#5+0s|!&LNQUYywNsyCIZyu8M|#%#}*hv&;bIN#%){YY=l-njw@DI$UFVhQV%7!NWqGBz+Y zGBPkSFfuSPS}+3w0RaLC2F^-J(@Rn?pn?t2FoFdGFoFZ?paTK{0s;siarEYrb6zQz zJ~{%F7&I|6F*!6gFgaQm4Kg+`H8M3ZIW#sfIG5@=0wMu1mkm1tLw}lvI-x@kVF8-- zR@xBrF$uB0mK{>ct#Iw7mOrazUo0969s22fFd^0ELuC2%c8pFHW@}%cN~fbu*{l+l zw-PNJ6Y+jVbl7$_6n{j^on>rC7MvOTLyd1zg@biLimAi9G2eKVt}E5D3WoeBc8rBM z*|l|9%DioCBTzmC2Y(q<^g$_F942hR4fWpx@gyD{mh%J{aZ6^Ne6D%E1}hYlZ4bn> zWPbUP?m3kEXd1L$wy`LV9)DYI0vEGC@*K{#yp2(5v15TVs$CN0Sncc9CyOc~0Cu1~ z1-_3o9Qen(l1xMoVkA~Arf@svrHs4@cS`}|-hd1puzA(mQUYVmw@^F+rU4Yf!Z=Em zsE_4Z@-;pY1r24OYY>T-3O)iPe}vXT=3NLL*!!=~K_Zb5rH%@-`1^jyEd$nGc(Y#| zrQRe4i!pn$TkH>XyKsB~d=kv~C$H${6`$kLN$Un3RVNG*E0Fe|uj zWpP+XHQ$8?^H1gYGKkD5$oJEdCE`?S0-995-gVJoIFc4yH^u>12cI0?e*jrBUeE%i ze~MT~X2$^5qYW!RD$IrC%4bD_=T9C`?RX11L#nIa-=1viMR!sD=}O!ml`&6t+oJw= zn`J(AEe5N%FqvftrHa9vJ$eJW*QhIsj)Ah-zh!O~GA8%LOCDKtZC7@C6psdx!>-Vb z5WBeM>PQr!F~8B$GhYBN0?+TaEmZ9a_!N?wm#GQA7yXGX zsEK1B$A&rA;4hr6ud5hW-JQj`^s`Fp0KN-DLO5Q-#!^Y4b;)`2%hyhh5t#bM`CmjfRK8Z|Y%prm17H_ZWUV%JFZC!Gw0^gy`fa zF&?0o9^dGEozdjtQs8iWs!PtU^fcE4FuEuJ7j3606>lkh4%YDYl8$Vs?)zt5wBvAH dSJ^6hiwr$-bs0wxP=M@{?()u|XS31K_99a$kRkv8