mirror of
https://github.com/yuzono/anime-extensions.git
synced 2026-06-13 13:39:44 +00:00
[ci] build only required modules (#6900)
* workflow * configs * workflow * workflow * workflow * workflow * workflow * workflow * workflow * workflow * workflow * workflow * rewrite python scripts * small tweak * Update .github/scripts/modules-to-build.py Co-authored-by: AwkwardPeak7 <48650614+AwkwardPeak7@users.noreply.github.com> * set full path of git * now? * i hate my life * and should work now * And some more changes * And some more changes 2 * Oops * support for always building some modules * string replace fix * don't run matrix chunk if empty * bruh moment * revert * test pr workflow - remove extension - modify extension - modify multisrc * fix gradlew command * Revert "test pr workflow" This reverts commit 8c3aa34555a26f2257d2d791104eb63bbd48856c. * skip step * skip step x2 * perhaps * make if work? * Reapply "test pr workflow" This reverts commit 9c7f2a7acd787b18b98ef99da733cc2f8077b2a7. * make if work! * Revert "Reapply "test pr workflow"" This reverts commit 43238b0d7bfaa81b8067c7206bb9fb081fa4dbba. * update job name * Revert "update job name" This reverts commit 361b6e7279b901a78fac3eb77e909f480cf54475. * final changes * Cleanup some common code * Cleanup settings.gradle.kts * Reapply "Reapply "test pr workflow"" This reverts commit 68524b649974e4d05b6a01d0ec297a5f28617071. * Revert "Reapply "Reapply "test pr workflow""" This reverts commit bafab8b8405cff9b9142d9f83c4f5adac92da6a0. * correct delete output name * pr test: multiple matrices * Revert "pr test: multiple matrices" This reverts commit 87fd5fcfd01dc4d83658312293fcc8ac3586086e. --------- Co-authored-by: FourTOne5 <107297513+FourTOne5@users.noreply.github.com> (cherry picked from commit 14ef26a5a6f417aa6f003a338f1ae79830ec49a2)
This commit is contained in:
2
.github/always_build.json
vendored
Normal file
2
.github/always_build.json
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
[
|
||||
]
|
||||
17
.github/scripts/commit-repo.sh
vendored
17
.github/scripts/commit-repo.sh
vendored
@@ -1,17 +0,0 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
rsync -a --delete --exclude .git --exclude .gitignore --exclude repo.json ../master/repo/ .
|
||||
git config --global user.email "github-actions[bot]@users.noreply.github.com"
|
||||
git config --global user.name "github-actions[bot]"
|
||||
git status
|
||||
if [ -n "$(git status --porcelain)" ]; then
|
||||
git add .
|
||||
git commit -m "Update extensions repo"
|
||||
git push
|
||||
|
||||
# Purge cached index on jsDelivr
|
||||
curl https://purge.jsdelivr.net/gh/yuzono/anime-repo@repo/index.min.json
|
||||
else
|
||||
echo "No changes to commit"
|
||||
fi
|
||||
28
.github/scripts/create-repo.py
vendored
28
.github/scripts/create-repo.py
vendored
@@ -10,10 +10,8 @@ VERSION_CODE_REGEX = re.compile(r"versionCode='([^']+)'")
|
||||
VERSION_NAME_REGEX = re.compile(r"versionName='([^']+)'")
|
||||
IS_NSFW_REGEX = re.compile(r"'tachiyomi.animeextension.nsfw' value='([^']+)'")
|
||||
APPLICATION_LABEL_REGEX = re.compile(r"^application-label:'([^']+)'", re.MULTILINE)
|
||||
APPLICATION_ICON_320_REGEX = re.compile(
|
||||
r"^application-icon-320:'([^']+)'", re.MULTILINE
|
||||
)
|
||||
LANGUAGE_REGEX = re.compile(r"aniyomi-([^\.]+)")
|
||||
APPLICATION_ICON_320_REGEX = re.compile(r"^application-icon-320:'([^']+)'", re.MULTILINE)
|
||||
LANGUAGE_REGEX = re.compile(r"aniyomi-([^.]+)")
|
||||
|
||||
*_, ANDROID_BUILD_TOOLS = (Path(os.environ["ANDROID_HOME"]) / "build-tools").iterdir()
|
||||
REPO_DIR = Path("repo")
|
||||
@@ -25,7 +23,6 @@ REPO_ICON_DIR.mkdir(parents=True, exist_ok=True)
|
||||
with open("output.json", encoding="utf-8") as f:
|
||||
inspector_data = json.load(f)
|
||||
|
||||
index_data = []
|
||||
index_min_data = []
|
||||
|
||||
for apk in REPO_APK_DIR.iterdir():
|
||||
@@ -86,23 +83,6 @@ for apk in REPO_APK_DIR.iterdir():
|
||||
)
|
||||
|
||||
index_min_data.append(min_data)
|
||||
index_data.append(
|
||||
{
|
||||
**common_data,
|
||||
"hasReadme": 0,
|
||||
"hasChangelog": 0,
|
||||
"sources": sources,
|
||||
}
|
||||
)
|
||||
|
||||
index_data.sort(key=lambda x: x["pkg"])
|
||||
index_min_data.sort(key=lambda x: x["pkg"])
|
||||
|
||||
with (REPO_DIR / "index.json").open("w", encoding="utf-8") as f:
|
||||
index_data_str = json.dumps(index_data, ensure_ascii=False, indent=2)
|
||||
|
||||
print(index_data_str)
|
||||
f.write(index_data_str)
|
||||
|
||||
with (REPO_DIR / "index.min.json").open("w", encoding="utf-8") as f:
|
||||
json.dump(index_min_data, f, ensure_ascii=False, separators=(",", ":"))
|
||||
with REPO_DIR.joinpath("index.min.json").open("w", encoding="utf-8") as index_file:
|
||||
json.dump(index_min_data, index_file, ensure_ascii=False, separators=(",", ":"))
|
||||
|
||||
91
.github/scripts/generate-build-matrices.py
vendored
Normal file
91
.github/scripts/generate-build-matrices.py
vendored
Normal file
@@ -0,0 +1,91 @@
|
||||
import itertools
|
||||
import json
|
||||
import os
|
||||
import re
|
||||
import subprocess
|
||||
import sys
|
||||
from pathlib import Path
|
||||
from typing import NoReturn
|
||||
|
||||
EXTENSION_REGEX = re.compile(r"^src/(?P<lang>\w+)/(?P<extension>\w+)")
|
||||
MULTISRC_LIB_REGEX = re.compile(r"^lib-multisrc/(?P<multisrc>\w+)")
|
||||
LIB_REGEX = re.compile(r"^lib/(?P<lib>\w+)")
|
||||
MODULE_REGEX = re.compile(r"^:src:(?P<lang>\w+):(?P<extension>\w+)$")
|
||||
|
||||
def run_command(command: str) -> str:
|
||||
result = subprocess.run(command, capture_output=True, text=True, shell=True)
|
||||
if result.returncode != 0:
|
||||
print(result.stderr.strip())
|
||||
sys.exit(result.returncode)
|
||||
return result.stdout.strip()
|
||||
|
||||
def get_module_list(ref: str) -> tuple[list[str], list[str]]:
|
||||
changed_files = run_command(f"git diff --name-only {ref}").splitlines()
|
||||
|
||||
modules = set()
|
||||
libs = set()
|
||||
deleted = set()
|
||||
|
||||
for file in map(lambda x: Path(x).as_posix(), changed_files):
|
||||
if match := EXTENSION_REGEX.search(file):
|
||||
lang = match.group("lang")
|
||||
extension = match.group("extension")
|
||||
if Path("src", lang, extension).is_dir():
|
||||
modules.add(f':src:{lang}:{extension}')
|
||||
deleted.add(f"{lang}.{extension}")
|
||||
elif match := MULTISRC_LIB_REGEX.search(file):
|
||||
multisrc = match.group("multisrc")
|
||||
if Path("lib-multisrc", multisrc).is_dir():
|
||||
libs.add(f":lib-multisrc:{multisrc}:printDependentExtensions")
|
||||
elif match := LIB_REGEX.search(file):
|
||||
lib = match.group("lib")
|
||||
if Path("lib", lib).is_dir():
|
||||
libs.add(f":lib:{lib}:printDependentExtensions")
|
||||
|
||||
def is_extension_module(module: str) -> bool:
|
||||
if not (match := MODULE_REGEX.search(module)):
|
||||
return False
|
||||
lang = match.group("lang")
|
||||
extension = match.group("extension")
|
||||
deleted.add(f"{lang}.{extension}")
|
||||
return True
|
||||
|
||||
modules.update([
|
||||
module for module in
|
||||
run_command("./gradlew -q " + " ".join(libs)).splitlines()
|
||||
if is_extension_module(module)
|
||||
])
|
||||
|
||||
if os.getenv("IS_PR_CHECK") != "true":
|
||||
with Path.cwd().joinpath(".github/always_build.json").open() as always_build_file:
|
||||
always_build = json.load(always_build_file)
|
||||
for extension in always_build:
|
||||
modules.add(":src:" + extension.replace(".", ":"))
|
||||
deleted.add(extension)
|
||||
|
||||
return list(modules), list(deleted)
|
||||
|
||||
def main() -> NoReturn:
|
||||
_, ref, build_type = sys.argv
|
||||
modules, deleted = get_module_list(ref)
|
||||
|
||||
chunked = {
|
||||
"chunk": [
|
||||
{"number": i + 1, "modules": modules}
|
||||
for i, modules in
|
||||
enumerate(itertools.batched(
|
||||
map(lambda x: f"{x}:assemble{build_type}", modules),
|
||||
int(os.getenv("CI_CHUNK_SIZE", 65))
|
||||
))
|
||||
]
|
||||
}
|
||||
|
||||
print(f"Module chunks to build:\n{json.dumps(chunked, indent=2)}\n\nModule to delete:\n{json.dumps(deleted, indent=2)}")
|
||||
|
||||
if os.getenv("CI") == "true":
|
||||
with open(os.getenv("GITHUB_OUTPUT"), 'a') as out_file:
|
||||
out_file.write(f"matrix={json.dumps(chunked)}\n")
|
||||
out_file.write(f"delete={json.dumps(deleted)}\n")
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
48
.github/scripts/merge-repo.py
vendored
Normal file
48
.github/scripts/merge-repo.py
vendored
Normal file
@@ -0,0 +1,48 @@
|
||||
import html
|
||||
import sys
|
||||
import json
|
||||
from pathlib import Path
|
||||
import shutil
|
||||
|
||||
REMOTE_REPO: Path = Path.cwd()
|
||||
LOCAL_REPO: Path = REMOTE_REPO.parent.joinpath("main/repo")
|
||||
|
||||
to_delete: list[str] = json.loads(sys.argv[1])
|
||||
|
||||
for module in to_delete:
|
||||
apk_name = f"aniyomi-{module}-v*.*.*.apk"
|
||||
icon_name = f"eu.kanade.tachiyomi.animeextension.{module}.png"
|
||||
for file in REMOTE_REPO.joinpath("apk").glob(apk_name):
|
||||
file.unlink()
|
||||
for file in REMOTE_REPO.joinpath("icon").glob(icon_name):
|
||||
file.unlink()
|
||||
|
||||
shutil.copytree(src=LOCAL_REPO.joinpath("apk"), dst=REMOTE_REPO.joinpath("apk"))
|
||||
shutil.copytree(src=LOCAL_REPO.joinpath("icon"), dst=REMOTE_REPO.joinpath("icon"))
|
||||
|
||||
with REMOTE_REPO.joinpath("index.min.json").open() as remote_index_file:
|
||||
remote_index = json.load(remote_index_file)
|
||||
|
||||
with LOCAL_REPO.joinpath("index.min.json").open() as local_index_file:
|
||||
local_index = json.load(local_index_file)
|
||||
|
||||
index = [
|
||||
item for item in remote_index
|
||||
if not any([item["pkg"].endswith(f".{module}") for module in to_delete])
|
||||
]
|
||||
index.extend(local_index)
|
||||
index.sort(key=lambda x: x["pkg"])
|
||||
|
||||
with REMOTE_REPO.joinpath("index.json").open("w", encoding="utf-8") as index_file:
|
||||
json.dump(index, index_file, ensure_ascii=False, indent=2)
|
||||
|
||||
with REMOTE_REPO.joinpath("index.min.json").open("w", encoding="utf-8") as index_min_file:
|
||||
json.dump(index, index_min_file, ensure_ascii=False, separators=(",", ":"))
|
||||
|
||||
with REMOTE_REPO.joinpath("index.html").open("w", encoding="utf-8") as index_html_file:
|
||||
index_html_file.write('<!DOCTYPE html>\n<html>\n<head>\n<meta charset="UTF-8">\n<title>apks</title>\n</head>\n<body>\n<pre>\n')
|
||||
for entry in index:
|
||||
apk_escaped = 'apk/' + html.escape(entry["apk"])
|
||||
name_escaped = html.escape(entry["name"])
|
||||
index_html_file.write(f'<a href="{apk_escaped}">{name_escaped}</a>\n')
|
||||
index_html_file.write('</pre>\n</body>\n</html>\n')
|
||||
16
.github/scripts/move-apks.py
vendored
16
.github/scripts/move-apks.py
vendored
@@ -1,16 +0,0 @@
|
||||
from pathlib import Path
|
||||
import shutil
|
||||
|
||||
REPO_APK_DIR = Path("repo/apk")
|
||||
|
||||
try:
|
||||
shutil.rmtree(REPO_APK_DIR)
|
||||
except FileNotFoundError:
|
||||
pass
|
||||
|
||||
REPO_APK_DIR.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
for apk in (Path.home() / "apk-artifacts").glob("**/*.apk"):
|
||||
apk_name = apk.name.replace("-release.apk", ".apk")
|
||||
|
||||
shutil.move(apk, REPO_APK_DIR / apk_name)
|
||||
12
.github/scripts/move-built-apks.py
vendored
Normal file
12
.github/scripts/move-built-apks.py
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
from pathlib import Path
|
||||
import shutil
|
||||
|
||||
REPO_APK_DIR = Path("repo/apk")
|
||||
|
||||
shutil.rmtree(REPO_APK_DIR, ignore_errors=True)
|
||||
REPO_APK_DIR.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
for apk in Path.home().joinpath("apk-artifacts").glob("**/*.apk"):
|
||||
apk_name = apk.name.replace("-release.apk", ".apk")
|
||||
|
||||
shutil.move(apk, REPO_APK_DIR.joinpath(apk_name))
|
||||
111
.github/workflows/build_pull_request.yml
vendored
111
.github/workflows/build_pull_request.yml
vendored
@@ -1,4 +1,4 @@
|
||||
name: PR build check
|
||||
name: PR check
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
@@ -14,17 +14,19 @@ concurrency:
|
||||
|
||||
env:
|
||||
CI_CHUNK_SIZE: 65
|
||||
IS_PR_CHECK: true
|
||||
|
||||
jobs:
|
||||
prepare:
|
||||
name: Prepare job
|
||||
runs-on: ubuntu-latest
|
||||
runs-on: 'ubuntu-24.04'
|
||||
outputs:
|
||||
individualMatrix: ${{ steps.generate-matrices.outputs.individualMatrix }}
|
||||
latestCommitMessage: ${{ steps.set-env.outputs.LATEST_COMMIT_MESSAGE }}
|
||||
matrix: ${{ steps.generate-matrices.outputs.matrix }}
|
||||
delete: ${{ steps.generate-matrices.outputs.delete }}
|
||||
steps:
|
||||
- name: Clone repo
|
||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
|
||||
- name: Checkout PR
|
||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
||||
|
||||
- name: Set env
|
||||
run: |
|
||||
@@ -56,78 +58,76 @@ jobs:
|
||||
./.github/scripts/bump-versions.py $isKmk "${{ steps.set-env.outputs.LATEST_COMMIT_MESSAGE }}" ${{ steps.modified-libs.outputs.all_changed_files }}
|
||||
echo "!!! This PR will bumping extensions version that uses a modified lib"
|
||||
|
||||
- name: Get number of modules
|
||||
run: |
|
||||
set -x
|
||||
projects=(src/*/*)
|
||||
|
||||
echo "NUM_INDIVIDUAL_MODULES=${#projects[@]}" >> $GITHUB_ENV
|
||||
|
||||
- id: generate-matrices
|
||||
name: Create output matrices
|
||||
uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7
|
||||
with:
|
||||
script: |
|
||||
const numIndividualModules = process.env.NUM_INDIVIDUAL_MODULES;
|
||||
const chunkSize = process.env.CI_CHUNK_SIZE;
|
||||
|
||||
const numIndividualChunks = Math.ceil(numIndividualModules / chunkSize);
|
||||
|
||||
console.log(`Individual modules: ${numIndividualModules} (${numIndividualChunks} chunks of ${chunkSize})`);
|
||||
|
||||
core.setOutput('individualMatrix', { 'chunk': [...Array(numIndividualChunks).keys()] });
|
||||
|
||||
build_individual:
|
||||
name: Build individual modules
|
||||
needs: prepare
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
matrix: ${{ fromJSON(needs.prepare.outputs.individualMatrix) }}
|
||||
steps:
|
||||
- name: Checkout PR
|
||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
|
||||
|
||||
- name: Set up JDK
|
||||
uses: actions/setup-java@c5195efecf7bdfc987ee8bae7a71cb8b11521c00 # v4
|
||||
- name: Set up Java
|
||||
uses: actions/setup-java@3a4f6e1af504cf6a31855fa899c6aa5355ba6c12 # v4.7.0
|
||||
with:
|
||||
java-version: 17
|
||||
distribution: temurin
|
||||
|
||||
- name: Set up Gradle
|
||||
uses: gradle/actions/setup-gradle@94baf225fe0a508e581a564467443d0e2379123b # v4.3.0
|
||||
with:
|
||||
cache-read-only: true
|
||||
|
||||
- id: generate-matrices
|
||||
name: Generate build matrices
|
||||
run: |
|
||||
git fetch origin master
|
||||
python ./.github/scripts/generate-build-matrices.py origin/master Release
|
||||
|
||||
build:
|
||||
name: Build extensions (${{ matrix.chunk.number }})
|
||||
needs: prepare
|
||||
runs-on: 'ubuntu-24.04'
|
||||
if: ${{ toJson(fromJson(needs.prepare.outputs.matrix).chunk) != '[]' }}
|
||||
strategy:
|
||||
matrix: ${{ fromJSON(needs.prepare.outputs.matrix) }}
|
||||
steps:
|
||||
- name: Checkout PR
|
||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
||||
|
||||
- name: Set up Java
|
||||
uses: actions/setup-java@c5195efecf7bdfc987ee8bae7a71cb8b11521c00 # v4.7.1
|
||||
with:
|
||||
java-version: 17
|
||||
distribution: temurin
|
||||
|
||||
- name: Set up Gradle
|
||||
uses: gradle/actions/setup-gradle@06832c7b30a0129d7fb559bcc6e43d26f6374244 # v4.3.1
|
||||
with:
|
||||
cache-read-only: true
|
||||
|
||||
- name: Prepare signing key
|
||||
run: |
|
||||
echo ${{ secrets.SIGNING_KEY }} | base64 -d > signingkey.jks
|
||||
chmod 600 signingkey.jks
|
||||
|
||||
- name: Set up Gradle
|
||||
uses: gradle/actions/setup-gradle@06832c7b30a0129d7fb559bcc6e43d26f6374244 # v4
|
||||
with:
|
||||
cache-read-only: ${{ matrix.chunk != 0 }}
|
||||
|
||||
- name: Build extensions (chunk ${{ matrix.chunk }})
|
||||
- name: Build extensions (${{ matrix.chunk.number }})
|
||||
env:
|
||||
CI_CHUNK_NUM: ${{ matrix.chunk }}
|
||||
ALIAS: ${{ secrets.ALIAS }}
|
||||
KEY_STORE_PASSWORD: ${{ secrets.KEY_STORE_PASSWORD }}
|
||||
KEY_PASSWORD: ${{ secrets.KEY_PASSWORD }}
|
||||
run: ./gradlew -p src assembleRelease
|
||||
run: |
|
||||
./gradlew $(echo '${{ toJson(matrix.chunk.modules) }}' | jq -r 'join(" ")')
|
||||
|
||||
- name: Upload APKs (chunk ${{ matrix.chunk }})
|
||||
- name: Upload APKs (${{ matrix.chunk.number }})
|
||||
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
|
||||
if: github.repository == 'yuzono/aniyomi-extensions'
|
||||
with:
|
||||
name: "individual-apks-${{ matrix.chunk }}"
|
||||
name: "individual-apks-${{ matrix.chunk.number }}"
|
||||
path: "**/*.apk"
|
||||
retention-days: 1
|
||||
|
||||
- name: Clean up CI files
|
||||
run: rm signingkey.jks
|
||||
|
||||
publish_repo:
|
||||
name: Check Publish repo
|
||||
publish:
|
||||
name: Check extension repo
|
||||
needs:
|
||||
- build_individual
|
||||
- prepare
|
||||
- build
|
||||
if: github.repository == 'yuzono/aniyomi-extensions'
|
||||
runs-on: ubuntu-latest
|
||||
runs-on: 'ubuntu-24.04'
|
||||
steps:
|
||||
- name: Download APK artifacts
|
||||
uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0
|
||||
@@ -148,7 +148,7 @@ jobs:
|
||||
- name: Create repo artifacts
|
||||
run: |
|
||||
cd PR
|
||||
python ./.github/scripts/move-apks.py
|
||||
python ./.github/scripts/move-built-apks.py
|
||||
INSPECTOR_LINK="$(curl -s "https://api.github.com/repos/komikku-app/aniyomi-extensions-inspector/releases/latest" | jq -r '.assets[0].browser_download_url')"
|
||||
curl -L "$INSPECTOR_LINK" -o ./Inspector.jar
|
||||
java -jar ./Inspector.jar "repo/apk" "output.json" "tmp"
|
||||
@@ -161,9 +161,10 @@ jobs:
|
||||
ref: repo
|
||||
path: repo
|
||||
|
||||
- name: Sync repo
|
||||
- name: Merge repo
|
||||
run: |
|
||||
rsync -a --delete --exclude .git --exclude .gitignore --exclude README.md --exclude repo.json PR/repo/ repo
|
||||
cd repo
|
||||
python ../${{ github.ref_name }}/.github/scripts/merge-repo.py ${{ needs.prepare.outputs.delete }}
|
||||
|
||||
# Showing which extensions are to be updated with this PR
|
||||
- name: Check Deploy repo
|
||||
|
||||
85
.github/workflows/build_push.yml
vendored
85
.github/workflows/build_push.yml
vendored
@@ -10,6 +10,8 @@ on:
|
||||
- '!.github/**'
|
||||
- '.github/scripts/**'
|
||||
- '.github/workflows/build_push.yml'
|
||||
# Manual trigger
|
||||
workflow_dispatch:
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
@@ -20,16 +22,18 @@ permissions:
|
||||
|
||||
env:
|
||||
CI_CHUNK_SIZE: 65
|
||||
IS_PR_CHECK: false
|
||||
|
||||
jobs:
|
||||
prepare:
|
||||
name: Prepare job
|
||||
runs-on: ubuntu-latest
|
||||
runs-on: 'ubuntu-24.04'
|
||||
outputs:
|
||||
individualMatrix: ${{ steps.generate-matrices.outputs.individualMatrix }}
|
||||
latestCommitMessage: ${{ steps.set-env.outputs.LATEST_COMMIT_MESSAGE }}
|
||||
matrix: ${{ steps.generate-matrices.outputs.matrix }}
|
||||
delete: ${{ steps.generate-matrices.outputs.delete }}
|
||||
steps:
|
||||
- name: Clone repo
|
||||
- name: Checkout ${{ github.ref_name }} branch
|
||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
||||
with:
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
@@ -68,81 +72,79 @@ jobs:
|
||||
./.github/scripts/bump-versions.py $isKmk "${{ steps.set-env.outputs.LATEST_COMMIT_MESSAGE }}" ${{ steps.modified-libs.outputs.all_changed_files }}
|
||||
git push
|
||||
|
||||
- name: Get number of modules
|
||||
run: |
|
||||
set -x
|
||||
projects=(src/*/*)
|
||||
- name: Set up Java
|
||||
uses: actions/setup-java@3a4f6e1af504cf6a31855fa899c6aa5355ba6c12 # v4.7.0
|
||||
with:
|
||||
java-version: 17
|
||||
distribution: temurin
|
||||
|
||||
echo "NUM_INDIVIDUAL_MODULES=${#projects[@]}" >> $GITHUB_ENV
|
||||
- name: Set up Gradle
|
||||
uses: gradle/actions/setup-gradle@94baf225fe0a508e581a564467443d0e2379123b # v4.3.0
|
||||
|
||||
- name: Get last successful CI commit
|
||||
id: last_successful_ci_commit
|
||||
uses: nrwl/nx-set-shas@e2e6dc8bce4b0387a05eb687735c39c41580b792 # v4.1.2
|
||||
|
||||
- id: generate-matrices
|
||||
name: Create output matrices
|
||||
uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7.0.1
|
||||
with:
|
||||
script: |
|
||||
const numIndividualModules = process.env.NUM_INDIVIDUAL_MODULES;
|
||||
const chunkSize = process.env.CI_CHUNK_SIZE;
|
||||
run: |
|
||||
python ./.github/scripts/generate-build-matrices.py ${{ steps.last_successful_ci_commit.outputs.base }} Release
|
||||
|
||||
const numIndividualChunks = Math.ceil(numIndividualModules / chunkSize);
|
||||
|
||||
console.log(`Individual modules: ${numIndividualModules} (${numIndividualChunks} chunks of ${chunkSize})`);
|
||||
|
||||
core.setOutput('individualMatrix', { 'chunk': [...Array(numIndividualChunks).keys()] });
|
||||
|
||||
build_individual:
|
||||
name: Build individual modules
|
||||
build:
|
||||
name: Build extensions (${{ matrix.chunk.number }})
|
||||
needs: prepare
|
||||
runs-on: ubuntu-latest
|
||||
runs-on: 'ubuntu-24.04'
|
||||
if: ${{ toJson(fromJson(needs.prepare.outputs.matrix).chunk) != '[]' }}
|
||||
strategy:
|
||||
matrix: ${{ fromJSON(needs.prepare.outputs.individualMatrix) }}
|
||||
matrix: ${{ fromJSON(needs.prepare.outputs.matrix) }}
|
||||
steps:
|
||||
- name: Checkout ${{ github.ref_name }} branch
|
||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
||||
with:
|
||||
ref: ${{ github.ref_name }}
|
||||
|
||||
- name: Set up JDK
|
||||
- name: Set up Java
|
||||
uses: actions/setup-java@c5195efecf7bdfc987ee8bae7a71cb8b11521c00 # v4.7.1
|
||||
with:
|
||||
java-version: 17
|
||||
distribution: temurin
|
||||
|
||||
- name: Set up Gradle
|
||||
uses: gradle/actions/setup-gradle@06832c7b30a0129d7fb559bcc6e43d26f6374244 # v4.3.1
|
||||
with:
|
||||
cache-read-only: ${{ matrix.chunk.number > 1 }}
|
||||
|
||||
- name: Prepare signing key
|
||||
run: |
|
||||
echo ${{ secrets.SIGNING_KEY }} | base64 -d > signingkey.jks
|
||||
chmod 600 signingkey.jks
|
||||
|
||||
- name: Set up Gradle
|
||||
uses: gradle/actions/setup-gradle@06832c7b30a0129d7fb559bcc6e43d26f6374244 # v4.3.1
|
||||
with:
|
||||
cache-read-only: ${{ matrix.chunk != 0 }}
|
||||
|
||||
- name: Build extensions (chunk ${{ matrix.chunk }})
|
||||
- name: Build extensions (${{ matrix.chunk.number }})
|
||||
env:
|
||||
CI_CHUNK_NUM: ${{ matrix.chunk }}
|
||||
ALIAS: ${{ secrets.ALIAS }}
|
||||
KEY_STORE_PASSWORD: ${{ secrets.KEY_STORE_PASSWORD }}
|
||||
KEY_PASSWORD: ${{ secrets.KEY_PASSWORD }}
|
||||
run: ./gradlew -p src assembleRelease
|
||||
run: |
|
||||
./gradlew $(echo '${{ toJson(matrix.chunk.modules) }}' | jq -r 'join(" ")')
|
||||
|
||||
- name: Upload APKs (chunk ${{ matrix.chunk }})
|
||||
- name: Upload APKs (${{ matrix.chunk.number }})
|
||||
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
|
||||
if: github.repository == 'yuzono/aniyomi-extensions'
|
||||
with:
|
||||
name: "individual-apks-${{ matrix.chunk }}"
|
||||
name: "individual-apks-${{ matrix.chunk.number }}"
|
||||
path: "**/*.apk"
|
||||
retention-days: 1
|
||||
|
||||
- name: Clean up CI files
|
||||
run: rm signingkey.jks
|
||||
|
||||
publish_repo:
|
||||
name: Publish repo
|
||||
publish:
|
||||
name: Publish extension repo
|
||||
needs:
|
||||
- prepare
|
||||
- build_individual
|
||||
- build
|
||||
if: github.repository == 'yuzono/aniyomi-extensions'
|
||||
runs-on: ubuntu-latest
|
||||
runs-on: 'ubuntu-24.04'
|
||||
steps:
|
||||
- name: Download APK artifacts
|
||||
uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0
|
||||
@@ -164,7 +166,7 @@ jobs:
|
||||
- name: Create repo artifacts
|
||||
run: |
|
||||
cd ${{ github.ref_name }}
|
||||
python ./.github/scripts/move-apks.py
|
||||
python ./.github/scripts/move-built-apks.py
|
||||
INSPECTOR_LINK="$(curl -s "https://api.github.com/repos/komikku-app/aniyomi-extensions-inspector/releases/latest" | jq -r '.assets[0].browser_download_url')"
|
||||
curl -L "$INSPECTOR_LINK" -o ./Inspector.jar
|
||||
java -jar ./Inspector.jar "repo/apk" "output.json" "tmp"
|
||||
@@ -178,9 +180,10 @@ jobs:
|
||||
ref: repo
|
||||
path: repo
|
||||
|
||||
- name: Sync repo
|
||||
- name: Merge repo
|
||||
run: |
|
||||
rsync -a --delete --exclude .git --exclude .gitignore --exclude README.md --exclude repo.json ${{ github.ref_name }}/repo/ repo
|
||||
cd repo
|
||||
python ../${{ github.ref_name }}/.github/scripts/merge-repo.py ${{ needs.prepare.outputs.delete }}
|
||||
|
||||
- name: Deploy repo
|
||||
uses: EndBug/add-and-commit@a94899bca583c204427a224a7af87c02f9b325d5 # v9.1.4
|
||||
|
||||
@@ -1,18 +1,10 @@
|
||||
buildscript {
|
||||
allprojects {
|
||||
repositories {
|
||||
mavenCentral()
|
||||
google()
|
||||
maven(url = "https://plugins.gradle.org/m2/")
|
||||
maven(url = "https://jitpack.io")
|
||||
}
|
||||
dependencies {
|
||||
classpath(libs.gradle.agp)
|
||||
classpath(libs.gradle.kotlin)
|
||||
classpath(libs.gradle.kotlin.serialization)
|
||||
classpath(libs.gradle.kotlinter)
|
||||
}
|
||||
}
|
||||
|
||||
allprojects {
|
||||
tasks.withType<org.jetbrains.kotlin.gradle.tasks.KotlinCompile>().configureEach {
|
||||
kotlinOptions {
|
||||
jvmTarget = JavaVersion.VERSION_1_8.toString()
|
||||
|
||||
@@ -2,6 +2,12 @@ plugins {
|
||||
`kotlin-dsl`
|
||||
}
|
||||
|
||||
repositories {
|
||||
gradlePluginPortal()
|
||||
mavenCentral()
|
||||
google()
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation(libs.gradle.agp)
|
||||
implementation(libs.gradle.kotlin)
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
apply(from = "../repositories.gradle.kts")
|
||||
|
||||
dependencyResolutionManagement {
|
||||
versionCatalogs {
|
||||
create("libs") {
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
import groovy.lang.MissingPropertyException
|
||||
import org.gradle.api.Project
|
||||
import org.gradle.api.artifacts.ProjectDependency
|
||||
import org.gradle.api.plugins.ExtensionAware
|
||||
import org.gradle.kotlin.dsl.extra
|
||||
|
||||
@@ -6,6 +8,34 @@ var ExtensionAware.baseVersionCode: Int
|
||||
get() = extra.get("baseVersionCode") as Int + baseKmkVersionCode
|
||||
set(value) = extra.set("baseVersionCode", value)
|
||||
|
||||
fun Project.getDependents(): Set<Project> {
|
||||
val dependentProjects = mutableSetOf<Project>()
|
||||
|
||||
rootProject.allprojects.forEach { project ->
|
||||
project.configurations.forEach { configuration ->
|
||||
configuration.dependencies.forEach { dependency ->
|
||||
if (dependency is ProjectDependency && dependency.path == path) {
|
||||
dependentProjects.add(project)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return dependentProjects
|
||||
}
|
||||
|
||||
fun Project.printDependentExtensions() {
|
||||
getDependents().forEach { project ->
|
||||
if (project.path.startsWith(":src:")) {
|
||||
println(project.path)
|
||||
} else if (project.path.startsWith(":lib-multisrc:")) {
|
||||
project.getDependents().forEach { println(it.path) }
|
||||
} else if (project.path.startsWith(":lib:")) {
|
||||
project.printDependentExtensions()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var ExtensionAware.baseKmkVersionCode: Int
|
||||
get() {
|
||||
return try {
|
||||
|
||||
@@ -17,3 +17,9 @@ android {
|
||||
dependencies {
|
||||
compileOnly(versionCatalogs.named("libs").findBundle("common").get())
|
||||
}
|
||||
|
||||
tasks.register("printDependentExtensions") {
|
||||
doLast {
|
||||
project.printDependentExtensions()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -53,3 +53,9 @@ tasks {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
tasks.register("printDependentExtensions") {
|
||||
doLast {
|
||||
project.printDependentExtensions()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,5 +21,7 @@ org.gradle.caching=true
|
||||
|
||||
# Enable AndroidX dependencies
|
||||
android.useAndroidX=true
|
||||
android.nonTransitiveRClass=false
|
||||
android.nonFinalResIds=false
|
||||
|
||||
android.enableBuildConfigAsBytecode=true
|
||||
android.defaults.buildfeatures.resvalues=false
|
||||
android.defaults.buildfeatures.shaders=false
|
||||
|
||||
@@ -1,16 +0,0 @@
|
||||
dependencyResolutionManagement {
|
||||
repositories {
|
||||
gradlePluginPortal()
|
||||
mavenCentral()
|
||||
google()
|
||||
maven(url = "https://jitpack.io")
|
||||
}
|
||||
}
|
||||
|
||||
pluginManagement {
|
||||
repositories {
|
||||
gradlePluginPortal()
|
||||
google()
|
||||
mavenCentral()
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,12 @@
|
||||
apply(from = "repositories.gradle.kts")
|
||||
/**
|
||||
* Add or remove modules to load as needed for local development here.
|
||||
*/
|
||||
loadAllIndividualExtensions()
|
||||
// loadIndividualExtension("all", "jellyfin")
|
||||
|
||||
/**
|
||||
* ===================================== COMMON CONFIGURATION ======================================
|
||||
*/
|
||||
include(":core")
|
||||
|
||||
// Load all modules under /lib
|
||||
@@ -8,26 +15,9 @@ File(rootDir, "lib").eachDir { include("lib:${it.name}") }
|
||||
// Load all modules under /lib-multisrc
|
||||
File(rootDir, "lib-multisrc").eachDir { include("lib-multisrc:${it.name}") }
|
||||
|
||||
if (System.getenv("CI") != "true") {
|
||||
// Local development (full project build)
|
||||
|
||||
/**
|
||||
* Add or remove modules to load as needed for local development here.
|
||||
*/
|
||||
loadAllIndividualExtensions()
|
||||
// loadIndividualExtension("all", "jellyfin")
|
||||
} else {
|
||||
// Running in CI (GitHub Actions)
|
||||
|
||||
val chunkSize = System.getenv("CI_CHUNK_SIZE").toInt()
|
||||
val chunk = System.getenv("CI_CHUNK_NUM").toInt()
|
||||
|
||||
// Loads individual extensions
|
||||
File(rootDir, "src").getChunk(chunk, chunkSize)?.forEach {
|
||||
loadIndividualExtension(it.parentFile.name, it.name)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* ======================================== HELPER FUNCTION ========================================
|
||||
*/
|
||||
fun loadAllIndividualExtensions() {
|
||||
File(rootDir, "src").eachDir { dir ->
|
||||
dir.eachDir { subdir ->
|
||||
@@ -39,18 +29,6 @@ fun loadIndividualExtension(lang: String, name: String) {
|
||||
include("src:$lang:$name")
|
||||
}
|
||||
|
||||
fun File.getChunk(chunk: Int, chunkSize: Int): List<File>? {
|
||||
return listFiles()
|
||||
// Lang folder
|
||||
?.filter { it.isDirectory }
|
||||
// Extension subfolders
|
||||
?.mapNotNull { dir -> dir.listFiles()?.filter { it.isDirectory } }
|
||||
?.flatten()
|
||||
?.sortedBy { it.name }
|
||||
?.chunked(chunkSize)
|
||||
?.get(chunk)
|
||||
}
|
||||
|
||||
fun File.eachDir(block: (File) -> Unit) {
|
||||
val files = listFiles() ?: return
|
||||
for (file in files) {
|
||||
|
||||
Reference in New Issue
Block a user