diff --git a/.gitea/workflows/ci.yml b/.gitea/workflows/ci.yml new file mode 100644 index 0000000..507761b --- /dev/null +++ b/.gitea/workflows/ci.yml @@ -0,0 +1,33 @@ +name: CI + +on: + push: + branches: [main] + pull_request: + +jobs: + check: + runs-on: ubuntu-latest + steps: + - name: 检出代码 + uses: actions/checkout@v4 + + - name: 校验 manifest.json + run: | + set -e + python3 - <<'PY' + import json + m = json.load(open('manifest.json')) + assert m.get('manifest_version') == 3, '必须是 Manifest V3' + for key in ('name', 'version', 'background', 'content_scripts'): + assert key in m, f'缺少字段: {key}' + print(f"manifest OK · {m['name']} v{m['version']}") + PY + + - name: JS 语法检查 + run: | + set -e + for f in background.js content/content.js popup/popup.js options/options.js; do + node --check "$f" && echo "✓ $f" + done + echo "ALL CHECKS PASSED" diff --git a/.gitea/workflows/release.yml b/.gitea/workflows/release.yml new file mode 100644 index 0000000..849782d --- /dev/null +++ b/.gitea/workflows/release.yml @@ -0,0 +1,100 @@ +name: Release + +on: + push: + tags: + - 'v[0-9]+.[0-9]+.[0-9]+' + +jobs: + release: + runs-on: ubuntu-latest + steps: + - name: 检出代码 + uses: actions/checkout@v4 + with: + fetch-depth: 0 # 生成 changelog 需要完整历史 + + - name: 校验 tag 与 manifest 版本一致 + run: | + set -euo pipefail + TAG="${GITHUB_REF_NAME#v}" + VERSION=$(python3 -c "import json; print(json.load(open('manifest.json'))['version'])") + if [ "$TAG" != "$VERSION" ]; then + echo "::error::tag ${GITHUB_REF_NAME} 与 manifest.json 版本 ${VERSION} 不一致。请先更新 manifest.json 的 version 再打 tag。" + exit 1 + fi + echo "VERSION=$VERSION" >> "$GITHUB_ENV" + echo "版本校验通过: v$VERSION" + + - name: 打包扩展 + run: | + set -euo pipefail + ZIP="poplingo-v${VERSION}.zip" + python3 - "$ZIP" <<'PY' + import os, sys, zipfile + zip_name = sys.argv[1] + items = ['manifest.json', 'background.js', 'README.md', 'content', 'popup', 'options', 'icons'] + with zipfile.ZipFile(zip_name, 'w', zipfile.ZIP_DEFLATED) as z: + for item in items: + if os.path.isfile(item): + z.write(item, item) + elif os.path.isdir(item): + for root, _, files in os.walk(item): + for f in files: + p = os.path.join(root, f) + z.write(p, p) + names = zipfile.ZipFile(zip_name).namelist() + assert 'manifest.json' in names, 'zip 缺少 manifest.json' + print(f'打包完成: {zip_name}({len(names)} 个文件)') + PY + echo "ZIP=$ZIP" >> "$GITHUB_ENV" + + - name: 生成 Release Notes + run: | + set -euo pipefail + PREV_TAG=$(git tag --sort=-creatordate | grep -v "^${GITHUB_REF_NAME}$" | head -1 || true) + if [ -n "$PREV_TAG" ]; then + NOTES=$(git log --pretty=format:'- %s' "${PREV_TAG}..${GITHUB_REF_NAME}") + echo "changelog 范围: ${PREV_TAG}..${GITHUB_REF_NAME}" + else + NOTES=$(git log --pretty=format:'- %s') + echo "首个版本,changelog 包含全部提交" + fi + export RELEASE_NOTES="${NOTES:-初始发布}" + python3 <<'PY' + import json, os + body = os.environ['RELEASE_NOTES'] + ( + f"\n\n## 📦 安装\n\n" + f"1. 下载附件 `poplingo-v{os.environ['VERSION']}.zip` 并解压\n" + f"2. 打开 `chrome://extensions/`,开启「开发者模式」,「加载已解压的扩展程序」选择解压目录\n" + f"3. 点击工具栏图标完成模型配置即可使用" + ) + meta = { + 'tag_name': os.environ['GITHUB_REF_NAME'], + 'name': '译泡 PopLingo v' + os.environ['VERSION'], + 'body': body, + 'draft': False, + 'prerelease': False, + } + with open('release_meta.json', 'w') as f: + json.dump(meta, f, ensure_ascii=False) + print('release_meta.json 已生成') + PY + + - name: 创建 Release 并上传附件 + env: + GITEA_TOKEN: ${{ secrets.GITEA_TOKEN }} + run: | + set -euo pipefail + API="${GITHUB_API_URL}/repos/${GITHUB_REPOSITORY}" + curl -sf -X POST "${API}/releases" \ + -H "Authorization: token ${GITEA_TOKEN}" \ + -H "Content-Type: application/json" \ + --data-binary @release_meta.json > release_resp.json + ID=$(python3 -c 'import json; print(json.load(open("release_resp.json"))["id"])') + echo "Release 已创建 (id=${ID})" + curl -sf -X POST "${API}/releases/${ID}/assets?name=${ZIP}" \ + -H "Authorization: token ${GITEA_TOKEN}" \ + -F "attachment=@${ZIP}" + echo + echo "✅ 发布完成: ${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY}/releases/tag/${GITHUB_REF_NAME}" diff --git a/README.md b/README.md index e45a4bc..f212d89 100644 --- a/README.md +++ b/README.md @@ -73,6 +73,27 @@ fanyi/ └── README.md ``` +## 🚀 版本发布(Gitea Actions 流水线) + +流水线跑在 NUC 的 act_runner 上,配置见 `.gitea/workflows/`: + +| 工作流 | 触发条件 | 作用 | +|---|---|---| +| `ci.yml` | push 到 `main` / PR | manifest 校验 + JS 语法检查 | +| `release.yml` | 推送 `vX.Y.Z` 标签 | 校验版本一致 → 打包 zip → 生成 Changelog → 创建 Release 并上传附件 | + +发版三步: + +```bash +# 1. 更新 manifest.json 中的 version 字段 +# 2. 提交 +git add -A && git commit -m "release: v1.0.1" +# 3. 打 tag 并推送(tag 必须与 manifest 版本一致,否则流水线报错) +git tag v1.0.1 && git push origin main --tags +``` + +发布地址:`https://git.zzzjy.cloud/zzzjy/PopLingo/releases` + ## ❓ 常见问题 - **本地 HTML 文件不生效**:在 `chrome://extensions/` → 本插件 → 详情 → 打开「允许访问文件网址」