diff --git a/release-tooling/auto-release.test.ts b/release-tooling/auto-release.test.ts index c44c605..7c8f6e2 100644 --- a/release-tooling/auto-release.test.ts +++ b/release-tooling/auto-release.test.ts @@ -2,7 +2,7 @@ import assert from "node:assert/strict"; import { readFileSync } from "node:fs"; import { test } from "node:test"; -test("auto-release's checkout persists no credentials, so the tag push authenticates as renovate-bot", () => { +test("auto-release's checkout doesn't persist credentials, so the tag push authenticates as renovate-bot", () => { const workflow = readFileSync(".gitea/workflows/renovate.yml", "utf8"); const job = workflow.slice(workflow.indexOf("\n auto-release:")); const checkout = job.slice(job.indexOf("actions/checkout@"), job.indexOf("\n - name:")); diff --git a/release-tooling/dockerhub-overview.test.ts b/release-tooling/dockerhub-overview.test.ts index a314f78..2763c4f 100644 --- a/release-tooling/dockerhub-overview.test.ts +++ b/release-tooling/dockerhub-overview.test.ts @@ -1,7 +1,7 @@ import assert from "node:assert/strict"; import { readFileSync } from "node:fs"; import { test } from "node:test"; -import { DESCRIPTION, jwtFrom, leftoverPlaceholders, renderOverview } from "./dockerhub-overview.ts"; +import { DESCRIPTION, hubPatch, jwtFrom, leftoverPlaceholders, renderOverview } from "./dockerhub-overview.ts"; const TEMPLATE = "release-tooling/dockerhub-overview.md.tmpl"; const template = () => readFileSync(TEMPLATE, "utf8"); @@ -49,9 +49,9 @@ test("jwtFrom accepts only a non-empty string token, never throwing on a hostile test("the short description opens a README sentence and fits Docker Hub's 100 characters", () => { const readme = readFileSync("README.md", "utf8").replaceAll("**", ""); - assert.ok(DESCRIPTION.length <= 100, `${DESCRIPTION.length} characters`); + assert.ok(DESCRIPTION.trim() !== "" && DESCRIPTION.length <= 100, `${DESCRIPTION.length} characters`); const escaped = DESCRIPTION.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"); - assert.match(readme, new RegExp(`^${escaped}(?=[\\s.:,])`, "m")); + assert.match(readme, new RegExp(`(?:\\n\\n|\\.\\s)${escaped}(?=[\\s.:,])`)); }); test("every command the overview shows, the README shows too", () => { @@ -65,5 +65,9 @@ test("every command the overview shows, the README shows too", () => { const shown = new Set(commands(readFileSync("README.md", "utf8"))); const published = commands(template()); assert.ok(published.length > 0, `${TEMPLATE} should show commands`); - for (const command of published) assert.ok(shown.has(command), `${TEMPLATE} runs ${command}, which README.md doesn't show`); + for (const command of published) assert.ok(shown.has(command), `${TEMPLATE} shows ${command}, which README.md doesn't`); +}); + +test("the PATCH carries the short description beside the overview", () => { + assert.deepEqual(hubPatch("# page"), { description: DESCRIPTION, full_description: "# page" }); }); diff --git a/release-tooling/dockerhub-overview.ts b/release-tooling/dockerhub-overview.ts index 7a7b8a4..5f95e40 100644 --- a/release-tooling/dockerhub-overview.ts +++ b/release-tooling/dockerhub-overview.ts @@ -1,6 +1,3 @@ -// Publishes the Docker Hub repository overview from dockerhub-overview.md.tmpl, rendering -// `{{VERSION}}` to the release being published, and the short description. - import { readFileSync } from "node:fs"; import { join } from "node:path"; @@ -10,6 +7,10 @@ const VERSION = /^\d+\.\d+\.\d+$/; export const DESCRIPTION = "A self-hostable foundation for server-rendered web applications"; +export function hubPatch(overview: string): { description: string; full_description: string } { + return { description: DESCRIPTION, full_description: overview }; +} + export function renderOverview(source: string, version: string): string { return source.replaceAll("{{VERSION}}", version); } @@ -83,7 +84,7 @@ async function main(): Promise { if (!jwt) return fail("Docker Hub login returned no token"); const res = await post(`${HUB}/repositories/${repo}/`, { - body: JSON.stringify({ description: DESCRIPTION, full_description: body }), + body: JSON.stringify(hubPatch(body)), headers: { authorization: `Bearer ${jwt}`, "content-type": "application/json" }, method: "PATCH", });