mirror of
https://github.com/narrrl/proton-stream.git
synced 2026-11-04 00:47:00 +01:00
- libmpv is built in its own step and saved with actions/cache/save right after, so a failure later in the job no longer discards a 12 minute build the way a post-job save did - lint's OldTargetApi fails the gate whenever a new platform ships, like the dependency freshness checks already marked informational; raising targetSdk is a deliberate change with its own device pass
290 lines
11 KiB
YAML
290 lines
11 KiB
YAML
name: Android
|
|
|
|
on:
|
|
push:
|
|
branches: [main]
|
|
# A `v*` tag reaches this workflow through release.yml, which calls it and
|
|
# publishes the signed APK. Triggering on the tag here as well would build
|
|
# the release twice.
|
|
workflow_call:
|
|
inputs:
|
|
signed_release:
|
|
required: false
|
|
default: false
|
|
type: boolean
|
|
pull_request:
|
|
paths:
|
|
- 'android/**'
|
|
- 'crates/pstr-android/**'
|
|
- 'crates/pstr-core/**'
|
|
- 'crates/pstr-meta/**'
|
|
- 'crates/pstr-stream/**'
|
|
- 'Cargo.toml'
|
|
- 'Cargo.lock'
|
|
- 'scripts/build-android.sh'
|
|
- 'scripts/build-libmpv-android.sh'
|
|
- '.github/workflows/android.yml'
|
|
workflow_dispatch:
|
|
inputs:
|
|
signed_release:
|
|
description: Build artifacts with the configured release key
|
|
required: false
|
|
default: false
|
|
type: boolean
|
|
|
|
permissions:
|
|
contents: read
|
|
|
|
env:
|
|
CARGO_TERM_COLOR: always
|
|
ANDROID_API: '36'
|
|
ANDROID_BUILD_TOOLS: '37.0.0'
|
|
ANDROID_NDK: '29.0.14206865'
|
|
ANDROID_NDK_HOME: /usr/local/lib/android/sdk/ndk/29.0.14206865
|
|
|
|
jobs:
|
|
build:
|
|
name: Validate, debug, and unsigned release
|
|
runs-on: ubuntu-24.04
|
|
steps:
|
|
- uses: actions/checkout@v7
|
|
with:
|
|
fetch-depth: 0
|
|
|
|
- name: Enforce release versions and tag ancestry
|
|
shell: bash
|
|
run: |
|
|
workspace_version="$(awk '/^\[workspace.package\]/{found=1; next} found && /^\[/{exit} found && /^version = /{gsub(/[" ]/, "", $3); print $3; exit}' Cargo.toml)"
|
|
test -n "$workspace_version"
|
|
if [[ ! "$workspace_version" =~ ^([0-9]+)\.([0-9]+)\.([0-9]+)([-+][0-9A-Za-z.-]+)?$ ]]; then
|
|
echo "::error::workspace version is not supported Android semver: $workspace_version"
|
|
exit 1
|
|
fi
|
|
major="${BASH_REMATCH[1]}"
|
|
minor="${BASH_REMATCH[2]}"
|
|
patch="${BASH_REMATCH[3]}"
|
|
test "$minor" -le 999
|
|
test "$patch" -le 999
|
|
expected_code=$((major * 1000000 + minor * 1000 + patch))
|
|
test "$expected_code" -ge 1
|
|
test "$expected_code" -le 2100000000
|
|
echo "EXPECTED_ANDROID_VERSION_NAME=$workspace_version" >> "$GITHUB_ENV"
|
|
echo "EXPECTED_ANDROID_VERSION_CODE=$expected_code" >> "$GITHUB_ENV"
|
|
if [[ "$GITHUB_REF" == refs/tags/v* ]]; then
|
|
tag="${GITHUB_REF_NAME#v}"
|
|
test "$tag" = "$workspace_version"
|
|
git fetch --no-tags origin +refs/heads/main:refs/remotes/origin/main
|
|
git merge-base --is-ancestor "$GITHUB_SHA" origin/main
|
|
fi
|
|
|
|
- uses: actions/setup-java@v5
|
|
with:
|
|
distribution: temurin
|
|
java-version: '17'
|
|
|
|
# The action's default `packages` includes `tools`, which cmdline-tools
|
|
# 16.0 no longer offers, so sdkmanager exits 1. The SDK pieces this
|
|
# build needs are installed explicitly below.
|
|
- uses: android-actions/setup-android@v3
|
|
with:
|
|
packages: platform-tools
|
|
log-accepted-android-sdk-licenses: false
|
|
|
|
- name: Install native build prerequisites
|
|
run: |
|
|
sudo apt-get update
|
|
sudo apt-get install --no-install-recommends \
|
|
autoconf automake build-essential cmake curl git gperf libdbus-1-dev \
|
|
libtool nasm ninja-build pkg-config python3 unzip wget xz-utils yasm
|
|
# Not apt's meson: noble ships 1.3.2, and the fontconfig that the pinned
|
|
# mpv-android revision builds requires >= 1.11.
|
|
pipx install meson==1.12.1
|
|
|
|
- name: Install Android SDK and NDK
|
|
run: >-
|
|
sdkmanager
|
|
"platforms;android-${ANDROID_API}"
|
|
"build-tools;${ANDROID_BUILD_TOOLS}"
|
|
"ndk;${ANDROID_NDK}"
|
|
|
|
- uses: dtolnay/rust-toolchain@stable
|
|
with:
|
|
toolchain: '1.96'
|
|
targets: aarch64-linux-android,x86_64-linux-android
|
|
|
|
# One cache for both jobs: the signed build compiles the same crates for
|
|
# the same targets. Saved on failure too, so a run that breaks late does
|
|
# not throw away everything it compiled before the break.
|
|
- uses: Swatinem/rust-cache@v2.9.1
|
|
with:
|
|
shared-key: android
|
|
cache-on-failure: true
|
|
|
|
# libmpv and its dependency tree are the slowest part of the build, and
|
|
# depend only on the pinned revision and the build script, which stamps
|
|
# its output with both and skips the build when the stamp matches. Built
|
|
# and saved in steps of its own, so a later failure in Gradle does not
|
|
# discard it the way a post-job cache save would.
|
|
- id: libmpv
|
|
uses: actions/cache/restore@v6
|
|
with:
|
|
path: android/app/build/generated/mpv
|
|
key: libmpv-${{ hashFiles('scripts/build-libmpv-android.sh') }}
|
|
|
|
- name: Build libmpv
|
|
run: bash scripts/build-libmpv-android.sh
|
|
|
|
- if: steps.libmpv.outputs.cache-hit != 'true'
|
|
uses: actions/cache/save@v6
|
|
with:
|
|
path: android/app/build/generated/mpv
|
|
key: ${{ steps.libmpv.outputs.cache-primary-key }}
|
|
|
|
- uses: gradle/actions/setup-gradle@v4
|
|
with:
|
|
gradle-version: '8.13'
|
|
|
|
- name: Validate Android version derivation and override
|
|
shell: bash
|
|
run: |
|
|
resolved="$(gradle --no-daemon -q -p android :app:printAndroidVersion)"
|
|
grep -Fx "versionName=$EXPECTED_ANDROID_VERSION_NAME" <<< "$resolved"
|
|
grep -Fx "versionCode=$EXPECTED_ANDROID_VERSION_CODE" <<< "$resolved"
|
|
if [[ "$EXPECTED_ANDROID_VERSION_CODE" -lt 2100000000 ]]; then
|
|
override_code=$((EXPECTED_ANDROID_VERSION_CODE + 1))
|
|
else
|
|
override_code=$((EXPECTED_ANDROID_VERSION_CODE - 1))
|
|
fi
|
|
overridden="$(ANDROID_VERSION_CODE="$override_code" gradle --no-daemon -q -p android :app:printAndroidVersion)"
|
|
grep -Fx "versionName=$EXPECTED_ANDROID_VERSION_NAME" <<< "$overridden"
|
|
grep -Fx "versionCode=$override_code" <<< "$overridden"
|
|
|
|
- name: Install native build helpers
|
|
run: |
|
|
cargo install cargo-ndk --version 4.1.2 --locked
|
|
cargo install uniffi --version 0.32.0 --features cli --locked
|
|
|
|
- name: Android checks and artifacts
|
|
run: bash scripts/build-android.sh all
|
|
|
|
signed-release:
|
|
name: Signed release
|
|
if: startsWith(github.ref, 'refs/tags/v') || inputs.signed_release
|
|
needs: build
|
|
runs-on: ubuntu-24.04
|
|
env:
|
|
ANDROID_RELEASE_STORE_PASSWORD: ${{ secrets.ANDROID_RELEASE_STORE_PASSWORD }}
|
|
ANDROID_RELEASE_KEY_ALIAS: ${{ secrets.ANDROID_RELEASE_KEY_ALIAS }}
|
|
ANDROID_RELEASE_KEY_PASSWORD: ${{ secrets.ANDROID_RELEASE_KEY_PASSWORD }}
|
|
steps:
|
|
- uses: actions/checkout@v7
|
|
|
|
- uses: actions/setup-java@v5
|
|
with:
|
|
distribution: temurin
|
|
java-version: '17'
|
|
|
|
# The action's default `packages` includes `tools`, which cmdline-tools
|
|
# 16.0 no longer offers, so sdkmanager exits 1. The SDK pieces this
|
|
# build needs are installed explicitly below.
|
|
- uses: android-actions/setup-android@v3
|
|
with:
|
|
packages: platform-tools
|
|
log-accepted-android-sdk-licenses: false
|
|
|
|
- name: Install native build prerequisites
|
|
run: |
|
|
sudo apt-get update
|
|
sudo apt-get install --no-install-recommends \
|
|
autoconf automake build-essential cmake curl git gperf libdbus-1-dev \
|
|
libtool nasm ninja-build pkg-config python3 unzip wget xz-utils yasm
|
|
# Not apt's meson: noble ships 1.3.2, and the fontconfig that the pinned
|
|
# mpv-android revision builds requires >= 1.11.
|
|
pipx install meson==1.12.1
|
|
|
|
- name: Install Android SDK and NDK
|
|
run: >-
|
|
sdkmanager
|
|
"platforms;android-${ANDROID_API}"
|
|
"build-tools;${ANDROID_BUILD_TOOLS}"
|
|
"ndk;${ANDROID_NDK}"
|
|
|
|
- uses: dtolnay/rust-toolchain@stable
|
|
with:
|
|
toolchain: '1.96'
|
|
targets: aarch64-linux-android,x86_64-linux-android
|
|
|
|
# One cache for both jobs: the signed build compiles the same crates for
|
|
# the same targets. Saved on failure too, so a run that breaks late does
|
|
# not throw away everything it compiled before the break.
|
|
- uses: Swatinem/rust-cache@v2.9.1
|
|
with:
|
|
shared-key: android
|
|
cache-on-failure: true
|
|
|
|
# libmpv and its dependency tree are the slowest part of the build, and
|
|
# depend only on the pinned revision and the build script, which stamps
|
|
# its output with both and skips the build when the stamp matches. Built
|
|
# and saved in steps of its own, so a later failure in Gradle does not
|
|
# discard it the way a post-job cache save would.
|
|
- id: libmpv
|
|
uses: actions/cache/restore@v6
|
|
with:
|
|
path: android/app/build/generated/mpv
|
|
key: libmpv-${{ hashFiles('scripts/build-libmpv-android.sh') }}
|
|
|
|
- name: Build libmpv
|
|
run: bash scripts/build-libmpv-android.sh
|
|
|
|
- if: steps.libmpv.outputs.cache-hit != 'true'
|
|
uses: actions/cache/save@v6
|
|
with:
|
|
path: android/app/build/generated/mpv
|
|
key: ${{ steps.libmpv.outputs.cache-primary-key }}
|
|
|
|
- uses: gradle/actions/setup-gradle@v4
|
|
with:
|
|
gradle-version: '8.13'
|
|
|
|
- name: Install native build helpers
|
|
run: |
|
|
cargo install cargo-ndk --version 4.1.2 --locked
|
|
cargo install uniffi --version 0.32.0 --features cli --locked
|
|
|
|
- name: Restore release keystore
|
|
env:
|
|
KEYSTORE_BASE64: ${{ secrets.ANDROID_RELEASE_KEYSTORE_BASE64 }}
|
|
run: |
|
|
test -n "$KEYSTORE_BASE64"
|
|
test -n "$ANDROID_RELEASE_STORE_PASSWORD"
|
|
test -n "$ANDROID_RELEASE_KEY_ALIAS"
|
|
test -n "$ANDROID_RELEASE_KEY_PASSWORD"
|
|
ANDROID_RELEASE_STORE_FILE="$RUNNER_TEMP/proton-stream-release.jks"
|
|
echo "ANDROID_RELEASE_STORE_FILE=$ANDROID_RELEASE_STORE_FILE" >> "$GITHUB_ENV"
|
|
printf '%s' "$KEYSTORE_BASE64" | base64 --decode > "$ANDROID_RELEASE_STORE_FILE"
|
|
|
|
- name: Build signed APK and AAB
|
|
run: bash scripts/build-android.sh signed
|
|
|
|
# The APK bundles a GPL libmpv, so its corresponding source ships next to
|
|
# it. The AAB is for Play only and stays out of the GitHub release.
|
|
- name: Stage release files
|
|
run: |
|
|
version="$(sed -n 's/^version = "\([^"]*\)"/\1/p' Cargo.toml | head -n1)"
|
|
mkdir -p dist/android
|
|
cp android/app/build/outputs/apk/release/app-release.apk \
|
|
"dist/android/proton-stream-$version-android.apk"
|
|
cp android/app/build/generated/mpv/mpv-android-source-*.tar.gz dist/android/
|
|
|
|
- uses: actions/upload-artifact@v7
|
|
with:
|
|
name: android
|
|
path: dist/android/*
|
|
if-no-files-found: error
|
|
|
|
- uses: actions/upload-artifact@v7
|
|
with:
|
|
name: android-bundle
|
|
path: android/app/build/outputs/bundle/release/*.aab
|
|
if-no-files-found: error
|