JP assets sync #23
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: JP assets sync | |
| # 统一 workflow:手动触发,自动判断冷启动/增量 | |
| # - 首次运行(无 cache):冷启动,全量下载 | |
| # - 后续运行(有 cache):增量,只下载 diff | |
| # - 可强制冷启动:workflow_dispatch.cold_start = true | |
| on: | |
| workflow_dispatch: | |
| inputs: | |
| cold_start: | |
| description: 'Force cold start (full re-download)' | |
| required: false | |
| default: false | |
| type: boolean | |
| permissions: | |
| contents: write | |
| jobs: | |
| sync: | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 480 | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@v5 | |
| - name: Set up Python | |
| uses: actions/setup-python@v5 | |
| with: | |
| python-version: "3.11" | |
| - name: Install azlassets | |
| run: | | |
| python -m pip install --upgrade pip | |
| pip install azlassets | |
| azl --help | |
| # Restore cache: state + last snapshots | |
| - name: Restore cache | |
| id: cache | |
| uses: actions/cache@v5 | |
| with: | |
| path: | | |
| jp-client-state.tar | |
| last_loadingbg | |
| last_gallerypic | |
| key: jp-assets-v2-${{ runner.os }}-${{ github.run_id }} | |
| restore-keys: | | |
| jp-assets-v2-${{ runner.os }}- | |
| # Determine mode: cold start if cache miss or forced | |
| # Note: cache-hit is only "true" for exact key match. restore-keys fallback = "false". | |
| # So we check if jp-client-state.tar actually exists (restored via restore-keys). | |
| - name: Determine run mode | |
| id: mode | |
| run: | | |
| HAS_CACHE=false | |
| if [ -f "jp-client-state.tar" ] && [ -s "jp-client-state.tar" ]; then | |
| HAS_CACHE=true | |
| fi | |
| if [ "$HAS_CACHE" != "true" ] || [ "${{ inputs.cold_start }}" == "true" ]; then | |
| echo "mode=cold" >> $GITHUB_OUTPUT | |
| echo "Mode: COLD START (full download)" | |
| else | |
| echo "mode=incremental" >> $GITHUB_OUTPUT | |
| echo "Mode: INCREMENTAL (diff sync)" | |
| tar -xf jp-client-state.tar | |
| fi | |
| # Download JP assets | |
| - name: Download JP assets | |
| run: | | |
| python - <<'PY' | |
| import sys | |
| import azl | |
| import azlassets.classes as cls | |
| import azlassets.updater as updater | |
| # Patch: VersionType __hash__ | |
| VT = getattr(cls, "VersionType", None) | |
| if VT and getattr(VT, "__hash__", None) is None: | |
| VT.__hash__ = lambda self: hash(str(self)) | |
| print("[patch] Patched VersionType.__hash__") | |
| # Patch: remove_asset / delete_asset_safe for directories | |
| import pathlib, shutil | |
| for attr in ('remove_asset', 'delete_asset_safe'): | |
| if hasattr(updater, attr): | |
| orig = getattr(updater, attr) | |
| def patched(f, orig): | |
| def wrapper(assetpath): | |
| p = pathlib.Path(assetpath.full) if hasattr(assetpath, 'full') else pathlib.Path(assetpath) | |
| if p.is_dir(): | |
| shutil.rmtree(p) | |
| print(f"[patch] Removed dir: {p}") | |
| else: | |
| f(assetpath) | |
| return wrapper | |
| setattr(updater, attr, patched(orig, orig)) | |
| print(f"[patch] Patched updater.{attr} for directory deletion") | |
| break | |
| # Download | |
| if "${{ steps.mode.outputs.mode }}" == "cold": | |
| sys.argv = ["azl", "download", "JP", "--force-refresh"] | |
| else: | |
| sys.argv = ["azl", "download", "JP"] | |
| azl.main() | |
| print("[done] Download complete.") | |
| # Extract | |
| sys.argv = ["azl", "extract", "JP"] | |
| azl.main() | |
| print("[done] Extract complete.") | |
| PY | |
| # Collect current files | |
| - name: Collect loadingbg | |
| run: python scripts/collect_loadingbg.py | |
| - name: Collect gallerypic | |
| run: python scripts/collect_gallerypic.py | |
| # Show collected | |
| - name: Show collected files | |
| run: | | |
| echo "=== loadingbg ===" | |
| if [ -d "current_loadingbg" ] && [ -n "$(ls -A current_loadingbg 2>/dev/null)" ]; then | |
| echo "$(ls current_loadingbg/ | wc -l) files, $(du -sh current_loadingbg/ | cut -f1)" | |
| else | |
| echo "(empty)" | |
| fi | |
| echo "=== gallerypic ===" | |
| if [ -d "current_gallerypic" ] && [ -n "$(ls -A current_gallerypic 2>/dev/null)" ]; then | |
| echo "$(ls current_gallerypic/ | wc -l) files, $(du -sh current_gallerypic/ | cut -f1)" | |
| else | |
| echo "(empty)" | |
| fi | |
| # Pack: cold start → only full zips | |
| - name: Pack full zips (cold start) | |
| if: steps.mode.outputs.mode == 'cold' | |
| run: | | |
| if [ -d "current_loadingbg" ] && [ -n "$(ls -A current_loadingbg 2>/dev/null)" ]; then | |
| zip -r loadingbg_full.zip current_loadingbg | |
| fi | |
| if [ -d "current_gallerypic" ] && [ -n "$(ls -A current_gallerypic 2>/dev/null)" ]; then | |
| zip -r gallerypic_full.zip current_gallerypic | |
| fi | |
| # Diff: incremental → diff + full zips | |
| - name: Diff and pack (incremental) | |
| if: steps.mode.outputs.mode == 'incremental' | |
| run: | | |
| bash scripts/diff_and_zip.sh | |
| bash scripts/diff_and_zip_gallerypic.sh | |
| - name: Read diff status | |
| if: steps.mode.outputs.mode == 'incremental' | |
| id: diffcheck | |
| run: | | |
| echo "has_diff=$(cat has_diff.flag 2>/dev/null || echo false)" >> $GITHUB_OUTPUT | |
| echo "has_diff_gallerypic=$(cat has_diff_gallerypic.flag 2>/dev/null || echo false)" >> $GITHUB_OUTPUT | |
| # Update cache: merge current into last to keep full snapshot | |
| - name: Update cache | |
| run: | | |
| # ⚠️ 关键:current_* 是 azl 增量提取的(仅 diff), | |
| # 必须**合并**到 last_* 才能保持 last 是「远端当前全量」。 | |
| # 漏写 merge 会导致 last_* 被替换成 current_* 的少量文件,丢失历史。 | |
| if [ -d "current_loadingbg" ] && [ -n "$(ls -A current_loadingbg 2>/dev/null)" ]; then | |
| mkdir -p last_loadingbg | |
| # 用 cp -r 覆盖同名,保留 last 中独有文件 | |
| # (不能用 cp -n no-clobber,否则 current 中的新版无法覆盖 last 中的旧版) | |
| cp -r current_loadingbg/. last_loadingbg/ | |
| echo "[cache] last_loadingbg merged: $(ls last_loadingbg | wc -l) files" | |
| else | |
| echo "[cache] current_loadingbg empty, keeping last_loadingbg ($(ls last_loadingbg 2>/dev/null | wc -l) files)" | |
| fi | |
| if [ -d "current_gallerypic" ] && [ -n "$(ls -A current_gallerypic 2>/dev/null)" ]; then | |
| mkdir -p last_gallerypic | |
| cp -r current_gallerypic/. last_gallerypic/ | |
| echo "[cache] last_gallerypic merged: $(ls last_gallerypic | wc -l) files" | |
| else | |
| echo "[cache] current_gallerypic empty, keeping last_gallerypic ($(ls last_gallerypic 2>/dev/null | wc -l) files)" | |
| fi | |
| # Pack state | |
| rm -rf state_tmp && mkdir -p state_tmp/ClientAssets | |
| if [ -d "ClientAssets/JP" ]; then | |
| cp -r ClientAssets/JP state_tmp/ClientAssets/ | |
| rm -rf state_tmp/ClientAssets/JP/AssetBundles | |
| fi | |
| tar -cf jp-client-state.tar -C state_tmp ClientAssets | |
| echo "Cache updated." | |
| # Generate meta | |
| - name: Generate meta info | |
| run: | | |
| echo "client=JP" > meta.txt | |
| echo "mode=${{ steps.mode.outputs.mode }}" >> meta.txt | |
| echo "generated_at=$(date -u +%Y-%m-%dT%H:%M:%SZ)" >> meta.txt | |
| if [ "${{ steps.mode.outputs.mode }}" == "incremental" ]; then | |
| echo "has_diff=${{ steps.diffcheck.outputs.has_diff }}" >> meta.txt | |
| echo "has_diff_gallerypic=${{ steps.diffcheck.outputs.has_diff_gallerypic }}" >> meta.txt | |
| fi | |
| # Publish Release | |
| - name: Publish to Release | |
| uses: softprops/action-gh-release@v2 | |
| with: | |
| tag_name: jp-loadingbg-latest | |
| name: JP assets (${{ steps.mode.outputs.mode }}) | |
| body: | | |
| JP assets sync (${{ steps.mode.outputs.mode }}). | |
| - jp-client-state.tar: azlassets logical state | |
| - loadingbg_full.zip / gallerypic_full.zip: full snapshots | |
| - loadingbg_diff.zip / gallerypic_diff.zip: incremental diffs (if any) | |
| files: | | |
| jp-client-state.tar | |
| loadingbg_full.zip | |
| gallerypic_full.zip | |
| meta.txt | |
| # Upload diff zips conditionally | |
| - name: Upload loadingbg diff | |
| if: steps.mode.outputs.mode == 'incremental' && steps.diffcheck.outputs.has_diff == 'true' | |
| uses: softprops/action-gh-release@v2 | |
| with: | |
| tag_name: jp-loadingbg-latest | |
| files: loadingbg_diff.zip | |
| - name: Upload gallerypic diff | |
| if: steps.mode.outputs.mode == 'incremental' && steps.diffcheck.outputs.has_diff_gallerypic == 'true' | |
| uses: softprops/action-gh-release@v2 | |
| with: | |
| tag_name: jp-loadingbg-latest | |
| files: gallerypic_diff.zip |