From 5890d96ddae80f943db62b3cbc8dbbc5fdb9b66b Mon Sep 17 00:00:00 2001 From: luvletter2333 Date: Sat, 21 Jan 2023 23:31:27 +0800 Subject: [PATCH] ci: use script to publish release and CI builds --- .github/scripts/upload.py | 133 ++++++++++++++++++++++++++++++++++ .github/workflows/debug.yml | 58 ++++++++++++--- .github/workflows/release.yml | 113 +++-------------------------- TMessagesProj/build.gradle | 9 ++- gradle.properties | 2 +- 5 files changed, 199 insertions(+), 116 deletions(-) create mode 100644 .github/scripts/upload.py diff --git a/.github/scripts/upload.py b/.github/scripts/upload.py new file mode 100644 index 000000000..908070365 --- /dev/null +++ b/.github/scripts/upload.py @@ -0,0 +1,133 @@ +import requests +import sys +import os + +def read_env(key): + if key in os.environ: + return os.environ[key] + else: + return "" + +APK_FOLDER = "apks" +API_PREFIX = "http://127.0.0.1:8081/bot" + os.environ["BOT_TOKEN"] + "/" + +BOT_TAGET = read_env("BOT_TARGET") +ADMIN_USERID = BOT_TAGET.replace("-100","") + +VERSION_NAME = read_env("VERSION_NAME") +VERSION_CODE = read_env("VERSION_CODE") +COMMIT_HASH = read_env("GITHUB_SHA") +COMMIT_MESSAGE = read_env("COMMIT_MESSAGE") + +APK_CHANNEL_ID = "@NekoXApks" +UPDATE_CHANNEL_ID = "@NekogramX" +UPDATE_METADATA_CHANNEL_ID = "@nekox_update_metadata" +CI_CHANNEL_ID = "@NekoX_CI" + +def generateReleaseMessage(first_apk_message_id, release_text) -> str: + rel_type = 'PRE_RELEASE' if 'preview' in VERSION_NAME else 'RELEASE' + return f""" +#{rel_type} [ ](https://t.me/{APK_CHANNEL_ID.replace("@","")}/{first_apk_message_id + 1}) *{VERSION_NAME}* + +{release_text} + +[GitHub Release](https://github.com/NekoX-Dev/NekoX/releases/{VERSION_NAME}) | [Apks](https://t.me/{APK_CHANNEL_ID.replace("@","")}/{first_apk_message_id}) | [Check Update](tg://update/) +""" + +def waitReply(mid): + last_update = 0 + while True: + print(f"Waiting reply for {mid} offset {last_update}...") + resp = requests.post(API_PREFIX + "getUpdates", json={"allowed_updates":["message"], "timeout": 20, "offset": last_update + 1}) + resp = resp.json() + if not resp["ok"]: + continue + resp = resp["result"] + for update in resp: + if 'message' in update: + msg = update["message"] + if 'from' in msg and str(msg['from']["id"]) == ADMIN_USERID: + if 'reply_to_message' in msg and str(msg["reply_to_message"]["message_id"]) == str(mid): + return msg + for update in resp: + last_update = max(last_update, update["update_id"]) + + +def sendMessage(message, user_id = BOT_TAGET) -> int: + data = { + "chat_id" : user_id, + "text": message, + "parse_mode": "Markdown" + } + resp = requests.post(API_PREFIX + "sendMessage", json=data).json() + # print(resp) + return int(resp["result"]["message_id"]) + + +def sendDocument(user_id, path, message = ""): + files = {'document': open(path, 'rb')} + data = {'chat_id': user_id, 'caption': message, 'parse_mode': 'Markdown'} + response = requests.post(API_PREFIX + "sendDocument", files=files, data=data) + # print(response.json()) + + +def sendRelease(): + apks = os.listdir(APK_FOLDER) + apks.sort() + # print(apks) + + # read message from admin + mid = sendMessage(f"Please reply the release message for the version {VERSION_NAME},{VERSION_CODE}:", user_id=BOT_TAGET) + admin_resp = waitReply(mid) + # print(admin_resp) + release_text = admin_resp["text"] + + # send message and apks to APK channel + message = f"=== {VERSION_NAME} ===" + apk_channel_first_id = sendMessage(message, user_id=APK_CHANNEL_ID) + + for apk in apks: + path = os.path.join(APK_FOLDER, apk) + sendDocument(user_id=APK_CHANNEL_ID, path=path) + + # generate release message and send to update channel + release_msg = generateReleaseMessage(apk_channel_first_id, release_text) + sendMessage(release_msg, user_id=UPDATE_CHANNEL_ID) + + # send release message to metadata channel + mid = sendMessage(release_text, user_id=UPDATE_METADATA_CHANNEL_ID) + meta_msg = f"{VERSION_NAME},{VERSION_CODE},{apk_channel_first_id},{mid}" + sendMessage(meta_msg, user_id=UPDATE_METADATA_CHANNEL_ID) + + +def sendCIRelease(): + apks = os.listdir(APK_FOLDER) + apks.sort() + apk = os.path.join(APK_FOLDER, apks[0]) + message = f"CI Build\n\n{COMMIT_MESSAGE}\n\n{COMMIT_HASH[0:8]}" + sendDocument(user_id=CI_CHANNEL_ID, path = apk, message=message) + + +if __name__ == '__main__': + if len(sys.argv) != 2: + print("Run Type: release, ci, debug") + os._exit(1) + mode = sys.argv[1] + try: + if mode == "release": + sendRelease() + elif mode == "ci": + if COMMIT_MESSAGE.startswith("ci"): + CI_CHANNEL_ID = BOT_TAGET + sendCIRelease() + elif mode == "debug": + APK_CHANNEL_ID = "@test_channel_nekox" + UPDATE_CHANNEL_ID = "@test_channel_nekox" + UPDATE_METADATA_CHANNEL_ID = "@test_channel_nekox" + sendRelease() + else: + os._exit(1) + except Exception as e: + print(e) + os._exit(1) + diff --git a/.github/workflows/debug.yml b/.github/workflows/debug.yml index 729245da1..3c03e37dd 100644 --- a/.github/workflows/debug.yml +++ b/.github/workflows/debug.yml @@ -434,28 +434,68 @@ jobs: with: name: telegram-bot-api-binary path: . - - name: Debug Build + - name: CI Build run: | export LOCAL_PROPERTIES="${{ secrets.LOCAL_PROPERTIES }}" export DEBUG_BUILD=true + export NATIVE_TARGET=universal ./gradlew TMessagesProj:assembleMiniRelease - - name: Send Build + + APK=$(find TMessagesProj/build/outputs/apk/mini/release -name 'NekoX*.apk') + echo "APK=$APK" >> $GITHUB_ENV + VERSION_CODE=$(grep -E "def verCode = ([0-9]+)" TMessagesProj/build.gradle | sed "s/def verCode = //") + VERSION_NAME=$(grep -E "def verName = " TMessagesProj/build.gradle | sed "s/def verName = //" | sed "s/\"//g") + echo "VERSION_CODE=$VERSION_CODE" >> $GITHUB_ENV + echo "VERSION_NAME=VERSION_NAME" >> $GITHUB_ENV + - uses: actions/upload-artifact@v2 + with: + name: ci-apk + path: ${{ env.APK }} + upload: + name: Upload Apks to Telegram + runs-on: ubuntu-latest + needs: + - build-dev + - telegram-bot-api + steps: + - name: Download artifacts + uses: actions/download-artifact@v2 + with: + name: ci-apk + path: apks + - name: Download Telegram Bot API Binary + uses: actions/download-artifact@master + with: + name: telegram-bot-api-binary + path: . + - name: Install Python Environment + run: | + sudo apt install python3 python3-pip -y + pip3 install requests + - name: Upload run: | chmod +x telegram-bot-api-binary function start() { ./telegram-bot-api-binary --api-id=21724 --api-hash=3e0cb5efcd52300aec5994fdfc5bdc16 --local 2>&1 > /dev/null & + sleep 5 } start curl http://127.0.0.1:8081/ || start curl http://127.0.0.1:8081/ || start curl http://127.0.0.1:8081/ || start - apk=$(find TMessagesProj/build/outputs/apk/mini/release -name 'NekoX*.apk' | head -n 1) - curl http://127.0.0.1:8081/bot${{ secrets.HELPER_BOT_TOKEN }}/sendDocument \ - -X POST \ - -F chat_id="${{ secrets.HELPER_BOT_TARGET }}" \ - -F document="@$apk" \ - -F caption="${{ github.event.head_commit.message }}\n$GITHUB_SHA" \ - --silent --show-error --fail >/dev/null + curl http://127.0.0.1:8081/ || start + + curl https://raw.githubusercontent.com/NekoX-Dev/NekoX/dev/.github/scripts/upload.py -o upload.py + + export BOT_TOKEN=${{ secrets.HELPER_BOT_TOKEN }} + export BOT_TARGET=${{ secrets.HELPER_BOT_TARGET }} + export COMMIT_MESSAGE="${{ github.event.head_commit.message }}" + export VERSION_NAME="${{ env.VERSION_NAME }}" + export VERSION_CODE="${{ env.VERSION_CODE }}" + echo ${{ env.VERSION_NAME }} + + python3 upload.py ci + pkill telegram-bot telegram-bot-api: diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index b8228ceec..0545b219e 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -370,7 +370,9 @@ jobs: - build - telegram-bot-api steps: - - name: Donwload Artifacts + - name: Checkout + uses: actions/checkout@v2 + - name: Download Artifacts uses: actions/download-artifact@v2 with: path: artifacts @@ -384,116 +386,21 @@ jobs: chmod +x telegram-bot-api-binary function start() { ./telegram-bot-api-binary --api-id=21724 --api-hash=3e0cb5efcd52300aec5994fdfc5bdc16 --local 2>&1 > /dev/null & + sleep 5 } start curl http://127.0.0.1:8081/ || start curl http://127.0.0.1:8081/ || start curl http://127.0.0.1:8081/ || start - curl http://127.0.0.1:8081/bot${{ secrets.TELEGRAM_TOKEN }}/sendMessage \ - -X POST \ - -F chat_id="${{ secrets.TELEGRAM_CHANNEL }}" \ - -F text="==== ${{ github.event.inputs.tag }} ====" \ - --silent --show-error --fail >/dev/null mkdir apks find artifacts -name "*.apk" -exec cp {} apks \; - function upload() { - for apk in $@; do - echo ">> Uploading $apk" - curl http://127.0.0.1:8081/bot${{ secrets.TELEGRAM_TOKEN }}/sendDocument \ - -X POST \ - -F chat_id="${{ secrets.TELEGRAM_CHANNEL }}" \ - -F document="@$apk" \ - --retry 5 \ - --retry-delay 5 \ - --silent --show-error --fail >/dev/null - sleep 1 - done - } - upload apks/NekoX-*-mini-*-release.apk - upload apks/NekoX-*-mini-*-releaseNoGcm.apk - upload apks/NekoX-*-full-*-release.apk - upload apks/NekoX-*-full-*-releaseNoGcm.apk + curl https://raw.githubusercontent.com/NekoX-Dev/NekoX/dev/.github/scripts/upload.py -o upload.py + export BOT_TOKEN="${{ secrets.HELPER_BOT_TOKEN }}" + export BOT_TARGET="${{ secrets.HELPER_BOT_TARGET }}" + export VERSION_CODE="$(grep -E "def verCode = ([0-9]+)" TMessagesProj/build.gradle | sed "s/def verCode = //")" + export VERSION_NAME="$(grep -E "def verName = " TMessagesProj/build.gradle | sed "s/def verName = //" | sed "s/\"//g")" + python3 upload.py release pkill telegram-bot - play: - name: Publish to Play Store - if: github.event.inputs.play != 'y' - runs-on: ubuntu-latest - needs: - - native - - v2ray - - shadowsocks - - shadowsocksr - steps: - - name: Checkout - uses: actions/checkout@v2 - - name: Setup Android SDK Tools - uses: android-actions/setup-android@v2 - - name: Fetch Status - run: | - git submodule status TMessagesProj/jni/ffmpeg > ffmpeg_status - git submodule status TMessagesProj/jni/boringssl > boringssl_status - git submodule status ss-rust/src/main/rust/shadowsocks-rust > shadowsocks_status - git submodule status 'ssr-libev/*' > shadowsocksr_status - git submodule status v2ray > v2ray_status - - name: Native Cache (armeabi-v7a) - uses: actions/cache@v2 - with: - path: | - TMessagesProj/src/main/libs - key: ${{ hashFiles('TMessagesProj/jni/**', 'ffmpeg_status', 'boringssl_status') }}-armeabi-v7a - - name: Native Cache (arm64-v8a) - uses: actions/cache@v2 - with: - path: | - TMessagesProj/src/main/libs - key: ${{ hashFiles('TMessagesProj/jni/**', 'ffmpeg_status', 'boringssl_status') }}-arm64-v8a - - name: Native Cache (x86) - uses: actions/cache@v2 - with: - path: | - TMessagesProj/src/main/libs - key: ${{ hashFiles('TMessagesProj/jni/**', 'ffmpeg_status', 'boringssl_status') }}-x86 - - name: Native Cache (x86_64) - uses: actions/cache@v2 - with: - path: | - TMessagesProj/src/main/libs - key: ${{ hashFiles('TMessagesProj/jni/**', 'ffmpeg_status', 'boringssl_status') }}-x86_64 - - name: V2ray Cache - uses: actions/cache@v2 - with: - path: | - TMessagesProj/libs/libv2ray.aar - key: ${{ hashFiles('bin/libs/v2ray/*', 'v2ray_status') }} - - name: Shadowsocks Cache - uses: actions/cache@v2 - with: - path: | - TMessagesProj/libs/ss-rust-release.aar - key: ${{ hashFiles('shadowsocks_status') }} - - name: ShadowsocksR Cache - uses: actions/cache@v2 - with: - path: | - TMessagesProj/libs/ssr-libev-release.aar - key: ${{ hashFiles('shadowsocksr_status') }} - - name: Fix Gradle Memoery - run: | - sed -i -e "s/16384/6144/g" gradle.properties -# echo "ndk.dir=${ANDROID_HOME}/ndk-bundle" > local.properties - - name: Gradle cache - uses: actions/cache@v2 - with: - path: ~/.gradle - key: gradle-${{ hashFiles('**/*.gradle') }} - - name: Publish to Play Store - run: | - export LOCAL_PROPERTIES="${{ secrets.LOCAL_PROPERTIES }}" - cat > service_account_credentials.json << EOF - ${{ secrets.ANDROID_PUBLISHER_CREDENTIALS }}" - EOF - sed -i -e 's@@@g' TMessagesProj/src/main/AndroidManifest.xml - ./gradlew TMessagesProj:publishMiniPlayReleaseApk telegram-bot-api: name: Telegram Bot API diff --git a/TMessagesProj/build.gradle b/TMessagesProj/build.gradle index 1ccc3b5dc..3b6bb24c8 100644 --- a/TMessagesProj/build.gradle +++ b/TMessagesProj/build.gradle @@ -85,14 +85,17 @@ android { enable false universalApk true } else { - if (!nativeTarget.isBlank()) { + if (nativeTarget.toLowerCase().equals("universal")) { enable false + universalApk true + } else if (!nativeTarget.isBlank()) { + enable true universalApk false reset() include nativeTarget } else { - enable false - universalApk true + enable true + universalApk false } } } diff --git a/gradle.properties b/gradle.properties index a14119af4..007391243 100644 --- a/gradle.properties +++ b/gradle.properties @@ -15,7 +15,7 @@ RELEASE_KEY_PASSWORD=android RELEASE_KEY_ALIAS=androidkey RELEASE_STORE_PASSWORD=android -org.gradle.jvmargs=-XX:MaxPermSize=4096m +org.gradle.jvmargs= org.gradle.daemon=true org.gradle.parallel=true org.gradle.configureondemand=false