From 88a24b44fd271ed94396325a6cd641f87bb14889 Mon Sep 17 00:00:00 2001 From: Dan Amouyal Date: Sun, 6 Sep 2026 21:23:32 +0300 Subject: [PATCH 1/3] fix(build): keep looking for a signing identity after the first miss `set -e` aborts the script when `grep` finds no "Developer ID Application" line, so the "Apple Development" fallback the loop was written for is never reached. On a machine that only has a development certificate, build-app.sh exits 1 right after "Build complete" with no message, leaving an unsigned, half-assembled bundle in build/. Let the substitution fail quietly so the loop can try the next kind. --- scripts/build-app.sh | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/scripts/build-app.sh b/scripts/build-app.sh index 25cec75..041b954 100755 --- a/scripts/build-app.sh +++ b/scripts/build-app.sh @@ -59,7 +59,9 @@ identity=${CODESIGN_IDENTITY:-} if [ -z "$identity" ]; then identities=$(security find-identity -v -p codesigning 2>/dev/null) for kind in "Developer ID Application" "Apple Development"; do - identity=$(printf '%s\n' "$identities" | grep -oE "\"${kind}[^\"]*\"" | head -1 | tr -d '"') + # `|| true`: grep exits 1 when the kind is absent, which would abort the + # script under `set -e` before the next kind is tried. + identity=$(printf '%s\n' "$identities" | grep -oE "\"${kind}[^\"]*\"" | head -1 | tr -d '"' || true) [ -n "$identity" ] && break done fi From 16a69de32385098747ad6ba1e242d859eeab649f Mon Sep 17 00:00:00 2001 From: Dan Amouyal Date: Sun, 6 Sep 2026 21:27:37 +0300 Subject: [PATCH 2/3] ci: build, test and check the app bundle on every push The project had no automated checks, so a release could ship a build that does not compile from a clean checkout. This runs on macos-15: swift build, the test suite with the machine-wide scan enabled (a runner starts empty, so the walk that is slow locally is quick here), scripts/build-app.sh, and a check that the assembled bundle has its binary, its Info.plist, the SwiftPM resource bundle Bundle.module needs and a valid signature. The last step reruns compile-strings.sh and fails on a diff, so a catalog edit committed without regenerating the .strings files is caught here rather than as a half-translated menu at runtime. Note: the bundle step needs the signing-identity fix, otherwise build-app.sh aborts on a runner, which has no certificate at all. --- .github/workflows/ci.yml | 47 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) create mode 100644 .github/workflows/ci.yml diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..cb7bff1 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,47 @@ +name: CI + +on: + push: + branches: [main] + pull_request: + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +jobs: + test: + runs-on: macos-15 + steps: + - uses: actions/checkout@v4 + + - name: Show toolchain + run: swift --version + + - name: Build + run: swift build -c release + + - name: Test + # The runner starts nearly empty, so the machine-wide scan that is too + # slow to run locally is quick here and worth enabling. + env: + SYSDATA_SCAN_TESTS: "1" + run: swift test + + - name: Assemble the app bundle + run: scripts/build-app.sh + + - name: Check the bundle is complete + run: | + app=build/SysDataMenu.app + test -x "$app/Contents/MacOS/SysDataMenu" + test -f "$app/Contents/Info.plist" + test -d "$app/Contents/Resources/SysDataMenu_SysDataMenu.bundle" + codesign --verify --deep --strict "$app" + + - name: Check the compiled strings are up to date + # compile-strings.sh regenerates the .strings files from the catalog; + # a stale commit shows up here instead of as mixed languages at runtime. + run: | + scripts/compile-strings.sh + git diff --exit-code -- Sources/SysDataMenu/Resources From 48c93293b570f02a24aa76a90a5884cb21b977cc Mon Sep 17 00:00:00 2001 From: Dan Amouyal Date: Sun, 6 Sep 2026 21:52:16 +0300 Subject: [PATCH 3/3] ci: leave the machine-wide scan off and bound the job Enabling it was wrong: a GitHub runner ships Xcode with its simulator runtimes and device support, so the walk is no quicker there than on a developer Mac. A trial run passed 23 minutes without finishing. Also gives the job a 20-minute ceiling so a hang costs one job rather than the six hours a runner will otherwise sit there. --- .github/workflows/ci.yml | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index cb7bff1..b80f56d 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -12,6 +12,7 @@ concurrency: jobs: test: runs-on: macos-15 + timeout-minutes: 20 steps: - uses: actions/checkout@v4 @@ -22,10 +23,8 @@ jobs: run: swift build -c release - name: Test - # The runner starts nearly empty, so the machine-wide scan that is too - # slow to run locally is quick here and worth enabling. - env: - SYSDATA_SCAN_TESTS: "1" + # The machine-wide scan stays off: a GitHub runner ships Xcode and its + # simulator runtimes, so it is no faster there than on a developer Mac. run: swift test - name: Assemble the app bundle