fix: handle double-encoded signing key (decode up to 2 levels) #22
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 | |
| on: | |
| push: | |
| tags: | |
| - "v*" | |
| env: | |
| CARGO_TERM_COLOR: always | |
| CARGO_HOME: /Users/runner/.cargo | |
| CARGO_INCREMENTAL: 0 | |
| TAURI_SIGNING_PRIVATE_KEY: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY }} | |
| TAURI_SIGNING_PRIVATE_KEY_PASSWORD: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY_PASSWORD }} | |
| jobs: | |
| release-macos: | |
| runs-on: macos-latest | |
| permissions: | |
| contents: write | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Install Rust | |
| uses: dtolnay/rust-toolchain@stable | |
| - name: Rust cache | |
| uses: Swatinem/rust-cache@v2 | |
| with: | |
| workspaces: ". -> target" | |
| cache-on-failure: true | |
| - name: Setup Node | |
| uses: actions/setup-node@v4 | |
| with: | |
| node-version: 20 | |
| cache: npm | |
| - name: Install frontend deps | |
| run: npm ci | |
| - name: Install system deps | |
| run: | | |
| # ffmpeg@7 required: mpv 0.40.0 uses FF_PROFILE_* macros removed in ffmpeg 8.x | |
| brew install meson ninja pkg-config ffmpeg@7 libass libplacebo dylibbundler | |
| # Make ffmpeg@7 visible to pkg-config (it is keg-only, not linked by default) | |
| echo "PKG_CONFIG_PATH=$(brew --prefix ffmpeg@7)/lib/pkgconfig${PKG_CONFIG_PATH:+:$PKG_CONFIG_PATH}" >> $GITHUB_ENV | |
| - name: Build libmpv | |
| run: ./scripts/build-libmpv.sh macos | |
| - name: Prepare signing key | |
| run: | | |
| # Tauri CLI requires the raw minisign format (starting with "untrusted comment:"). | |
| # The secret may be stored as: | |
| # (a) base64-encoded raw key, or | |
| # (b) raw key with actual newlines, or | |
| # (c) raw key with escaped \n (two chars) instead of real newlines. | |
| # We normalize to raw format and always write to GITHUB_ENV so the key | |
| # is guaranteed to have proper newlines when Tauri reads it. | |
| python3 - << 'EOF' | |
| import base64, os, sys | |
| key = os.environ.get("TAURI_SIGNING_PRIVATE_KEY", "") | |
| print(f"[signing] Key length: {len(key)}, has newlines: {'yes' if chr(10) in key else 'no'}") | |
| if not key.strip(): | |
| print("[signing] ERROR: no signing key set.") | |
| sys.exit(1) | |
| # Normalize literal \n (two chars) to actual newlines | |
| key = key.replace("\\n", "\n") | |
| def try_b64(s): | |
| try: | |
| return base64.b64decode(s.strip(), validate=True).decode("utf-8") | |
| except Exception: | |
| return None | |
| if "untrusted comment:" in key: | |
| final_key = key | |
| print("[signing] Raw minisign key detected.") | |
| else: | |
| # Try up to 2 levels of base64 decoding to handle both | |
| # single-encoded and accidentally double-encoded secrets. | |
| current = key | |
| final_key = None | |
| for depth in range(1, 3): | |
| decoded = try_b64(current) | |
| if decoded is None: | |
| print(f"[signing] ERROR: base64 decode failed at depth {depth}.") | |
| sys.exit(1) | |
| if "untrusted comment:" in decoded: | |
| final_key = decoded | |
| print(f"[signing] Key decoded at depth {depth}.") | |
| break | |
| current = decoded | |
| if final_key is None: | |
| print("[signing] ERROR: key is not a valid minisign private key.") | |
| sys.exit(1) | |
| with open(os.environ["GITHUB_ENV"], "a") as f: | |
| f.write("TAURI_SIGNING_PRIVATE_KEY<<__ENDKEY__\n") | |
| f.write(final_key.rstrip("\n") + "\n") | |
| f.write("__ENDKEY__\n") | |
| print("[signing] Key written to GITHUB_ENV.") | |
| EOF | |
| - name: Build and publish release | |
| uses: tauri-apps/tauri-action@v0 | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| with: | |
| projectPath: apps/desktop | |
| tagName: ${{ github.ref_name }} | |
| releaseName: "MaxVideoPlayer ${{ github.ref_name }}" | |
| releaseBody: | | |
| See the [CHANGELOG](https://github.com/MaxMB15/MaxVideoPlayer/blob/main/CHANGELOG.md) for details. | |
| releaseDraft: true | |
| prerelease: false | |
| updaterJsonPath: latest.json | |
| updaterJsonKeepUniversal: false |