This repository has been archived by the owner on Apr 24, 2024. It is now read-only.
Check Bilibili Version #3821
This file contains 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: Check Bilibili Version | |
on: | |
workflow_dispatch: | |
inputs: | |
only_cache: | |
type: boolean | |
description: Only for cache? | |
required: true | |
default: false | |
force: | |
type: boolean | |
description: Force build? | |
required: true | |
default: false | |
schedule: | |
- cron: '1 1-10 * * 1-5' | |
# To make cache always available | |
- cron: '1 23 */5 * *' | |
# push: | |
# branches: [me] | |
concurrency: | |
group: ${{ github.workflow }} | |
cancel-in-progress: false | |
jobs: | |
check: | |
name: Check Version | |
runs-on: ubuntu-latest | |
env: | |
ONLY_CACHE: ${{ github.event.inputs.only_cache == 'true' }} | |
FORCE: ${{ github.event.inputs.force == 'true' }} | |
outputs: | |
new_bili: ${{ steps.check.outputs.new_bili }} | |
new_my: ${{ steps.check.outputs.new_my }} | |
changelog: ${{ steps.check.outputs.changelog }} | |
ver: ${{ steps.check.outputs.ver }} | |
ver_code: ${{ steps.check.outputs.ver_code }} | |
url: ${{ steps.check.outputs.url }} | |
size: ${{ steps.check.outputs.size }} | |
md5: ${{ steps.check.outputs.md5 }} | |
sn: ${{ steps.check.outputs.sn }} | |
iv: ${{ steps.check.outputs.iv }} | |
cycle: ${{ steps.check.outputs.cycle }} | |
steps: | |
- name: Check event | |
run: | | |
event_name="${{ github.event_name }}" | |
time_hour=`date +%k` | |
if [[ "$event_name" = "schedule" && $time_hour -eq 23 ]]; then | |
echo "ONLY_CACHE=true" >> $GITHUB_ENV | |
echo "Only for cache by schedule event." | |
fi | |
- name: Checkout | |
uses: actions/checkout@v3 | |
- name: Setup Python | |
if: env.ONLY_CACHE != 'true' | |
uses: actions/setup-python@v4 | |
with: | |
python-version: '3.9.x' | |
- name: Generate random number | |
id: get-random | |
run: | | |
random=`date +%s` | |
echo "random=$random" >> $GITHUB_OUTPUT | |
- name: Version file cache | |
uses: actions/cache@v3 | |
with: | |
path: version | |
key: cache-version-V40-${{ steps.get-random.outputs.random }} | |
restore-keys: cache-version-V40 | |
- name: Check version | |
if: env.ONLY_CACHE != 'true' | |
id: check | |
run: | | |
if [[ "$FORCE" != "true" && -f "version" ]]; then | |
changelog=`awk -F "=" '$1 == "changelog" {print $2}' version` | |
ver=`awk -F "=" '$1 == "ver" {print $2}' version` | |
ver_code=`awk -F "=" '$1 == "ver_code" {print $2}' version` | |
url=`awk -F "=" '$1 == "url" {print $2}' version` | |
size=`awk -F "=" '$1 == "size" {print $2}' version` | |
md5=`awk -F "=" '$1 == "md5" {print $2}' version` | |
sn=`awk -F "=" '$1 == "sn" {print $2}' version` | |
iv=`awk -F "=" '$1 == "iv" {print $2}' version` | |
cycle=`awk -F "=" '$1 == "cycle" {print $2}' version` | |
my_ver=`awk -F "=" '$1 == "my_ver" {print $2}' version` | |
else | |
ver="7.26.0"; ver_code="7260200"; sn="11711174"; iv="7260210" | |
fi | |
pip3 install -U pip | |
pip3 install -U requests | |
py_get_ver_info=$(cat <<EOM | |
import re | |
import requests | |
url = 'https://app.bilibili.com/x/v2/version/fawkes/upgrade' | |
params = { | |
'abi': 'arm64-v8a', | |
'appid': 'tv.danmaku.bili', | |
'appkey': '1d8b6e7d45233436', | |
'build': '$ver_code', | |
'channel': 'master', | |
'env': 'prod', | |
'iv': '$iv', | |
'mobi_app': 'android', | |
'nt': '1', | |
'ov': '31', | |
'platform': 'android', | |
'sn': '$sn', | |
'vn': '$ver', | |
} | |
headers = { | |
'user-agent': 'Mozilla/5.0 BiliDroid/$ver ([email protected])', | |
'app-key': 'android64', | |
'env': 'prod', | |
'buvid': 'XX61AAD69F83AE28E1FA13EDEFCA9431F1C02', | |
'cache-control': 'no-cache', | |
} | |
try: | |
resp = requests.get(url, params, headers=headers).json() | |
if resp['code'] == -304: | |
print('no') | |
else: | |
content = resp['data']['content'] | |
ver = resp['data']['version'] | |
ver_code = resp['data']['version_code'] | |
url = resp['data']['url'] | |
size = resp['data']['size'] | |
md5 = resp['data']['md5'] | |
cycle = resp['data']['cycle'] | |
sn = '' | |
sn_regex = re.compile(r'^https?://dl\.hdslb\.com/mobile/pack/android64/(\d+)/iBiliPlayer-apinkRelease-\d+\.\d+\.\d+-b\d+\.apk$') | |
if matcher := sn_regex.match(url): | |
sn = matcher.group(1) | |
iv = int(ver_code) + 10 | |
result = f'{content}|{ver}|{ver_code}|{url}|{size}|{md5}|{sn}|{iv}|{cycle}' | |
print(result.replace('\n', r'\n')) | |
except Exception: | |
print('') | |
EOM | |
) | |
n_my_ver=`awk -F "=" '$1 == "appVerName" {print $2}' gradle.properties` | |
push_event="${{ github.event_name == 'push' }}" | |
ver_info="`python3 -c "$py_get_ver_info"`" | |
function check_module_version(){ | |
if [ "$n_my_ver" != "$my_ver" ]; then | |
echo "Found new module: $n_my_ver" | |
sed -r -i "s/(my_ver)=.*/\1=$n_my_ver/" version | |
echo "new_my=1" >> $GITHUB_OUTPUT | |
echo "changelog=$changelog" >> $GITHUB_OUTPUT | |
echo "ver=$ver" >> $GITHUB_OUTPUT | |
echo "ver_code=$ver_code" >> $GITHUB_OUTPUT | |
echo "url=$url" >> $GITHUB_OUTPUT | |
echo "size=$size" >> $GITHUB_OUTPUT | |
echo "md5=$md5" >> $GITHUB_OUTPUT | |
echo "sn=$sn" >> $GITHUB_OUTPUT | |
echo "iv=$iv" >> $GITHUB_OUTPUT | |
echo "cycle=$cycle" >> $GITHUB_OUTPUT | |
else | |
echo "Not found new module." | |
echo "new_my=0" >> $GITHUB_OUTPUT | |
fi | |
} | |
if [ -z "$ver_info" ]; then | |
exit 0 | |
elif [ "$push_event" = "true" ]; then | |
check_module_version | |
exit 0 | |
elif [ "$ver_info" = "no" ]; then | |
echo "Not found new bilibili." | |
echo "new_bili=0" >> $GITHUB_OUTPUT | |
check_module_version | |
exit 0 | |
fi | |
OLD_IFS="$IFS" | |
IFS="|" | |
infos=($ver_info) | |
IPS="$OLD_IFS" | |
n_changelog="${infos[0]}" | |
n_ver="${infos[1]}" | |
n_ver_code="${infos[2]}" | |
n_url="${infos[3]}" | |
n_size="${infos[4]}" | |
n_md5="${infos[5]}" | |
n_sn="${infos[6]}" | |
n_iv="${infos[7]}" | |
n_cycle="${infos[8]}" | |
echo "Found new bilibili: $n_ver ($n_ver_code) b$n_sn" | |
echo "Changelog: $n_changelog" | |
echo "Download url: $n_url" | |
if [[ -n "$my_ver" && "$n_my_ver" != "$my_ver" ]]; then | |
echo "Found new module: $n_my_ver" | |
echo "new_my=1" >> $GITHUB_OUTPUT | |
fi | |
echo "changelog=$n_changelog" > version | |
echo "ver=$n_ver" >> version | |
echo "ver_code=$n_ver_code" >> version | |
echo "url=$n_url" >> version | |
echo "size=$n_size" >> version | |
echo "md5=$n_md5" >> version | |
echo "sn=$n_sn" >> version | |
echo "iv=$n_iv" >> version | |
echo "cycle=$n_cycle" >> version | |
echo "my_ver=$n_my_ver" >> version | |
echo "new_bili=1" >> $GITHUB_OUTPUT | |
echo "changelog=$n_changelog" >> $GITHUB_OUTPUT | |
echo "ver=$n_ver" >> $GITHUB_OUTPUT | |
echo "ver_code=$n_ver_code" >> $GITHUB_OUTPUT | |
echo "url=$n_url" >> $GITHUB_OUTPUT | |
echo "size=$n_size" >> $GITHUB_OUTPUT | |
echo "md5=$n_md5" >> $GITHUB_OUTPUT | |
echo "sn=$n_sn" >> $GITHUB_OUTPUT | |
echo "iv=$n_iv" >> $GITHUB_OUTPUT | |
echo "cycle=$n_cycle" >> $GITHUB_OUTPUT | |
module: | |
name: Build Module | |
runs-on: ubuntu-latest | |
needs: check | |
if: needs.check.outputs.new_bili == '1' || needs.check.outputs.new_my == '1' | |
env: | |
CCACHE_DIR: ${{ github.workspace }}/.ccache | |
CCACHE_COMPILERCHECK: "%compiler% -dumpmachine; %compiler% -dumpversion" | |
CCACHE_NOHASHDIR: true | |
CCACHE_MAXSIZE: 1G | |
steps: | |
- name: Checkout | |
uses: actions/checkout@v3 | |
with: | |
submodules: 'recursive' | |
fetch-depth: 0 | |
- name: Set up JDK 17 | |
uses: actions/setup-java@v3 | |
with: | |
distribution: 'temurin' | |
java-version: 17 | |
cache: 'gradle' | |
- name: Retrieve version | |
run: | | |
version=`awk -F "=" '$1 == "appVerName" {print $2}' gradle.properties` | |
if [[ "${{ needs.check.outputs.new_bili }}" = "1" && "${{ needs.check.outputs.new_my }}" != "1" ]]; then | |
commit_count=`git rev-list HEAD --count` | |
version="${version}.r${commit_count}" | |
fi | |
echo "VERSION=$version" >> $GITHUB_ENV | |
- name: Set up ccache | |
uses: hendrikmuhs/[email protected] | |
with: | |
key: ${{ runner.os }}-${{ github.sha }} | |
restore-keys: ${{ runner.os }} | |
- name: Generate signing config | |
run: | | |
key_base64="${{ secrets.SIGNING_KEY }}" | |
echo -n "$key_base64" | base64 -d > app/signing.jks | |
echo "releaseStoreFile=signing.jks" >> gradle.properties | |
echo "releaseStorePassword=android" >> gradle.properties | |
echo "releaseKeyAlias=androiddebugkey" >> gradle.properties | |
echo "releaseKeyPassword=android" >> gradle.properties | |
- name: Build with Gradle | |
run: ./gradlew --no-daemon --build-cache -PappVerName=$VERSION assembleRelease | |
- name: Upload built release apk | |
if: success() | |
uses: actions/upload-artifact@v3 | |
with: | |
name: release | |
path: ${{ github.workspace }}/app/release/BiliRoamingX-v${{ env.VERSION }}.apk | |
patch: | |
name: Patch APK | |
runs-on: ubuntu-latest | |
needs: [ check, module ] | |
if: needs.check.outputs.new_bili == '1' || needs.check.outputs.new_my == '1' | |
steps: | |
- name: Set up JDK 17 | |
uses: actions/setup-java@v3 | |
with: | |
distribution: 'temurin' | |
java-version: 17 | |
- name: Set up Android SDK | |
run: | | |
echo "ANDROID_HOME=/usr/local/lib/android/sdk" >> $GITHUB_ENV | |
echo "/usr/local/lib/android/sdk/build-tools/32.0.0" >> $GITHUB_PATH | |
- name: Set up Python | |
uses: actions/setup-python@v4 | |
with: | |
python-version: '3.x' | |
- name: Prepare Python packages | |
run: | | |
pip install -U pip | |
pip install -U wheel | |
pip install pyrogram==2.0.59 tgcrypto==1.2.4 | |
pip install -U requests | |
- name: Download release artifact | |
uses: actions/download-artifact@v3 | |
with: | |
name: release | |
- name: Get xposed module path | |
run: | | |
module_apk=`echo BiliRoamingX-*.apk` | |
echo "MODULE_APK=$module_apk" >> $GITHUB_ENV | |
- name: Download bilibili apk | |
run: wget -nv -O Bilibili.apk ${{ needs.check.outputs.url }} | |
- name: Get app info | |
run: | | |
echo "VER_CODE=`aapt dump badging Bilibili.apk | awk -F "[ =']" '$6 == "versionCode" {print $8}'`" >> $GITHUB_ENV | |
echo "VER_NAME=`aapt dump badging Bilibili.apk | awk -F "[ =']" '$10 == "versionName" {print $12}'`" >> $GITHUB_ENV | |
echo "M_VER_CODE=`aapt dump badging $MODULE_APK | awk -F "[ =']" '$6 == "versionCode" {print $8}'`" >> $GITHUB_ENV | |
echo "M_VER_NAME=`aapt dump badging $MODULE_APK | awk -F "[ =']" '$10 == "versionName" {print $12}'`" >> $GITHUB_ENV | |
- name: Append version | |
run: | | |
sn="${{ needs.check.outputs.sn }}" | |
mkdir patched | |
mv Bilibili.apk patched/Bili-v$VER_NAME-b$sn-official.apk | |
echo "BILIBILI_NAME=Bili-v$VER_NAME-b$sn" >> $GITHUB_ENV | |
echo "BILIBILI_APK=patched/Bili-v$VER_NAME-b$sn-official.apk" >> $GITHUB_ENV | |
- name: Download jar patcher | |
run: wget -nv -O lspatch.jar https://github.com/LSPosed/LSPatch/releases/download/v0.5.1/lspatch.jar | |
- name: Apply patch | |
run: | | |
echo "Patch with builtin module." | |
java -jar lspatch.jar -m $MODULE_APK --sigbypasslv 2 $BILIBILI_APK | |
patched_apk=`echo $BILIBILI_NAME-*.apk` | |
renamed=patched/$BILIBILI_NAME-m$M_VER_CODE-with-module.apk | |
mv $patched_apk $renamed | |
echo "PATCHED_APK=$renamed" >> $GITHUB_ENV | |
- name: Calculate size and md5 | |
id: extra-info | |
run: | | |
size=`du -b $PATCHED_APK | awk '{print $1}'` | |
md5=`md5sum $PATCHED_APK | awk '{print $1}'` | |
build_time=`date +%s` | |
echo "size=$size" >> $GITHUB_OUTPUT | |
echo "md5=$md5" >> $GITHUB_OUTPUT | |
echo "build_time=$build_time" >> $GITHUB_OUTPUT | |
- name: Release patched-builtin apk | |
uses: zjns/action-gh-release@v2 | |
with: | |
token: ${{ secrets.HUB_TOKEN }} | |
tag_name: ${{ format('bili-v{0}-b{1}-m{2}', env.VER_NAME, needs.check.outputs.sn, env.M_VER_CODE) }} | |
name: ${{ format('{0} {1} {2} {3} {4} {5} {6} {7}', env.VER_NAME, env.VER_CODE, env.M_VER_NAME, env.M_VER_CODE, needs.check.outputs.sn, steps.extra-info.outputs.size, steps.extra-info.outputs.md5, steps.extra-info.outputs.build_time) }} | |
body: ${{ needs.check.outputs.changelog }} | |
prerelease: false | |
draft: false | |
files: ${{ env.PATCHED_APK }} | |
- name: Fetch upstream changelog | |
if: needs.check.outputs.new_my == '1' | |
run: | | |
py_get_up_changelog=$(cat <<EOM | |
import requests | |
url = 'https://api.github.com/repos/yujincheng08/BiliRoaming/releases/tags/v$M_VER_NAME' | |
headers = { | |
'Authorization': 'token ${{ secrets.HUB_TOKEN }}' | |
} | |
changelog = '可直接更新,原版更新日志请看 https://github.com/yujincheng08/BiliRoaming/releases/tag/v$M_VER_NAME' | |
try: | |
resp = requests.get(url, headers=headers).json() | |
changelog = resp['body'].split('更新日志\r\n', 1)[1].replace('\r', '') | |
changelog = f'可直接更新,原版更新日志:\n{changelog}' | |
print(changelog) | |
except Exception: | |
print(changelog) | |
EOM | |
) | |
up_changelog="`python -c "$py_get_up_changelog"`" | |
echo -n "$up_changelog" > up_changelog.txt | |
- name: Release module apk | |
if: needs.check.outputs.new_my == '1' | |
uses: zjns/action-gh-release@v2 | |
with: | |
token: ${{ secrets.HUB_TOKEN }} | |
tag_name: ${{ format('v{0}', env.M_VER_NAME) }} | |
name: ${{ env.M_VER_NAME }} | |
body: ${{ format('可直接更新,原版更新日志请看 https://github.com/yujincheng08/BiliRoaming/releases/tag/v{0}', env.M_VER_NAME) }} | |
body_path: up_changelog.txt | |
prerelease: false | |
draft: false | |
files: ${{ env.MODULE_APK }} | |
- name: Release module apk (CI) | |
#if: needs.check.outputs.new_my != '1' | |
if: ${{ 'A' == 'B' }} | |
uses: zjns/action-gh-release@v2 | |
with: | |
token: ${{ secrets.HUB_TOKEN }} | |
tag_name: ${{ format('v{0}', env.M_VER_NAME) }} | |
name: ${{ env.M_VER_NAME }} | |
body: 'CI版本' | |
prerelease: false | |
draft: false | |
files: ${{ env.MODULE_APK }} | |
- name: Send to Telegram (New Bilibili) | |
shell: python | |
#if: needs.check.outputs.new_bili == '1' | |
if: ${{ 'A' == 'B' }} | |
env: | |
API_ID: ${{ secrets.TELEGRAM_API_ID }} | |
API_HASH: ${{ secrets.TELEGRAM_API_HASH }} | |
CHANNEL_ID: ${{ secrets.TELEGRAM_TO }} | |
CHANNEL_ID_ME: ${{ secrets.TELEGRAM_TO_ME }} | |
SESSION: ${{ secrets.TELEGRAM_SESSION }} | |
RUN_URL: ${{ format('{0}/{1}/actions/runs/{2}', github.server_url, github.repository, github.run_id) }} | |
run: | | |
import asyncio | |
import inspect | |
import os | |
from pyrogram import Client | |
from pyrogram.types import InputMediaDocument | |
async def main(): | |
session = os.environ["SESSION"] | |
bot = Client( | |
"client", | |
session_string=session, | |
) | |
async with bot: | |
ver_name = os.environ["VER_NAME"] | |
ver_code = os.environ["VER_CODE"] | |
m_ver_name = os.environ["M_VER_NAME"] | |
m_ver_code = os.environ["M_VER_CODE"] | |
channel_id = int(os.environ["CHANNEL_ID"]) | |
channel_id_me = int(os.environ["CHANNEL_ID_ME"]) | |
changelog = "${{ needs.check.outputs.changelog }}" | |
cycle = "${{ needs.check.outputs.cycle }}" | |
msg_p1 = "#Bilibili #BiliRoaming" | |
msg_p2 = f"发现新版本哔哩哔哩!\n\n更新日志:\n<pre>{changelog}</pre>" | |
msg_p3 = inspect.cleandoc(""" | |
文件说明: | |
- 以<b>official</b>结尾的为官方原版 | |
- 以<b>with-module</b>结尾的为内置模块LSPatch版本 | |
- <b>内置版</b>可在<b>应用内</b>收到新的内置修改版更新 | |
""") | |
msg_p4 = f"Bilibili: {ver_name} ({ver_code}) 64位 本版第{cycle}次迭代\nBiliRoamingX: {m_ver_name} ({m_ver_code})" | |
msg_p5 = f"Auto generated by [me]({os.environ['RUN_URL']})." | |
caption = "{}\n{}\n\n{}\n\n{}\n{}".format(msg_p1, msg_p2, msg_p3, msg_p4, msg_p5) | |
official = InputMediaDocument(media=os.environ["BILIBILI_APK"], caption="") | |
patched = InputMediaDocument(media=os.environ["PATCHED_APK"], caption="") | |
module = InputMediaDocument(media=os.environ["MODULE_APK"], caption=caption) | |
result = await bot.send_media_group( | |
chat_id=channel_id_me, | |
media=[official, patched, module], | |
) | |
file_ids = [m.document.file_id for m in result] | |
official.media = file_ids[0] | |
patched.media = file_ids[1] | |
module.media = file_ids[2] | |
await bot.send_media_group( | |
chat_id=channel_id, | |
media=[official, patched, module], | |
) | |
async def wait(): | |
try: | |
await asyncio.wait_for(main(), timeout=600) | |
except asyncio.TimeoutError: | |
print("message send timeout!!!") | |
exit(1) | |
asyncio.run(wait()) | |
- name: Send to Telegram (New module) | |
shell: python | |
#if: needs.check.outputs.new_my == '1' | |
if: ${{ 'A' == 'B' }} | |
env: | |
API_ID: ${{ secrets.TELEGRAM_API_ID }} | |
API_HASH: ${{ secrets.TELEGRAM_API_HASH }} | |
CHANNEL_ID: ${{ secrets.TELEGRAM_TO }} | |
CHANNEL_ID_ME: ${{ secrets.TELEGRAM_TO_ME }} | |
SESSION: ${{ secrets.TELEGRAM_SESSION }} | |
RUN_URL: ${{ format('{0}/{1}/actions/runs/{2}', github.server_url, github.repository, github.run_id) }} | |
run: | | |
import asyncio | |
import os | |
from pyrogram import Client | |
from pyrogram.types import InputMediaDocument | |
async def main(): | |
session = os.environ["SESSION"] | |
bot = Client( | |
"client", | |
session_string=session, | |
) | |
async with bot: | |
ver_name = os.environ["VER_NAME"] | |
ver_code = os.environ["VER_CODE"] | |
m_ver_name = os.environ["M_VER_NAME"] | |
m_ver_code = os.environ["M_VER_CODE"] | |
channel_id = int(os.environ["CHANNEL_ID"]) | |
channel_id_me = int(os.environ["CHANNEL_ID_ME"]) | |
msg_p1 = "#Bilibili #BiliRoaming" | |
msg_p2 = "发现新版本漫游!" | |
msg_p3 = "可在<b>应用内</b>收到新的内置修改版更新" | |
msg_p4 = f"Bilibili: {ver_name} ({ver_code}) 64位\nBiliRoamingX: {m_ver_name} ({m_ver_code})" | |
msg_p5 = f"Auto generated by [me]({os.environ['RUN_URL']})." | |
caption = "{}\n{}\n\n{}\n\n{}\n{}".format(msg_p1, msg_p2, msg_p3, msg_p4, msg_p5) | |
module = InputMediaDocument(media=os.environ["MODULE_APK"], caption="") | |
patched = InputMediaDocument(media=os.environ["PATCHED_APK"], caption=caption) | |
result = await bot.send_media_group( | |
chat_id=channel_id_me, | |
media=[module, patched], | |
) | |
file_ids = [m.document.file_id for m in result] | |
module.media = file_ids[0] | |
patched.media = file_ids[1] | |
await bot.send_media_group( | |
chat_id=channel_id, | |
media=[module, patched], | |
) | |
async def wait(): | |
try: | |
await asyncio.wait_for(main(), timeout=600) | |
except asyncio.TimeoutError: | |
print("message send timeout!!!") | |
exit(1) | |
asyncio.run(wait()) |