UNPKG

@ruan-cat/release-toolkit

Version:

基于 changelogen 增强 changesets 工作流的发布工具包,提供语义化提交解析和 GitHub Release 同步功能。

1 lines 35.3 kB
{"version":3,"sources":["../src/index.ts","../src/plugins/changelog-with-changelogen.ts","../src/configs/changelogen.config.ts","../src/scripts/sync-github-release.ts"],"sourcesContent":["/**\n * @ruan-cat/release-toolkit\n *\n * 基于 changelogen 增强 changesets 工作流的发布工具包\n * 提供语义化提交解析和 GitHub Release 同步功能\n */\n\n// 导出 changesets 插件\nexport { default as changelogFunctions } from \"./plugins/changelog-with-changelogen.ts\";\nexport * from \"./plugins/changelog-with-changelogen.ts\";\n\n// 导出 GitHub Release 同步工具\nexport { GitHubReleaseSync, runSync } from \"./scripts/sync-github-release.ts\";\nexport type { PublishedPackage, ChangelogEntry } from \"./scripts/sync-github-release.ts\";\n\n// 导出 changelogen 配置\nexport { default as changelogConfig } from \"./configs/changelogen.config.ts\";\n\n// 有疑惑 不明白为什么AI需要重新导出 commitlint-config 的类型功能 先注释掉 未来再考虑删除\n// // 重新导出 commitlint-config 的类型功能 (方便使用)\n// export {\n// \textractCommitTypes,\n// \tcreateEmojiTypeMap,\n// \tcreateTypeEmojiMap,\n// \tgetSupportedTypes,\n// } from \"@ruan-cat/commitlint-config\";\n// export type { CommitType } from \"@ruan-cat/commitlint-config\";\n","import type { ChangelogFunctions } from \"@changesets/types\";\nimport { consola } from \"consola\";\nimport { commitTypes, type CommitType } from \"@ruan-cat/commitlint-config\";\nimport { getGitDiff, parseCommits, loadChangelogConfig, type GitCommit, type ChangelogConfig } from \"changelogen\";\nimport changelogConfig from \"../configs/changelogen.config.ts\";\n\n/**\n * 创建 type -> emoji 映射\n */\nfunction createTypeEmojiMap(): Map<string, { emoji: string; description: string }> {\n\tconst map = new Map<string, { emoji: string; description: string }>();\n\tcommitTypes.forEach(({ type, emoji, description }) => {\n\t\tmap.set(type, { emoji, description });\n\t});\n\treturn map;\n}\n\n/**\n * 创建 emoji -> type 映射\n */\nfunction createEmojiTypeMap(): Map<string, string> {\n\tconst map = new Map<string, string>();\n\tcommitTypes.forEach(({ type, emoji }) => {\n\t\tmap.set(emoji, type);\n\t});\n\treturn map;\n}\n\n/**\n * 从 git commit 历史中获取提交信息并解析\n */\nasync function getCommitsFromGitHistory(from?: string, to?: string): Promise<GitCommit[]> {\n\ttry {\n\t\t// 加载 changelogen 配置\n\t\tconst config = await loadChangelogConfig(process.cwd(), {\n\t\t\t...changelogConfig,\n\t\t\tfrom: from || \"\",\n\t\t\tto: to || \"HEAD\",\n\t\t});\n\n\t\tconsola.debug(\"Loaded changelogen config:\", config);\n\n\t\t// 使用 changelogen 获取 git 提交差异\n\t\tconst rawCommits = await getGitDiff(config.from, config.to);\n\t\tconsola.debug(`Found ${rawCommits.length} raw commits from git history`);\n\n\t\t// 使用 changelogen 解析提交信息\n\t\tconst parsedCommits = parseCommits(rawCommits, config);\n\t\tconsola.debug(`Parsed ${parsedCommits.length} semantic commits`);\n\n\t\treturn parsedCommits;\n\t} catch (error) {\n\t\tconsola.error(\"Error getting commits from git history:\", error);\n\t\treturn [];\n\t}\n}\n\n/**\n * 将 changelogen 的 GitCommit 转换为变更日志行\n */\nfunction formatCommitToChangelogLine(commit: GitCommit, repoUrl?: string): string {\n\tlet line = \"- \";\n\n\t// 添加 emoji (从类型映射中获取)\n\tconst typeEmojiMap = createTypeEmojiMap();\n\tconst typeInfo = typeEmojiMap.get(commit.type);\n\tif (typeInfo?.emoji) {\n\t\tline += `${typeInfo.emoji} `;\n\t}\n\n\t// 添加类型标签\n\tif (commit.type && commit.type !== \"other\") {\n\t\tline += `**${commit.type}**`;\n\n\t\t// 添加作用域\n\t\tif (commit.scope) {\n\t\t\tline += `(${commit.scope})`;\n\t\t}\n\n\t\tline += \": \";\n\t}\n\n\t// 添加 BREAKING CHANGE 标记\n\tif (commit.isBreaking) {\n\t\tline += \"**BREAKING**: \";\n\t}\n\n\t// 添加描述\n\tline += commit.description;\n\n\t// 添加提交链接\n\tif (repoUrl) {\n\t\tconst commitUrl = `${repoUrl}/commit/${commit.shortHash}`;\n\t\tline += ` ([${commit.shortHash}](${commitUrl}))`;\n\t}\n\n\treturn line;\n}\n\n/**\n * 生成增强的变更日志行 - 集成 changelogen 功能\n */\nconst getReleaseLine: ChangelogFunctions[\"getReleaseLine\"] = async (changeset, type, changelogOpts) => {\n\ttry {\n\t\tconst repoUrl = `https://github.com/${changelogOpts?.repo || \"ruan-cat/monorepo\"}`;\n\n\t\t// 方案1: 如果有关联的提交,直接使用提交哈希\n\t\tif (changeset.commit) {\n\t\t\tconsola.debug(`Processing changeset ${changeset.id} with commit ${changeset.commit}`);\n\n\t\t\t// 尝试从 git 历史中获取该特定提交的详细信息\n\t\t\tconst commits = await getCommitsFromGitHistory(changeset.commit, changeset.commit);\n\n\t\t\tif (commits.length > 0) {\n\t\t\t\tconst commit = commits[0];\n\t\t\t\tconst line = formatCommitToChangelogLine(commit, repoUrl);\n\t\t\t\tconsola.debug(`Generated changelog line from git commit for ${changeset.id}:`, line);\n\t\t\t\treturn line;\n\t\t\t}\n\n\t\t\t// 如果无法获取 git 提交信息,回退到基于 changeset 内容的解析\n\t\t\tconsola.warn(`Could not find git commit ${changeset.commit}, falling back to changeset parsing`);\n\t\t}\n\n\t\t// 方案2: 基于 changeset 内容解析 (回退方案)\n\t\tconsola.debug(`Processing changeset ${changeset.id} without commit, using changeset content`);\n\n\t\t// 尝试从 changeset 摘要中提取语义化提交信息\n\t\tconst firstLine = changeset.summary.split(\"\\n\")[0];\n\t\tconst typeEmojiMap = createTypeEmojiMap();\n\t\tconst emojiTypeMap = createEmojiTypeMap();\n\n\t\t// 简化的语义化解析\n\t\tlet line = \"- \";\n\t\tlet emoji = \"\";\n\t\tlet commitType = \"\";\n\t\tlet scope = \"\";\n\t\tlet description = firstLine;\n\t\tlet isBreaking = false;\n\n\t\t// 检查是否是 BREAKING CHANGE\n\t\tisBreaking = firstLine.includes(\"!:\") || firstLine.toLowerCase().includes(\"breaking\");\n\n\t\t// 尝试匹配 emoji + conventional 格式\n\t\tconst emojiConventionalMatch = firstLine.match(\n\t\t\t/^([\\u{1f000}-\\u{1f9ff}|\\u{2600}-\\u{27bf}|\\u{2700}-\\u{27BF}|\\u{1F600}-\\u{1F64F}|\\u{1F300}-\\u{1F5FF}|\\u{1F680}-\\u{1F6FF}|\\u{1F1E0}-\\u{1F1FF}|\\u{2600}-\\u{26FF}|\\u{2700}-\\u{27BF}])\\s+(\\w+)(\\([^)]+\\))?(!)?\\s*:\\s*(.+)$/u,\n\t\t);\n\n\t\tif (emojiConventionalMatch) {\n\t\t\t[, emoji, commitType, scope, , description] = emojiConventionalMatch;\n\t\t\tscope = scope ? scope.slice(1, -1) : \"\";\n\t\t} else {\n\t\t\t// 尝试匹配纯 conventional 格式\n\t\t\tconst conventionalMatch = firstLine.match(/^(\\w+)(\\([^)]+\\))?(!)?\\s*:\\s*(.+)$/);\n\t\t\tif (conventionalMatch) {\n\t\t\t\t[, commitType, scope, , description] = conventionalMatch;\n\t\t\t\tscope = scope ? scope.slice(1, -1) : \"\";\n\t\t\t\tconst typeInfo = typeEmojiMap.get(commitType);\n\t\t\t\temoji = typeInfo?.emoji || \"\";\n\t\t\t}\n\t\t}\n\n\t\t// 构建变更日志行\n\t\tif (emoji) {\n\t\t\tline += `${emoji} `;\n\t\t}\n\n\t\tif (commitType && commitType !== \"other\") {\n\t\t\tline += `**${commitType}**`;\n\t\t\tif (scope) {\n\t\t\t\tline += `(${scope})`;\n\t\t\t}\n\t\t\tline += \": \";\n\t\t}\n\n\t\tif (isBreaking) {\n\t\t\tline += \"**BREAKING**: \";\n\t\t}\n\n\t\tline += description;\n\n\t\t// 如果有提交哈希,添加链接\n\t\tif (changeset.commit) {\n\t\t\tconst commitUrl = `${repoUrl}/commit/${changeset.commit}`;\n\t\t\tline += ` ([${changeset.commit.substring(0, 7)}](${commitUrl}))`;\n\t\t}\n\n\t\tconsola.debug(`Generated changelog line for ${changeset.id}:`, line);\n\t\treturn line;\n\t} catch (error) {\n\t\tconsola.error(`Error processing changeset ${changeset.id}:`, error);\n\t\treturn `- ${changeset.summary}`;\n\t}\n};\n\n/**\n * 生成变更日志依赖行\n */\nconst getDependencyReleaseLine: ChangelogFunctions[\"getDependencyReleaseLine\"] = async (\n\tchangesets,\n\tdependenciesUpdated,\n\tchangelogOpts,\n) => {\n\tif (dependenciesUpdated.length === 0) return \"\";\n\n\tconst updatedDependencies = dependenciesUpdated.map((dependency) => {\n\t\tconst type = dependency.type === \"patch\" ? \"Patch\" : dependency.type === \"minor\" ? \"Minor\" : \"Major\";\n\t\treturn ` - ${dependency.name}@${dependency.newVersion} (${type})`;\n\t});\n\n\treturn `- Updated dependencies:\\n${updatedDependencies.join(\"\\n\")}`;\n};\n\n/**\n * 从 git commit 历史生成完整的变更日志内容\n * 这个功能可以独立于 changesets 使用\n */\nexport async function generateChangelogFromGitHistory(\n\tfrom?: string,\n\tto?: string,\n\toptions?: {\n\t\trepo?: string;\n\t\tincludeAuthors?: boolean;\n\t\tgroupByType?: boolean;\n\t},\n): Promise<string> {\n\ttry {\n\t\tconsola.info(\"Generating changelog from git commit history...\");\n\n\t\tconst commits = await getCommitsFromGitHistory(from, to);\n\t\tif (commits.length === 0) {\n\t\t\tconsola.warn(\"No commits found in the specified range\");\n\t\t\treturn \"\";\n\t\t}\n\n\t\tconst repoUrl = options?.repo ? `https://github.com/${options.repo}` : undefined;\n\t\tlet changelog = \"\";\n\n\t\tif (options?.groupByType) {\n\t\t\t// 按类型分组生成变更日志\n\t\t\tconst commitsByType = new Map<string, GitCommit[]>();\n\n\t\t\tcommits.forEach((commit) => {\n\t\t\t\tconst type = commit.type || \"other\";\n\t\t\t\tif (!commitsByType.has(type)) {\n\t\t\t\t\tcommitsByType.set(type, []);\n\t\t\t\t}\n\t\t\t\tcommitsByType.get(type)!.push(commit);\n\t\t\t});\n\n\t\t\t// 按重要性排序类型\n\t\t\tconst typeOrder = [\n\t\t\t\t\"feat\",\n\t\t\t\t\"fix\",\n\t\t\t\t\"perf\",\n\t\t\t\t\"revert\",\n\t\t\t\t\"docs\",\n\t\t\t\t\"style\",\n\t\t\t\t\"refactor\",\n\t\t\t\t\"test\",\n\t\t\t\t\"build\",\n\t\t\t\t\"ci\",\n\t\t\t\t\"chore\",\n\t\t\t\t\"other\",\n\t\t\t];\n\t\t\tconst sortedTypes = Array.from(commitsByType.keys()).sort((a, b) => {\n\t\t\t\tconst indexA = typeOrder.indexOf(a);\n\t\t\t\tconst indexB = typeOrder.indexOf(b);\n\t\t\t\treturn (indexA === -1 ? 999 : indexA) - (indexB === -1 ? 999 : indexB);\n\t\t\t});\n\n\t\t\t// 为每个类型生成变更日志节\n\t\t\tfor (const type of sortedTypes) {\n\t\t\t\tconst typeCommits = commitsByType.get(type)!;\n\t\t\t\tif (typeCommits.length === 0) continue;\n\n\t\t\t\t// 获取类型显示名称\n\t\t\t\tconst typeEmojiMap = createTypeEmojiMap();\n\t\t\t\tconst typeInfo = typeEmojiMap.get(type);\n\t\t\t\tconst typeTitle = typeInfo ? `${typeInfo.emoji} ${typeInfo.description}` : type.toUpperCase();\n\n\t\t\t\tchangelog += `\\n### ${typeTitle}\\n\\n`;\n\n\t\t\t\ttypeCommits.forEach((commit) => {\n\t\t\t\t\tchangelog += formatCommitToChangelogLine(commit, repoUrl) + \"\\n\";\n\t\t\t\t});\n\t\t\t}\n\t\t} else {\n\t\t\t// 按时间顺序生成变更日志\n\t\t\tcommits.forEach((commit) => {\n\t\t\t\tchangelog += formatCommitToChangelogLine(commit, repoUrl) + \"\\n\";\n\t\t\t});\n\t\t}\n\n\t\t// 添加贡献者信息\n\t\tif (options?.includeAuthors) {\n\t\t\tconst authors = new Set<string>();\n\t\t\tcommits.forEach((commit) => {\n\t\t\t\tcommit.authors.forEach((author) => {\n\t\t\t\t\tauthors.add(author.name);\n\t\t\t\t});\n\t\t\t});\n\n\t\t\tif (authors.size > 0) {\n\t\t\t\tchangelog += `\\n### Contributors\\n\\n`;\n\t\t\t\tArray.from(authors)\n\t\t\t\t\t.sort()\n\t\t\t\t\t.forEach((author) => {\n\t\t\t\t\t\tchangelog += `- ${author}\\n`;\n\t\t\t\t\t});\n\t\t\t}\n\t\t}\n\n\t\tconsola.success(`Generated changelog with ${commits.length} commits`);\n\t\treturn changelog;\n\t} catch (error) {\n\t\tconsola.error(\"Error generating changelog from git history:\", error);\n\t\treturn \"\";\n\t}\n}\n\n/**\n * 混合模式:结合 changesets 和 git commit 历史生成变更日志\n * 当 changesets 不足时,自动补充 git commit 信息\n */\nexport async function generateHybridChangelog(\n\tchangesets: any[],\n\toptions?: {\n\t\trepo?: string;\n\t\tfrom?: string;\n\t\tto?: string;\n\t\tfallbackToGit?: boolean;\n\t},\n): Promise<string> {\n\ttry {\n\t\tlet changelog = \"\";\n\n\t\t// 首先处理 changesets\n\t\tif (changesets && changesets.length > 0) {\n\t\t\tconsola.info(`Processing ${changesets.length} changesets...`);\n\n\t\t\tfor (const changeset of changesets) {\n\t\t\t\t// 这里可以调用 getReleaseLine 函数来处理每个 changeset\n\t\t\t\t// 但由于我们在插件上下文外,需要模拟调用\n\t\t\t\tconst line = await getReleaseLine(changeset, \"patch\", { repo: options?.repo });\n\t\t\t\tchangelog += line + \"\\n\";\n\t\t\t}\n\t\t}\n\n\t\t// 如果启用回退到 git 且 changesets 不足,补充 git commit 信息\n\t\tif (options?.fallbackToGit && (!changesets || changesets.length === 0)) {\n\t\t\tconsola.info(\"No changesets found, falling back to git commit history...\");\n\n\t\t\tconst gitChangelog = await generateChangelogFromGitHistory(options.from, options.to, {\n\t\t\t\trepo: options.repo,\n\t\t\t\tgroupByType: true,\n\t\t\t\tincludeAuthors: true,\n\t\t\t});\n\n\t\t\tchangelog += gitChangelog;\n\t\t}\n\n\t\treturn changelog;\n\t} catch (error) {\n\t\tconsola.error(\"Error generating hybrid changelog:\", error);\n\t\treturn \"\";\n\t}\n}\n\n/**\n * 导出 changesets changelog 函数\n */\nexport const changelogFunctions: ChangelogFunctions = {\n\tgetReleaseLine,\n\tgetDependencyReleaseLine,\n};\n\nexport default changelogFunctions;\n","import type { ChangelogConfig } from \"changelogen\";\n\n// TODO: 目前设计是 该配置文件预期在纯 cjs 环境内使用 作为一个规范数据的配置文件 而不是面向 changelogen cli 功能的配置文件。\nimport { commitTypes } from \"@ruan-cat/commitlint-config\";\n\n/**\n * 基于 @ruan-cat/commitlint-config 的 changelogen 配置\n * 支持 emoji + conventional commits 格式解析\n *\n * changelogen 内置支持以下 emoji commit 格式:\n * - :sparkles: feat: 新增功能\n * - ✨ feat: 新增功能\n * - 🐞 fix: 修复问题\n * - 📃 docs: 更新文档\n */\n\n// 获取提交类型配置 - 直接使用 commitTypes 数组\n\n// 创建完整的类型映射,包括 emoji 和 type 的关联\nconst createCompleteTypeMapping = () => {\n\tconst typeMapping: Record<string, { title: string; semver: \"major\" | \"minor\" | \"patch\" }> = {};\n\n\t// 从 commitlint-config 获取的标准类型\n\tcommitTypes.forEach(({ type, description, emoji }) => {\n\t\ttypeMapping[type] = {\n\t\t\ttitle: emoji ? `${emoji} ${description}` : description,\n\t\t\tsemver: getSemverByType(type),\n\t\t};\n\t});\n\n\t// 添加常见的 gitmoji 类型映射(changelogen 支持这些)\n\tconst gitmojiMapping = {\n\t\t// 新功能类\n\t\tsparkles: { title: \"✨ 新增功能\", semver: \"minor\" as const },\n\t\tzap: { title: \"⚡ 性能优化\", semver: \"patch\" as const },\n\n\t\t// 修复类\n\t\tbug: { title: \"🐞 修复问题\", semver: \"patch\" as const },\n\t\tambulance: { title: \"🚑 紧急修复\", semver: \"patch\" as const },\n\n\t\t// 文档类\n\t\tmemo: { title: \"📝 更新文档\", semver: \"patch\" as const },\n\n\t\t// 构建类\n\t\tpackage: { title: \"📦 构建系统\", semver: \"patch\" as const },\n\t\trocket: { title: \"🚀 部署功能\", semver: \"patch\" as const },\n\n\t\t// 其他\n\t\tother: { title: \"其他更改\", semver: \"patch\" as const },\n\t};\n\n\treturn { ...typeMapping, ...gitmojiMapping };\n};\n\n// changelogen 默认配置值\nconst config: Partial<ChangelogConfig> = {\n\t// 仓库配置\n\trepo: {\n\t\tprovider: \"github\",\n\t\trepo: \"ruan-cat/monorepo\",\n\t},\n\n\t// 完整的提交类型映射 - 支持 emoji + conventional commits\n\ttypes: createCompleteTypeMapping(),\n\n\t// 作用域映射 - 增强 scope 显示,支持中文映射\n\tscopeMap: {\n\t\tapi: \"接口\",\n\t\tui: \"界面\",\n\t\tdocs: \"文档\",\n\t\ttest: \"测试\",\n\t\tconfig: \"配置\",\n\t\tdeps: \"依赖\",\n\t\trelease: \"发布\",\n\t},\n\n\t// 默认配置参数\n\tcwd: process.cwd(),\n\tfrom: \"\",\n\tto: \"HEAD\",\n\n\t// 排除的作者(包括机器人账号)\n\texcludeAuthors: [\"renovate[bot]\", \"dependabot[bot]\", \"github-actions[bot]\"],\n\n\t// GitHub token 配置 - 将通过环境变量读取\n\ttokens: {},\n\n\t// 输出配置 - 生成 CHANGELOG.md 文件\n\toutput: \"CHANGELOG.md\",\n\n\t// 发布配置\n\tpublish: {\n\t\targs: [],\n\t\tprivate: false,\n\t},\n\n\t// Git 标签配置\n\tsignTags: false,\n\n\t// 模板配置 - 自定义提交和标签消息格式\n\ttemplates: {\n\t\tcommitMessage: \"📢 publish: release package(s) {{newVersion}}\",\n\t\ttagMessage: \"{{newVersion}}\",\n\t\ttagBody: \"Released on {{date}}\",\n\t},\n};\n\n/**\n * 根据提交类型获取对应的语义化版本级别\n */\nfunction getSemverByType(type: string): \"major\" | \"minor\" | \"patch\" {\n\tswitch (type) {\n\t\tcase \"feat\":\n\t\t\treturn \"minor\"; // 新功能 -> 次版本号\n\t\tcase \"fix\":\n\t\t\treturn \"patch\"; // 修复 -> 补丁版本号\n\t\tcase \"perf\":\n\t\t\treturn \"patch\"; // 性能优化 -> 补丁版本号\n\t\tcase \"revert\":\n\t\t\treturn \"patch\"; // 回滚 -> 补丁版本号\n\t\tcase \"docs\":\n\t\tcase \"style\":\n\t\tcase \"refactor\":\n\t\tcase \"test\":\n\t\tcase \"chore\":\n\t\tcase \"build\":\n\t\tcase \"ci\":\n\t\tdefault:\n\t\t\treturn \"patch\"; // 其他类型 -> 补丁版本号\n\t}\n}\n\nexport default config;\n","#!/usr/bin/env tsx\n\nimport { Octokit } from \"@octokit/rest\";\nimport { readFileSync, existsSync } from \"fs\";\nimport { resolve, dirname } from \"path\";\nimport { consola } from \"consola\";\n\nexport interface PublishedPackage {\n\tname: string;\n\tversion: string;\n}\n\nexport interface ChangelogEntry {\n\tversion: string;\n\treleaseNotes: string;\n\tdate?: string;\n}\n\nexport class GitHubReleaseSync {\n\tprivate octokit: Octokit;\n\tprivate repo: { owner: string; repo: string };\n\n\tconstructor(\n\t\tprivate options: {\n\t\t\ttoken: string;\n\t\t\trepository: string; // 格式: \"owner/repo\"\n\t\t},\n\t) {\n\t\tthis.octokit = new Octokit({\n\t\t\tauth: options.token,\n\t\t\tlog: consola,\n\t\t});\n\n\t\tconst [owner, repo] = options.repository.split(\"/\");\n\t\tif (!owner || !repo) {\n\t\t\tthrow new Error(`Invalid repository format: ${options.repository}. Expected \"owner/repo\"`);\n\t\t}\n\n\t\tthis.repo = { owner, repo };\n\t\tconsola.info(`Initialized GitHub Release Sync for ${owner}/${repo}`);\n\t}\n\n\t/**\n\t * 解析 CHANGELOG.md 获取最新版本的发布说明\n\t */\n\tprivate parseLatestChangelog(changelogPath: string): ChangelogEntry | null {\n\t\ttry {\n\t\t\tif (!existsSync(changelogPath)) {\n\t\t\t\tconsola.warn(`Changelog not found: ${changelogPath}`);\n\t\t\t\treturn null;\n\t\t\t}\n\n\t\t\tconst content = readFileSync(changelogPath, \"utf-8\");\n\t\t\tconst lines = content.split(\"\\n\");\n\n\t\t\tlet version = \"\";\n\t\t\tlet releaseNotes = \"\";\n\t\t\tlet isInLatestVersion = false;\n\t\t\tlet hasFoundFirstVersion = false;\n\n\t\t\tfor (const line of lines) {\n\t\t\t\t// 匹配版本标题 (## 1.0.0 或 ## [1.0.0] 等)\n\t\t\t\tconst versionMatch = line.match(/^##\\s+(\\[)?([^\\]]+)(\\])?/);\n\n\t\t\t\tif (versionMatch) {\n\t\t\t\t\tif (!hasFoundFirstVersion) {\n\t\t\t\t\t\t// 第一个版本就是最新版本\n\t\t\t\t\t\tversion = versionMatch[2];\n\t\t\t\t\t\tisInLatestVersion = true;\n\t\t\t\t\t\thasFoundFirstVersion = true;\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t} else {\n\t\t\t\t\t\t// 遇到第二个版本,停止收集\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// 如果在最新版本中,收集发布说明\n\t\t\t\tif (isInLatestVersion && line.trim()) {\n\t\t\t\t\treleaseNotes += line + \"\\n\";\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (!version) {\n\t\t\t\tconsola.warn(`No version found in changelog: ${changelogPath}`);\n\t\t\t\treturn null;\n\t\t\t}\n\n\t\t\treturn {\n\t\t\t\tversion: version.trim(),\n\t\t\t\treleaseNotes: releaseNotes.trim(),\n\t\t\t};\n\t\t} catch (error) {\n\t\t\tconsola.error(`Error parsing changelog ${changelogPath}:`, error);\n\t\t\treturn null;\n\t\t}\n\t}\n\n\t/**\n\t * 创建或更新 GitHub Release\n\t */\n\tprivate async createOrUpdateRelease(\n\t\ttagName: string,\n\t\tname: string,\n\t\tbody: string,\n\t\ttargetCommitish = \"main\",\n\t): Promise<void> {\n\t\ttry {\n\t\t\t// 检查 release 是否已存在\n\t\t\ttry {\n\t\t\t\tconst { data: existingRelease } = await this.octokit.rest.repos.getReleaseByTag({\n\t\t\t\t\t...this.repo,\n\t\t\t\t\ttag: tagName,\n\t\t\t\t});\n\n\t\t\t\t// 如果存在,更新它\n\t\t\t\tconsola.info(`Updating existing release: ${tagName}`);\n\t\t\t\tawait this.octokit.rest.repos.updateRelease({\n\t\t\t\t\t...this.repo,\n\t\t\t\t\trelease_id: existingRelease.id,\n\t\t\t\t\tname,\n\t\t\t\t\tbody,\n\t\t\t\t\tdraft: false,\n\t\t\t\t\tprerelease: false,\n\t\t\t\t});\n\n\t\t\t\tconsola.success(`Updated GitHub release: ${tagName}`);\n\t\t\t} catch (error: any) {\n\t\t\t\tif (error.status === 404) {\n\t\t\t\t\t// 如果不存在,创建新的\n\t\t\t\t\tconsola.info(`Creating new release: ${tagName}`);\n\t\t\t\t\tawait this.octokit.rest.repos.createRelease({\n\t\t\t\t\t\t...this.repo,\n\t\t\t\t\t\ttag_name: tagName,\n\t\t\t\t\t\ttarget_commitish: targetCommitish,\n\t\t\t\t\t\tname,\n\t\t\t\t\t\tbody,\n\t\t\t\t\t\tdraft: false,\n\t\t\t\t\t\tprerelease: false,\n\t\t\t\t\t});\n\n\t\t\t\t\tconsola.success(`Created GitHub release: ${tagName}`);\n\t\t\t\t} else {\n\t\t\t\t\tthrow error;\n\t\t\t\t}\n\t\t\t}\n\t\t} catch (error) {\n\t\t\tconsola.error(`Failed to create/update release ${tagName}:`, error);\n\t\t\tthrow error;\n\t\t}\n\t}\n\n\t/**\n\t * 从已发布的包列表同步到 GitHub Release\n\t */\n\tasync syncFromChangesets(publishedPackages: PublishedPackage[]): Promise<void> {\n\t\tif (!publishedPackages?.length) {\n\t\t\tconsola.info(\"No packages were published, skipping GitHub release sync\");\n\t\t\treturn;\n\t\t}\n\n\t\tconsola.info(`Syncing ${publishedPackages.length} published packages to GitHub Releases`);\n\n\t\tfor (const pkg of publishedPackages) {\n\t\t\ttry {\n\t\t\t\tconsola.info(`Processing package: ${pkg.name}@${pkg.version}`);\n\n\t\t\t\t// 根据包名确定 CHANGELOG.md 路径\n\t\t\t\t// 假设包在 packages/ 目录下\n\t\t\t\tconst packageDir = pkg.name.startsWith(\"@\")\n\t\t\t\t\t? pkg.name.split(\"/\")[1] // @scope/name -> name\n\t\t\t\t\t: pkg.name;\n\n\t\t\t\tconst changelogPath = resolve(process.cwd(), \"packages\", packageDir, \"CHANGELOG.md\");\n\n\t\t\t\t// 解析 CHANGELOG.md\n\t\t\t\tconst changelog = this.parseLatestChangelog(changelogPath);\n\n\t\t\t\tif (!changelog) {\n\t\t\t\t\tconsola.warn(`Skipping ${pkg.name} - no changelog found or parsed`);\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\t// 验证版本一致性\n\t\t\t\tif (changelog.version !== pkg.version) {\n\t\t\t\t\tconsola.warn(`Version mismatch for ${pkg.name}: changelog=${changelog.version}, published=${pkg.version}`);\n\t\t\t\t}\n\n\t\t\t\t// 创建发布信息\n\t\t\t\tconst tagName = `${pkg.name}@${pkg.version}`;\n\t\t\t\tconst releaseName = `${pkg.name} v${pkg.version}`;\n\n\t\t\t\t// 为发布说明添加包信息头部\n\t\t\t\tconst releaseBody = `# ${pkg.name} v${pkg.version}\\n\\n${changelog.releaseNotes}`;\n\n\t\t\t\t// 创建或更新 GitHub Release\n\t\t\t\tawait this.createOrUpdateRelease(tagName, releaseName, releaseBody);\n\t\t\t} catch (error) {\n\t\t\t\tconsola.error(`Failed to sync package ${pkg.name}:`, error);\n\t\t\t\t// 继续处理其他包,不要因为一个包失败就停止\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t}\n\n\t\tconsola.success(\"GitHub release sync completed\");\n\t}\n}\n\n/**\n * 从环境变量运行同步脚本\n */\nasync function runSync() {\n\ttry {\n\t\tconst token = process.env.GITHUB_TOKEN;\n\t\tconst publishedPackagesJson = process.env.PUBLISHED_PACKAGES;\n\t\tconst repository = process.env.GITHUB_REPOSITORY || \"ruan-cat/monorepo\";\n\n\t\tif (!token) {\n\t\t\tthrow new Error(\"GITHUB_TOKEN environment variable is required\");\n\t\t}\n\n\t\tif (!publishedPackagesJson) {\n\t\t\tconsola.info(\"PUBLISHED_PACKAGES is empty, no packages to sync\");\n\t\t\treturn;\n\t\t}\n\n\t\tlet publishedPackages: PublishedPackage[];\n\t\ttry {\n\t\t\tpublishedPackages = JSON.parse(publishedPackagesJson);\n\t\t} catch (error) {\n\t\t\tthrow new Error(`Failed to parse PUBLISHED_PACKAGES JSON: ${error}`);\n\t\t}\n\n\t\tconst sync = new GitHubReleaseSync({ token, repository });\n\t\tawait sync.syncFromChangesets(publishedPackages);\n\t} catch (error) {\n\t\tconsola.error(\"GitHub Release sync failed:\", error);\n\t\tprocess.exit(1);\n\t}\n}\n\n// 如果直接运行此脚本,执行同步\nif (typeof import.meta.url !== \"undefined\" && import.meta.url === `file://${process.argv[1]}`) {\n\trunSync();\n}\n\nexport { runSync };\n"],"mappings":"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","names":["import_commitlint_config","config","line","import_consola"]}