Files
lunar-mini/mini/ci/resolve-upload-desc.cjs
gouki 9c178e6d49 ci: 添加小程序自动部署配置
- 添加 Gitea Actions workflow: miniapp-preview.yml
- 添加 CI 脚本: upload-ci.cjs, preview-ci.cjs
- 添加版本解析: resolve-version.cjs, resolve-upload-desc.cjs
- 添加 mini/package.json 用于 miniprogram-ci 依赖
2026-08-06 09:20:43 +00:00

152 lines
3.6 KiB
JavaScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/**
* Build the WeChat upload "项目备注" from recent change summaries.
* Prefer recent git commit subjects (Chinese commit messages in this repo);
* fall back to the latest CHANGELOG bullets when git history is unavailable.
*/
const fs = require("node:fs");
const path = require("node:path");
const { execFileSync } = require("node:child_process");
const DEFAULT_MAX_LENGTH = 100;
function cleanCommitSubject(subject) {
return String(subject || "")
.trim()
.replace(
/^(feat|fix|docs|style|refactor|perf|test|chore|ci|build|revert)(\([^)]*\))?:\s*/i,
"",
)
.replace(/\s+/g, " ")
.trim();
}
function truncateDesc(text, maxLength = DEFAULT_MAX_LENGTH) {
const value = String(text || "").trim();
if (!value) {
return "";
}
if ([...value].length <= maxLength) {
return value;
}
const chars = [...value].slice(0, Math.max(0, maxLength - 1));
return `${chars.join("")}…`;
}
function collectRecentCommitSubjects(repoRoot, limit = 5) {
try {
const output = execFileSync(
"git",
[
"log",
`-${Math.max(1, limit * 3)}`,
"--pretty=%s",
"--",
"mini/",
"CHANGELOG.md",
"Features.md",
],
{
cwd: repoRoot,
encoding: "utf8",
stdio: ["ignore", "pipe", "ignore"],
},
);
const subjects = [];
const seen = new Set();
for (const line of output.split("\n")) {
const cleaned = cleanCommitSubject(line);
if (!cleaned || seen.has(cleaned)) {
continue;
}
// Skip pure docs/chore noise when better subjects exist.
if (/^(说明|文档|记录)/.test(cleaned) && subjects.length > 0) {
continue;
}
seen.add(cleaned);
subjects.push(cleaned);
if (subjects.length >= limit) {
break;
}
}
return subjects;
} catch {
return [];
}
}
function collectRecentChangelogBullets(repoRoot, limit = 5) {
const changelogPath = path.join(repoRoot, "CHANGELOG.md");
if (!fs.existsSync(changelogPath)) {
return [];
}
const lines = fs.readFileSync(changelogPath, "utf8").split(/\r?\n/);
const bullets = [];
const seen = new Set();
for (const line of lines) {
const match = line.match(/^\s*-\s+(.+)\s*$/);
if (!match) {
continue;
}
const bullet = match[1].replace(/\s+/g, " ").trim();
if (!bullet || seen.has(bullet)) {
continue;
}
seen.add(bullet);
bullets.push(bullet);
if (bullets.length >= limit) {
break;
}
}
return bullets;
}
function resolveUploadDesc({
repoRoot,
versionLabel = "",
maxLength = DEFAULT_MAX_LENGTH,
maxItems = 3,
} = {}) {
const root = repoRoot || process.cwd();
const fromGit = collectRecentCommitSubjects(root, maxItems);
const fromChangelog = collectRecentChangelogBullets(root, maxItems);
const parts = fromGit.length > 0 ? fromGit : fromChangelog;
if (parts.length === 0) {
const shortSha = String(versionLabel || "")
.trim()
.slice(0, 7);
return truncateDesc(
shortSha ? `CI upload ${shortSha}` : "CI upload",
maxLength,
);
}
// Fit as many summaries as possible within the WeChat remark limit.
const selected = [];
for (const part of parts) {
const candidate = [...selected, part].join("");
if ([...candidate].length > maxLength) {
if (selected.length === 0) {
return truncateDesc(part, maxLength);
}
break;
}
selected.push(part);
}
return truncateDesc(selected.join(""), maxLength);
}
module.exports = {
cleanCommitSubject,
collectRecentChangelogBullets,
collectRecentCommitSubjects,
resolveUploadDesc,
truncateDesc,
};