Files
Platform-CI/.gitea/actions/quickstack-oci/release.test.mjs
T
vadimenovikau a4247d2697
Platform CI tests / QuickStack deploy action tests (push) Successful in 27s
Nuvisphere/Platform-CI: Immutable QuickStack OCI deployment / Build once and deploy exact digest (push) Successful in 25s
feat: centralize candidate promotion pipelines
2026-08-20 11:40:37 +02:00

125 lines
3.9 KiB
JavaScript
Raw 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.
import assert from "node:assert/strict";
import fs from "node:fs";
import os from "node:os";
import path from "node:path";
import test from "node:test";
import {
ensureTag,
loadRelease,
parseReleaseNotes,
publishRelease,
resolveGiteaApiUrl,
} from "./release.mjs";
function response(status, body) {
return new Response(JSON.stringify(body), {
status,
headers: { "content-type": "application/json" },
});
}
test("loads canonical release metadata and notes", () => {
const root = fs.mkdtempSync(path.join(os.tmpdir(), "platform-ci-release-"));
fs.mkdirSync(path.join(root, "content/releases"), { recursive: true });
fs.writeFileSync(path.join(root, "content/releases/latest.json"), '{"version":"v1.2.3"}');
fs.writeFileSync(path.join(root, "content/releases/v1.2.3.md"), `---
title: "Stable release"
releasedAt: '2026-08-20'
summary: "Release summary"
---
## Changes
Everything works.`);
const loaded = loadRelease(root);
assert.equal(loaded.tag, "v1.2.3");
assert.equal(loaded.release.name, "v1.2.3 Stable release");
assert.match(loaded.release.body, /^## Changes/);
fs.rmSync(root, { recursive: true, force: true });
});
test("parses canonical frontmatter and rejects missing fields", () => {
assert.equal(parseReleaseNotes(`---
title: Stable
releasedAt: 2026-08-20
summary: Done
---
Notes`).title, "Stable");
assert.throws(() => parseReleaseNotes("No frontmatter"), /frontmatter/);
});
test("resolves the Gitea API URL from compatible runner variables", () => {
assert.equal(resolveGiteaApiUrl({ GITEA_API_URL: "https://gitea.example/api/v1/" }), "https://gitea.example/api/v1");
assert.equal(resolveGiteaApiUrl({ GITHUB_SERVER_URL: "https://gitea.example" }), "https://gitea.example/api/v1");
});
test("creates a missing tag and preserves an existing matching tag", async () => {
const requests = [];
const created = await ensureTag({
apiUrl: "https://gitea.example/api/v1",
repository: "owner/repo",
token: "secret",
tag: "v1.2.3",
target: "a".repeat(40),
fetchImpl: async (url, options) => {
requests.push({ url, options });
if (requests.length === 1) return response(404, { message: "missing" });
return response(201, { name: "v1.2.3", commit: { sha: "a".repeat(40) } });
},
});
assert.equal(created.name, "v1.2.3");
assert.equal(requests[1].options.method, "POST");
await ensureTag({
apiUrl: "https://gitea.example/api/v1",
repository: "owner/repo",
token: "secret",
tag: "v1.2.3",
target: "a".repeat(40),
fetchImpl: async () => response(200, { commit: { sha: "a".repeat(40) } }),
});
});
test("refuses to reuse a tag that points at another commit", async () => {
await assert.rejects(
ensureTag({
apiUrl: "https://gitea.example/api/v1",
repository: "owner/repo",
token: "secret",
tag: "v1.2.3",
target: "a".repeat(40),
fetchImpl: async () => response(200, { commit: { sha: "b".repeat(40) } }),
}),
/already points/,
);
});
test("creates and updates releases idempotently", async () => {
const release = { tag_name: "v1.2.3", name: "Stable", body: "Notes", draft: false, prerelease: false };
const createRequests = [];
await publishRelease({
apiUrl: "https://gitea.example/api/v1",
repository: "owner/repo",
token: "secret",
release,
fetchImpl: async (url, options) => {
createRequests.push({ url, options });
return createRequests.length === 1 ? response(404, {}) : response(201, { id: 7 });
},
});
assert.equal(createRequests[1].options.method, "POST");
const updateRequests = [];
await publishRelease({
apiUrl: "https://gitea.example/api/v1",
repository: "owner/repo",
token: "secret",
release,
fetchImpl: async (url, options) => {
updateRequests.push({ url, options });
return updateRequests.length === 1 ? response(200, { id: 9 }) : response(200, { id: 9 });
},
});
assert.equal(updateRequests[1].options.method, "PATCH");
});