From a8ece73038d32ad7fc7eb628045bb8c4ef435f37 Mon Sep 17 00:00:00 2001 From: OpenClaw Agent Date: Tue, 15 Sep 2026 06:28:57 +0800 Subject: [PATCH] =?UTF-8?q?ci:=20=E8=87=AA=E5=8A=A8=E5=8C=96=E6=8F=90?= =?UTF-8?q?=E5=8F=96=20CHANGELOG.md=20=E4=BD=9C=E4=B8=BA=20GitHub=20Releas?= =?UTF-8?q?e=20=E6=8F=8F=E8=BF=B0=EF=BC=8C=E5=B9=B6=E5=90=8C=E6=AD=A5?= =?UTF-8?q?=E5=8E=86=E5=8F=B2=20Release=20Notes?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/build-apk.yml | 20 +++++++++ .github/workflows/sync-releases.yml | 68 +++++++++++++++++++++++++++++ CHANGELOG.md | 41 +++++++++++++++++ 3 files changed, 129 insertions(+) create mode 100644 .github/workflows/sync-releases.yml create mode 100644 CHANGELOG.md diff --git a/.github/workflows/build-apk.yml b/.github/workflows/build-apk.yml index 666da02..757936f 100644 --- a/.github/workflows/build-apk.yml +++ b/.github/workflows/build-apk.yml @@ -99,12 +99,32 @@ jobs: path: ${{ steps.prepare_apk.outputs.apk_path }} retention-days: 30 + - name: Extract Release Notes from CHANGELOG + if: startsWith(github.ref, 'refs/tags/v') + run: | + python3 -c " + import re + version = '${{ steps.prepare_apk.outputs.version }}' + tag = 'v' + version if not version.startswith('v') else version + try: + with open('CHANGELOG.md', 'r', encoding='utf-8') as f: + content = f.read() + pattern = r'### ' + re.escape(tag) + r'[^\n]*\n(.*?)(?=\n### v|\Z)' + m = re.search(pattern, content, re.DOTALL) + notes = m.group(1).strip() if m else '' + except Exception: + notes = '' + with open('current_release_notes.md', 'w', encoding='utf-8') as f: + f.write(notes) + " + - name: Create GitHub Release if: startsWith(github.ref, 'refs/tags/v') uses: softprops/action-gh-release@v2 with: files: ${{ steps.prepare_apk.outputs.apk_path }} name: Work Hours Tracker v${{ steps.prepare_apk.outputs.version }} + body_path: current_release_notes.md draft: false prerelease: false generate_release_notes: true diff --git a/.github/workflows/sync-releases.yml b/.github/workflows/sync-releases.yml new file mode 100644 index 0000000..0e6276c --- /dev/null +++ b/.github/workflows/sync-releases.yml @@ -0,0 +1,68 @@ +name: Sync Release Notes + +on: + workflow_dispatch: + push: + paths: + - 'CHANGELOG.md' + - '.github/workflows/sync-releases.yml' + +jobs: + update-releases: + runs-on: ubuntu-latest + permissions: + contents: write + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Update GitHub Releases + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + REPO: ${{ github.repository }} + run: | + python3 -c " + import os, urllib.request, json, re + + token = os.environ['GITHUB_TOKEN'] + repo = os.environ['REPO'] + headers = { + 'Authorization': f'Bearer {token}', + 'Accept': 'application/vnd.github+json', + 'User-Agent': 'Actions-Release-Syncer' + } + + # 1. 解析 CHANGELOG.md 中的各版本内容 + with open('CHANGELOG.md', 'r', encoding='utf-8') as f: + content = f.read() + + pattern = r'### (v\d+\.\d+\.\d+)[^\n]*\n(.*?)(?=\n### v|\Z)' + matches = re.findall(pattern, content, re.DOTALL) + changelogs = {tag: body.strip() for tag, body in matches} + print('Found changelogs for tags:', list(changelogs.keys())) + + # 2. 获取现有的 releases + url = f'https://api.github.com/repos/{repo}/releases' + req = urllib.request.Request(url, headers=headers) + with urllib.request.urlopen(req) as resp: + releases = json.loads(resp.read().decode()) + + # 3. 逐个更新 release body + for r in releases: + tag = r.get('tag_name') + rel_id = r.get('id') + if tag in changelogs: + new_body = changelogs[tag] + # 补全 compare 链接 + if 'Full Changelog' not in new_body: + new_body += f'\n\n---\n**Full Changelog**: https://github.com/{repo}/commits/{tag}' + + update_url = f'https://api.github.com/repos/{repo}/releases/{rel_id}' + data = json.dumps({'body': new_body}).encode('utf-8') + up_req = urllib.request.Request(update_url, data=data, headers=headers, method='PATCH') + with urllib.request.urlopen(up_req) as up_resp: + print(f'Successfully updated release {tag} (ID: {rel_id})') + else: + print(f'No changelog found for tag {tag}') + " diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..f6a3a2f --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,41 @@ +## 七、 版本发布历史 (Changelog) + +### v1.0.2 (2026-09-15) +- **修复 (MCP 状态联动与生命周期)**: + - 修复退出登录后前端 `mcp` 响应式对象残留已开启状态、点击关闭弹出「未登录」错误的问题。 + - 新增 `resetMcpState(authNeeded)` 函数,在 `doLogout` 成功退出时联动重置 MCP 状态并清空掩码。 + - `loadMcpStatus` 增加登录凭证前置检测与 401/403 异常拦截重置;在 `doLogin` 成功后自动拉取当前账号的专属 MCP 状态。 + - 未登录时 MCP 接入开关与生成令牌按钮自动置灰禁用,右上角徽章明确显示「本设备请先登录」,`toggleMcp` 增加前置拦截提示。 +- **Android 原生资产与版本**: + - 静态资产同步至 `android/app/src/main/assets/www/`。 + - 版本号升级:`versionCode 3`,`versionName "1.0.2"`。 + +### v1.0.1 (2026-09-15) +- **应用名称统一**: + - Android 原生应用名称统一由「工时记账」修改为「工时打卡」(`strings.xml`)。 + - `MainActivity.java` 连续双击返回退出提示文案同步更新为「再按一次退出工时打卡」。 +- **默认远程服务器探活与回退**: + - `sync.js` 预设 `DEFAULT_REMOTE_BASE = 'https://daka.kory.kdns.fr'`。 + - 深度适配 Android WebView `file:///android_asset/...` 环境,未手动指定服务器地址时自动探活并回退到默认远程服务器。 +- **设置页交互分流与体验重构**: + - 底部导航栏点击「设置」原生切换至 `
` 独立全屏视图,保持打卡、汇总、设置三页平级体验。 + - 顶部导航栏齿轮图标保留快速弹出轻量半屏抽屉(`settingsOpen`)能力,满足快捷调整设置的需求。 +- **登录 / 注册模式解耦**: + - 在设置页「云端同步」卡片中引入「账号登录 / 注册新账号」模式切换(`authMode`)。 + - 彻底解除了等待服务端异步探测返回 `allowRegister` 按钮才浮现的延迟限制。 +- **文档与发版**: + - 补充 README「六、 Android 客户端与移动端打包」章节。 + - 版本号升级:`versionCode 2`,`versionName "1.0.1"`。 + +### v1.0.0 (2026-09-15) +- **Android 原生离线客户端支持**: + - 新增基于 Android WebView 的原生包装容器(`android/` 工程)。 + - 将前端静态资产封装在本地 assets,支持完全脱网离线运行及沉浸式体验。 +- **构建环境与依赖约束修复**: + - 解决 GitHub Actions CI 构建 Release APK 出现的 Kotlin stdlib 多版本冲突(`Duplicate class kotlin.collections.jdk8.CollectionsJDK8Kt`)。 + - 在 `android/app/build.gradle` 引入 Kotlin BOM 平台依赖约束:`org.jetbrains.kotlin:kotlin-bom:1.8.22`。 +- **CI/CD 自动化构建流水线**: + - 新增 `.github/workflows/build-apk.yml` 自动化构建工作流。 + - 支持推送 `v*` 标签时自动编译、签名并发布 GitHub Release 及附带 APK 校验和。 +- **系统核心基线**: + - Local-First 本地优先架构、纯函数薪酬计算引擎(`shared/payroll.js`)、启动自愈守卫、多用户数据隔离与用户级只读 MCP 服务。