# Technical Documentation: NoName-exe/revanced-extended

> ℹ️ **Provenance:** In-Tree Documentation (8 Chapters) · [CodeWiki Reference](https://codewiki.google/github.com/NoName-exe/revanced-extended) · Recency: Active (< 180 days)

## File: README.md

#### ⚠️ Do not download modules from 3rd party sources like random websites you found on Google. There are many that uses my modules and impersonates ReVanced.

# ReVanced eXtended
[](https://github.com/NoName-exe/revanced-extended/actions/workflows/ci.yml)

Get the [latest CI release](https://github.com/NoName-exe/revanced-extended/releases/latest).

## Features
 * Updated with the latest versions of patches.
 * Cleans APKs from unneeded libs to make them smaller.
 * Fully open-source, every binary or APK is compiled without human intervention.
 * Modules:
     * Recompile invalidated odex for YouTube and YouTube-Music for faster usage.
     * Receive updates from Magisk app.
     * Should not break safetynet or trigger root detections used by certain apps.
     * Handle installation of the correct version of the stock app and all that.
     * Support Magisk and KernelSU.

 ## Notes
* Use [zygisk-detach](https://github.com/j-hc/zygisk-detach) to block Play Store from updating YouTube and YouTube-Music.
* Non-root versions of YouTube and YouTube-Music require [MicroG](https://github.com/MorpheApp/MicroG-RE) to work.

## Credits
[j-hc](https://github.com/j-hc) for [zygisk-detach](https://github.com/j-hc/zygisk-detach) and the [script on which this is based on](https://github.com/j-hc/revanced-magisk-module).

[Morphe Team](https://github.com/MorpheApp) for [MicroG](https://github.com/MorpheApp/MicroG-RE) and their [patches](https://github.com/MorpheApp/morphe-patches).

[Gnad Gnaoh](https://github.com/gnadgnaoh) for helping me figure some stuff out.

---

## File: CONFIG.md

# Config

Adding another revanced app is as easy as this:
```toml
[Some-App]
apkmirror-dlurl = "https://www.apkmirror.com/apk/inc/app"
# or uptodown-dlurl = "https://app.en.uptodown.com/android"
```

> [!WARNING]
> When a patch name itself contains a single quote, double it inside the string (e.g. 'Hide ''Get Music Premium''').

## More about other options:

There exists an example below with all defaults shown and all the keys explicitly set.  
**All keys are optional** (except download urls) and are assigned to their default values if not set explicitly.  

```toml
parallel-jobs = 1                    # amount of cores to use for parallel patching, if not set $(nproc) is used
compression-level = 9                # module zip compression level
remove-rv-integrations-checks = true # remove checks from the revanced integrations
dpi = "nodpi anydpi 120-640dpi"      # dpi packages to be searched in order. default: "nodpi anydpi"

patches-source = "revanced/revanced-patches" # where to fetch patches bundle from. default: "revanced/revanced-patches"
cli-source = "ReVanced/revanced-cli"             # where to fetch cli from. default: "ReVanced/revanced-cli"
# options like cli-source can also set per app
rv-brand = "ReVanced Extended" # rebrand from 'ReVanced' to something different. default: "ReVanced"

patches-version = "v2.160.0" # 'latest', 'dev', or a version number. default: "latest"
cli-version = "v5.0.0"       # 'latest', 'dev', or a version number. default: "latest"

[Some-App]
app-name = "SomeApp" # if set, release name becomes SomeApp instead of Some-App. default is same as table name, which is 'Some-App' here.
enabled = true       # whether to build the app. default: true
build-mode = "apk"   # 'both', 'apk' or 'module'. default: apk

# 'auto' option gets the latest possible version supported by all the included patches
# 'latest' gets the latest stable without checking patches support. 'beta' gets the latest beta/alpha
# whitespace seperated list of patches to exclude. default: ""
version = "auto"     # 'auto', 'latest', 'beta' or a version number (e.g. '17.40.41'). default: auto

# optional args to be passed to cli. can be used to set patch options
# multiline strings in the config is supported
patcher-args = """\
  -OdarkThemeBackgroundColor=#FF0F0F0F \
  -Oanother-option=value \
  """

excluded-patches = """\
  'Some Patch' \
  'Some Other Patch' \
  """

included-patches = "'Some Patch'"                          # whitespace seperated list of non-default patches to include. default: ""
include-stock = "merged"                                   # 'merged', 'split' or 'disable'. default: merged
exclusive-patches = false                                  # exclude all patches by default. default: false

apkmirror-dlurl = "https://www.apkmirror.com/apk/inc/app"
uptodown-dlurl = "https://spotify.en.uptodown.com/android"
# direct download url. the url must have point to an apk file with name format shown in this example
direct-dlurl = "https://website/com.google.android.youtube-20.40.45-all.apk"

module-prop-name = "some-app-module"                       # module prop name.
dpi = "360-480dpi"                                         # used to select apk variant from apkmirror. default: nodpi
arch = "arm64-v8a"                                         # 'arm64-v8a', 'arm-v7a', 'all', 'both'. 'both' downloads both arm64-v8a and arm-v7a. default: all
```

---

## File: sig.txt

a2a1ad7ba7f41dfca4514e2afeb90691719af6d0fdbed4b09bbf0ed897701ceb com.google.android.apps.youtube.music
3d7a1223019aa39d9ea0e3436ab7c0896bfb4fb679f4de5fe7c23f326c8f994a com.google.android.youtube
970b91143813b4c9d5f3634f672c9fcaa5621b4efaaedafd6c235cbbb869736f com.reddit.frontpage
1338f9b049893cc70b78432a177582f90bd4bc6296ea4ed35bcc7df59687ac53 tv.twitch.android.app

---

## File: .github/ISSUE_TEMPLATE/bug_report.md

---
name: Bug report
about: Bug report
title: ''
labels: ''
assignees: ''

---

**DO NOT REPORT REVANCED STUFF IN THIS REPO**  
if you delete these lines and proceed to report revanced stuff like **patch bugs** or **patch requests**, you will be **blocked** from this repo

Use issues only to report bugs of the rvmm builder or the modules

---

## File: .github/ISSUE_TEMPLATE/config.yml

blank_issues_enabled: false

---

## File: .github/workflows/build.yml

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: |
          rel_title=$(find build -maxdepth 1 -name "youtube-morphe-module-*.zip" -printf '%P\n')
          if gh release view "$TAG" >/dev/null 2>&1; then
            gh release edit "$TAG" --title "Morphe" --notes "$BODY"
            gh release upload "$TAG" ./build/* --clobber
          else
            gh release create "$TAG" ./build/* --title "$rel_title" --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"

---

## File: .github/workflows/ci.yml

name: CI
on:
  workflow_dispatch:
  schedule:
    - cron: "0 0 * * *"

jobs:
  check:
    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

      - name: Should build?
        id: should_build
        shell: bash
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        run: |
          if ! git checkout origin/update build.md; then
            echo "first time building!"
            echo "SHOULD_BUILD=1" >> $GITHUB_OUTPUT
          else
            UPDATE_CFG=$(./build.sh config.toml --config-update)
            if [ "$UPDATE_CFG" ]; then
              echo "'$UPDATE_CFG'"
              echo "SHOULD_BUILD=1" >> $GITHUB_OUTPUT
            else
              echo "SHOULD_BUILD=0" >> $GITHUB_OUTPUT
            fi
          fi

      - name: Clear older runs
        env:
          GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        run: |
          gh run list -L400 --json databaseId -q '.[].databaseId' | tail -n+10 | xargs -IID gh api "repos/$GITHUB_REPOSITORY/actions/runs/ID" -X DELETE || :

    outputs:
      SHOULD_BUILD: ${{ steps.should_build.outputs.SHOULD_BUILD }}

  build:
    permissions: write-all
    needs: check
    uses: ./.github/workflows/build.yml
    if: ${{ needs.check.outputs.SHOULD_BUILD == 1 }}
    secrets: inherit

---

## File: .github/workflows/sync.yml

name: Sync Upstream

env:
  UPSTREAM_URL: "https://github.com/j-hc/revanced-magisk-module.git"
  WORKFLOW_TOKEN: ${{ secrets.WORKFLOW_TOKEN }}
  UPSTREAM_BRANCH: "main"
  DOWNSTREAM_BRANCH: "main"

on:
  schedule:
    - cron: '0 20 * * *'
  workflow_dispatch:

jobs:
  sync:
    runs-on: ubuntu-latest
    steps:
      - name: Sync Upstream
        uses: dabreadman/sync-upstream-repo@v1.3.0
        with: 
          upstream_repo: ${{ env.UPSTREAM_URL }}
          upstream_branch: ${{ env.UPSTREAM_BRANCH }}
          downstream_branch: ${{ env.DOWNSTREAM_BRANCH }}
          token: ${{ env.WORKFLOW_TOKEN }}

--- METRICS ---
- Files Extracted: 8
- Estimated Token Budget: ~3597 tokens
- Recency Window: Active (< 180 days)
- Canonical Reference: https://codewiki.google/github.com/NoName-exe/revanced-extended
