From dcc8fae0c0f073d3a56b97dfc25e68964af491ed Mon Sep 17 00:00:00 2001 From: Eric Arellano <14852634+Eric-Arellano@users.noreply.github.com> Date: Mon, 6 May 2024 16:01:44 -0400 Subject: [PATCH 1/5] Move release notes helpers to releaseNotes.ts No other changes made. --- scripts/lib/api/conversionPipeline.ts | 62 +-------------------- scripts/lib/api/releaseNotes.ts | 80 ++++++++++++++++++++++----- 2 files changed, 69 insertions(+), 73 deletions(-) diff --git a/scripts/lib/api/conversionPipeline.ts b/scripts/lib/api/conversionPipeline.ts index 31697a0eeed..25987641807 100644 --- a/scripts/lib/api/conversionPipeline.ts +++ b/scripts/lib/api/conversionPipeline.ts @@ -16,7 +16,6 @@ import { readFile, writeFile } from "fs/promises"; import { mkdirp } from "mkdirp"; import { globby } from "globby"; import { uniqBy } from "lodash"; -import transformLinks from "transform-markdown-links"; import { ObjectsInv } from "./objectsInv"; import { sphinxHtmlToMarkdown } from "./htmlToMd"; @@ -33,10 +32,8 @@ import removeMathBlocksIndentation from "./removeMathBlocksIndentation"; import { Pkg } from "./Pkg"; import { pathExists } from "../fs"; import { - addNewReleaseNotes, - generateReleaseNotesIndex, - updateHistoricalTocFiles, - writeReleaseNoteForVersion, + maybeUpdateReleaseNotesFolder, + handleReleaseNotesFile, } from "./releaseNotes"; export async function runConversionPipeline( @@ -175,61 +172,6 @@ async function writeMarkdownResults( } } -/** - * Determine what to do with release-notes.mdx, such as simply ignoring it. - * - * @returns true if the release notes file should be written. - */ -async function handleReleaseNotesFile( - result: HtmlToMdResultWithUrl, - pkg: Pkg, -): Promise { - // Dev versions haven't been released yet and we don't want to modify the release notes - // of prior versions. - if (pkg.isDev()) { - return false; - } - - // When the release notes are a single file, only use them if this is the latest version rather - // than a historical release. - if (!pkg.hasSeparateReleaseNotes) { - return pkg.isLatest(); - } - - // Else, there is a distinct release note per version. So, we use the release note but - // have custom logic to handle it. - - const baseUrl = pkg.isHistorical() - ? `/api/${pkg.name}/${pkg.versionWithoutPatch}` - : `/api/${pkg.name}`; - result.markdown = transformLinks(result.markdown, (link, _) => - link.startsWith("http") || link.startsWith("#") || link.startsWith("/") - ? link - : `${baseUrl}/${link}`, - ); - - await writeReleaseNoteForVersion(pkg, result.markdown); - return false; -} - -/** - * If there was a new release notes file, update the release notes index page and _toc.json for - * every docs version. - */ -async function maybeUpdateReleaseNotesFolder( - pkg: Pkg, - markdownPath: string, -): Promise { - if (!pkg.hasSeparateReleaseNotes || !pkg.isLatest()) { - return; - } - addNewReleaseNotes(pkg); - await updateHistoricalTocFiles(pkg); - console.log("Generating release-notes/index"); - const indexMarkdown = generateReleaseNotesIndex(pkg); - await writeFile(`${markdownPath}/release-notes/index.mdx`, indexMarkdown); -} - async function writeTocFile( pkg: Pkg, markdownPath: string, diff --git a/scripts/lib/api/releaseNotes.ts b/scripts/lib/api/releaseNotes.ts index bfe29b1b1dc..8e69385e23b 100644 --- a/scripts/lib/api/releaseNotes.ts +++ b/scripts/lib/api/releaseNotes.ts @@ -14,9 +14,72 @@ import { parse } from "path"; import { readFile, writeFile, readdir } from "fs/promises"; import { $ } from "zx"; +import transformLinks from "transform-markdown-links"; import { getRoot, pathExists } from "../fs"; import type { Pkg, ReleaseNoteEntry } from "./Pkg"; +import type { HtmlToMdResultWithUrl } from "./HtmlToMdResult"; + +// --------------------------------------------------------------------------- +// Generic release notes handling +// --------------------------------------------------------------------------- + +/** + * Determine what to do with release-notes.mdx, such as simply ignoring it. + * + * @returns true if the release notes file should be written. + */ +export async function handleReleaseNotesFile( + result: HtmlToMdResultWithUrl, + pkg: Pkg, +): Promise { + // Dev versions haven't been released yet and we don't want to modify the release notes + // of prior versions. + if (pkg.isDev()) { + return false; + } + + // When the release notes are a single file, only use them if this is the latest version rather + // than a historical release. + if (!pkg.hasSeparateReleaseNotes) { + return pkg.isLatest(); + } + + // Else, there is a distinct release note per version. So, we use the release note but + // have custom logic to handle it. + const baseUrl = pkg.isHistorical() + ? `/api/${pkg.name}/${pkg.versionWithoutPatch}` + : `/api/${pkg.name}`; + result.markdown = transformLinks(result.markdown, (link, _) => + link.startsWith("http") || link.startsWith("#") || link.startsWith("/") + ? link + : `${baseUrl}/${link}`, + ); + await writeReleaseNoteForVersion(pkg, result.markdown); + return false; +} + +// --------------------------------------------------------------------------- +// Utils for release-note per version +// --------------------------------------------------------------------------- + +/** + * If there was a new release notes file, update the release notes index page and _toc.json for + * every docs version. + */ +export async function maybeUpdateReleaseNotesFolder( + pkg: Pkg, + markdownPath: string, +): Promise { + if (!pkg.hasSeparateReleaseNotes || !pkg.isLatest()) { + return; + } + addNewReleaseNotes(pkg); + await updateHistoricalTocFiles(pkg); + console.log("Generating release-notes/index"); + const indexMarkdown = generateReleaseNotesIndex(pkg); + await writeFile(`${markdownPath}/release-notes/index.mdx`, indexMarkdown); +} /** * Check for markdown files in `docs/api/package-name/release-notes/ @@ -57,7 +120,7 @@ export const findLegacyReleaseNotes = async ( return legacyReleaseNoteEntries; }; -export function addNewReleaseNotes(pkg: Pkg): void { +function addNewReleaseNotes(pkg: Pkg): void { if (pkg.releaseNoteEntries[0].title === pkg.versionWithoutPatch) { // Entries already includes most recent release notes return; @@ -68,7 +131,7 @@ export function addNewReleaseNotes(pkg: Pkg): void { }); } -export function generateReleaseNotesIndex(pkg: Pkg): string { +function generateReleaseNotesIndex(pkg: Pkg): string { let markdown = `--- title: ${pkg.title} release notes description: New features, bug fixes, and other changes in previous versions of ${pkg.title}. @@ -87,20 +150,11 @@ New features, bug fixes, and other changes in previous versions of ${pkg.title}. return markdown; } -/** - * Path to release notes file for the version we're adding - */ -export function currentReleaseNotesPath(pkg: Pkg): string { - return `${getRoot()}/docs/api/${pkg.name}/release-notes/${ - pkg.versionWithoutPatch - }.mdx`; -} - /** * Adds a new entry for the release notes of the current API version to the _toc.json * of all historical API versions. */ -export async function updateHistoricalTocFiles(pkg: Pkg): Promise { +async function updateHistoricalTocFiles(pkg: Pkg): Promise { console.log("Updating _toc.json files for the historical versions"); const historicalFolders = ( @@ -148,7 +202,7 @@ function addNewReleaseNoteToc(releaseNotesNode: any, newVersion: string) { * Creates the release note file for the minor version found in `pkg`.If the file * already exists, it will keep the initial header and overwrite the rest of the content. */ -export async function writeReleaseNoteForVersion( +async function writeReleaseNoteForVersion( pkg: Pkg, releaseNoteMarkdown: string, ): Promise { From 301e081f82d3a6cec075185cbc1b8de1b1ffe2d3 Mon Sep 17 00:00:00 2001 From: Eric Arellano <14852634+Eric-Arellano@users.noreply.github.com> Date: Mon, 6 May 2024 16:21:08 -0400 Subject: [PATCH 2/5] Generalize addFrontMatter handling of release notes better Before, we were checking if it was Qiskit. But we should be consistent for all packages that have separate release notes. --- scripts/lib/api/addFrontMatter.test.ts | 2 +- scripts/lib/api/addFrontMatter.ts | 15 ++++++++------- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/scripts/lib/api/addFrontMatter.test.ts b/scripts/lib/api/addFrontMatter.test.ts index 87572dfdefc..0221ebc784b 100644 --- a/scripts/lib/api/addFrontMatter.test.ts +++ b/scripts/lib/api/addFrontMatter.test.ts @@ -105,7 +105,7 @@ python_api_name: quantum_software `--- title: My Quantum Project 0.1 release notes description: Changes made in My Quantum Project 0.1 -in_page_toc_max_heading_level: 2 +in_page_toc_max_heading_level: 3 --- # Some release notes! diff --git a/scripts/lib/api/addFrontMatter.ts b/scripts/lib/api/addFrontMatter.ts index 9b89a7c8c83..702ddee6a53 100644 --- a/scripts/lib/api/addFrontMatter.ts +++ b/scripts/lib/api/addFrontMatter.ts @@ -45,13 +45,14 @@ python_api_name: ${result.meta.apiName} ${markdown} `; } else if (result.isReleaseNotes) { - const versionStr = pkg.hasSeparateReleaseNotes - ? ` ${pkg.versionWithoutPatch}` - : ""; - const descriptionSuffix = pkg.hasSeparateReleaseNotes - ? `in ${pkg.title}${versionStr}` - : `to ${pkg.title}`; - const maxHeadingLevel = pkg.name == "qiskit" ? 3 : 2; + let versionStr = ""; + let descriptionSuffix = `to ${pkg.title}`; + let maxHeadingLevel = 2; + if (pkg.hasSeparateReleaseNotes) { + versionStr = ` ${pkg.versionWithoutPatch}`; + descriptionSuffix = `in ${pkg.title}${versionStr}`; + maxHeadingLevel = 3; + } result.markdown = `--- title: ${pkg.title}${versionStr} release notes description: Changes made ${descriptionSuffix} From 10f4e02def3a39522f60d9b8332d30eb166280e4 Mon Sep 17 00:00:00 2001 From: Eric Arellano <14852634+Eric-Arellano@users.noreply.github.com> Date: Mon, 6 May 2024 16:22:04 -0400 Subject: [PATCH 3/5] Remove hasSeparateReleaseNotes by using releaseNoteEntries instead It was redundant to have both. Now, we have a method hasSeparateReleaseNotes() that dynamically computes the value --- scripts/lib/api/Pkg.ts | 14 +++++--------- scripts/lib/api/addFrontMatter.test.ts | 4 +++- scripts/lib/api/addFrontMatter.ts | 2 +- scripts/lib/api/conversionPipeline.test.ts | 1 - scripts/lib/api/generateToc.ts | 2 +- scripts/lib/api/releaseNotes.ts | 6 +++--- 6 files changed, 13 insertions(+), 16 deletions(-) diff --git a/scripts/lib/api/Pkg.ts b/scripts/lib/api/Pkg.ts index 2640348b978..fdafc0e0aa1 100644 --- a/scripts/lib/api/Pkg.ts +++ b/scripts/lib/api/Pkg.ts @@ -31,7 +31,6 @@ export class Pkg { readonly name: string; readonly title: string; readonly githubSlug: string; - readonly hasSeparateReleaseNotes: boolean; readonly version: string; readonly versionWithoutPatch: string; readonly type: PackageType; @@ -45,7 +44,6 @@ export class Pkg { name: string; title: string; githubSlug: string; - hasSeparateReleaseNotes: boolean; version: string; versionWithoutPatch: string; type: PackageType; @@ -56,7 +54,6 @@ export class Pkg { this.name = kwargs.name; this.title = kwargs.title; this.githubSlug = kwargs.githubSlug; - this.hasSeparateReleaseNotes = kwargs.hasSeparateReleaseNotes; this.version = kwargs.version; this.versionWithoutPatch = kwargs.versionWithoutPatch; this.type = kwargs.type; @@ -85,7 +82,6 @@ export class Pkg { title: "Qiskit SDK", name: "qiskit", githubSlug: "qiskit/qiskit", - hasSeparateReleaseNotes: true, releaseNoteEntries, nestModulesInToc: true, }); @@ -97,7 +93,6 @@ export class Pkg { title: "Qiskit Runtime IBM Client", name: "qiskit-ibm-runtime", githubSlug: "qiskit/qiskit-ibm-runtime", - hasSeparateReleaseNotes: false, releaseNoteEntries: [], }); } @@ -108,7 +103,6 @@ export class Pkg { title: "Qiskit IBM Provider (deprecated)", name: "qiskit-ibm-provider", githubSlug: "qiskit/qiskit-ibm-provider", - hasSeparateReleaseNotes: false, releaseNoteEntries: [], }); } @@ -120,7 +114,6 @@ export class Pkg { name?: string; title?: string; githubSlug?: string; - hasSeparateReleaseNotes?: boolean; version?: string; versionWithoutPatch?: string; type?: PackageType; @@ -132,7 +125,6 @@ export class Pkg { name: kwargs.name ?? "my-quantum-project", title: kwargs.title ?? "My Quantum Project", githubSlug: kwargs.githubSlug ?? "qiskit/my-quantum-project", - hasSeparateReleaseNotes: kwargs.hasSeparateReleaseNotes ?? false, version: kwargs.version ?? "0.1.0", versionWithoutPatch: kwargs.versionWithoutPatch ?? "0.1", type: kwargs.type ?? "latest", @@ -174,8 +166,12 @@ export class Pkg { return this.name !== "qiskit" || +this.versionWithoutPatch >= 0.45; } + hasSeparateReleaseNotes(): boolean { + return this.releaseNoteEntries.length > 0; + } + releaseNotesTitle(): string { - const versionStr = this.hasSeparateReleaseNotes + const versionStr = this.hasSeparateReleaseNotes() ? ` ${this.versionWithoutPatch}` : ""; return `${this.title}${versionStr} release notes`; diff --git a/scripts/lib/api/addFrontMatter.test.ts b/scripts/lib/api/addFrontMatter.test.ts index 0221ebc784b..41ed9055cde 100644 --- a/scripts/lib/api/addFrontMatter.test.ts +++ b/scripts/lib/api/addFrontMatter.test.ts @@ -63,7 +63,9 @@ test("addFrontMatter()", () => { }, ]; const pkg = Pkg.mock({ - hasSeparateReleaseNotes: true, + releaseNoteEntries: [ + { title: "0.1", url: "/api/my-quantum-project/release-notes/0.1" }, + ], }); addFrontMatter(results, pkg); diff --git a/scripts/lib/api/addFrontMatter.ts b/scripts/lib/api/addFrontMatter.ts index 702ddee6a53..f09ba4b9d70 100644 --- a/scripts/lib/api/addFrontMatter.ts +++ b/scripts/lib/api/addFrontMatter.ts @@ -48,7 +48,7 @@ ${markdown} let versionStr = ""; let descriptionSuffix = `to ${pkg.title}`; let maxHeadingLevel = 2; - if (pkg.hasSeparateReleaseNotes) { + if (pkg.hasSeparateReleaseNotes()) { versionStr = ` ${pkg.versionWithoutPatch}`; descriptionSuffix = `in ${pkg.title}${versionStr}`; maxHeadingLevel = 3; diff --git a/scripts/lib/api/conversionPipeline.test.ts b/scripts/lib/api/conversionPipeline.test.ts index f449c2cfb1a..e25f9b8a7bf 100644 --- a/scripts/lib/api/conversionPipeline.test.ts +++ b/scripts/lib/api/conversionPipeline.test.ts @@ -55,7 +55,6 @@ test("qiskit-sphinx-theme", async () => { name: "qiskit-sphinx-theme", title: "Qiskit Sphinx Theme", githubSlug: "Qiskit/qiskit_sphinx_theme", - hasSeparateReleaseNotes: false, version: "0.1.1", versionWithoutPatch: "0.1", type: "latest", diff --git a/scripts/lib/api/generateToc.ts b/scripts/lib/api/generateToc.ts index d67929e3c7d..7f795c5757b 100644 --- a/scripts/lib/api/generateToc.ts +++ b/scripts/lib/api/generateToc.ts @@ -271,7 +271,7 @@ function generateReleaseNotesEntries(pkg: Pkg) { const releaseNotesEntry: TocEntry = { title: "Release notes", }; - if (pkg.releaseNoteEntries.length) { + if (pkg.hasSeparateReleaseNotes()) { releaseNotesEntry.children = pkg.releaseNoteEntries; } else { releaseNotesEntry.url = releaseNotesUrl; diff --git a/scripts/lib/api/releaseNotes.ts b/scripts/lib/api/releaseNotes.ts index 8e69385e23b..7ecc6ec5cb4 100644 --- a/scripts/lib/api/releaseNotes.ts +++ b/scripts/lib/api/releaseNotes.ts @@ -41,7 +41,7 @@ export async function handleReleaseNotesFile( // When the release notes are a single file, only use them if this is the latest version rather // than a historical release. - if (!pkg.hasSeparateReleaseNotes) { + if (!pkg.hasSeparateReleaseNotes()) { return pkg.isLatest(); } @@ -71,7 +71,7 @@ export async function maybeUpdateReleaseNotesFolder( pkg: Pkg, markdownPath: string, ): Promise { - if (!pkg.hasSeparateReleaseNotes || !pkg.isLatest()) { + if (!pkg.hasSeparateReleaseNotes() || !pkg.isLatest()) { return; } addNewReleaseNotes(pkg); @@ -206,7 +206,7 @@ async function writeReleaseNoteForVersion( pkg: Pkg, releaseNoteMarkdown: string, ): Promise { - if (!pkg.hasSeparateReleaseNotes) { + if (!pkg.hasSeparateReleaseNotes()) { throw new Error( `The package ${pkg.name} doesn't have separate release notes`, ); From 27b7a73fd21552ab17623d5bf23474a06926c05a Mon Sep 17 00:00:00 2001 From: Eric Arellano <14852634+Eric-Arellano@users.noreply.github.com> Date: Mon, 6 May 2024 16:46:13 -0400 Subject: [PATCH 4/5] Use new ReleaseNotesConfig class This will soon have the additional kwarg `enabled`. The class is nice because it allows us to have default args and to group related config options into a single place. --- scripts/lib/api/Pkg.ts | 27 ++++++++++++++-------- scripts/lib/api/addFrontMatter.test.ts | 10 ++++---- scripts/lib/api/conversionPipeline.test.ts | 1 - scripts/lib/api/generateToc.test.ts | 18 +++++++++++---- scripts/lib/api/generateToc.ts | 2 +- scripts/lib/api/releaseNotes.ts | 8 ++++--- 6 files changed, 43 insertions(+), 23 deletions(-) diff --git a/scripts/lib/api/Pkg.ts b/scripts/lib/api/Pkg.ts index fdafc0e0aa1..a64a12a6336 100644 --- a/scripts/lib/api/Pkg.ts +++ b/scripts/lib/api/Pkg.ts @@ -22,6 +22,14 @@ export interface ReleaseNoteEntry { url: string; } +export class ReleaseNotesConfig { + readonly separatePages: ReleaseNoteEntry[]; + + constructor(kwargs: { separatePages?: ReleaseNoteEntry[] }) { + this.separatePages = kwargs.separatePages ?? []; + } +} + type PackageType = "latest" | "historical" | "dev"; /** @@ -34,7 +42,7 @@ export class Pkg { readonly version: string; readonly versionWithoutPatch: string; readonly type: PackageType; - readonly releaseNoteEntries: ReleaseNoteEntry[]; + readonly releaseNotesConfig: ReleaseNotesConfig; readonly nestModulesInToc: boolean; readonly tocGrouping?: TocGrouping; @@ -47,7 +55,7 @@ export class Pkg { version: string; versionWithoutPatch: string; type: PackageType; - releaseNoteEntries: ReleaseNoteEntry[]; + releaseNotesConfig?: ReleaseNotesConfig; nestModulesInToc?: boolean; tocGrouping?: TocGrouping; }) { @@ -57,7 +65,8 @@ export class Pkg { this.version = kwargs.version; this.versionWithoutPatch = kwargs.versionWithoutPatch; this.type = kwargs.type; - this.releaseNoteEntries = kwargs.releaseNoteEntries; + this.releaseNotesConfig = + kwargs.releaseNotesConfig ?? new ReleaseNotesConfig({}); this.nestModulesInToc = kwargs.nestModulesInToc ?? false; this.tocGrouping = kwargs.tocGrouping; } @@ -82,7 +91,9 @@ export class Pkg { title: "Qiskit SDK", name: "qiskit", githubSlug: "qiskit/qiskit", - releaseNoteEntries, + releaseNotesConfig: new ReleaseNotesConfig({ + separatePages: releaseNoteEntries, + }), nestModulesInToc: true, }); } @@ -93,7 +104,6 @@ export class Pkg { title: "Qiskit Runtime IBM Client", name: "qiskit-ibm-runtime", githubSlug: "qiskit/qiskit-ibm-runtime", - releaseNoteEntries: [], }); } @@ -103,7 +113,6 @@ export class Pkg { title: "Qiskit IBM Provider (deprecated)", name: "qiskit-ibm-provider", githubSlug: "qiskit/qiskit-ibm-provider", - releaseNoteEntries: [], }); } @@ -117,7 +126,7 @@ export class Pkg { version?: string; versionWithoutPatch?: string; type?: PackageType; - releaseNoteEntries?: ReleaseNoteEntry[]; + releaseNotesConfig?: ReleaseNotesConfig; nestModulesInToc?: boolean; tocGrouping?: TocGrouping; }): Pkg { @@ -128,7 +137,7 @@ export class Pkg { version: kwargs.version ?? "0.1.0", versionWithoutPatch: kwargs.versionWithoutPatch ?? "0.1", type: kwargs.type ?? "latest", - releaseNoteEntries: kwargs.releaseNoteEntries ?? [], + releaseNotesConfig: kwargs.releaseNotesConfig, nestModulesInToc: kwargs.nestModulesInToc ?? false, tocGrouping: kwargs.tocGrouping ?? undefined, }); @@ -167,7 +176,7 @@ export class Pkg { } hasSeparateReleaseNotes(): boolean { - return this.releaseNoteEntries.length > 0; + return this.releaseNotesConfig.separatePages.length > 0; } releaseNotesTitle(): string { diff --git a/scripts/lib/api/addFrontMatter.test.ts b/scripts/lib/api/addFrontMatter.test.ts index 41ed9055cde..abdcb5aa8c0 100644 --- a/scripts/lib/api/addFrontMatter.test.ts +++ b/scripts/lib/api/addFrontMatter.test.ts @@ -13,7 +13,7 @@ import { expect, test } from "@jest/globals"; import addFrontMatter from "./addFrontMatter"; -import { Pkg } from "./Pkg"; +import { Pkg, ReleaseNotesConfig } from "./Pkg"; import { HtmlToMdResult } from "./HtmlToMdResult"; test("addFrontMatter()", () => { @@ -63,9 +63,11 @@ test("addFrontMatter()", () => { }, ]; const pkg = Pkg.mock({ - releaseNoteEntries: [ - { title: "0.1", url: "/api/my-quantum-project/release-notes/0.1" }, - ], + releaseNotesConfig: new ReleaseNotesConfig({ + separatePages: [ + { title: "0.1", url: "/api/my-quantum-project/release-notes/0.1" }, + ], + }), }); addFrontMatter(results, pkg); diff --git a/scripts/lib/api/conversionPipeline.test.ts b/scripts/lib/api/conversionPipeline.test.ts index e25f9b8a7bf..54ffdd8e5cf 100644 --- a/scripts/lib/api/conversionPipeline.test.ts +++ b/scripts/lib/api/conversionPipeline.test.ts @@ -58,7 +58,6 @@ test("qiskit-sphinx-theme", async () => { version: "0.1.1", versionWithoutPatch: "0.1", type: "latest", - releaseNoteEntries: [], }); const markdownFolder = pkg.outputDir(docsBaseFolder); diff --git a/scripts/lib/api/generateToc.test.ts b/scripts/lib/api/generateToc.test.ts index 9d84f0d44ba..cea7deca3a4 100644 --- a/scripts/lib/api/generateToc.test.ts +++ b/scripts/lib/api/generateToc.test.ts @@ -13,7 +13,7 @@ import { describe, expect, test } from "@jest/globals"; import { generateToc } from "./generateToc"; -import { Pkg } from "./Pkg"; +import { Pkg, ReleaseNotesConfig } from "./Pkg"; import type { TocGroupingEntry } from "./TocGrouping"; const DEFAULT_ARGS = { @@ -276,10 +276,18 @@ describe("generateToc", () => { test("TOC with distinct release note files", () => { const toc = generateToc( Pkg.mock({ - releaseNoteEntries: [ - { title: "0.39", url: "/api/my-quantum-project/release-notes/0.39" }, - { title: "0.38", url: "/api/my-quantum-project/release-notes/0.38" }, - ], + releaseNotesConfig: new ReleaseNotesConfig({ + separatePages: [ + { + title: "0.39", + url: "/api/my-quantum-project/release-notes/0.39", + }, + { + title: "0.38", + url: "/api/my-quantum-project/release-notes/0.38", + }, + ], + }), }), [ { diff --git a/scripts/lib/api/generateToc.ts b/scripts/lib/api/generateToc.ts index 7f795c5757b..4e33987d6c4 100644 --- a/scripts/lib/api/generateToc.ts +++ b/scripts/lib/api/generateToc.ts @@ -272,7 +272,7 @@ function generateReleaseNotesEntries(pkg: Pkg) { title: "Release notes", }; if (pkg.hasSeparateReleaseNotes()) { - releaseNotesEntry.children = pkg.releaseNoteEntries; + releaseNotesEntry.children = pkg.releaseNotesConfig.separatePages; } else { releaseNotesEntry.url = releaseNotesUrl; } diff --git a/scripts/lib/api/releaseNotes.ts b/scripts/lib/api/releaseNotes.ts index 7ecc6ec5cb4..65945c9a8bb 100644 --- a/scripts/lib/api/releaseNotes.ts +++ b/scripts/lib/api/releaseNotes.ts @@ -121,11 +121,13 @@ export const findLegacyReleaseNotes = async ( }; function addNewReleaseNotes(pkg: Pkg): void { - if (pkg.releaseNoteEntries[0].title === pkg.versionWithoutPatch) { + if ( + pkg.releaseNotesConfig.separatePages[0].title === pkg.versionWithoutPatch + ) { // Entries already includes most recent release notes return; } - pkg.releaseNoteEntries.unshift({ + pkg.releaseNotesConfig.separatePages.unshift({ title: pkg.versionWithoutPatch, url: `/api/${pkg.name}/release-notes/${pkg.versionWithoutPatch}`, }); @@ -144,7 +146,7 @@ New features, bug fixes, and other changes in previous versions of ${pkg.title}. ## Release notes by version `; - for (const entry of pkg.releaseNoteEntries) { + for (const entry of pkg.releaseNotesConfig.separatePages) { markdown += `* [${entry.title}](${entry.url})\n`; } return markdown; From 85745778dbecef89bf412a2b1ac225ad014acb01 Mon Sep 17 00:00:00 2001 From: Eric Arellano <14852634+Eric-Arellano@users.noreply.github.com> Date: Mon, 6 May 2024 17:16:06 -0400 Subject: [PATCH 5/5] Simplify how separate versions are specified Before, we required that you specify the version & the URL for the entry. But the full URL is only necessary in generateToc.ts, which already has the prefix for the URL. It's much simpler if instead we only pass the version strings. --- docs/api/qiskit/release-notes/index.mdx | 86 ++++++++++++------------- scripts/lib/api/Pkg.ts | 19 ++---- scripts/lib/api/addFrontMatter.test.ts | 4 +- scripts/lib/api/generateToc.test.ts | 11 +--- scripts/lib/api/generateToc.ts | 6 +- scripts/lib/api/releaseNotes.ts | 32 +++------ 6 files changed, 67 insertions(+), 91 deletions(-) diff --git a/docs/api/qiskit/release-notes/index.mdx b/docs/api/qiskit/release-notes/index.mdx index ac686f8c927..3f3499e6e11 100644 --- a/docs/api/qiskit/release-notes/index.mdx +++ b/docs/api/qiskit/release-notes/index.mdx @@ -9,46 +9,46 @@ New features, bug fixes, and other changes in previous versions of Qiskit SDK. ## Release notes by version -* [1.0](/api/qiskit/release-notes/1.0) -* [0.46](/api/qiskit/release-notes/0.46) -* [0.45](/api/qiskit/release-notes/0.45) -* [0.44](/api/qiskit/release-notes/0.44) -* [0.43](/api/qiskit/release-notes/0.43) -* [0.42](/api/qiskit/release-notes/0.42) -* [0.41](/api/qiskit/release-notes/0.41) -* [0.40](/api/qiskit/release-notes/0.40) -* [0.39](/api/qiskit/release-notes/0.39) -* [0.38](/api/qiskit/release-notes/0.38) -* [0.37](/api/qiskit/release-notes/0.37) -* [0.36](/api/qiskit/release-notes/0.36) -* [0.35](/api/qiskit/release-notes/0.35) -* [0.34](/api/qiskit/release-notes/0.34) -* [0.33](/api/qiskit/release-notes/0.33) -* [0.32](/api/qiskit/release-notes/0.32) -* [0.31](/api/qiskit/release-notes/0.31) -* [0.30](/api/qiskit/release-notes/0.30) -* [0.29](/api/qiskit/release-notes/0.29) -* [0.28](/api/qiskit/release-notes/0.28) -* [0.27](/api/qiskit/release-notes/0.27) -* [0.26](/api/qiskit/release-notes/0.26) -* [0.25](/api/qiskit/release-notes/0.25) -* [0.24](/api/qiskit/release-notes/0.24) -* [0.23](/api/qiskit/release-notes/0.23) -* [0.22](/api/qiskit/release-notes/0.22) -* [0.21](/api/qiskit/release-notes/0.21) -* [0.20](/api/qiskit/release-notes/0.20) -* [0.19](/api/qiskit/release-notes/0.19) -* [0.18](/api/qiskit/release-notes/0.18) -* [0.17](/api/qiskit/release-notes/0.17) -* [0.16](/api/qiskit/release-notes/0.16) -* [0.15](/api/qiskit/release-notes/0.15) -* [0.14](/api/qiskit/release-notes/0.14) -* [0.13](/api/qiskit/release-notes/0.13) -* [0.12](/api/qiskit/release-notes/0.12) -* [0.11](/api/qiskit/release-notes/0.11) -* [0.10](/api/qiskit/release-notes/0.10) -* [0.9](/api/qiskit/release-notes/0.9) -* [0.8](/api/qiskit/release-notes/0.8) -* [0.7](/api/qiskit/release-notes/0.7) -* [0.6](/api/qiskit/release-notes/0.6) -* [0.5](/api/qiskit/release-notes/0.5) +* [1.0](./1.0) +* [0.46](./0.46) +* [0.45](./0.45) +* [0.44](./0.44) +* [0.43](./0.43) +* [0.42](./0.42) +* [0.41](./0.41) +* [0.40](./0.40) +* [0.39](./0.39) +* [0.38](./0.38) +* [0.37](./0.37) +* [0.36](./0.36) +* [0.35](./0.35) +* [0.34](./0.34) +* [0.33](./0.33) +* [0.32](./0.32) +* [0.31](./0.31) +* [0.30](./0.30) +* [0.29](./0.29) +* [0.28](./0.28) +* [0.27](./0.27) +* [0.26](./0.26) +* [0.25](./0.25) +* [0.24](./0.24) +* [0.23](./0.23) +* [0.22](./0.22) +* [0.21](./0.21) +* [0.20](./0.20) +* [0.19](./0.19) +* [0.18](./0.18) +* [0.17](./0.17) +* [0.16](./0.16) +* [0.15](./0.15) +* [0.14](./0.14) +* [0.13](./0.13) +* [0.12](./0.12) +* [0.11](./0.11) +* [0.10](./0.10) +* [0.9](./0.9) +* [0.8](./0.8) +* [0.7](./0.7) +* [0.6](./0.6) +* [0.5](./0.5) diff --git a/scripts/lib/api/Pkg.ts b/scripts/lib/api/Pkg.ts index a64a12a6336..350881657a4 100644 --- a/scripts/lib/api/Pkg.ts +++ b/scripts/lib/api/Pkg.ts @@ -12,21 +12,16 @@ import { join } from "path/posix"; -import { findLegacyReleaseNotes } from "./releaseNotes"; +import { findSeparateReleaseNotesVersions } from "./releaseNotes"; import { getRoot } from "../fs"; import { determineHistoricalQiskitGithubUrl } from "../qiskitMetapackage"; import { TocGrouping } from "./TocGrouping"; -export interface ReleaseNoteEntry { - title: string; - url: string; -} - export class ReleaseNotesConfig { - readonly separatePages: ReleaseNoteEntry[]; + readonly separatePagesVersions: string[]; - constructor(kwargs: { separatePages?: ReleaseNoteEntry[] }) { - this.separatePages = kwargs.separatePages ?? []; + constructor(kwargs: { separatePagesVersions?: string[] }) { + this.separatePagesVersions = kwargs.separatePagesVersions ?? []; } } @@ -85,14 +80,14 @@ export class Pkg { }; if (name === "qiskit") { - const releaseNoteEntries = await findLegacyReleaseNotes(name); + const releaseNoteEntries = await findSeparateReleaseNotesVersions(name); return new Pkg({ ...args, title: "Qiskit SDK", name: "qiskit", githubSlug: "qiskit/qiskit", releaseNotesConfig: new ReleaseNotesConfig({ - separatePages: releaseNoteEntries, + separatePagesVersions: releaseNoteEntries, }), nestModulesInToc: true, }); @@ -176,7 +171,7 @@ export class Pkg { } hasSeparateReleaseNotes(): boolean { - return this.releaseNotesConfig.separatePages.length > 0; + return this.releaseNotesConfig.separatePagesVersions.length > 0; } releaseNotesTitle(): string { diff --git a/scripts/lib/api/addFrontMatter.test.ts b/scripts/lib/api/addFrontMatter.test.ts index abdcb5aa8c0..23a8aaf9793 100644 --- a/scripts/lib/api/addFrontMatter.test.ts +++ b/scripts/lib/api/addFrontMatter.test.ts @@ -64,9 +64,7 @@ test("addFrontMatter()", () => { ]; const pkg = Pkg.mock({ releaseNotesConfig: new ReleaseNotesConfig({ - separatePages: [ - { title: "0.1", url: "/api/my-quantum-project/release-notes/0.1" }, - ], + separatePagesVersions: ["0.1"], }), }); diff --git a/scripts/lib/api/generateToc.test.ts b/scripts/lib/api/generateToc.test.ts index cea7deca3a4..3aea2de5db2 100644 --- a/scripts/lib/api/generateToc.test.ts +++ b/scripts/lib/api/generateToc.test.ts @@ -277,16 +277,7 @@ describe("generateToc", () => { const toc = generateToc( Pkg.mock({ releaseNotesConfig: new ReleaseNotesConfig({ - separatePages: [ - { - title: "0.39", - url: "/api/my-quantum-project/release-notes/0.39", - }, - { - title: "0.38", - url: "/api/my-quantum-project/release-notes/0.38", - }, - ], + separatePagesVersions: ["0.39", "0.38"], }), }), [ diff --git a/scripts/lib/api/generateToc.ts b/scripts/lib/api/generateToc.ts index 4e33987d6c4..f8e8cc9f4e5 100644 --- a/scripts/lib/api/generateToc.ts +++ b/scripts/lib/api/generateToc.ts @@ -272,7 +272,11 @@ function generateReleaseNotesEntries(pkg: Pkg) { title: "Release notes", }; if (pkg.hasSeparateReleaseNotes()) { - releaseNotesEntry.children = pkg.releaseNotesConfig.separatePages; + releaseNotesEntry.children = + pkg.releaseNotesConfig.separatePagesVersions.map((vers) => ({ + title: vers, + url: `${releaseNotesUrl}/${vers}`, + })); } else { releaseNotesEntry.url = releaseNotesUrl; } diff --git a/scripts/lib/api/releaseNotes.ts b/scripts/lib/api/releaseNotes.ts index 65945c9a8bb..b4827142cb7 100644 --- a/scripts/lib/api/releaseNotes.ts +++ b/scripts/lib/api/releaseNotes.ts @@ -17,7 +17,7 @@ import { $ } from "zx"; import transformLinks from "transform-markdown-links"; import { getRoot, pathExists } from "../fs"; -import type { Pkg, ReleaseNoteEntry } from "./Pkg"; +import type { Pkg } from "./Pkg"; import type { HtmlToMdResultWithUrl } from "./HtmlToMdResult"; // --------------------------------------------------------------------------- @@ -82,13 +82,13 @@ export async function maybeUpdateReleaseNotesFolder( } /** - * Check for markdown files in `docs/api/package-name/release-notes/ - * then sort them and create entries for the TOC. + * Check for markdown files in `docs/api//release-notes/, + * then sort them and return the list of versions. */ -export const findLegacyReleaseNotes = async ( +export const findSeparateReleaseNotesVersions = async ( pkgName: string, -): Promise => { - const legacyReleaseNoteVersions = ( +): Promise => { + return ( await $`ls ${getRoot()}/docs/api/${pkgName}/release-notes`.quiet() ).stdout .trim() @@ -109,28 +109,16 @@ export const findLegacyReleaseNotes = async ( return 0; }) .reverse(); - - const legacyReleaseNoteEntries = []; - for (let version of legacyReleaseNoteVersions) { - legacyReleaseNoteEntries.push({ - title: version, - url: `/api/${pkgName}/release-notes/${version}`, - }); - } - return legacyReleaseNoteEntries; }; function addNewReleaseNotes(pkg: Pkg): void { if ( - pkg.releaseNotesConfig.separatePages[0].title === pkg.versionWithoutPatch + pkg.releaseNotesConfig.separatePagesVersions[0] === pkg.versionWithoutPatch ) { // Entries already includes most recent release notes return; } - pkg.releaseNotesConfig.separatePages.unshift({ - title: pkg.versionWithoutPatch, - url: `/api/${pkg.name}/release-notes/${pkg.versionWithoutPatch}`, - }); + pkg.releaseNotesConfig.separatePagesVersions.unshift(pkg.versionWithoutPatch); } function generateReleaseNotesIndex(pkg: Pkg): string { @@ -146,8 +134,8 @@ New features, bug fixes, and other changes in previous versions of ${pkg.title}. ## Release notes by version `; - for (const entry of pkg.releaseNotesConfig.separatePages) { - markdown += `* [${entry.title}](${entry.url})\n`; + for (const version of pkg.releaseNotesConfig.separatePagesVersions) { + markdown += `* [${version}](./${version})\n`; } return markdown; }