62 lines
4.5 KiB
JavaScript
62 lines
4.5 KiB
JavaScript
import assert from "node:assert/strict"
|
|
import { execFileSync } from "node:child_process"
|
|
import { copyFileSync, mkdirSync, mkdtempSync, readFileSync, rmSync, writeFileSync } from "node:fs"
|
|
import { tmpdir } from "node:os"
|
|
import { basename, dirname, join, resolve } from "node:path"
|
|
import { fileURLToPath } from "node:url"
|
|
import test from "node:test"
|
|
|
|
const source = fileURLToPath(new URL("./compute-release.mjs", import.meta.url))
|
|
|
|
const cases = [
|
|
{ name: "исправление повышает patch", commits: [["fix(ui): исправить отображение"]], version: "1.47.7", bump: "patch" },
|
|
{ name: "новая возможность повышает minor", commits: [["feat(ui): добавить раздел"]], version: "1.48.0", bump: "minor" },
|
|
{ name: "breaking со scope повышает major", commits: [["chore(release)!: подготовить вторую основную версию"]], version: "2.0.0", bump: "major" },
|
|
{ name: "breaking без scope повышает major", commits: [["feat!: заменить контракт"]], version: "2.0.0", bump: "major" },
|
|
{ name: "footer со пробелом повышает major", commits: [["fix(api): заменить контракт", "BREAKING CHANGE: изменён контракт"]], version: "2.0.0", bump: "major" },
|
|
{ name: "footer с дефисом повышает major", commits: [["fix(api): заменить контракт", "BREAKING-CHANGE: изменён контракт"]], version: "2.0.0", bump: "major" },
|
|
{ name: "major имеет приоритет в смешанной истории", commits: [["chore(release)!: подготовить выпуск"], ["feat(ui): добавить раздел"], ["fix(ui): исправить отображение"]], version: "2.0.0", bump: "major" },
|
|
{ name: "после второй версии сохраняется patch", base: "2.0.0", commits: [["fix(ui): исправить отображение"]], version: "2.0.1", bump: "patch" },
|
|
{ name: "после второй версии сохраняется minor", base: "2.0.0", commits: [["feat(ui): добавить раздел"]], version: "2.1.0", bump: "minor" },
|
|
{ name: "готовый тег не выпускается повторно", base: "2.0.0", commits: [], version: "2.0.0", bump: "none" },
|
|
]
|
|
|
|
for (const scenario of cases) test(scenario.name, () => {
|
|
const parent = resolve(tmpdir())
|
|
const root = mkdtempSync(join(parent, "mm-release-"))
|
|
const git = (...args) => execFileSync("git", args, { cwd: root, stdio: "pipe" })
|
|
try {
|
|
mkdirSync(join(root, ".ci/scripts"), { recursive: true })
|
|
copyFileSync(source, join(root, ".ci/scripts/compute-release.mjs"))
|
|
git("init", "--initial-branch=main")
|
|
git("config", "user.name", "Release Test")
|
|
git("config", "user.email", "release@example.invalid")
|
|
git("config", "core.hooksPath", ".git/hooks")
|
|
writeFileSync(join(root, "fixture"), "baseline")
|
|
git("add", "fixture")
|
|
git("commit", "-m", "chore(test): создать исходную базу")
|
|
git("tag", `v${scenario.base ?? "1.47.6"}`)
|
|
for (const [index, [subject, body]] of scenario.commits.entries()) {
|
|
writeFileSync(join(root, "fixture"), `change ${index}`)
|
|
git("add", "fixture")
|
|
git("commit", "-m", subject, ...(body ? ["-m", body] : []))
|
|
}
|
|
execFileSync(process.execPath, [join(root, ".ci/scripts/compute-release.mjs")], {
|
|
cwd: root, stdio: "pipe",
|
|
env: { ...process.env, BASE_VERSION: "1.0.0", RELEASE_OUTPUT_DIR: ".ci/release", GITHUB_OUTPUT: join(root, "outputs"), GITEA_REPOSITORY: "test/repo", GITEA_SERVER_URL: "https://example.invalid" },
|
|
})
|
|
const manifest = JSON.parse(readFileSync(join(root, ".ci/release/release-manifest.json"), "utf8"))
|
|
const output = readFileSync(join(root, "outputs"), "utf8")
|
|
assert.equal(manifest.version, scenario.version)
|
|
assert.equal(manifest.tag, `v${scenario.version}`)
|
|
assert.equal(manifest.releaseUrl, `https://example.invalid/test/repo/releases/tag/v${scenario.version}`)
|
|
assert.match(output, new RegExp(`^bump=${scenario.bump}$`, "m"))
|
|
assert.match(output, new RegExp(`^should_release=${scenario.bump !== "none"}$`, "m"))
|
|
if (scenario.bump !== "none") assert.match(readFileSync(join(root, ".ci/release/release_notes.md"), "utf8"), new RegExp(`# v${scenario.version.replaceAll(".", "\\.")}`))
|
|
} finally {
|
|
assert.equal(dirname(resolve(root)), parent)
|
|
assert.ok(basename(root).startsWith("mm-release-"))
|
|
rmSync(root, { recursive: true, force: true })
|
|
}
|
|
})
|