diff --git a/.github/workflows/publish-extension.yml b/.github/workflows/publish-extension.yml index 4e6671b..fc44a6a 100644 --- a/.github/workflows/publish-extension.yml +++ b/.github/workflows/publish-extension.yml @@ -35,16 +35,19 @@ jobs: with: node-version: "18" + - name: 安装 Node.js 依赖 + run: npm ci + # 第四步:验证 manifest 文件格式 - name: 验证 manifest 文件 run: | # 验证 Chrome manifest.json 是否为有效的 JSON node -e "JSON.parse(require('fs').readFileSync('manifest.json', 'utf8'))" - echo "✅ Chrome manifest.json 格式有效" + echo "[OK] Chrome manifest.json 格式有效" # 验证 Firefox manifest 是否为有效的 JSON node -e "JSON.parse(require('fs').readFileSync('manifest-firefox.json', 'utf8'))" - echo "✅ Firefox manifest.json 格式有效" + echo "[OK] Firefox manifest.json 格式有效" # 第五步:设置版本号 - name: 从输入设置版本 @@ -52,17 +55,23 @@ jobs: run: | # 从工作流输入获取版本号 VERSION="${{ inputs.version }}" + if ! printf '%s' "$VERSION" | grep -Eq '^[0-9]+\.[0-9]+\.[0-9]+$'; then + echo "版本号格式非法: $VERSION" + exit 1 + fi echo "version=$VERSION" >> $GITHUB_OUTPUT echo "手动设置版本: $VERSION" # 第六步:更新所有配置文件中的版本号 - name: 更新 manifest 版本 + env: + VERSION: ${{ steps.version.outputs.version }} run: | # 更新 Chrome manifest.json 中的版本 node -e " const fs = require('fs'); const manifest = JSON.parse(fs.readFileSync('manifest.json', 'utf8')); - manifest.version = '${{ steps.version.outputs.version }}'; + manifest.version = process.env.VERSION; fs.writeFileSync('manifest.json', JSON.stringify(manifest, null, 2)); console.log('已更新 Chrome manifest.json 版本为:', manifest.version); " @@ -71,22 +80,18 @@ jobs: node -e " const fs = require('fs'); const manifest = JSON.parse(fs.readFileSync('manifest-firefox.json', 'utf8')); - manifest.version = '${{ steps.version.outputs.version }}'; + manifest.version = process.env.VERSION; fs.writeFileSync('manifest-firefox.json', JSON.stringify(manifest, null, 2)); console.log('已更新 Firefox manifest.json 版本为:', manifest.version); " # 第七步:同步更新 package.json 版本 - name: 更新 package.json 版本 + env: + VERSION: ${{ steps.version.outputs.version }} run: | - # 更新 package.json 中的版本以保持一致性 - node -e " - const fs = require('fs'); - const pkg = JSON.parse(fs.readFileSync('package.json', 'utf8')); - pkg.version = '${{ steps.version.outputs.version }}'; - fs.writeFileSync('package.json', JSON.stringify(pkg, null, 2)); - console.log('已更新 package.json 版本为:', pkg.version); - " + npm version "$VERSION" --no-git-tag-version + echo "已同步 package.json 和 package-lock.json 版本为: $VERSION" # 第八步:提交版本更改并创建 Git 标签 - name: 提交并推送版本更新 @@ -96,7 +101,7 @@ jobs: git config --local user.name "GitHub Action" # 添加更新的文件 - git add manifest.json manifest-firefox.json package.json + git add manifest.json manifest-firefox.json package.json package-lock.json # 检查是否有需要提交的更改 if git diff --staged --quiet; then @@ -112,25 +117,26 @@ jobs: git push origin HEAD:main git push origin "v${{ steps.version.outputs.version }}" - echo "✅ 版本更新已提交并推送到主分支,包含标签" + echo "[OK] 版本更新已提交并推送到主分支,包含标签" fi - name: 构建扩展包 run: | - echo "🏗️ 开始构建扩展包..." + echo "开始构建扩展包..." # 运行构建脚本构建所有平台 python build.py --platform all --package - echo "📦 扩展包构建完成" + echo "扩展包构建完成" ls -la packages/ || echo "packages 目录不存在" - name: 运行测试 run: | - echo "🧪 运行基础测试..." + echo "运行基础测试..." python dev.py test + npm run test:unit - echo "🔍 运行代码检查..." + echo "运行代码检查..." python dev.py lint - name: 发布到 Chrome 应用商店 @@ -178,9 +184,10 @@ jobs: files: | packages/Xget-Now_${{ steps.version.outputs.version }}.chromium.zip packages/Xget-Now_${{ steps.version.outputs.version }}.firefox.xpi + packages/Xget-Now_${{ steps.version.outputs.version }}.userscript.user.js generate_release_notes: true body: | - ## 📦 扩展包下载 + ## 扩展包下载 ### Chromium - **文件**: `Xget-Now_${{ steps.version.outputs.version }}.chromium.zip` @@ -192,11 +199,16 @@ jobs: - **支持**: Firefox 或其他基于 Firefox 的浏览器 - **Manifest**: v2 - ## 🚀 安装方法 + ### Userscript + - **文件**: `Xget-Now_${{ steps.version.outputs.version }}.userscript.user.js` + - **支持**: 用户脚本管理器 + - **能力**: GitHub、GitLab、Gitea、Codeberg、Hugging Face、PyPI、npm、SourceForge 下载加速 + + ## 安装方法 详细的安装说明请参考:[手动安装指南](https://github.com/xixu-me/Xget-Now?tab=readme-ov-file#%E6%89%8B%E5%8A%A8%E5%AE%89%E8%A3%85) - ## 📝 更新日志 + ## 更新日志 详细的更改内容请查看下方的自动生成的发布说明。 @@ -205,51 +217,52 @@ jobs: - name: 检查发布结果 run: | - echo "📊 发布结果摘要:" + echo "发布结果摘要:" echo "================================" - echo "📦 版本: ${{ steps.version.outputs.version }}" + echo "版本: ${{ steps.version.outputs.version }}" echo "" if [ "${{ steps.chrome-publish.outcome }}" = "success" ]; then - echo "✅ Chrome 应用商店: 发布成功" + echo "[OK] Chrome 应用商店: 发布成功" elif [ "${{ steps.chrome-publish.outcome }}" = "failure" ]; then - echo "❌ Chrome 应用商店: 发布失败" + echo "[FAIL] Chrome 应用商店: 发布失败" else - echo "⚠️ Chrome 应用商店: 已跳过(缺少密钥或其他原因)" + echo "[WARN] Chrome 应用商店: 已跳过(缺少密钥或其他原因)" fi if [ "${{ steps.edge-publish.outcome }}" = "success" ]; then - echo "✅ Edge 加载项: 发布成功" + echo "[OK] Edge 加载项: 发布成功" elif [ "${{ steps.edge-publish.outcome }}" = "failure" ]; then - echo "❌ Edge 加载项: 发布失败" + echo "[FAIL] Edge 加载项: 发布失败" else - echo "⚠️ Edge 加载项: 已跳过(缺少密钥或其他原因)" + echo "[WARN] Edge 加载项: 已跳过(缺少密钥或其他原因)" fi if [ "${{ steps.firefox-publish.outcome }}" = "success" ]; then - echo "✅ Firefox 附加组件: 发布成功" + echo "[OK] Firefox 附加组件: 发布成功" elif [ "${{ steps.firefox-publish.outcome }}" = "failure" ]; then - echo "❌ Firefox 附加组件: 发布失败" + echo "[FAIL] Firefox 附加组件: 发布失败" else - echo "⚠️ Firefox 附加组件: 已跳过(缺少密钥或其他原因)" + echo "[WARN] Firefox 附加组件: 已跳过(缺少密钥或其他原因)" fi echo "" - echo "✅ GitHub 发布: 已创建包含所有扩展文件" + echo "[OK] GitHub 发布: 已创建包含所有扩展文件" echo "================================" - name: 通知成功 run: | echo "" - echo "🎉 成功发布 Xget Now ${{ steps.version.outputs.version }}!" + echo "成功发布 Xget Now ${{ steps.version.outputs.version }}" echo "================================" - echo "🔗 Chrome 应用商店: https://chrome.google.com/webstore/detail/${{ secrets.CHROME_EXTENSION_ID }}" - echo "🔗 Edge 加载项: 查看发布页面获取最新信息" - echo "🦊 Firefox 附加组件: 查看 Mozilla Add-ons 获取最新信息" - echo "📦 GitHub 发布: https://github.com/${{ github.repository }}/releases/tag/v${{ steps.version.outputs.version }}" - echo "📖 安装指南: https://github.com/${{ github.repository }}#installation" + echo "Chrome 应用商店: https://chrome.google.com/webstore/detail/${{ secrets.CHROME_EXTENSION_ID }}" + echo "Edge 加载项: 查看发布页面获取最新信息" + echo "Firefox 附加组件: 查看 Mozilla Add-ons 获取最新信息" + echo "GitHub 发布: https://github.com/${{ github.repository }}/releases/tag/v${{ steps.version.outputs.version }}" + echo "安装指南: https://github.com/${{ github.repository }}#installation" echo "" - echo "📁 发布的文件:" + echo "发布的文件:" echo " - Xget-Now_${{ steps.version.outputs.version }}.chromium.zip (Chromium)" echo " - Xget-Now_${{ steps.version.outputs.version }}.firefox.xpi (Firefox)" + echo " - Xget-Now_${{ steps.version.outputs.version }}.userscript.user.js (Userscript)" echo "================================" diff --git a/.github/workflows/test-build.yml b/.github/workflows/test-build.yml index 1885e3d..766e77f 100644 --- a/.github/workflows/test-build.yml +++ b/.github/workflows/test-build.yml @@ -45,6 +45,9 @@ jobs: with: node-version: "18" + - name: 安装 Node.js 依赖 + run: npm ci + - name: 验证 manifest 文件 run: | echo "验证 Chrome manifest..." @@ -78,6 +81,8 @@ jobs: "src/content/index.js" "src/popup/popup.js" "src/popup/index.html" + "src/shared/download-core.js" + "src/userscript/index.js" "src/shared/compat/webext-compat.js" "src/shared/compat/firefox-compat.js" "src/shared/platform-detector.js" @@ -88,9 +93,9 @@ jobs: for file in "${required_files[@]}"; do if [ -f "$file" ]; then - echo "✅ $file" + echo "[OK] $file" else - echo "❌ $file 缺失" + echo "[FAIL] $file 缺失" exit 1 fi done @@ -99,6 +104,7 @@ jobs: run: | echo "运行基础测试..." python dev.py test + npm run test:unit - name: 运行代码检查 run: | @@ -112,10 +118,10 @@ jobs: # 验证构建结果 if [ -d "build/chrome" ]; then - echo "✅ Chrome 构建目录已创建" + echo "[OK] Chrome 构建目录已创建" ls -la build/chrome/ else - echo "❌ Chrome 构建失败" + echo "[FAIL] Chrome 构建失败" exit 1 fi @@ -126,10 +132,23 @@ jobs: # 验证构建结果 if [ -d "build/firefox" ]; then - echo "✅ Firefox 构建目录已创建" + echo "[OK] Firefox 构建目录已创建" ls -la build/firefox/ else - echo "❌ Firefox 构建失败" + echo "[FAIL] Firefox 构建失败" + exit 1 + fi + + - name: 测试 userscript 构建 + run: | + echo "测试 userscript 构建..." + python build.py --platform userscript + + if [ -f "build/userscript/xget-now.user.js" ]; then + echo "[OK] userscript 构建文件已生成" + ls -la build/userscript/ + else + echo "[FAIL] userscript 构建失败" exit 1 fi @@ -137,26 +156,36 @@ jobs: run: | echo "测试扩展包生成..." python build.py --platform all --package + VERSION=$(node -p 'require("./package.json").version') # 验证扩展包 if [ -d "packages" ]; then - echo "✅ 扩展包目录已创建" + echo "[OK] 扩展包目录已创建" ls -la packages/ - # 检查是否有 Chrome 和 Firefox 包 - if [ -f packages/xget-now-chrome-v*.zip ]; then - echo "✅ Chrome 扩展包已生成" + # 检查是否有 Chrome、Firefox 和 userscript 包 + if [ -f "packages/Xget-Now_${VERSION}.chromium.zip" ]; then + echo "[OK] Chrome 扩展包已生成" else - echo "❌ Chrome 扩展包生成失败" + echo "[FAIL] Chrome 扩展包生成失败" + exit 1 fi - if [ -f packages/xget-now-firefox-v*.zip ]; then - echo "✅ Firefox 扩展包已生成" + if [ -f "packages/Xget-Now_${VERSION}.firefox.xpi" ]; then + echo "[OK] Firefox 扩展包已生成" else - echo "❌ Firefox 扩展包生成失败" + echo "[FAIL] Firefox 扩展包生成失败" + exit 1 + fi + + if [ -f "packages/Xget-Now_${VERSION}.userscript.user.js" ]; then + echo "[OK] userscript 包已生成" + else + echo "[FAIL] userscript 包生成失败" + exit 1 fi else - echo "❌ 扩展包生成失败" + echo "[FAIL] 扩展包生成失败" exit 1 fi @@ -193,6 +222,19 @@ jobs: } " + echo "检查 userscript 构建..." + node -e " + const fs = require('fs'); + const userscript = fs.readFileSync('build/userscript/xget-now.user.js', 'utf8'); + if (!userscript.includes('@grant GM_xmlhttpRequest')) { + throw new Error('userscript 构建缺少 GM_xmlhttpRequest grant'); + } + if (!userscript.includes('@run-at document-start')) { + throw new Error('userscript 构建缺少 document-start 配置'); + } + console.log('Userscript 元数据验证通过'); + " + - name: 上传构建结果 uses: actions/upload-artifact@v7 with: @@ -205,15 +247,16 @@ jobs: - name: 测试总结 run: | echo "" - echo "🎉 所有测试通过!" + echo "所有测试通过" echo "================================" - echo "✅ Manifest 文件验证" - echo "✅ 必需文件检查" - echo "✅ 基础测试" - echo "✅ 代码检查" - echo "✅ Chrome 构建" - echo "✅ Firefox 构建" - echo "✅ 扩展包生成" - echo "✅ 构建结果验证" + echo "[OK] Manifest 文件验证" + echo "[OK] 必需文件检查" + echo "[OK] 基础测试" + echo "[OK] 代码检查" + echo "[OK] Chrome 构建" + echo "[OK] Firefox 构建" + echo "[OK] userscript 构建" + echo "[OK] 扩展包生成" + echo "[OK] 构建结果验证" echo "================================" - echo "🚀 准备发布!" + echo "准备发布" diff --git a/build.py b/build.py index d117ba8..8cc9701 100644 --- a/build.py +++ b/build.py @@ -379,11 +379,11 @@ def validate_manifest(manifest_path, platform): "applications" in manifest or "browser_specific_settings" in manifest ), "Firefox 需要应用ID" - print(f"✓ {platform} manifest 验证通过") + print(f"[OK] {platform} manifest 验证通过") return True except Exception as e: - print(f"✗ {platform} manifest 验证失败: {e}") + print(f"[FAIL] {platform} manifest 验证失败: {e}") return False @@ -440,7 +440,7 @@ def main(): # 总结 print("\n构建总结:") for platform, build_dir in build_results: - print(f"✓ {platform}: {build_dir}") + print(f"[OK] {platform}: {build_dir}") if args.package: print("\n构建包位于 packages/ 目录") diff --git a/dev.py b/dev.py index ab38d10..29b2b7c 100644 --- a/dev.py +++ b/dev.py @@ -68,6 +68,8 @@ def watch_files(): "src/content/index.js", "src/popup/popup.js", "src/popup/index.html", + "src/shared/download-core.js", + "src/userscript/index.js", "src/shared/compat/webext-compat.js", "src/shared/compat/firefox-compat.js", "src/shared/platform-detector.js", @@ -101,9 +103,9 @@ def watch_files(): text=True, ) if result.returncode == 0: - print("✓ 构建成功") + print("[OK] 构建成功") else: - print(f"✗ 构建失败: {result.stderr}") + print(f"[FAIL] 构建失败: {result.stderr}") time.sleep(1) @@ -154,11 +156,11 @@ def run_tests(): assert manifest["manifest_version"] == 2, "Firefox 需要 Manifest V2" assert "browser_action" in manifest, "Firefox 需要 browser_action 字段" - print(f"✓ {platform} manifest 测试通过") + print(f"[OK] {platform} manifest 测试通过") return True except Exception as e: - print(f"✗ {platform} manifest 测试失败: {e}") + print(f"[FAIL] {platform} manifest 测试失败: {e}") return False # 测试文件存在性 @@ -170,6 +172,8 @@ def run_tests(): "src/content/index.js", "src/popup/popup.js", "src/popup/index.html", + "src/shared/download-core.js", + "src/userscript/index.js", "src/shared/compat/webext-compat.js", "src/shared/compat/firefox-compat.js", "src/shared/platform-detector.js", @@ -179,9 +183,9 @@ def run_tests(): all_exist = True for file in required_files: if os.path.exists(file): - print(f"✓ {file} 存在") + print(f"[OK] {file} 存在") else: - print(f"✗ {file} 不存在") + print(f"[FAIL] {file} 不存在") all_exist = False return all_exist @@ -220,6 +224,8 @@ def lint_code(): "src/background/index.js", "src/content/index.js", "src/popup/popup.js", + "src/shared/download-core.js", + "src/userscript/index.js", "src/shared/compat/webext-compat.js", "src/shared/compat/firefox-compat.js", "src/shared/platform-detector.js", @@ -271,11 +277,11 @@ def lint_code(): issues.append("建议使用 console.error 处理错误") if issues: - print(f" ⚠ {file} 发现问题:") + print(f" [WARN] {file} 发现问题:") for issue in issues: print(f" - {issue}") else: - print(f" ✓ {file} 无明显问题") + print(f" [OK] {file} 无明显问题") def main(): diff --git a/src/popup/index.html b/src/popup/index.html index c0ad8a6..56d7da8 100644 --- a/src/popup/index.html +++ b/src/popup/index.html @@ -409,7 +409,6 @@ class="link-item" style="margin-bottom: 10px; display: inline-block" > - URL 转换器