name: Build Modules on: workflow_call: inputs: from_ci: type: boolean required: false default: true workflow_dispatch: jobs: run: permissions: write-all runs-on: ubuntu-latest steps: - uses: actions/setup-java@v5 with: distribution: "zulu" java-version: "21" - name: Checkout uses: actions/checkout@v6 with: fetch-depth: 0 submodules: true - name: Update config if: ${{ inputs.from_ci }} run: | if git checkout origin/update build.md; then UPDATE_CFG=$(./build.sh config.toml --config-update) if [ "$UPDATE_CFG" ]; then echo "$UPDATE_CFG" > config.json fi fi - name: Get next version code id: next_ver_code env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} run: | TAG=$(gh release list -L 1 | awk -F '\t' '{print $3}') if [ -z "$TAG" ]; then TAG=0; fi echo "NEXT_VER_CODE=$((TAG + 1))" >> $GITHUB_OUTPUT - name: Build modules/APKs run: if [ -f "config.json" ]; then ./build.sh config.json; else ./build.sh config.toml; fi env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} GITHUB_REPOSITORY: $GITHUB_REPOSITORY NEXT_VER_CODE: ${{ steps.next_ver_code.outputs.NEXT_VER_CODE }} - name: Get output id: get_output run: | DELIM="$(openssl rand -hex 8)" echo "BUILD_LOG<<${DELIM}" >> "$GITHUB_OUTPUT" cat build.md >> "$GITHUB_OUTPUT" echo "${DELIM}" >> "$GITHUB_OUTPUT" cp -f build.md build.tmp - name: Upload release env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} TAG: ${{ steps.next_ver_code.outputs.NEXT_VER_CODE }} BODY: ${{ steps.get_output.outputs.BUILD_LOG }} run: | if gh release view "$TAG" >/dev/null 2>&1; then gh release edit "$TAG" --title "Release" --notes "$BODY" gh release upload "$TAG" ./build/* --clobber else gh release create "$TAG" ./build/* --title "Release" --notes "$BODY" fi - name: Update modules changelog and update json id: update_config run: | git checkout -f update || git switch --discard-changes --orphan update cp -f build.tmp build.md get_update_json() { echo "{ \"version\": \"$1\", \"versionCode\": ${{ steps.next_ver_code.outputs.NEXT_VER_CODE }}, \"zipUrl\": \"$2\", \"changelog\": \"https://raw.githubusercontent.com/$GITHUB_REPOSITORY/update/build.md\" }" } cd build || { echo "build folder not found"; exit 1; } for OUTPUT in *module*.zip; do [ "$OUTPUT" = "*module*.zip" ] && continue ZIP_S=$(unzip -p "$OUTPUT" module.prop) if ! UPDATE_JSON=$(echo "$ZIP_S" | grep updateJson); then continue; fi UPDATE_JSON="${UPDATE_JSON##*/}" VER=$(echo "$ZIP_S" | grep version=) VER="${VER##*=}" DLURL="$GITHUB_SERVER_URL/$GITHUB_REPOSITORY/releases/download/${{ steps.next_ver_code.outputs.NEXT_VER_CODE }}/${OUTPUT}" get_update_json "$VER" "$DLURL" >"../$UPDATE_JSON" done cd .. find . -name "*-update.json" | grep . || : >dummy-update.json - name: Commit module json changes run: | git config user.name "github-actions[bot]" git config user.email "github-actions[bot]@users.noreply.github.com" git add build.md *-update.json if ! git diff --cached --quiet; then git commit -m "Bump version ${{ steps.next_ver_code.outputs.NEXT_VER_CODE }}" git push origin HEAD:update else echo "no changes!" fi - name: Report to Telegram env: TG_TOKEN: ${{ secrets.TG_TOKEN }} if: env.TG_TOKEN != null run: | cd build || { echo "build folder not found"; exit 1; } TG_CHAT="@rvc_magisk" NL=$'\n' APKS="" MODULES="" for OUTPUT in *; do DL_URL="$GITHUB_SERVER_URL/$GITHUB_REPOSITORY/releases/download/${{ steps.next_ver_code.outputs.NEXT_VER_CODE }}/${OUTPUT}" if [[ $OUTPUT = *.apk ]]; then APKS+="${NL}📦[${OUTPUT}](${DL_URL})" elif [[ $OUTPUT = *.zip ]]; then MODULES+="${NL}📦[${OUTPUT}](${DL_URL})" fi done MODULES=${MODULES#"$NL"} APKS=${APKS#"$NL"} BODY="$(sed 's/^\* \*\*/↪ \*\*/g; s/^\* `/↪ \*\*/g; s/`/\*/g; s/^\* /\↪/g; s/\*\*/\*/g; s/###//g; s/^- /↪ /g; /^==/d;' ../build.md)" MSG="*New build!* ${BODY} *▼ Download Links:* Modules: ${MODULES} APKs: ${APKS} " echo "'$MSG'" MSG=${MSG:0:9450} POST="https://api.telegram.org/bot${TG_TOKEN}/sendMessage" curl -X POST --data-urlencode "parse_mode=Markdown" --data-urlencode "disable_web_page_preview=true" --data-urlencode "text=${MSG}" --data-urlencode "chat_id=${TG_CHAT}" "$POST" - name: Report to Discord env: DISCORD_WEBHOOK_URL: ${{ secrets.DISCORD_WEBHOOK_URL }} if: env.DISCORD_WEBHOOK_URL != null run: | cd build || { echo "build folder not found"; exit 1; } NL=$'\n' APKS="" MODULES="" for OUTPUT in *; do DL_URL="$GITHUB_SERVER_URL/$GITHUB_REPOSITORY/releases/download/${{ steps.next_ver_code.outputs.NEXT_VER_CODE }}/${OUTPUT}" if [[ $OUTPUT = *.apk ]]; then APKS+="${NL}- [${OUTPUT}](${DL_URL})" elif [[ $OUTPUT = *.zip ]]; then MODULES+="${NL}- [${OUTPUT}](${DL_URL})" fi done MODULES=${MODULES#"$NL"} APKS=${APKS#"$NL"} BODY="$(sed 's/^\* \*\*/- \*\*/g; s/^\* `/- \*\*/g; s/`/\*/g; s/^\* /\-/g; s/\*\*/\*/g; s/###//g; s/^- /- /g; /^==/d;' ../build.md)" MSG="**New build is ready!** ${BODY} **Download Links:** " MODULES_MSG=" **Modules:** ${MODULES} " APKS_MSG=" **APKs:** ${APKS} " curl -X POST -H "Content-Type: application/json" \ -d "$(jq -n --arg content "$MSG" '{content: $content}')" \ "$DISCORD_WEBHOOK_URL" # curl -X POST -H "Content-Type: application/json" \ # -d "$(jq -n --arg content "$MODULES_MSG" '{content: $content}')" \ # "$DISCORD_WEBHOOK_URL" curl -X POST -H "Content-Type: application/json" \ -d "$(jq -n --arg content "$APKS_MSG" '{content: $content}')" \ "$DISCORD_WEBHOOK_URL" - name: Report to Noob Discord env: DISCORD_WEBHOOK_NOOB_URL: ${{ secrets.DISCORD_WEBHOOK_NOOB_URL }} if: env.DISCORD_WEBHOOK_NOOB_URL != null run: | cd build || { echo "build folder not found"; exit 1; } NL=$'\n' APKS="" MODULES="" for OUTPUT in *; do DL_URL="$GITHUB_SERVER_URL/$GITHUB_REPOSITORY/releases/download/${{ steps.next_ver_code.outputs.NEXT_VER_CODE }}/${OUTPUT}" if [[ $OUTPUT = *.apk ]]; then APKS+="${NL}- [${OUTPUT}](${DL_URL})" elif [[ $OUTPUT = *.zip ]]; then MODULES+="${NL}- [${OUTPUT}](${DL_URL})" fi done MODULES=${MODULES#"$NL"} APKS=${APKS#"$NL"} BODY="$(sed 's/^\* \*\*/- \*\*/g; s/^\* `/- \*\*/g; s/`/\*/g; s/^\* /\-/g; s/\*\*/\*/g; s/###//g; s/^- /- /g; /^==/d;' ../build.md)" MSG="**New build is ready!** ${BODY} **Download Links:** " MODULES_MSG=" **Modules:** ${MODULES} " APKS_MSG=" **APKs:** ${APKS} " curl -X POST -H "Content-Type: application/json" \ -d "$(jq -n --arg content "$MSG" '{content: $content}')" \ "$DISCORD_WEBHOOK_NOOB_URL" # curl -X POST -H "Content-Type: application/json" \ # -d "$(jq -n --arg content "$MODULES_MSG" '{content: $content}')" \ # "$DISCORD_WEBHOOK_NOOB_URL" curl -X POST -H "Content-Type: application/json" \ -d "$(jq -n --arg content "$APKS_MSG" '{content: $content}')" \ "$DISCORD_WEBHOOK_NOOB_URL" - name: Send Email Notification (Resend) env: RESEND_API_KEY: ${{ secrets.RESEND_API_KEY }} MAIL_TO: ${{ secrets.MAIL_TO }} MAIL_CC: ${{ secrets.MAIL_CC }} MAIL_BCC: ${{ secrets.MAIL_BCC }} MAIL_FROM: ${{ secrets.MAIL_FROM }} if: env.RESEND_API_KEY != null && env.MAIL_TO != null run: | VERSION="${{ steps.next_ver_code.outputs.NEXT_VER_CODE }}" RELEASE_URL="${{ github.server_url }}/${{ github.repository }}/releases/tag/${VERSION}" REPO="${{ github.repository }}" # Set default FROM address if not provided FROM_ADDRESS="${MAIL_FROM:-ReVanced Build Bot }" # Build download links from build folder (separate APKs and Modules) cd build || { echo "build folder not found"; exit 1; } APK_LINKS="" MODULE_LINKS="" for OUTPUT in *; do DL_URL="${{ github.server_url }}/${{ github.repository }}/releases/download/${VERSION}/${OUTPUT}" if [[ $OUTPUT = *.apk ]]; then APK_LINKS+="
  • 📦 ${OUTPUT}
  • " elif [[ $OUTPUT = *.zip ]]; then MODULE_LINKS+="
  • 📁 ${OUTPUT}
  • " fi done cd .. # Get current time in Vietnam timezone (UTC+7) BUILD_TIME=$(TZ='Asia/Ho_Chi_Minh' date '+%Y-%m-%d %H:%M:%S (UTC+7)') # Get changelog from build.md and convert to HTML if [ -f "build.md" ]; then # Convert markdown to simple HTML CHANGELOG_HTML=$(sed 's/^### \(.*\)/

    \1<\/h3>/g; s/^\* \*\*\(.*\)\*\*/
  • \1<\/strong><\/li>/g; s/^\* \(.*\)/
  • \1<\/li>/g; s/^- \(.*\)/
  • \1<\/li>/g; s/`\([^`]*\)`/\1<\/code>/g; /^==/d; /^$/d' build.md | tr '\n' ' ') else CHANGELOG_HTML="

    No changelog available.

    " fi # Create HTML email body (similar structure to Telegram) HTML_BODY=$(cat <

    🎉 New ReVanced Build!

    Version: v${VERSION}

    🕐 ${BUILD_TIME}

    📋 Changelog

    ${CHANGELOG_HTML}

    � Download Links

    $(if [ -n "$MODULE_LINKS" ]; then echo "

    � Modules:

      ${MODULE_LINKS}
    "; fi) $(if [ -n "$APK_LINKS" ]; then echo "

    📱 APKs:

      ${APK_LINKS}
    "; fi)

    This is an automated message from ReVanced Build Bot

    Repository: ${REPO}

    EOF ) # Build JSON payload with TO, CC and BCC recipients # Resend allows up to 50 recipients per field (to, cc, bcc) JSON_PAYLOAD=$(jq -n \ --arg from "$FROM_ADDRESS" \ --arg to "$MAIL_TO" \ --arg cc "$MAIL_CC" \ --arg bcc "$MAIL_BCC" \ --arg subject "🚀 New ReVanced Build Available - v${VERSION}" \ --arg html "$HTML_BODY" \ '{ from: $from, to: ($to | split(",") | map(select(. != "") | gsub("^\\s+|\\s+$"; ""))), subject: $subject, html: $html } + (if $cc != "" then {cc: ($cc | split(",") | map(select(. != "") | gsub("^\\s+|\\s+$"; "")))} else {} end) + (if $bcc != "" then {bcc: ($bcc | split(",") | map(select(. != "") | gsub("^\\s+|\\s+$"; "")))} else {} end)' ) echo "📧 Sending email notification..." # Send email via Resend API RESPONSE=$(curl -s -X POST "https://api.resend.com/emails" \ -H "Authorization: Bearer ${RESEND_API_KEY}" \ -H "Content-Type: application/json" \ -d "$JSON_PAYLOAD") echo "Response: $RESPONSE" echo "✅ Email sent successfully!"