Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c471c0f348 | ||
|
|
cc365c2cd8 |
+107
-23
@@ -4,6 +4,14 @@ on:
|
|||||||
push:
|
push:
|
||||||
tags:
|
tags:
|
||||||
- 'v[0-9]+.[0-9]+.[0-9]+'
|
- 'v[0-9]+.[0-9]+.[0-9]+'
|
||||||
|
workflow_dispatch:
|
||||||
|
inputs:
|
||||||
|
version:
|
||||||
|
description: '要发布的版本号(不含 v 前缀,例如 1.0.1)'
|
||||||
|
required: true
|
||||||
|
notes:
|
||||||
|
description: '发布说明(可选,留空自动生成 changelog)'
|
||||||
|
required: false
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
release:
|
release:
|
||||||
@@ -14,17 +22,76 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
fetch-depth: 0 # 生成 changelog 需要完整历史
|
fetch-depth: 0 # 生成 changelog 需要完整历史
|
||||||
|
|
||||||
- name: 校验 tag 与 manifest 版本一致
|
- name: 确定版本号
|
||||||
|
env:
|
||||||
|
EVENT_NAME: ${{ github.event_name }}
|
||||||
|
INPUT_VERSION: ${{ inputs.version }}
|
||||||
run: |
|
run: |
|
||||||
set -euo pipefail
|
set -euo pipefail
|
||||||
TAG="${GITHUB_REF_NAME#v}"
|
if [ "$EVENT_NAME" = "workflow_dispatch" ]; then
|
||||||
VERSION=$(python3 -c "import json; print(json.load(open('manifest.json'))['version'])")
|
VERSION="$INPUT_VERSION"
|
||||||
if [ "$TAG" != "$VERSION" ]; then
|
else
|
||||||
echo "::error::tag ${GITHUB_REF_NAME} 与 manifest.json 版本 ${VERSION} 不一致。请先更新 manifest.json 的 version 再打 tag。"
|
VERSION="${GITHUB_REF_NAME#v}"
|
||||||
|
fi
|
||||||
|
if ! [[ "$VERSION" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
|
||||||
|
echo "::error::版本号格式应为 X.Y.Z(收到:${VERSION:-空})"
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
echo "VERSION=$VERSION" >> "$GITHUB_ENV"
|
echo "VERSION=$VERSION" >> "$GITHUB_ENV"
|
||||||
echo "版本校验通过: v$VERSION"
|
echo "TAG=v$VERSION" >> "$GITHUB_ENV"
|
||||||
|
echo "本次发版:v$VERSION(触发方式:$EVENT_NAME)"
|
||||||
|
|
||||||
|
- name: 网页触发:同步 manifest 版本并打 tag
|
||||||
|
if: ${{ github.event_name == 'workflow_dispatch' }}
|
||||||
|
env:
|
||||||
|
GITEA_TOKEN: ${{ secrets.GITEA_TOKEN }}
|
||||||
|
ACTOR: ${{ github.actor }}
|
||||||
|
run: |
|
||||||
|
set -euo pipefail
|
||||||
|
CUR=$(python3 -c "import json; print(json.load(open('manifest.json'))['version'])")
|
||||||
|
if [ "$CUR" != "$VERSION" ]; then
|
||||||
|
python3 - "$VERSION" <<'PY'
|
||||||
|
import json, sys
|
||||||
|
v = sys.argv[1]
|
||||||
|
m = json.load(open('manifest.json'))
|
||||||
|
m['version'] = v
|
||||||
|
with open('manifest.json', 'w') as f:
|
||||||
|
json.dump(m, f, ensure_ascii=False, indent=2)
|
||||||
|
f.write('\n')
|
||||||
|
PY
|
||||||
|
git config user.name "${ACTOR}"
|
||||||
|
git config user.email "${ACTOR}@users.noreply.${GITHUB_SERVER_URL#https://}"
|
||||||
|
git add manifest.json
|
||||||
|
git commit -m "release: v${VERSION} [skip ci]"
|
||||||
|
echo "manifest.json 版本 $CUR -> $VERSION,已提交([skip ci] 防止重复触发流水线)"
|
||||||
|
else
|
||||||
|
echo "manifest.json 已是 $VERSION,无需提交"
|
||||||
|
fi
|
||||||
|
if git rev-parse -q --verify "refs/tags/${TAG}" >/dev/null; then
|
||||||
|
TAG_SHA=$(git rev-parse "${TAG}^{commit}")
|
||||||
|
HEAD_SHA=$(git rev-parse HEAD)
|
||||||
|
if [ "$TAG_SHA" != "$HEAD_SHA" ]; then
|
||||||
|
echo "::error::tag ${TAG} 已存在且指向其他提交,请先处理(删除旧 tag 或换版本号)"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
echo "tag ${TAG} 已存在且指向当前提交,复用"
|
||||||
|
else
|
||||||
|
git tag "$TAG"
|
||||||
|
fi
|
||||||
|
HOST="${GITHUB_SERVER_URL#https://}"
|
||||||
|
PUSH_URL="https://x-access-token:${GITEA_TOKEN}@${HOST}/${GITHUB_REPOSITORY}.git"
|
||||||
|
git push "$PUSH_URL" "HEAD:${GITHUB_REF_NAME}" 2>/dev/null || echo "分支无新提交,跳过推送"
|
||||||
|
git push "$PUSH_URL" "$TAG" 2>/dev/null || echo "tag 已在远端,跳过推送"
|
||||||
|
|
||||||
|
- name: 校验版本一致性
|
||||||
|
run: |
|
||||||
|
set -euo pipefail
|
||||||
|
MV=$(python3 -c "import json; print(json.load(open('manifest.json'))['version'])")
|
||||||
|
if [ "$MV" != "$VERSION" ]; then
|
||||||
|
echo "::error::manifest.json 版本 $MV 与目标 $VERSION 不一致"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
echo "版本一致性校验通过:v$VERSION"
|
||||||
|
|
||||||
- name: 打包扩展
|
- name: 打包扩展
|
||||||
run: |
|
run: |
|
||||||
@@ -50,15 +117,22 @@ jobs:
|
|||||||
echo "ZIP=$ZIP" >> "$GITHUB_ENV"
|
echo "ZIP=$ZIP" >> "$GITHUB_ENV"
|
||||||
|
|
||||||
- name: 生成 Release Notes
|
- name: 生成 Release Notes
|
||||||
|
env:
|
||||||
|
INPUT_NOTES: ${{ inputs.notes }}
|
||||||
run: |
|
run: |
|
||||||
set -euo pipefail
|
set -euo pipefail
|
||||||
PREV_TAG=$(git tag --sort=-creatordate | grep -v "^${GITHUB_REF_NAME}$" | head -1 || true)
|
if [ -n "${INPUT_NOTES:-}" ]; then
|
||||||
if [ -n "$PREV_TAG" ]; then
|
NOTES="$INPUT_NOTES"
|
||||||
NOTES=$(git log --pretty=format:'- %s' "${PREV_TAG}..${GITHUB_REF_NAME}")
|
echo "使用手动填写的发布说明"
|
||||||
echo "changelog 范围: ${PREV_TAG}..${GITHUB_REF_NAME}"
|
|
||||||
else
|
else
|
||||||
NOTES=$(git log --pretty=format:'- %s')
|
PREV_TAG=$(git tag --sort=-creatordate | grep -v "^${TAG}$" | head -1 || true)
|
||||||
echo "首个版本,changelog 包含全部提交"
|
if [ -n "$PREV_TAG" ]; then
|
||||||
|
NOTES=$(git log --pretty=format:'- %s' "${PREV_TAG}..${TAG}")
|
||||||
|
echo "changelog 范围: ${PREV_TAG}..${TAG}"
|
||||||
|
else
|
||||||
|
NOTES=$(git log --pretty=format:'- %s')
|
||||||
|
echo "首个版本,changelog 包含全部提交"
|
||||||
|
fi
|
||||||
fi
|
fi
|
||||||
export RELEASE_NOTES="${NOTES:-初始发布}"
|
export RELEASE_NOTES="${NOTES:-初始发布}"
|
||||||
python3 <<'PY'
|
python3 <<'PY'
|
||||||
@@ -70,7 +144,7 @@ jobs:
|
|||||||
f"3. 点击工具栏图标完成模型配置即可使用"
|
f"3. 点击工具栏图标完成模型配置即可使用"
|
||||||
)
|
)
|
||||||
meta = {
|
meta = {
|
||||||
'tag_name': os.environ['GITHUB_REF_NAME'],
|
'tag_name': os.environ['TAG'],
|
||||||
'name': '译泡 PopLingo v' + os.environ['VERSION'],
|
'name': '译泡 PopLingo v' + os.environ['VERSION'],
|
||||||
'body': body,
|
'body': body,
|
||||||
'draft': False,
|
'draft': False,
|
||||||
@@ -81,20 +155,30 @@ jobs:
|
|||||||
print('release_meta.json 已生成')
|
print('release_meta.json 已生成')
|
||||||
PY
|
PY
|
||||||
|
|
||||||
- name: 创建 Release 并上传附件
|
- name: 创建 Release 并上传附件(幂等,可安全重试)
|
||||||
env:
|
env:
|
||||||
GITEA_TOKEN: ${{ secrets.GITEA_TOKEN }}
|
GITEA_TOKEN: ${{ secrets.GITEA_TOKEN }}
|
||||||
run: |
|
run: |
|
||||||
set -euo pipefail
|
set -euo pipefail
|
||||||
API="${GITHUB_API_URL}/repos/${GITHUB_REPOSITORY}"
|
API="${GITHUB_API_URL}/repos/${GITHUB_REPOSITORY}"
|
||||||
curl -sf -X POST "${API}/releases" \
|
AUTH="Authorization: token ${GITEA_TOKEN}"
|
||||||
-H "Authorization: token ${GITEA_TOKEN}" \
|
EXIST=$(curl -sf -H "$AUTH" "${API}/releases/tags/${TAG}" || true)
|
||||||
-H "Content-Type: application/json" \
|
if [ -n "$EXIST" ]; then
|
||||||
--data-binary @release_meta.json > release_resp.json
|
ID=$(echo "$EXIST" | python3 -c 'import json,sys; print(json.load(sys.stdin)["id"])')
|
||||||
ID=$(python3 -c 'import json; print(json.load(open("release_resp.json"))["id"])')
|
HAS_ASSET=$(echo "$EXIST" | python3 -c "import json,sys; r=json.load(sys.stdin); print(1 if any(a['name']=='$ZIP' for a in r.get('assets',[])) else 0)")
|
||||||
echo "Release 已创建 (id=${ID})"
|
echo "Release ${TAG} 已存在(id=${ID}),复用"
|
||||||
|
if [ "$HAS_ASSET" = "1" ]; then
|
||||||
|
echo "附件 ${ZIP} 已存在,无需重复上传"
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
curl -sf -X POST "${API}/releases" \
|
||||||
|
-H "$AUTH" -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})"
|
||||||
|
fi
|
||||||
curl -sf -X POST "${API}/releases/${ID}/assets?name=${ZIP}" \
|
curl -sf -X POST "${API}/releases/${ID}/assets?name=${ZIP}" \
|
||||||
-H "Authorization: token ${GITEA_TOKEN}" \
|
-H "$AUTH" -F "attachment=@${ZIP}"
|
||||||
-F "attachment=@${ZIP}"
|
|
||||||
echo
|
echo
|
||||||
echo "✅ 发布完成: ${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY}/releases/tag/${GITHUB_REF_NAME}"
|
echo "✅ 发布完成: ${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY}/releases/tag/${TAG}"
|
||||||
|
|||||||
@@ -82,7 +82,17 @@ fanyi/
|
|||||||
| `ci.yml` | push 到 `main` / PR | manifest 校验 + JS 语法检查 |
|
| `ci.yml` | push 到 `main` / PR | manifest 校验 + JS 语法检查 |
|
||||||
| `release.yml` | 推送 `vX.Y.Z` 标签 | 校验版本一致 → 打包 zip → 生成 Changelog → 创建 Release 并上传附件 |
|
| `release.yml` | 推送 `vX.Y.Z` 标签 | 校验版本一致 → 打包 zip → 生成 Changelog → 创建 Release 并上传附件 |
|
||||||
|
|
||||||
发版三步:
|
### 方式一:网页触发(推荐)
|
||||||
|
|
||||||
|
打开仓库 **Actions → Release workflow → Run workflow**,填入版本号(如 `1.0.2`),点 Run 即可。流水线会自动:
|
||||||
|
|
||||||
|
1. 把 `manifest.json` 的 `version` 同步为该版本号并提交(提交带 `[skip ci]`,避免重复触发)
|
||||||
|
2. 创建并推送 `vX.Y.Z` 标签
|
||||||
|
3. 打包 zip、生成 changelog、创建 Release 并上传附件
|
||||||
|
|
||||||
|
可选填「发布说明」,留空则自动生成;重复触发同一版本是幂等的,不会重复发布。
|
||||||
|
|
||||||
|
### 方式二:本地打 tag
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# 1. 更新 manifest.json 中的 version 字段
|
# 1. 更新 manifest.json 中的 version 字段
|
||||||
|
|||||||
+2
-2
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"manifest_version": 3,
|
"manifest_version": 3,
|
||||||
"name": "译泡 · PopLingo — AI 划词翻译",
|
"name": "译泡 · PopLingo — AI 划词翻译",
|
||||||
"version": "1.0.0",
|
"version": "1.0.1",
|
||||||
"description": "划词即译的大模型翻译气泡:DeepSeek / OpenAI / Kimi / 智谱 / 通义 / Gemini / Claude / Ollama,流式输出。",
|
"description": "划词即译的大模型翻译气泡:DeepSeek / OpenAI / Kimi / 智谱 / 通义 / Gemini / Claude / Ollama,流式输出。",
|
||||||
"minimum_chrome_version": "116",
|
"minimum_chrome_version": "116",
|
||||||
"permissions": [
|
"permissions": [
|
||||||
@@ -60,4 +60,4 @@
|
|||||||
"description": "翻译当前选中的文本"
|
"description": "翻译当前选中的文本"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user