Files
GameServerManager/scripts/resolve-build-version.js
2026-07-30 20:59:51 +08:00

106 lines
3.0 KiB
JavaScript

const fs = require('fs')
const path = require('path')
const { execFileSync } = require('child_process')
const projectRoot = path.join(__dirname, '..')
const packageVersion = require('../package.json').version
function normalizeBuildVersion(value) {
return String(value || '')
.trim()
.replace(/^refs\/tags\//i, '')
.replace(/^v(?=\d)/i, '')
.replace(/[^0-9A-Za-z._-]+/g, '-')
.replace(/^[._-]+|[._-]+$/g, '')
.slice(0, 100)
}
function readGitDescription(cwd) {
try {
const result = execFileSync(
'git',
['describe', '--tags', '--always', '--dirty', '--long'],
{
cwd,
encoding: 'utf8',
stdio: ['ignore', 'pipe', 'ignore']
}
)
const version = normalizeBuildVersion(result)
const exactCleanTag = version.match(/^(.*)-0-g[0-9a-f]+$/i)
return exactCleanTag?.[1] || version
} catch {
// Source archives may not include Git metadata; use the package fallback.
}
return ''
}
function resolveBuildMetadata(options = {}) {
const env = options.env || process.env
const cwd = options.cwd || projectRoot
const candidates = [
{ value: env.BUILD_VERSION, isTag: false },
{ value: env.RELEASE_TAG, isTag: true },
{
value: env.GITHUB_REF_TYPE === 'tag' ? env.GITHUB_REF_NAME : '',
isTag: true
},
{ value: env.APP_VERSION, isTag: false },
{ value: env.VITE_APP_VERSION, isTag: false }
]
for (const candidate of candidates) {
const version = normalizeBuildVersion(candidate.value)
if (version) {
return {
version,
isStable: candidate.isTag && isStableTagVersion(env, version)
}
}
}
const gitVersion = readGitDescription(cwd)
if (gitVersion) {
const commitOnly = gitVersion.match(/^([0-9a-f]{7,40})(-dirty)?$/i)
const version = commitOnly
? `dev-${commitOnly[1].slice(0, 12)}${commitOnly[2] || ''}`
: gitVersion
return { version, isStable: false }
}
return {
version: normalizeBuildVersion(packageVersion) || 'development',
isStable: false
}
}
function isStableTagVersion(env, version) {
const isPrerelease = String(env.RELEASE_PRERELEASE || '').toLowerCase() === 'true'
return !isPrerelease && /^\d+\.\d+\.\d+$/.test(version)
}
function resolveBuildVersion(options = {}) {
return resolveBuildMetadata(options).version
}
function appendGitHubValue(filePath, name, value) {
if (!filePath) return
fs.appendFileSync(filePath, `${name}=${value}\n`, 'utf8')
}
if (require.main === module) {
const metadata = resolveBuildMetadata()
appendGitHubValue(process.env.GITHUB_OUTPUT, 'version', metadata.version)
appendGitHubValue(process.env.GITHUB_OUTPUT, 'is_stable', String(metadata.isStable))
appendGitHubValue(process.env.GITHUB_ENV, 'APP_VERSION', metadata.version)
appendGitHubValue(process.env.GITHUB_ENV, 'VITE_APP_VERSION', metadata.version)
console.log(`Resolved build version: ${metadata.version} (stable tag: ${metadata.isStable})`)
}
module.exports = {
normalizeBuildVersion,
resolveBuildMetadata,
resolveBuildVersion
}