Repository navigation
changing license and release 2.6.6 #10
Workflow file for this run
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Release | |
| # Build both variants (online + offline) and publish them in the same Release. | |
| # Users choose which APK to install from the GitHub Releases page. | |
| on: | |
| push: | |
| tags: | |
| - "v*" | |
| workflow_dispatch: | |
| permissions: | |
| contents: write | |
| jobs: | |
| build: | |
| runs-on: ubuntu-latest | |
| env: | |
| MG4_KEYSTORE_BASE64: ${{ secrets.MG4_KEYSTORE_BASE64 }} | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: actions/setup-java@v4 | |
| with: | |
| distribution: temurin | |
| java-version: "17" | |
| - name: Setup Gradle | |
| uses: gradle/actions/setup-gradle@v4 | |
| - name: Decode platform keystore | |
| run: | | |
| # An absent secret used to SKIP this step silently. Gradle then created no signing | |
| # config and the workflow published an UNSIGNED APK -- which no device can install | |
| # now that the T-901 signature check is enforced again. Fail loudly instead, which | |
| # is what beta.yml already does. | |
| if [ -z "$MG4_KEYSTORE_BASE64" ]; then | |
| echo "::error::MG4_KEYSTORE_BASE64 is missing. The APK would be unsigned and every" | |
| echo "::error::client would reject it at install time (signature check T-901)." | |
| exit 1 | |
| fi | |
| # Tolerate newlines/spaces in the secret; printf avoids a stray trailing newline. | |
| printf '%s' "$MG4_KEYSTORE_BASE64" | tr -d '[:space:]' | base64 -d > "$RUNNER_TEMP/platform.keystore" | |
| # Validation: a PKCS12/JKS keystore starts with 0x30 (DER SEQUENCE). Otherwise the secret is corrupt. | |
| if [ "$(head -c1 "$RUNNER_TEMP/platform.keystore" | od -An -tx1 | tr -d ' ')" != "30" ]; then | |
| echo "::error::MG4_KEYSTORE_BASE64 is invalid. Recreate the secret with: base64 -w0 platform.keystore" | |
| exit 1 | |
| fi | |
| echo "MG4_KEYSTORE=$RUNNER_TEMP/platform.keystore" >> "$GITHUB_ENV" | |
| - name: Build online + offline release APKs | |
| env: | |
| MG4_KEYSTORE_PASSWORD: ${{ secrets.MG4_KEYSTORE_PASSWORD }} | |
| MG4_KEY_ALIAS: ${{ secrets.MG4_KEY_ALIAS }} | |
| MG4_KEY_PASSWORD: ${{ secrets.MG4_KEY_PASSWORD }} | |
| run: | | |
| chmod +x gradlew | |
| ./gradlew assembleOnlineRelease assembleOfflineRelease --no-daemon | |
| - name: Collect APKs | |
| run: | | |
| mkdir -p dist | |
| find app/build/outputs/apk -name "MG4Control-*-*.apk" -exec cp {} dist/ \; | |
| ls -la dist/ | |
| # /!\ --min-sdk-version 23 is REQUIRED for this report to tell the truth. Without it, | |
| # apksigner uses the APK's own minSdk (28), verifies with v3 only, and prints | |
| # "Verified using v1 scheme: false" on an APK that DOES carry a v1 signature. | |
| - name: Verify signature schemes | |
| run: | | |
| APKSIGNER=$(ls "$ANDROID_SDK_ROOT"/build-tools/*/apksigner | sort -V | tail -1) | |
| for f in dist/*.apk; do | |
| echo "-- $(basename "$f") --" | |
| "$APKSIGNER" verify --print-certs -v --min-sdk-version 23 "$f" \ | |
| | grep -E 'Verified using v[0-9]|certificate SHA-256 digest' | |
| # Actual presence of the v1 signature, regardless of what apksigner chose to verify | |
| # with. On AAOS 9 the OTA check reads the archive through getPackageArchiveInfo(), | |
| # which reports no certificate without v1 -- the app then refuses the update. | |
| # Better to break the build than to publish that. | |
| if ! unzip -l "$f" | grep -qE 'META-INF/.*[.](SF|RSA|DSA|EC)$'; then | |
| echo "::error::$(basename "$f") has NO v1 (JAR) signature - clients would reject it" | |
| exit 1 | |
| fi | |
| echo " v1 (JAR) present : YES" | |
| echo " size : $(stat -c%s "$f") bytes" | |
| echo " sha256 : $(sha256sum "$f" | cut -d' ' -f1)" | |
| done | |
| - name: Upload APKs as workflow artifacts | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: mg4control-apks | |
| path: dist/*.apk | |
| - name: Publish to GitHub Release | |
| uses: softprops/action-gh-release@v2 | |
| with: | |
| # Tag push -> stable release on the tag. Manual run -> prerelease "ci-<run>". | |
| tag_name: ${{ startsWith(github.ref, 'refs/tags/') && github.ref_name || format('ci-{0}', github.run_number) }} | |
| name: ${{ startsWith(github.ref, 'refs/tags/') && github.ref_name || format('CI build {0}', github.run_number) }} | |
| prerelease: ${{ !startsWith(github.ref, 'refs/tags/') }} | |
| files: dist/*.apk | |
| body: | | |
| ## MG4Control ${{ startsWith(github.ref, 'refs/tags/') && github.ref_name || format('ci-{0}', github.run_number) }} | |
| Two variants are provided — **pick one**: | |
| | Variant | File | Network | Auto-update | Target | | |
| |---|---|---|---|---| | |
| | **Online** | `MG4Control-online-*.apk` | yes | yes | standard use | | |
| | **Offline** 🔒 | `MG4Control-offline-*.apk` | none (network perms removed) | no | hardened on-vehicle deployment | | |
| > The offline APK has a distinct applicationId (`com.mg4.control.offline`) and can coexist with the online one. |