mirror of https://github.com/NekoX-Dev/NekoX.git
ci: use script to publish release and CI builds
This commit is contained in:
parent
c71626f80e
commit
5890d96dda
|
@ -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)
|
||||||
|
|
|
@ -434,28 +434,68 @@ jobs:
|
||||||
with:
|
with:
|
||||||
name: telegram-bot-api-binary
|
name: telegram-bot-api-binary
|
||||||
path: .
|
path: .
|
||||||
- name: Debug Build
|
- name: CI Build
|
||||||
run: |
|
run: |
|
||||||
export LOCAL_PROPERTIES="${{ secrets.LOCAL_PROPERTIES }}"
|
export LOCAL_PROPERTIES="${{ secrets.LOCAL_PROPERTIES }}"
|
||||||
export DEBUG_BUILD=true
|
export DEBUG_BUILD=true
|
||||||
|
export NATIVE_TARGET=universal
|
||||||
./gradlew TMessagesProj:assembleMiniRelease
|
./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: |
|
run: |
|
||||||
chmod +x telegram-bot-api-binary
|
chmod +x telegram-bot-api-binary
|
||||||
function start() {
|
function start() {
|
||||||
./telegram-bot-api-binary --api-id=21724 --api-hash=3e0cb5efcd52300aec5994fdfc5bdc16 --local 2>&1 > /dev/null &
|
./telegram-bot-api-binary --api-id=21724 --api-hash=3e0cb5efcd52300aec5994fdfc5bdc16 --local 2>&1 > /dev/null &
|
||||||
|
sleep 5
|
||||||
}
|
}
|
||||||
start
|
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/ || 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/ || start
|
||||||
curl http://127.0.0.1:8081/bot${{ secrets.HELPER_BOT_TOKEN }}/sendDocument \
|
|
||||||
-X POST \
|
curl https://raw.githubusercontent.com/NekoX-Dev/NekoX/dev/.github/scripts/upload.py -o upload.py
|
||||||
-F chat_id="${{ secrets.HELPER_BOT_TARGET }}" \
|
|
||||||
-F document="@$apk" \
|
export BOT_TOKEN=${{ secrets.HELPER_BOT_TOKEN }}
|
||||||
-F caption="${{ github.event.head_commit.message }}\n$GITHUB_SHA" \
|
export BOT_TARGET=${{ secrets.HELPER_BOT_TARGET }}
|
||||||
--silent --show-error --fail >/dev/null
|
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
|
pkill telegram-bot
|
||||||
|
|
||||||
telegram-bot-api:
|
telegram-bot-api:
|
||||||
|
|
|
@ -370,7 +370,9 @@ jobs:
|
||||||
- build
|
- build
|
||||||
- telegram-bot-api
|
- telegram-bot-api
|
||||||
steps:
|
steps:
|
||||||
- name: Donwload Artifacts
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v2
|
||||||
|
- name: Download Artifacts
|
||||||
uses: actions/download-artifact@v2
|
uses: actions/download-artifact@v2
|
||||||
with:
|
with:
|
||||||
path: artifacts
|
path: artifacts
|
||||||
|
@ -384,116 +386,21 @@ jobs:
|
||||||
chmod +x telegram-bot-api-binary
|
chmod +x telegram-bot-api-binary
|
||||||
function start() {
|
function start() {
|
||||||
./telegram-bot-api-binary --api-id=21724 --api-hash=3e0cb5efcd52300aec5994fdfc5bdc16 --local 2>&1 > /dev/null &
|
./telegram-bot-api-binary --api-id=21724 --api-hash=3e0cb5efcd52300aec5994fdfc5bdc16 --local 2>&1 > /dev/null &
|
||||||
|
sleep 5
|
||||||
}
|
}
|
||||||
start
|
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/ || 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
|
mkdir apks
|
||||||
find artifacts -name "*.apk" -exec cp {} apks \;
|
find artifacts -name "*.apk" -exec cp {} apks \;
|
||||||
function upload() {
|
curl https://raw.githubusercontent.com/NekoX-Dev/NekoX/dev/.github/scripts/upload.py -o upload.py
|
||||||
for apk in $@; do
|
export BOT_TOKEN="${{ secrets.HELPER_BOT_TOKEN }}"
|
||||||
echo ">> Uploading $apk"
|
export BOT_TARGET="${{ secrets.HELPER_BOT_TARGET }}"
|
||||||
curl http://127.0.0.1:8081/bot${{ secrets.TELEGRAM_TOKEN }}/sendDocument \
|
export VERSION_CODE="$(grep -E "def verCode = ([0-9]+)" TMessagesProj/build.gradle | sed "s/def verCode = //")"
|
||||||
-X POST \
|
export VERSION_NAME="$(grep -E "def verName = " TMessagesProj/build.gradle | sed "s/def verName = //" | sed "s/\"//g")"
|
||||||
-F chat_id="${{ secrets.TELEGRAM_CHANNEL }}" \
|
python3 upload.py release
|
||||||
-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
|
|
||||||
pkill telegram-bot
|
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@<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />@@g' TMessagesProj/src/main/AndroidManifest.xml
|
|
||||||
./gradlew TMessagesProj:publishMiniPlayReleaseApk
|
|
||||||
|
|
||||||
telegram-bot-api:
|
telegram-bot-api:
|
||||||
name: Telegram Bot API
|
name: Telegram Bot API
|
||||||
|
|
|
@ -85,14 +85,17 @@ android {
|
||||||
enable false
|
enable false
|
||||||
universalApk true
|
universalApk true
|
||||||
} else {
|
} else {
|
||||||
if (!nativeTarget.isBlank()) {
|
if (nativeTarget.toLowerCase().equals("universal")) {
|
||||||
enable false
|
enable false
|
||||||
|
universalApk true
|
||||||
|
} else if (!nativeTarget.isBlank()) {
|
||||||
|
enable true
|
||||||
universalApk false
|
universalApk false
|
||||||
reset()
|
reset()
|
||||||
include nativeTarget
|
include nativeTarget
|
||||||
} else {
|
} else {
|
||||||
enable false
|
enable true
|
||||||
universalApk true
|
universalApk false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
RELEASE_KEY_PASSWORD=android
|
RELEASE_KEY_PASSWORD=android
|
||||||
RELEASE_KEY_ALIAS=androidkey
|
RELEASE_KEY_ALIAS=androidkey
|
||||||
RELEASE_STORE_PASSWORD=android
|
RELEASE_STORE_PASSWORD=android
|
||||||
org.gradle.jvmargs=-XX:MaxPermSize=4096m
|
org.gradle.jvmargs=
|
||||||
org.gradle.daemon=true
|
org.gradle.daemon=true
|
||||||
org.gradle.parallel=true
|
org.gradle.parallel=true
|
||||||
org.gradle.configureondemand=false
|
org.gradle.configureondemand=false
|
||||||
|
|
Loading…
Reference in New Issue