Automation Script ota-publish.sh
Prior to the creation of the pure Dart tk-ota-push CLI, compiling, signing, and publishing OTA artifacts was orchestrated by the shell script ota-publish.sh (tkushpatch_releases/ota-publish.sh).
This script remains a robust reference tool, particularly for developers operating exclusively on macOS or Linux systems and for legacy Bash CI/CD pipelines.
1. Supported Execution Modes
The script accepts two positional arguments: the execution mode and optionally the target version (e.g., 1.0.0+13). If omitted, the version is extracted automatically from pubspec.yaml.
./ota-publish.sh <mode> [version]
| Mode | Target Platform | Action Performed |
|---|---|---|
release | Android | Compiles the release APK, extracts application binary, computes the pubspec.lock hash, and locks the Release on the server. |
patch | Android | Compiles the new application binary, verifies hash integrity against the active Release, and publishes the OTA patch. |
release-ios | iOS | Compiles Runner.app, extracts the reference App binary and diff_base into .shorebird_cache/, and locks the iOS Release. |
patch-ios | iOS | Compiles app.dill, generates an ELF snapshot (gen_snapshot_arm64), links patch artifact (aot-tools.dill link), and publishes the patch. |
release-all | Android + iOS | Runs release followed by release-ios to lock both platforms in a single command. |
patch-all | Android + iOS | Runs patch followed by patch-ios to deploy the OTA patch across Android and iOS simultaneously. |
2. Step-by-Step Script Pipeline
The script executes a rigorous sequence ensuring binary integrity before making any network calls:
- Key Synchronization: Fetches the public signing key from the TkushPatch server.
- Immutability Check: Verifies that the targeted release is not locked.
- Build & Publish: Compiles the artifact and transmits the update to the server.
- Confirmation: Verifies patch status and logs build telemetry.
Step 1: RSA Public Key Synchronization
The script queries /api/admin/v1/crypto/public-key on your on-premise TkushPatch Server server and automatically updates the patch_public_key field in shorebird.yaml:
PUB_KEY=$(curl -s "$OTA_SERVER_URL/api/admin/v1/crypto/public-key" | sed -n 's/.*"patch_public_key":"\([^"]*\)".*/\1/p')
Step 2: Protection Against Release Overwrite (HTTP 409)
Before triggering heavy builds, the script verifies whether the requested release is already locked on the server via /releases/lookup. If it exists, execution aborts immediately to avoid overwriting production Store binaries.
Step 3: Shorebird Toolchain Discovery
The script locates the tools embedded by Shorebird on macOS:
SHOREBIRD_FLUTTER_DIR="$(ls -d "$HOME"/.shorebird/bin/cache/flutter/* | head -n 1)"
SHOREBIRD_FLUTTER="$SHOREBIRD_FLUTTER_DIR/bin/flutter"
SHOREBIRD_DART="$SHOREBIRD_FLUTTER_DIR/bin/cache/dart-sdk/bin/dart"
GEN_SNAPSHOT_IOS="$SHOREBIRD_FLUTTER_DIR/bin/cache/artifacts/engine/ios-release/gen_snapshot_arm64"
ANALYZE_SNAPSHOT_IOS="$SHOREBIRD_FLUTTER_DIR/bin/cache/artifacts/engine/ios-release/analyze_snapshot_arm64"
ENGINE_REV="$(cat "$SHOREBIRD_FLUTTER_DIR/bin/internal/engine.version" | tr -d '[:space:]')"
AOT_TOOLS_DILL="$HOME/.shorebird/bin/cache/artifacts/aot-tools/$ENGINE_REV/aot-tools.dill"
Step 4: iOS Cache Management (diff_base)
For iOS, Shorebird requires the original reference binary (App) and link supplement files. The script stores these in a local cache directory:
.shorebird_cache/ios_release_<version>/
├── App
├── diff_base
├── Runner.app
└── supplement/
├── App.arm64.link
└── App.arm64_table.json
During patch-ios, the script performs a strict checksum comparison: the SHA-256 of the local diff_base must match exactly the reference hash on TkushPatch Server. Any difference aborts the build, preventing SIGSEGV crashes on end-user iPhones.
3. Comparison: ota-publish.sh vs tk-ota-push CLI
While the shell script is functional for quick local checks, the pure Dart tk-ota-push CLI is the recommended tool for production environments:
| Feature | Shell Script ota-publish.sh | Dart CLI tk-ota-push |
|---|---|---|
| OS Compatibility | macOS and Linux only (Bash) | Native multiplatform (macOS, Linux, Windows) |
| Authentication | Static environment variable only | Interactive PKCE Web login (login), Enterprise SSO, auto-refresh |
| Multi-Tenancy | Manual override | Native (tenant_id resolved in shorebird.yaml, session, or flag) |
| Multi-Flavors & ABI | Monolithic Android/iOS targets | Multi-Flavors (--flavor, --target), multi-ABI (aarch64 + arm) |
| Native Integrity Checks | pubspec.lock hash only | Full binary scanner (classes.dex, manifests, C++ libraries) |
| CI/CD Integration | Plain text stdout | Structured JSON output (--json), POSIX standard exit codes |
| Governance & Rollout | 100% direct rollout only | Staged 4-eyes rollout (--staged), percentage (--rollout), geo-fencing |