mirror of
https://github.com/TommyFang2077/dsh-desktop.git
synced 2026-08-17 09:06:36 +08:00
release: v0.1.2
- bundle dshmarket 1.10.1; drop the duplicate vision settings section (modlens card is the single config surface) - embed the updater signing public key in every build (Makefile / CI / Flatpak); in-app updates now actually run - structured release notes per version: docs/release-notes/v<version>.md feeds GitHub, Gitea and the in-app update panel - gate releases on the notes file; Gitea publish reads/patches the same body
This commit is contained in:
@@ -48,18 +48,34 @@ done
|
||||
exit 1
|
||||
}
|
||||
|
||||
# Structured release body from docs/release-notes/v<version>.md; legacy
|
||||
# fallback only when the file is missing (the version job normally gates it).
|
||||
RELEASE_NOTES="docs/release-notes/v${RELEASE_VERSION}.md"
|
||||
if [[ -f "$RELEASE_NOTES" ]]; then
|
||||
release_body=$(cat "$RELEASE_NOTES")
|
||||
else
|
||||
release_body="大陆镜像安装包;文件与 GitHub Release 同源。应用内更新包由 Tauri 签名校验。"
|
||||
fi
|
||||
|
||||
release_json=$(curl_retry curl --fail --silent --show-error -H "$AUTH" "$API/releases/tags/$RELEASE_TAG")
|
||||
release_id=$(printf '%s' "$release_json" | jq -r '.id // empty')
|
||||
if [[ -z "$release_id" ]]; then
|
||||
release_payload=$(jq -n \
|
||||
--arg tag "$RELEASE_TAG" \
|
||||
--arg name "DeepSeek Harness Desktop $RELEASE_TAG" \
|
||||
--arg body "大陆镜像安装包;文件与 GitHub Release 同源。应用内更新包由 Tauri 签名校验。" \
|
||||
--arg body "$release_body" \
|
||||
'{tag_name:$tag,target_commitish:$tag,name:$name,body:$body,draft:false,prerelease:false}')
|
||||
release_json=$(curl_retry curl --fail --silent --show-error \
|
||||
-X POST -H "$AUTH" -H 'Content-Type: application/json' \
|
||||
--data "$release_payload" "$API/releases")
|
||||
release_id=$(printf '%s' "$release_json" | jq -r '.id')
|
||||
else
|
||||
# The mirror may have synced an older, terse GitHub body; keep the Gitea
|
||||
# copy identical to the structured notes file on every publish.
|
||||
curl_retry curl --fail --silent --show-error -X PATCH -H "$AUTH" \
|
||||
-H 'Content-Type: application/json' \
|
||||
--data "$(jq -n --arg body "$release_body" '{body:$body}')" \
|
||||
"$API/releases/$release_id" >/dev/null
|
||||
fi
|
||||
|
||||
# Versioned generic package: immutable URLs consumed by latest.json.
|
||||
|
||||
67
scripts/release-notes.py
Executable file
67
scripts/release-notes.py
Executable file
@@ -0,0 +1,67 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Extract release-copy fragments from a structured per-version notes file.
|
||||
|
||||
Notes live under docs/release-notes/v<version>.md in this layout:
|
||||
|
||||
# DeepSeek Harness Desktop v0.1.2
|
||||
|
||||
**摘要 / Summary:** one short bilingual paragraph …
|
||||
|
||||
## 新功能 / Features
|
||||
- …
|
||||
|
||||
## 修复 / Fixes
|
||||
- …
|
||||
|
||||
## 安装与更新 / Install & Update
|
||||
- …
|
||||
|
||||
Subcommands:
|
||||
body FILE the full file (GitHub / Gitea release body)
|
||||
notes FILE the 摘要 / Summary paragraph, one line (in-app update notes)
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import argparse
|
||||
import re
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
TITLE_RE = re.compile(r"^# .+$", re.M)
|
||||
SUMMARY_RE = re.compile(r"^\*\*摘要\s*/\s*Summary:\*\*\s*(.+)$", re.M)
|
||||
|
||||
|
||||
def load(path: Path) -> str:
|
||||
text = path.read_text(encoding="utf-8")
|
||||
if TITLE_RE.search(text) is None:
|
||||
raise SystemExit(f"{path}: expected a '# ' title line")
|
||||
return text
|
||||
|
||||
|
||||
def read_body(path: Path) -> str:
|
||||
text = load(path)
|
||||
if not text.endswith("\n"):
|
||||
text += "\n"
|
||||
return text
|
||||
|
||||
|
||||
def read_notes(path: Path) -> str:
|
||||
text = load(path)
|
||||
match = SUMMARY_RE.search(text)
|
||||
if match is None:
|
||||
raise SystemExit(f"{path}: missing '**摘要 / Summary:**' line")
|
||||
return match.group(1).strip()
|
||||
|
||||
|
||||
def main() -> None:
|
||||
parser = argparse.ArgumentParser(description=__doc__.splitlines()[0])
|
||||
parser.add_argument("subcommand", choices=["body", "notes"])
|
||||
parser.add_argument("file")
|
||||
args = parser.parse_args()
|
||||
out = read_body(Path(args.file)) if args.subcommand == "body" else read_notes(Path(args.file))
|
||||
sys.stdout.write(out if out.endswith("\n") else out + "\n")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in New Issue
Block a user