From 0931afbd783f3b49ff8f958c5a8a2e80085637c4 Mon Sep 17 00:00:00 2001 From: sepehr-safari Date: Mon, 13 Jul 2026 03:07:52 +0300 Subject: [PATCH] chore(repo): make release scripts pure ASCII and guard in CI The macOS one-line installer (install-macos.sh) is fetched and run via `curl | bash`, so it must survive the oldest bundled bash. A non-ASCII byte next to a $variable under `set -u` on macOS's bash 3.2.57 folds into the variable name and aborts the install; in any non-UTF-8 locale, non-ASCII in emitted strings prints as mojibake. Replace the em-dashes, ellipsis, and arrows in install-macos.sh, package-macos.sh, and smoke.sh with ASCII equivalents (spacing preserved), and add a CI job that fails on any non-ASCII byte in scripts/*.sh so it cannot regress. --- .github/workflows/ci.yml | 17 +++++++++++++++++ scripts/install-macos.sh | 6 +++--- scripts/package-macos.sh | 4 ++-- scripts/smoke.sh | 14 +++++++------- 4 files changed, 29 insertions(+), 12 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index ee8f741..02fccd4 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -77,3 +77,20 @@ jobs: name: gui-screenshots path: .zig-cache/native-sdk-automation/screenshot-*.png if-no-files-found: ignore + + scripts: + name: scripts (pure ASCII) + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v5 + - name: Assert scripts are pure ASCII + # A `curl | bash` installer must run on the oldest bundled bash (macOS + # ships 3.2.57): a non-ASCII byte next to a $variable under `set -u` folds + # into the variable name and aborts the install. Keep every script ASCII. + run: | + bad="$(LC_ALL=C perl -ne 'print "$ARGV:$.: $_" if /[^\x00-\x7F]/; close ARGV if eof' scripts/*.sh)" + if [ -n "$bad" ]; then + printf '%s\n' "$bad" + echo "::error::scripts/*.sh must be pure ASCII (see lines above)" + exit 1 + fi diff --git a/scripts/install-macos.sh b/scripts/install-macos.sh index 5fdc3dd..039d195 100755 --- a/scripts/install-macos.sh +++ b/scripts/install-macos.sh @@ -43,7 +43,7 @@ curl -fSL --progress-bar -o "$tmp/$name" "$base/$name" || fail "download failed" note "Verifying SHA-256" got="$(shasum -a 256 "$tmp/$name" | awk '{ print $1 }')" -[ "$got" = "$sha" ] || fail "checksum mismatch — expected $sha, got $got (not installing)" +[ "$got" = "$sha" ] || fail "checksum mismatch - expected $sha, got $got (not installing)" note "Mounting the disk image" mnt="$(hdiutil attach "$tmp/$name" -nobrowse -readonly | grep -o '/Volumes/.*' | head -1)" @@ -52,7 +52,7 @@ mnt="$(hdiutil attach "$tmp/$name" -nobrowse -readonly | grep -o '/Volumes/.*' | sudo="" if [ ! -w /Applications ]; then sudo="sudo" - note "/Applications needs administrator access — you may be prompted for your password" + note "/Applications needs administrator access - you may be prompted for your password" fi note "Installing to /Applications" @@ -66,4 +66,4 @@ $sudo xattr -dr com.apple.quarantine "$dest" 2>/dev/null || true note "Opening $app" open "$dest" -note "Done — OCPP DebugKit Studio is installed in /Applications." +note "Done - OCPP DebugKit Studio is installed in /Applications." diff --git a/scripts/package-macos.sh b/scripts/package-macos.sh index d51bf95..9d23fc6 100755 --- a/scripts/package-macos.sh +++ b/scripts/package-macos.sh @@ -7,8 +7,8 @@ # because the SDK's codesign invocation does not quote the bundle path: a path # with spaces splits into multiple arguments and ad-hoc signing silently fails, # leaving an unsigned bundle (which will not launch on Apple silicon). Signing -# the space-free name and renaming afterwards keeps the seal intact — the ad-hoc -# signature covers bundle contents, not the directory name — and we build the +# the space-free name and renaming afterwards keeps the seal intact - the ad-hoc +# signature covers bundle contents, not the directory name - and we build the # .dmg ourselves so it wraps the renamed, signed bundle. # # Usage: scripts/package-macos.sh (run after `native build`) diff --git a/scripts/smoke.sh b/scripts/smoke.sh index ae4bf74..d5635f9 100755 --- a/scripts/smoke.sh +++ b/scripts/smoke.sh @@ -1,9 +1,9 @@ #!/usr/bin/env bash # # Automation-driven GUI test: launch the app, wait for its embedded automation -# server, then DRIVE the headline flows through the automation protocol — +# server, then DRIVE the headline flows through the automation protocol - # clicking real widgets and asserting the rendered semantics tree after each -# step — and capture deterministic screenshots as artifacts. Portable: uses a +# step - and capture deterministic screenshots as artifacts. Portable: uses a # virtual framebuffer (Xvfb) when available (CI), otherwise runs the window # directly (local macOS). The app must be built with -Dautomation=true. # @@ -17,7 +17,7 @@ CANVAS=main-canvas SAMPLE=src/ocpp/testdata/normal-session.json if [ ! -x "$BIN" ]; then - echo "smoke: $BIN not found — build first: native build -Dautomation=true" >&2 + echo "smoke: $BIN not found - build first: native build -Dautomation=true" >&2 exit 1 fi @@ -47,7 +47,7 @@ APP_PID=$! trap 'kill "$APP_PID" >/dev/null 2>&1 || true' EXIT # The numeric widget id for the widget whose accessibility name equals $1. Each -# snapshot line is `widget @w/# role= name="