From dce31f97298aece171f82ddbc8a5f4669641c724 Mon Sep 17 00:00:00 2001 From: voson Date: Fri, 9 Jan 2026 16:54:56 +0800 Subject: [PATCH] =?UTF-8?q?docs:=20=E6=9B=B4=E6=96=B0=E5=91=BD=E4=BB=A4?= =?UTF-8?q?=E6=96=87=E6=A1=A3=E5=92=8C=E5=8F=91=E5=B8=83=E8=84=9A=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 更新 release-android.md: 明确前置条件和通用项目支持 - 更新 auto-commit.md: 添加中英文 commit 信息平台选择规则 - 更新 commit-push.md: 添加中英文 commit 信息平台选择规则 - 更新 sync-oc-push.md: 添加中英文 commit 信息平台选择规则 - 更新 release-android.mjs: 支持从 tags 自动推断项目名,不再硬编码 android 前缀 - 更新 AGENTS.md: 补充中文交流规则的注意事项 --- AGENTS.md | 19 ++- bin/release-android.mjs | 240 +++++++++++++++++++++++++++++-------- command/auto-commit.md | 46 +++---- command/commit-push.md | 46 +++---- command/release-android.md | 41 +++---- command/sync-oc-push.md | 15 ++- 6 files changed, 292 insertions(+), 115 deletions(-) diff --git a/AGENTS.md b/AGENTS.md index 83d68f4..c49173c 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -9,4 +9,21 @@ - 用户明确要求使用其他语言 - 技术术语在中文中没有合适的翻译(可以中英文混用,如 "React Hooks") -这是用户的个人偏好设置,适用于所有项目。 +### 重要注意事项 + +1. **不要因为文档、命令或代码是英文就切换语言** + - 即使项目文档是英文的,回复时仍然用中文解释 + - 即使执行的命令是英文的,回复时仍然用中文说明 + - 即使错误信息是英文的,回复时仍然用中文分析 + +2. **工具输出可以保持原语言** + - 代码本身使用英文(函数名、变量名等) + - 终端命令使用英文 + - 但你对这些内容的解释和说明必须用中文 + +3. **用户交互始终用中文** + - 所有对话、提问、确认都用中文 + - 所有建议、总结、分析都用中文 + - 所有错误解释和问题诊断都用中文 + +这是用户的个人偏好设置,适用于所有项目和所有交互场景。 diff --git a/bin/release-android.mjs b/bin/release-android.mjs index 23c9eb2..028ae02 100755 --- a/bin/release-android.mjs +++ b/bin/release-android.mjs @@ -17,9 +17,14 @@ * - GITEA_REPO (optional): Override repository name * * Usage: - * node release-android.mjs [android-dir] + * node release-android.mjs [--project ] [android-dir] * - * If android-dir is not specified, will auto-detect from current directory. + * --project Specify project name (e.g., admin-tool, android) + * android-dir Android project directory (optional, auto-detect if not specified) + * + * Examples: + * node release-android.mjs --project admin-tool + * node release-android.mjs --project android ./android */ import fs from 'node:fs'; @@ -179,11 +184,76 @@ function readVersion(androidDir) { } /** - * Get tag name based on project structure + * Infer project name from Android directory name and git tags + * Returns the prefix used in tags (e.g., "myapp", "android", or "") */ -function getTagName(version, isMonorepoProject) { - // Monorepo uses prefixed tag, standalone uses v-prefix - return isMonorepoProject ? `android-${version}` : `v${version}`; +function inferProjectName(gitRoot, androidDir) { + try { + // First, try to infer from Android directory name + const dirName = path.basename(androidDir); + + // Get all tags with version pattern + const tags = execSync('git tag -l --sort=-version:refname', { + cwd: gitRoot, + encoding: 'utf-8', + shell: true, + stdio: ['pipe', 'pipe', 'pipe'] + }).trim().split('\n').filter(Boolean); + + if (tags.length === 0) { + return null; + } + + // If directory name matches any tag prefix, prefer that + // For example: if dir is "admin-tool", look for "admin-tool-*" tags + const dirPrefixTags = tags.filter(tag => tag.startsWith(`${dirName}-`)); + if (dirPrefixTags.length > 0) { + return dirName; + } + + // If directory is "android" or "app", try "android" prefix + if (dirName === 'android' || dirName === 'app') { + const androidTags = tags.filter(tag => tag.startsWith('android-')); + if (androidTags.length > 0) { + return 'android'; + } + } + + // Fallback: try to extract prefix from recent tags + // Patterns: "myapp-1.0.0", "android-1.0.0", "v1.0.0" + for (const tag of tags.slice(0, 10)) { // Check recent 10 tags + const match = tag.match(/^(.+?)-\d+\.\d+/); + if (match) { + return match[1]; // Return prefix like "myapp", "android" + } + if (tag.match(/^v\d+\.\d+/)) { + return ''; // v-prefix style (no project name) + } + } + + return null; + } catch { + return null; + } +} + +/** + * Get latest tag that matches the pattern + */ +function getLatestTag(gitRoot, projectPrefix) { + try { + const pattern = projectPrefix ? `${projectPrefix}-*` : 'v*'; + const tag = execSync(`git tag -l '${pattern}' --sort=-version:refname | head -1`, { + cwd: gitRoot, + encoding: 'utf-8', + shell: true, + stdio: ['pipe', 'pipe', 'pipe'] + }).trim(); + + return tag || null; + } catch { + return null; + } } /** @@ -236,7 +306,7 @@ function getTagInfo(tagName, gitRoot) { * Build Android APK */ function buildApk(androidDir, javaHome) { - console.log('Building APK...'); + console.log('正在构建 APK...'); execSync('./gradlew assembleRelease --quiet', { cwd: androidDir, stdio: 'inherit', @@ -290,12 +360,12 @@ function uploadToGitea(config) { const existingRelease = releases.find((r) => r.tag_name === tagName); if (existingRelease) { releaseId = existingRelease.id; - console.log(`Found existing Release (ID: ${releaseId})`); + console.log(`找到已存在的 Release (ID: ${releaseId})`); // Delete existing asset with same name const existingAsset = (existingRelease.assets || []).find((a) => a.name === fileName); if (existingAsset) { - console.log(`Deleting existing asset: ${fileName}`); + console.log(`删除已存在的文件: ${fileName}`); execSync( `curl -s -X DELETE -H "Authorization: token ${token}" "${repoApiBase}/releases/${releaseId}/assets/${existingAsset.id}"`, { shell: true, stdio: ['pipe', 'pipe', 'pipe'] } @@ -305,7 +375,7 @@ function uploadToGitea(config) { } if (!releaseId) { - console.log('Creating new Release...'); + console.log('创建新 Release...'); const releaseData = { tag_name: tagName, name: `Android APK ${tagName}`, @@ -331,11 +401,11 @@ function uploadToGitea(config) { } releaseId = releaseInfo.id; - console.log(`Release created (ID: ${releaseId})`); + console.log(`Release 已创建 (ID: ${releaseId})`); } // Upload APK - console.log('Uploading APK...'); + console.log('上传 APK...'); const uploadUrl = `${repoApiBase}/releases/${releaseId}/assets?name=${encodeURIComponent(fileName)}`; const uploadResult = curlJson( `curl -s -X POST "${uploadUrl}" \ @@ -357,12 +427,33 @@ function uploadToGitea(config) { // Main // ============================================================================ +/** + * Parse command line arguments + */ +function parseArgs() { + const args = process.argv.slice(2); + let projectName = null; + let androidDir = null; + + for (let i = 0; i < args.length; i++) { + const arg = args[i]; + if (arg === '--project' && i + 1 < args.length) { + projectName = args[i + 1]; + i++; // skip next arg + } else if (!arg.startsWith('--')) { + androidDir = arg; + } + } + + return { projectName, androidDir }; +} + function main() { const cwd = process.cwd(); - const argDir = process.argv[2]; + const { projectName, androidDir: argDir } = parseArgs(); console.log('='.repeat(60)); - console.log('Android Release Script'); + console.log('Android 发布脚本'); console.log('='.repeat(60)); // 1. Find Android project root @@ -370,23 +461,23 @@ function main() { const androidDir = findAndroidRoot(searchDir); if (!androidDir) { - console.error('Error: Cannot find Android project'); - console.error('Make sure you are in an Android project directory or specify the path'); - console.error('Usage: release-android [android-dir]'); + console.error('错误:找不到 Android 项目'); + console.error('请确保当前目录是 Android 项目或指定正确的路径'); + console.error('用法: release-android [android-dir]'); process.exit(1); } - console.log(`Android project: ${androidDir}`); + console.log(`Android 项目: ${androidDir}`); // 2. Find git root const gitRoot = findGitRoot(androidDir); if (!gitRoot) { - console.error('Error: Not a git repository'); + console.error('错误:不是 git 仓库'); process.exit(1); } - console.log(`Git root: ${gitRoot}`); + console.log(`Git 根目录: ${gitRoot}`); const monorepo = isMonorepo(androidDir, gitRoot); - console.log(`Project type: ${monorepo ? 'Monorepo' : 'Standalone'}`); + console.log(`项目类型: ${monorepo ? 'Monorepo' : '独立项目'}`); // 3. Detect Gitea configuration const detected = detectGiteaConfig(gitRoot); @@ -396,14 +487,14 @@ function main() { const GITEA_REPO = process.env.GITEA_REPO || detected.repo || ''; if (!GITEA_TOKEN) { - console.error('Error: GITEA_TOKEN environment variable is not set'); - console.error('Please set: export GITEA_TOKEN="your_token"'); + console.error('错误:未设置 GITEA_TOKEN 环境变量'); + console.error('请设置: export GITEA_TOKEN="your_token"'); process.exit(1); } if (!GITEA_API_URL || !GITEA_OWNER || !GITEA_REPO) { - console.error('Error: Cannot detect Gitea repository configuration'); - console.error('Please set environment variables: GITEA_API_URL, GITEA_OWNER, GITEA_REPO'); + console.error('错误:无法检测 Gitea 仓库配置'); + console.error('请设置环境变量: GITEA_API_URL, GITEA_OWNER, GITEA_REPO'); process.exit(1); } @@ -412,20 +503,73 @@ function main() { // 4. Read version const version = readVersion(androidDir); if (!version) { - console.error('Error: Cannot read versionName from build.gradle'); + console.error('错误:无法从 build.gradle 读取 versionName'); process.exit(1); } - console.log(`Version: ${version}`); + console.log(`版本: ${version}`); - // 5. Check tag - const tagName = getTagName(version, monorepo); - const tagInfo = getTagInfo(tagName, gitRoot); + // 5. Determine project prefix + let projectPrefix; + + if (projectName) { + // Use provided project name + console.log(`项目前缀: ${projectName} (指定)`); + projectPrefix = projectName; + + // Verify that tags with this prefix exist + const testTag = getLatestTag(gitRoot, projectPrefix); + if (!testTag) { + console.error(`错误:找不到匹配 "${projectPrefix}-*" 模式的 git tag`); + console.error(''); + console.error('可用的 tags:'); + try { + const allTags = execSync('git tag -l --sort=-version:refname | head -10', { + cwd: gitRoot, + encoding: 'utf-8', + shell: true, + stdio: ['pipe', 'pipe', 'pipe'] + }).trim(); + console.error(allTags || ' (未找到 tags)'); + } catch { + console.error(' (无法列出 tags)'); + } + console.error(''); + console.error(`请创建正确前缀的 tag:`); + console.error(` git tag -a ${projectPrefix}-${version} -m "发布说明"`); + console.error(` git push origin ${projectPrefix}-${version}`); + process.exit(1); + } + } else { + // Infer project name from directory and tags + projectPrefix = inferProjectName(gitRoot, androidDir); + if (projectPrefix === null) { + console.error('错误:无法从 git tags 推断项目名称'); + console.error('请确保至少存在一个以下格式的 tag:'); + console.error(' myapp-1.0.0 或 v1.0.0'); + console.error(''); + console.error('或使用 --project 明确指定项目名称:'); + console.error(' node release-android.mjs --project admin-tool'); + process.exit(1); + } + console.log(`项目前缀: ${projectPrefix || '(v-style)'} (自动检测)`); + } - if (!tagInfo.exists) { - console.error(`Error: Git tag "${tagName}" not found`); + const tagName = getLatestTag(gitRoot, projectPrefix); + if (!tagName) { + const expectedTag = projectPrefix ? `${projectPrefix}-${version}` : `v${version}`; + console.error(`错误:找不到匹配的 git tag`); + console.error(`期望的 tag 格式: ${expectedTag}`); console.error(''); - console.error('Please create a tag before releasing:'); - console.error(` git tag -a ${tagName} -m "Release notes"`); + console.error('请先创建 tag:'); + console.error(` git tag -a ${expectedTag} -m "发布说明"`); + console.error(` git push origin ${expectedTag}`); + process.exit(1); + } + + const tagInfo = getTagInfo(tagName, gitRoot); + if (!tagInfo.exists) { + console.error(`错误:Git tag "${tagName}" 不存在`); + console.error('请推送 tag:'); console.error(` git push origin ${tagName}`); process.exit(1); } @@ -434,37 +578,39 @@ function main() { // 6. Detect Java const javaHome = detectJavaHome(); if (!javaHome) { - console.error('Error: Cannot find Java Runtime'); - console.error('Please install JDK or ensure Android Studio is properly installed'); + console.error('错误:找不到 Java 运行环境'); + console.error('请安装 JDK 或确保 Android Studio 已正确安装'); process.exit(1); } console.log(`Java: ${javaHome}`); console.log(''); - console.log('Building...'); + console.log('开始构建...'); // 7. Build APK try { buildApk(androidDir, javaHome); } catch (err) { - console.error('Build failed:', err.message); + console.error('构建失败:', err.message); process.exit(1); } // 8. Find APK const apk = findApk(androidDir); if (!apk) { - console.error('Error: APK file not found'); - console.error('Check build output at: app/build/outputs/apk/release/'); + console.error('错误:找不到 APK 文件'); + console.error('检查构建输出: app/build/outputs/apk/release/'); process.exit(1); } - console.log(`APK: ${apk.path} (${apk.signed ? 'signed' : 'unsigned'})`); + console.log(`APK: ${apk.path} (${apk.signed ? '已签名' : '未签名'})`); // 9. Upload to Gitea - const fileName = `${GITEA_REPO}-android-${version}.apk`; + const fileName = projectPrefix + ? `${projectPrefix}-${version}.apk` + : `${GITEA_REPO}-${version}.apk`; console.log(''); - console.log('Uploading to Gitea...'); + console.log('上传到 Gitea...'); try { const result = uploadToGitea({ @@ -480,13 +626,13 @@ function main() { console.log(''); console.log('='.repeat(60)); - console.log('Release successful!'); - console.log(`File: ${fileName}`); - console.log(`Size: ${(result.fileSize / 1024 / 1024).toFixed(2)} MB`); + console.log('发布成功!'); + console.log(`文件: ${fileName}`); + console.log(`大小: ${(result.fileSize / 1024 / 1024).toFixed(2)} MB`); console.log(`URL: ${result.releaseUrl}`); console.log('='.repeat(60)); } catch (err) { - console.error('Upload failed:', err.message); + console.error('上传失败:', err.message); process.exit(1); } } diff --git a/command/auto-commit.md b/command/auto-commit.md index 1843b35..49ab9f8 100644 --- a/command/auto-commit.md +++ b/command/auto-commit.md @@ -130,9 +130,13 @@ Based on changes in staging area, **analyze and generate meaningful commit messa - Use [Conventional Commits](https://www.conventionalcommits.org/) specification - Commit message should concisely but accurately describe "why" rather than just "what" - Common types: `feat` (new feature), `fix` (fix), `docs` (documentation), `refactor` (refactoring), `chore` (miscellaneous), `test` (test), etc. +- **Language selection**: + - **Default (macOS/Linux)**: Use Chinese (中文) for commit messages + - **Windows**: Use English due to encoding issues with Cursor Shell tool - **If monorepo and this commit only affects single subproject, include subproject name in commit message**: - Format: `(): `, where `` is subproject name - - Example: `feat(ios): support OGG Opus upload` or `fix(electron): fix clipboard injection failure` + - Example (Chinese): `feat(ios): 支持 OGG Opus 上传` or `fix(electron): 修复剪贴板注入失败` + - Example (English): `feat(ios): support OGG Opus upload` or `fix(electron): fix clipboard injection failure` - If affecting multiple subprojects or entire repository, no need to add scope ### 6. Update Project Version Number @@ -149,11 +153,27 @@ Based on changes in staging area, **analyze and generate meaningful commit messa Execute commit with generated commit message (staging area now includes user's changes and version number update). -**Windows encoding issue solution:** +**Commit message language by platform:** -Cursor's Shell tool has encoding issues when passing Chinese parameters on Windows, causing garbled Git commit messages. +**macOS/Linux** (use Chinese commit messages): -**Correct approach**: Use **English** commit message +```bash +# Single line commit +git commit -m "feat(android): 添加新功能" + +# Multi-line commit (recommended) +git commit -m "$(cat <<'EOF' +feat(android): 添加新功能 + +- 详细说明 1 +- 详细说明 2 +EOF +)" +``` + +**Windows** (use English commit messages): + +Due to Cursor's Shell tool encoding issues on Windows, **must use English** commit messages. ```powershell # Single line commit @@ -163,26 +183,12 @@ git commit -m "feat(android): add new feature" git commit --message="fix(android): fix code review issues" --message="- Fix syntax error" --message="- Use JSONObject instead of manual JSON" ``` -**Prohibited methods** (will cause garbled text): +**Windows prohibited methods** (will cause garbled text): - No Chinese commit messages - Cursor Shell tool encoding error when passing Chinese parameters - No `Out-File -Encoding utf8` - writes UTF-8 with BOM - No Write tool to write temp files - encoding uncontrollable - No PowerShell here-string `@"..."@` - newline parsing issues -**For Chinese commit messages**: Please manually execute `git commit` in terminal, or use Git GUI tools other than Cursor. - -**macOS/Linux alternative** (supports Chinese): - -```bash -git commit -m "$(cat <<'EOF' -feat(android): new feature description - -- Detail 1 -- Detail 2 -EOF -)" -``` - ### 8. Create Tag > **Executed by default**. Only skip this step when user explicitly inputs "skip" or "skip tag". @@ -228,7 +234,7 @@ Examples (multi-line commit, more recommended): - **Create tag by default**: Unless user inputs "skip" or "skip tag", create tag by default. - **Update version before commit**: First determine version number and modify version file, then commit at once, avoid using `--amend`. - **Version file must be verified**: After updating version number and `git add`, must run `git diff --cached --name-only` to confirm version file is in staging area before executing commit. -- **Windows encoding issues**: Cursor Shell tool garbles Chinese parameters, must use **English** commit messages. For Chinese, please manually execute in terminal. +- **Commit message language**: Default use Chinese (macOS/Linux); Windows must use English due to Cursor Shell tool encoding issues. - **monorepo scope**: If staging area only affects single subproject, commit message should have scope; if affecting multiple subprojects, no scope needed. - **monorepo tag format**: Use `-` format (e.g., `ios-0.1.0`, `android-1.1.0`). - **No version file case**: If project type cannot be identified or no version file (like pure Go project), only create git tag, don't update any files. diff --git a/command/commit-push.md b/command/commit-push.md index f9f1783..a4791e5 100644 --- a/command/commit-push.md +++ b/command/commit-push.md @@ -130,9 +130,13 @@ Based on changes in staging area, **analyze and generate meaningful commit messa - Use [Conventional Commits](https://www.conventionalcommits.org/) specification - Commit message should concisely but accurately describe "why" rather than just "what" - Common types: `feat` (new feature), `fix` (fix), `docs` (documentation), `refactor` (refactoring), `chore` (miscellaneous), `test` (test), etc. +- **Language selection**: + - **Default (macOS/Linux)**: Use Chinese (中文) for commit messages + - **Windows**: Use English due to encoding issues with Cursor Shell tool - **If monorepo and this commit only affects single subproject, include subproject name in commit message**: - Format: `(): `, where `` is subproject name - - Example: `feat(ios): support OGG Opus upload` or `fix(electron): fix clipboard injection failure` + - Example (Chinese): `feat(ios): 支持 OGG Opus 上传` or `fix(electron): 修复剪贴板注入失败` + - Example (English): `feat(ios): support OGG Opus upload` or `fix(electron): fix clipboard injection failure` - If affecting multiple subprojects or entire repository, no need to add scope ### 6. Update Project Version Number @@ -149,11 +153,27 @@ Based on changes in staging area, **analyze and generate meaningful commit messa Execute commit with generated commit message (staging area now includes user's changes and version number update). -**Windows encoding issue solution:** +**Commit message language by platform:** -Cursor's Shell tool has encoding issues when passing Chinese parameters on Windows, causing garbled Git commit messages. +**macOS/Linux** (use Chinese commit messages): -**Correct approach**: Use **English** commit message +```bash +# Single line commit +git commit -m "feat(android): 添加新功能" + +# Multi-line commit (recommended) +git commit -m "$(cat <<'EOF' +feat(android): 添加新功能 + +- 详细说明 1 +- 详细说明 2 +EOF +)" +``` + +**Windows** (use English commit messages): + +Due to Cursor's Shell tool encoding issues on Windows, **must use English** commit messages. ```powershell # Single line commit @@ -163,26 +183,12 @@ git commit -m "feat(android): add new feature" git commit --message="fix(android): fix code review issues" --message="- Fix syntax error" --message="- Use JSONObject instead of manual JSON" ``` -**Prohibited methods** (will cause garbled text): +**Windows prohibited methods** (will cause garbled text): - No Chinese commit messages - Cursor Shell tool encoding error when passing Chinese parameters - No `Out-File -Encoding utf8` - writes UTF-8 with BOM - No Write tool to write temp files - encoding uncontrollable - No PowerShell here-string `@"..."@` - newline parsing issues -**For Chinese commit messages**: Please manually execute `git commit` in terminal, or use Git GUI tools other than Cursor. - -**macOS/Linux alternative** (supports Chinese): - -```bash -git commit -m "$(cat <<'EOF' -feat(android): new feature description - -- Detail 1 -- Detail 2 -EOF -)" -``` - ### 8. Create Tag > **Executed by default**. Only skip this step when user explicitly inputs "skip" or "skip tag". @@ -247,7 +253,7 @@ git push origin - - **Create tag by default**: Unless user inputs "skip" or "skip tag", create and push tag by default. - **Update version before commit**: First determine version number and modify version file, then commit at once, avoid using `--amend`. - **Version file must be verified**: After updating version number and `git add`, must run `git diff --cached --name-only` to confirm version file is in staging area before executing commit. -- **Windows encoding issues**: Cursor Shell tool garbles Chinese parameters, must use **English** commit messages. For Chinese, please manually execute in terminal. +- **Commit message language**: Default use Chinese (macOS/Linux); Windows must use English due to Cursor Shell tool encoding issues. - **monorepo scope**: If staging area only affects single subproject, commit message should have scope; if affecting multiple subprojects, no scope needed. - **monorepo tag format**: Use `-` format (e.g., `ios-0.1.0`, `android-1.1.0`). - **No version file case**: If project type cannot be identified or no version file (like pure Go project), only create git tag, don't update any files. diff --git a/command/release-android.md b/command/release-android.md index 58b5bad..dd90951 100644 --- a/command/release-android.md +++ b/command/release-android.md @@ -1,14 +1,20 @@ --- -description: Build and release Android APK to Gitea +description: Build and release Android APK to Gitea (generic for any Android project) --- # Android Release Command -Build Android APK and upload to Gitea Release. +Build Android APK and upload to Gitea Release for the current directory's Android project. -## Prerequisites Check +## Prerequisites -First, verify the environment: +Before running this command: + +1. **Create and push the git tag first** (e.g., `myapp-1.0.0`, `android-1.0.0`, or `v1.0.0`) +2. Ensure `GITEA_TOKEN` environment variable is set +3. Ensure Android project exists in current directory + +Check the environment: ```bash # Check GITEA_TOKEN @@ -17,40 +23,25 @@ echo "GITEA_TOKEN: ${GITEA_TOKEN:+SET}" # Check current directory for Android project ls -la app/build.gradle.kts 2>/dev/null || ls -la android/app/build.gradle.kts 2>/dev/null || echo "No Android project found" -# Check current version -grep -h 'versionName' app/build.gradle.kts android/app/build.gradle.kts 2>/dev/null | head -1 - -# Check existing tags -git tag -l '*android*' -l 'v*' | tail -5 +# Check recent tags (script will use the latest tag) +git tag -l | tail -10 ``` -## Release Process - -**If there are uncommitted changes:** -1. Increment version: update `versionCode` (+1) and `versionName` in `app/build.gradle.kts` -2. Commit the changes with a descriptive message -3. Create annotated git tag: - - Monorepo: `git tag -a android-{version} -m "Release notes"` - - Standalone: `git tag -a v{version} -m "Release notes"` -4. Push commit and tag: `git push && git push origin {tag}` - -**If no uncommitted changes but tag doesn't exist:** -1. Create tag and push it - ## Build and Upload -After tag is created and pushed, run: +After creating and pushing the tag, run: ```bash -node ~/.config/opencode/bin/release-android.mjs +node ~/.opencode/bin/release-android.mjs ``` The script will: - Auto-detect Android project root (standalone or monorepo) +- Auto-detect project name from recent git tags or directory name - Auto-detect Gitea config from git remote URL (HTTPS/SSH) - Auto-detect Java from Android Studio - Build release APK -- Upload to Gitea Release +- Upload to Gitea Release matching the tag pattern ## Error Handling diff --git a/command/sync-oc-push.md b/command/sync-oc-push.md index f4e3925..25bfbb0 100644 --- a/command/sync-oc-push.md +++ b/command/sync-oc-push.md @@ -48,13 +48,24 @@ git add command/ skill/ opencode.json Generate concise commit message based on change content: - Use [Conventional Commits](https://www.conventionalcommits.org/) specification +- **Language selection**: + - **Default (macOS/Linux)**: Use Chinese (中文) for commit messages + - **Windows**: Use English due to encoding issues with Cursor Shell tool - Common types: - `feat`: New command or config - `fix`: Fix command or config issues - `docs`: Documentation update - `chore`: Miscellaneous adjustments -**Examples**: +**Examples (macOS/Linux - Chinese)**: + +```bash +git commit -m "feat: 添加 Vue.js 开发命令" +git commit -m "fix: 修正 MCP 服务器配置" +git commit -m "docs: 更新 review 命令说明" +``` + +**Examples (Windows - English)**: ```bash git commit -m "feat: add new developer command for Vue.js" @@ -72,4 +83,4 @@ git push origin main - **Only sync config files**: Only add `command/`, `skill/` and `opencode.json`, don't commit other local data. - **Sensitive info**: `opencode.json` may contain API keys, ensure remote repository access permissions are set correctly. -- **English commit**: To avoid encoding issues, suggest using English commit messages. +- **Commit message language**: Default use Chinese (macOS/Linux); Windows must use English due to Cursor Shell tool encoding issues.