Skip to content

Commit 4729016

Browse files
authored
Merge pull request #83 from TypeType-Video/release/1.8.0
release: prepare TypeType Android 1.8.0
2 parents e21b078 + d5d2141 commit 4729016

252 files changed

Lines changed: 18236 additions & 334 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

‎.github/workflows/android-beta.yml‎

Lines changed: 199 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,199 @@
1+
name: Android Beta
2+
3+
on:
4+
push:
5+
branches:
6+
- beta
7+
paths:
8+
- 'app/**'
9+
- 'player/**'
10+
- 'baseline-profile/**'
11+
- 'gradle/**'
12+
- '*.gradle.kts'
13+
- 'gradle.properties'
14+
- 'settings.gradle.kts'
15+
pull_request:
16+
branches:
17+
- beta
18+
paths:
19+
- 'app/**'
20+
- 'player/**'
21+
- 'baseline-profile/**'
22+
- 'gradle/**'
23+
- '*.gradle.kts'
24+
- 'gradle.properties'
25+
- 'settings.gradle.kts'
26+
workflow_dispatch:
27+
28+
permissions:
29+
contents: read
30+
31+
concurrency:
32+
group: android-beta
33+
cancel-in-progress: false
34+
35+
env:
36+
CI: true
37+
FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true
38+
JAVA_TOOL_OPTIONS: -Djava.awt.headless=true
39+
GRADLE_OPTS: -Dorg.gradle.workers.max=8 -Dorg.gradle.daemon.idletimeout=900000
40+
ANDROID_HOME: /opt/android-sdk
41+
ANDROID_SDK_ROOT: /opt/android-sdk
42+
JAVA_HOME: /usr/lib/jvm/java-26-openjdk
43+
GRADLE_USER_HOME: /var/tmp/typetype-android-gradle-user-home
44+
GITHUB_REPO: TypeType-Video/TypeType-Android
45+
46+
jobs:
47+
release:
48+
runs-on: [self-hosted, Linux, X64, arko, android]
49+
timeout-minutes: 35
50+
permissions:
51+
contents: write
52+
steps:
53+
- name: Checkout
54+
uses: actions/checkout@v7.0.1
55+
56+
- name: Install Android SDK platform
57+
run: |
58+
platform="$ANDROID_HOME/platforms/android-37.0"
59+
(
60+
flock 9
61+
if [ ! -f "$platform/android.jar" ]; then
62+
rm -rf "$platform"
63+
"$ANDROID_HOME/cmdline-tools/latest/bin/sdkmanager" \
64+
--sdk_root="$ANDROID_HOME" \
65+
"platforms;android-37.0"
66+
fi
67+
test -f "$platform/android.jar"
68+
) 9>"$ANDROID_HOME/.platform-install.lock"
69+
70+
- name: Validate beta release version
71+
env:
72+
GH_TOKEN: ${{ github.token }}
73+
run: |
74+
version_name="$(sed -nE 's/^[[:space:]]*versionName = "([^"]+)"/\1/p' app/build.gradle.kts)"
75+
version_code="$(sed -nE 's/^[[:space:]]*versionCode = ([0-9]+)/\1/p' app/build.gradle.kts)"
76+
release_tag="v${version_name}"
77+
78+
[[ "$version_name" =~ ^[0-9]+\.[0-9]+\.[0-9]+-beta\.[1-9][0-9]*$ ]]
79+
[[ "$version_code" =~ ^[1-9][0-9]*$ ]]
80+
81+
latest_code="$(
82+
gh api \
83+
-H 'Accept: application/vnd.github+json' \
84+
--paginate "repos/${GITHUB_REPO}/releases" \
85+
--jq '.[] | select(.draft == false and .prerelease == true) | .assets[]?.name | capture("^dev\\.typetype\\.android_(?<code>[0-9]+)\\.apk$").code' \
86+
2>/dev/null | sort -nu | tail -n 1
87+
)"
88+
latest_code="${latest_code:-0}"
89+
90+
if [ "$version_code" -le "$latest_code" ]; then
91+
echo "versionCode $version_code must be greater than latest beta $latest_code" >&2
92+
exit 1
93+
fi
94+
95+
if gh api "repos/${GITHUB_REPO}/git/ref/tags/${release_tag}" > /dev/null 2>&1; then
96+
echo "Tag ${release_tag} already exists" >&2
97+
exit 1
98+
fi
99+
100+
{
101+
echo "RELEASE_VERSION=${version_name}"
102+
echo "RELEASE_CODE=${version_code}"
103+
echo "RELEASE_TAG=${release_tag}"
104+
} >> "$GITHUB_ENV"
105+
106+
- name: Prepare signing
107+
env:
108+
ANDROID_KEYSTORE_BASE64: ${{ secrets.ANDROID_KEYSTORE_BASE64 }}
109+
ANDROID_KEYSTORE_PASSWORD: ${{ secrets.ANDROID_KEYSTORE_PASSWORD }}
110+
ANDROID_KEY_ALIAS: ${{ secrets.ANDROID_KEY_ALIAS }}
111+
ANDROID_KEY_PASSWORD: ${{ secrets.ANDROID_KEY_PASSWORD }}
112+
run: |
113+
test -n "$ANDROID_KEYSTORE_BASE64"
114+
test -n "$ANDROID_KEYSTORE_PASSWORD"
115+
test -n "$ANDROID_KEY_ALIAS"
116+
test -n "$ANDROID_KEY_PASSWORD"
117+
printf '%s' "$ANDROID_KEYSTORE_BASE64" | base64 --decode > release.keystore
118+
{
119+
printf 'storeFile=%s\n' "$PWD/release.keystore"
120+
printf 'storePassword=%s\n' "$ANDROID_KEYSTORE_PASSWORD"
121+
printf 'keyAlias=%s\n' "$ANDROID_KEY_ALIAS"
122+
printf 'keyPassword=%s\n' "$ANDROID_KEY_PASSWORD"
123+
} > keystore.properties
124+
125+
- name: Verify and build beta release
126+
timeout-minutes: 25
127+
run: |
128+
./gradlew --build-cache --stacktrace \
129+
:baseline-profile:assemble \
130+
:player:testDebugUnitTest \
131+
:app:testDebugUnitTest \
132+
:player:lintDebug \
133+
:app:lintDebug \
134+
:app:assembleDebug \
135+
:app:assembleRelease
136+
137+
- name: Upload lint report
138+
if: ${{ always() }}
139+
uses: actions/upload-artifact@v7.0.1
140+
with:
141+
name: typetype-beta-lint-report
142+
path: |
143+
app/build/reports/lint-results-debug.html
144+
player/build/reports/lint-results-debug.html
145+
if-no-files-found: ignore
146+
retention-days: 14
147+
148+
- name: Verify and prepare beta APK
149+
run: |
150+
mkdir -p artifacts
151+
apk="$(find app/build/outputs/apk/release -name '*.apk' | head -n 1)"
152+
test -n "$apk"
153+
build_tools="$(find "$ANDROID_HOME/build-tools" -mindepth 1 -maxdepth 1 -type d | sort -V | tail -n 1)"
154+
test -n "$build_tools"
155+
156+
"$build_tools/zipalign" -c -P 16 -v 4 "$apk"
157+
"$build_tools/apksigner" verify --verbose --print-certs "$apk"
158+
159+
apk_application_id="$("$ANDROID_HOME/cmdline-tools/latest/bin/apkanalyzer" manifest application-id "$apk")"
160+
apk_version="$("$ANDROID_HOME/cmdline-tools/latest/bin/apkanalyzer" manifest version-name "$apk")"
161+
apk_code="$("$ANDROID_HOME/cmdline-tools/latest/bin/apkanalyzer" manifest version-code "$apk")"
162+
test "$apk_application_id" = "dev.typetype.android"
163+
test "$apk_version" = "$RELEASE_VERSION"
164+
test "$apk_code" = "$RELEASE_CODE"
165+
166+
cp "$apk" "artifacts/dev.typetype.android_${RELEASE_CODE}.apk"
167+
(
168+
cd artifacts
169+
sha256sum "dev.typetype.android_${RELEASE_CODE}.apk" \
170+
> "dev.typetype.android_${RELEASE_CODE}.apk.sha256"
171+
sha256sum -c "dev.typetype.android_${RELEASE_CODE}.apk.sha256"
172+
)
173+
174+
- name: Upload beta APK
175+
uses: actions/upload-artifact@v7.0.1
176+
with:
177+
name: typetype-beta-apk
178+
path: |
179+
artifacts/*.apk
180+
artifacts/*.sha256
181+
if-no-files-found: error
182+
compression-level: 0
183+
retention-days: 30
184+
185+
- name: Publish GitHub prerelease
186+
if: ${{ github.event_name != 'pull_request' }}
187+
uses: softprops/action-gh-release@v2
188+
with:
189+
tag_name: ${{ env.RELEASE_TAG }}
190+
name: TypeType Android ${{ env.RELEASE_VERSION }}
191+
body: ${{ github.event.head_commit.message }}
192+
prerelease: true
193+
make_latest: false
194+
generate_release_notes: false
195+
target_commitish: beta
196+
files: |
197+
artifacts/*.apk
198+
artifacts/*.sha256
199+
fail_on_unmatched_files: true

‎.github/workflows/android.yml‎

Lines changed: 44 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ env:
4242
ANDROID_SDK_ROOT: /opt/android-sdk
4343
JAVA_HOME: /usr/lib/jvm/java-26-openjdk
4444
GRADLE_USER_HOME: /var/tmp/typetype-android-gradle-user-home
45+
TYPETYPE_SDK_PATH: .ci/TypeType-SDK
4546

4647
jobs:
4748
verify:
@@ -69,20 +70,34 @@ jobs:
6970
- name: Verify Android project
7071
timeout-minutes: 25
7172
run: |
72-
./gradlew --build-cache --stacktrace \
73-
:baseline-profile:assemble \
74-
:player:testDebugUnitTest \
75-
:app:testDebugUnitTest \
76-
:player:lintDebug \
77-
:app:lintDebug \
78-
:app:assembleDebug \
73+
set -euo pipefail
74+
tasks=(
75+
:baseline-profile:assemble
76+
:player:testDebugUnitTest
77+
:app:testDebugUnitTest
78+
:player:lintDebug
79+
:app:lintDebug
80+
:app:assembleDebug
7981
:app:assembleRelease
82+
)
83+
if [[ -f "$TYPETYPE_SDK_PATH/settings.gradle.kts" ]]; then
84+
tasks+=(
85+
:tv:testDebugUnitTest
86+
:tv:lintDebug
87+
:tv:assembleDebug
88+
)
89+
else
90+
echo "::notice::TV verification skipped because the private TypeType-SDK checkout is unavailable."
91+
fi
92+
./gradlew --build-cache --stacktrace "${tasks[@]}"
8093
8194
- name: Upload debug APK
8295
uses: actions/upload-artifact@v7.0.1
8396
with:
8497
name: typetype-debug-apk
85-
path: app/build/outputs/apk/debug/*.apk
98+
path: |
99+
app/build/outputs/apk/debug/*.apk
100+
tv/build/outputs/apk/debug/*.apk
86101
if-no-files-found: error
87102
compression-level: 0
88103
retention-days: 14
@@ -95,6 +110,7 @@ jobs:
95110
path: |
96111
app/build/reports/lint-results-debug.html
97112
player/build/reports/lint-results-debug.html
113+
tv/build/reports/lint-results-debug.html
98114
if-no-files-found: ignore
99115
retention-days: 14
100116

@@ -156,14 +172,26 @@ jobs:
156172
- name: Verify Android project and build release
157173
timeout-minutes: 25
158174
run: |
159-
./gradlew --build-cache --stacktrace \
160-
:baseline-profile:assemble \
161-
:player:testDebugUnitTest \
162-
:app:testDebugUnitTest \
163-
:player:lintDebug \
164-
:app:lintDebug \
165-
:app:assembleDebug \
175+
set -euo pipefail
176+
tasks=(
177+
:baseline-profile:assemble
178+
:player:testDebugUnitTest
179+
:app:testDebugUnitTest
180+
:player:lintDebug
181+
:app:lintDebug
182+
:app:assembleDebug
166183
:app:assembleRelease
184+
)
185+
if [[ -f "$TYPETYPE_SDK_PATH/settings.gradle.kts" ]]; then
186+
tasks+=(
187+
:tv:testDebugUnitTest
188+
:tv:lintDebug
189+
:tv:assembleDebug
190+
)
191+
else
192+
echo "::notice::TV verification skipped because the private TypeType-SDK checkout is unavailable."
193+
fi
194+
./gradlew --build-cache --stacktrace "${tasks[@]}"
167195
168196
- name: Upload lint report
169197
if: ${{ always() }}
@@ -173,6 +201,7 @@ jobs:
173201
path: |
174202
app/build/reports/lint-results-debug.html
175203
player/build/reports/lint-results-debug.html
204+
tv/build/reports/lint-results-debug.html
176205
if-no-files-found: ignore
177206
retention-days: 14
178207

‎.gitignore‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@ google-services.json
3131
# Android Profiling
3232
*.hprof
3333
.DS_Store
34+
__pycache__/
35+
*.py[cod]
3436

3537
# Local documentation
3638
/docs/

‎CONTRIBUTING.md‎

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,8 @@ Gradle wrapper.
3333
```sh
3434
git switch dev
3535
./gradlew :app:assembleDebug
36+
# Android TV
37+
./gradlew :tv:assembleDebug
3638
```
3739

3840
On first launch, the app asks for a TypeType instance. Use your own test
@@ -67,6 +69,8 @@ the contract advertised by the selected TypeType instance.
6769
| `player` | TypeType playback integration for Media3 |
6870
| `app/src/test` | JVM unit and repository tests |
6971
| `app/src/androidTest` | Room, Compose, platform, and device tests |
72+
| `tv/src/main` | Native Android TV UI, navigation, focus, and playback |
73+
| `tv/src/test` | Android TV JVM unit tests |
7074

7175
Most changes only touch one or two of these areas. As a rule of thumb,
7276
composables render state, repositories decide how data is loaded and cached,
@@ -121,6 +125,15 @@ Before opening a pull request, run the same core checks as CI:
121125
:app:assembleRelease
122126
```
123127

128+
For TV changes, also run:
129+
130+
```sh
131+
./gradlew --no-daemon \
132+
:tv:testDebugUnitTest \
133+
:tv:lintDebug \
134+
:tv:assembleDebug
135+
```
136+
124137
Add the checks that make sense for your change. You are not expected to own
125138
every Android version or device; if something could not be tested, mention it
126139
in the pull request so another contributor can help. Useful checks include:

‎README.md‎

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,10 @@ require Google Play Services.
2929
TypeType Android uses the TypeType Server selected during setup for extraction,
3030
playback sessions, recommendations, synchronization, and downloads.
3131

32+
The Android TV client is part of this repository in the `tv` module. It is a
33+
separate native TV application that uses the same TypeType SDK and server
34+
contracts as the mobile client.
35+
3236
## Screenshots
3337

3438
| Welcome | Add an instance | Home |
@@ -50,6 +54,19 @@ playback sessions, recommendations, synchronization, and downloads.
5054
sleep timer.
5155
- Download supported videos and import existing data.
5256

57+
## Android TV
58+
59+
Build the TV client with the included Gradle wrapper:
60+
61+
```sh
62+
./gradlew :tv:assembleDebug
63+
```
64+
65+
The TV module targets Android TV devices from API 23 onward and keeps its TV
66+
navigation, focus behavior, layouts, and playback presentation independent from
67+
the mobile UI. Local builds automatically use a sibling `TypeType-SDK`
68+
checkout; set `TYPETYPE_SDK_PATH` when the SDK is stored elsewhere.
69+
5370
## Install
5471

5572
### F-Droid

‎app/build.gradle.kts‎

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,8 @@ android {
2626
applicationId = "dev.typetype.android"
2727
minSdk = 23
2828
targetSdk = 37
29-
versionCode = 10700
30-
versionName = "1.7.0"
29+
versionCode = 10820
30+
versionName = "1.8.0"
3131
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
3232
resValue("string", "app_name", "TypeType")
3333
}
@@ -140,6 +140,10 @@ dependencies {
140140
implementation(libs.androidx.activity.compose)
141141
implementation(libs.androidx.browser)
142142
implementation(libs.androidx.lifecycle.runtime.compose)
143+
implementation(libs.jsoup)
144+
implementation(libs.unifiedpush.connector) {
145+
exclude(group = "com.google.crypto.tink", module = "tink")
146+
}
143147
implementation(libs.androidx.navigation.compose)
144148
debugImplementation(libs.androidx.compose.ui.test.manifest)
145149
debugImplementation(libs.androidx.compose.ui.tooling)

0 commit comments

Comments
 (0)