Skip to content

Commit f4aaa5c

Browse files
authored
Merge pull request #136 from kalzEOS/feat/player-consistent-time-format
Ship TV performance and stability pass in v3.3.6
2 parents 3b43eeb + 13b674d commit f4aaa5c

22 files changed

Lines changed: 1131 additions & 107 deletions
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
name: Pre-release Channel
2+
3+
on:
4+
workflow_dispatch:
5+
inputs:
6+
target_branch:
7+
description: Branch to build from
8+
required: true
9+
tag_name:
10+
description: Pre-release tag (example XtreamPlayerv3.3.6-rc1)
11+
required: true
12+
release_title:
13+
description: Release title (example Xtream Player v3.3.6-rc1)
14+
required: true
15+
release_notes:
16+
description: Release notes (must start with # Changes:)
17+
required: true
18+
19+
jobs:
20+
publish-pre-release:
21+
runs-on: ubuntu-latest
22+
permissions:
23+
contents: write
24+
steps:
25+
- name: Checkout target branch
26+
uses: actions/checkout@v4
27+
with:
28+
ref: ${{ inputs.target_branch }}
29+
30+
- name: Set up JDK 17
31+
uses: actions/setup-java@v4
32+
with:
33+
distribution: temurin
34+
java-version: "17"
35+
cache: gradle
36+
37+
- name: Validate Metadata
38+
run: |
39+
set -euo pipefail
40+
notes_file="$(mktemp)"
41+
printf '%s\n' "${{ inputs.release_notes }}" > "${notes_file}"
42+
./scripts/validate_release_metadata.sh \
43+
"${{ inputs.tag_name }}" \
44+
"${{ inputs.release_title }}" \
45+
"${notes_file}" \
46+
"true" \
47+
"${{ inputs.target_branch }}"
48+
49+
- name: Build Release APK
50+
run: |
51+
set -euo pipefail
52+
./gradlew :app:assembleRelease --stacktrace
53+
54+
- name: Resolve APK Path
55+
id: apk
56+
run: |
57+
set -euo pipefail
58+
apk_path="$(ls -1 app/build/outputs/apk/release/*.apk | head -n 1)"
59+
if [[ -z "${apk_path}" ]]; then
60+
echo "No APK found."
61+
exit 1
62+
fi
63+
echo "apk_path=${apk_path}" >> "${GITHUB_OUTPUT}"
64+
65+
- name: Publish Pre-release
66+
uses: softprops/action-gh-release@v2
67+
with:
68+
tag_name: ${{ inputs.tag_name }}
69+
target_commitish: ${{ inputs.target_branch }}
70+
name: ${{ inputs.release_title }}
71+
body: ${{ inputs.release_notes }}
72+
prerelease: true
73+
files: ${{ steps.apk.outputs.apk_path }}
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
name: Release Safety Rails
2+
3+
on:
4+
release:
5+
types: [published, edited]
6+
7+
jobs:
8+
validate-release:
9+
runs-on: ubuntu-latest
10+
steps:
11+
- name: Checkout
12+
uses: actions/checkout@v4
13+
14+
- name: Validate Metadata
15+
env:
16+
TAG_NAME: ${{ github.event.release.tag_name }}
17+
RELEASE_TITLE: ${{ github.event.release.name }}
18+
RELEASE_NOTES: ${{ github.event.release.body }}
19+
IS_PRERELEASE: ${{ github.event.release.prerelease }}
20+
TARGET_BRANCH: ${{ github.event.release.target_commitish }}
21+
run: |
22+
set -euo pipefail
23+
title="${RELEASE_TITLE:-${TAG_NAME}}"
24+
notes_file="$(mktemp)"
25+
printf '%s\n' "${RELEASE_NOTES}" > "${notes_file}"
26+
./scripts/validate_release_metadata.sh \
27+
"${TAG_NAME}" \
28+
"${title}" \
29+
"${notes_file}" \
30+
"${IS_PRERELEASE}" \
31+
"${TARGET_BRANCH}"
32+
33+
- name: Validate Release Assets
34+
env:
35+
TAG_NAME: ${{ github.event.release.tag_name }}
36+
IS_PRERELEASE: ${{ github.event.release.prerelease }}
37+
run: |
38+
set -euo pipefail
39+
version="${TAG_NAME#XtreamPlayerv}"
40+
apk_count="$(jq '[.release.assets[] | select(.name | endswith(".apk"))] | length' "${GITHUB_EVENT_PATH}")"
41+
if [[ "${apk_count}" -lt 1 ]]; then
42+
echo "Release must include at least one APK asset."
43+
exit 1
44+
fi
45+
bad_assets="$(jq -r '.release.assets[] | .name' "${GITHUB_EVENT_PATH}" | awk -v v="${version}" 'index($0, v)==0')"
46+
if [[ -n "${bad_assets}" ]]; then
47+
echo "Every release asset name must include version ${version}."
48+
echo "${bad_assets}"
49+
exit 1
50+
fi

.github/workflows/tv-qa.yml

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
name: TV QA
2+
3+
on:
4+
pull_request:
5+
push:
6+
branches:
7+
- main
8+
- "feat/**"
9+
10+
jobs:
11+
qa:
12+
runs-on: ubuntu-latest
13+
timeout-minutes: 30
14+
steps:
15+
- name: Checkout
16+
uses: actions/checkout@v4
17+
18+
- name: Set up JDK 17
19+
uses: actions/setup-java@v4
20+
with:
21+
distribution: temurin
22+
java-version: "17"
23+
cache: gradle
24+
25+
- name: Compile + Unit Tests + Lint
26+
run: |
27+
set -euo pipefail
28+
./gradlew :app:compileDebugKotlin :app:testDebugUnitTest :app:lintDebug --stacktrace
29+
30+
- name: Upload Lint Report
31+
if: always()
32+
uses: actions/upload-artifact@v4
33+
with:
34+
name: lint-report
35+
path: app/build/reports/lint-results-debug.html
36+
if-no-files-found: ignore
37+
38+
- name: Upload Unit Test Report
39+
if: always()
40+
uses: actions/upload-artifact@v4
41+
with:
42+
name: unit-test-report
43+
path: app/build/reports/tests/testDebugUnitTest
44+
if-no-files-found: ignore

app/build.gradle.kts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@ import java.util.Properties
33
import org.gradle.api.provider.Property
44
import org.jetbrains.kotlin.gradle.dsl.JvmTarget
55

6-
val appVersionCode = 132
7-
val appVersionName = "3.3.5"
6+
val appVersionCode = 133
7+
val appVersionName = "3.3.6"
88

99
plugins {
1010
alias(libs.plugins.android.application)
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
package com.example.xtreamplayer
2+
3+
import android.view.KeyEvent
4+
import android.view.View
5+
import androidx.test.core.app.ActivityScenario
6+
import androidx.test.ext.junit.runners.AndroidJUnit4
7+
import org.junit.Assert.assertFalse
8+
import org.junit.Test
9+
import org.junit.runner.RunWith
10+
11+
@RunWith(AndroidJUnit4::class)
12+
class TvDpadSmokeTest {
13+
14+
@Test
15+
fun dpadTraversalDoesNotCloseActivity() {
16+
ActivityScenario.launch(MainActivity::class.java).use { scenario ->
17+
scenario.onActivity { activity ->
18+
val root = activity.findViewById<View>(android.R.id.content)
19+
val keys =
20+
listOf(
21+
KeyEvent.KEYCODE_DPAD_DOWN,
22+
KeyEvent.KEYCODE_DPAD_DOWN,
23+
KeyEvent.KEYCODE_DPAD_RIGHT,
24+
KeyEvent.KEYCODE_DPAD_LEFT,
25+
KeyEvent.KEYCODE_DPAD_UP,
26+
KeyEvent.KEYCODE_DPAD_CENTER
27+
)
28+
keys.forEach { keyCode ->
29+
root.dispatchKeyEvent(KeyEvent(KeyEvent.ACTION_DOWN, keyCode))
30+
root.dispatchKeyEvent(KeyEvent(KeyEvent.ACTION_UP, keyCode))
31+
}
32+
assertFalse(activity.isFinishing)
33+
}
34+
}
35+
}
36+
}

0 commit comments

Comments
 (0)