From 209776a9e853c8a2a4e44dffb540d2f29226bb6e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=89=8B=E7=93=9C=E4=B8=80=E5=8D=81=E9=9B=AA?= Date: Tue, 3 Feb 2026 15:28:13 +0800 Subject: [PATCH] Cache QQ installer and handle win64 files Update GitHub Actions release workflow to use a cached QQ x64 installer (updated NT_URL), add cache key generation and actions/cache usage, and implement a download-and-extract step that reuses the cache. Adjust temporary directory usage (WORK_TMPDIR/NODE_EXTRACT), add LightQuic.dll to copy targets, and copy specific win64 files into an OUT_DIR/win64 folder. Update packages/napcat-develop/loadNapCat.cjs to recognize and copy win64 artifacts: add TARGET_WIN64_DIR, include LightQuic.dll, define win64ItemsToCopy (SSOShareInfoHelper64.dll, parent-ipc-core-x64.dll), validate their presence, ensure target directories, and copy win64 files into dist/win64. These changes speed CI by caching the installer and ensure required win64 DLLs are packaged alongside the main distribution. --- .github/workflows/release.yml | 54 +++++++++++++++++++++++--- packages/napcat-develop/loadNapCat.cjs | 19 ++++++++- 2 files changed, 67 insertions(+), 6 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index fb4d1f63..726e51a2 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -125,18 +125,54 @@ jobs: cd "$TMPDIR" # ----------------------------- - # 1) 下载 QQ x64 + # 1) 下载 QQ x64 (使用缓存) # ----------------------------- # JS_URL="https://cdn-go.cn/qq-web/im.qq.com_new/latest/rainbow/windowsConfig.js" # JS_URL="https://slave.docadan488.workers.dev/proxy?url=https://cdn-go.cn/qq-web/im.qq.com_new/latest/rainbow/windowsConfig.js" # NT_URL=$(curl -fsSL "$JS_URL" | grep -oP '"ntDownloadX64Url"\s*:\s*"\K[^"]+') - NT_URL="https://dldir1v6.qq.com/qqfile/qq/QQNT/eb263b35/QQ9.9.23.42086_x64.exe" + NT_URL="https://dldir1v6.qq.com/qqfile/qq/QQNT/32876254/QQ9.9.27.45627_x64.exe" QQ_ZIP="$(basename "$NT_URL")" - aria2c -x16 -s16 -k1M -o "$QQ_ZIP" "$NT_URL" + # 根据 URL 生成缓存键 + QQ_CACHE_KEY="qq-x64-$(echo "$NT_URL" | md5sum | cut -d' ' -f1)" + echo "QQ_CACHE_KEY=$QQ_CACHE_KEY" >> $GITHUB_ENV + echo "QQ_ZIP=$QQ_ZIP" >> $GITHUB_ENV + echo "NT_URL=$NT_URL" >> $GITHUB_ENV + + - name: Cache QQ x64 Installer + id: cache-qq + uses: actions/cache@v4 + with: + path: ~/qq-cache + key: ${{ env.QQ_CACHE_KEY }} + + - name: Download and Extract QQ x64 + run: | + set -euo pipefail + TMPDIR=$(mktemp -d) + cd "$TMPDIR" + + QQ_CACHE_DIR="$HOME/qq-cache" + mkdir -p "$QQ_CACHE_DIR" + + if [ -f "$QQ_CACHE_DIR/$QQ_ZIP" ]; then + echo "Using cached QQ installer: $QQ_ZIP" + cp "$QQ_CACHE_DIR/$QQ_ZIP" "$QQ_ZIP" + else + echo "Downloading QQ installer: $QQ_ZIP" + aria2c -x16 -s16 -k1M -o "$QQ_ZIP" "$NT_URL" + cp "$QQ_ZIP" "$QQ_CACHE_DIR/$QQ_ZIP" + fi QQ_EXTRACT="$TMPDIR/qq_extracted" mkdir -p "$QQ_EXTRACT" 7z x -y -o"$QQ_EXTRACT" "$QQ_ZIP" >/dev/null + echo "QQ_EXTRACT=$QQ_EXTRACT" >> $GITHUB_ENV + echo "WORK_TMPDIR=$TMPDIR" >> $GITHUB_ENV + + - name: Download Node.js and Assemble NapCat.Shell.Windows.Node.zip + run: | + set -euo pipefail + cd "$WORK_TMPDIR" # ----------------------------- # 2) 下载 Node.js Windows x64 zip 22.11.0 @@ -146,7 +182,7 @@ jobs: NODE_ZIP="node-v$NODE_VER-win-x64.zip" aria2c -x1 -s1 -k1M -o "$NODE_ZIP" "$NODE_URL" - NODE_EXTRACT="$TMPDIR/node_extracted" + NODE_EXTRACT="$WORK_TMPDIR/node_extracted" mkdir -p "$NODE_EXTRACT" unzip -q "$NODE_ZIP" -d "$NODE_EXTRACT" @@ -164,11 +200,18 @@ jobs: # ----------------------------- # 5) 拷贝 QQ 文件到 NapCat.Shell.Windows.Node # ----------------------------- - QQ_TARGETS=("avif_convert.dll" "broadcast_ipc.dll" "config.json" "libglib-2.0-0.dll" "libgobject-2.0-0.dll" "libvips-42.dll" "ncnn.dll" "opencv.dll" "package.json" "QBar.dll" "wrapper.node") + QQ_TARGETS=("avif_convert.dll" "broadcast_ipc.dll" "config.json" "libglib-2.0-0.dll" "libgobject-2.0-0.dll" "libvips-42.dll" "ncnn.dll" "opencv.dll" "package.json" "QBar.dll" "wrapper.node" "LightQuic.dll") for name in "${QQ_TARGETS[@]}"; do find "$QQ_EXTRACT" -iname "$name" -exec cp -a {} "$OUT_DIR" \; || true done + # ----------------------------- + # 5.1) 拷贝 win64 目录下的文件 + # ----------------------------- + mkdir -p "$OUT_DIR/win64" + find "$QQ_EXTRACT" -ipath "*/win64/SSOShareInfoHelper64.dll" -exec cp -a {} "$OUT_DIR/win64/" \; || true + find "$QQ_EXTRACT" -ipath "*/win64/parent-ipc-core-x64.dll" -exec cp -a {} "$OUT_DIR/win64/" \; || true + # ----------------------------- # 6) 拷贝仓库文件 napcat.bat 和 index.js # ----------------------------- @@ -178,6 +221,7 @@ jobs: # ----------------------------- # 7) 拷贝 Node.exe 到 NapCat.Shell.Windows.Node # ----------------------------- + NODE_VER="22.11.0" cp -a "$NODE_EXTRACT/node-v$NODE_VER-win-x64/node.exe" "$OUT_DIR/" || true - name: Upload Artifact diff --git a/packages/napcat-develop/loadNapCat.cjs b/packages/napcat-develop/loadNapCat.cjs index ef72dd09..df5c1686 100644 --- a/packages/napcat-develop/loadNapCat.cjs +++ b/packages/napcat-develop/loadNapCat.cjs @@ -32,6 +32,7 @@ if (versionFolders.length === 0) { const BASE_DIR = path.join(versionsDir, selectedFolder, 'resources', 'app'); console.log(`BASE_DIR: ${BASE_DIR}`); const TARGET_DIR = path.join(__dirname, 'dist'); +const TARGET_WIN64_DIR = path.join(__dirname, 'dist', 'win64'); const QQNT_FILE = path.join(__dirname, 'QQNT.dll'); const NAPCAT_MJS_PATH = path.join(__dirname, '..', 'napcat-shell', 'dist', 'napcat.mjs'); @@ -46,6 +47,12 @@ const itemsToCopy = [ 'package.json', 'QBar.dll', 'wrapper.node', + 'LightQuic.dll' +]; + +const win64ItemsToCopy = [ + 'SSOShareInfoHelper64.dll', + 'parent-ipc-core-x64.dll' ]; async function copyAll () { @@ -53,13 +60,23 @@ async function copyAll () { const configPath = path.join(TARGET_DIR, 'config.json'); const allItemsExist = await fs.pathExists(qqntDllPath) && await fs.pathExists(configPath) && - (await Promise.all(itemsToCopy.map(item => fs.pathExists(path.join(TARGET_DIR, item))))).every(exists => exists); + (await Promise.all(itemsToCopy.map(item => fs.pathExists(path.join(TARGET_DIR, item))))).every(exists => exists) && + (await Promise.all(win64ItemsToCopy.map(item => fs.pathExists(path.join(TARGET_WIN64_DIR, item))))).every(exists => exists); if (!allItemsExist) { console.log('Copying required files...'); await fs.ensureDir(TARGET_DIR); + await fs.ensureDir(TARGET_WIN64_DIR); await fs.copy(QQNT_FILE, qqntDllPath, { overwrite: true }); await fs.copy(path.join(versionsDir, 'config.json'), configPath, { overwrite: true }); + + // 复制 win64 目录下的文件 + await Promise.all(win64ItemsToCopy.map(async (item) => { + await fs.copy(path.join(BASE_DIR, 'win64', item), path.join(TARGET_WIN64_DIR, item), { overwrite: true }); + console.log(`Copied ${item} to win64`); + })); + + // 复制根目录下的文件 await Promise.all(itemsToCopy.map(async (item) => { await fs.copy(path.join(BASE_DIR, item), path.join(TARGET_DIR, item), { overwrite: true }); console.log(`Copied ${item}`);