Files
lunar-mini/mini/ci/resolve-version.cjs
T
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

96 lines
2.7 KiB
JavaScript

/**
* Resolve the WeChat Mini Program upload version.
*
* WeChat requires x.y.z with each segment in 0..999.
* Server and miniapp versions are independent on purpose.
*
* Priority:
* 1. MINIAPP_VERSION_OVERRIDE — full manual version (rare / release pinning)
* 2. MINIAPP_BUILD_NUMBER — auto version from CI run number
* 3. package.json version — local / fallback
*/
const fs = require("node:fs");
const path = require("node:path");
function readPackageVersion(projectPath) {
const packageJson = JSON.parse(
fs.readFileSync(path.join(projectPath, "package.json"), "utf8"),
);
if (!packageJson.version) {
throw new Error("package.json version is missing.");
}
return String(packageJson.version);
}
function parseSemverParts(version) {
const parts = String(version)
.trim()
.split(".")
.map((part) => Number.parseInt(part, 10));
if (
parts.length < 1 ||
parts.some((part) => !Number.isInteger(part) || part < 0 || part > 999)
) {
throw new Error(
`Invalid version "${version}". WeChat requires x.y.z with each segment 0-999.`,
);
}
return {
major: parts[0] ?? 0,
minor: parts[1] ?? 0,
patch: parts[2] ?? 0,
};
}
/**
* Encode a monotonic CI build number into WeChat x.y.z.
* Keeps package.json major; puts build into minor.patch with base 100.
* Examples (major=1): build 99 → 1.0.99, build 100 → 1.1.0, build 101 → 1.1.1
*/
function versionFromBuildNumber(major, buildNumber) {
if (!Number.isInteger(buildNumber) || buildNumber < 1) {
throw new Error("MINIAPP_BUILD_NUMBER must be a positive integer.");
}
if (!Number.isInteger(major) || major < 0 || major > 999) {
throw new Error("package.json major version must be an integer 0-999.");
}
const minor = Math.floor(buildNumber / 100) % 1000;
const patch = buildNumber % 100;
return `${major}.${minor}.${patch}`;
}
/** @param {Record<string, string | undefined>} [env] */
function resolveVersion(projectPath, env = process.env) {
const override = (env.MINIAPP_VERSION_OVERRIDE || "").trim();
if (override) {
parseSemverParts(override);
return override;
}
const packageVersion = readPackageVersion(projectPath);
const { major } = parseSemverParts(packageVersion);
const buildRaw = (env.MINIAPP_BUILD_NUMBER || "").trim();
if (buildRaw) {
const buildNumber = Number.parseInt(buildRaw, 10);
return versionFromBuildNumber(major, buildNumber);
}
// Legacy fixed override — prefer not to use; keeps version stuck across uploads.
const legacy = (env.MINIAPP_VERSION || "").trim();
if (legacy) {
parseSemverParts(legacy);
return legacy;
}
return packageVersion;
}
module.exports = {
parseSemverParts,
resolveVersion,
versionFromBuildNumber,
};