diff --git a/README.md b/README.md index b1bde759381..8c4020c83bc 100644 --- a/README.md +++ b/README.md @@ -372,7 +372,7 @@ In this case, no commit will be automatically created. This is useful when new docs content is published, usually corresponding to new releases or hotfixes for content issues. If you're generating a patch release, also see the below subsection for additional steps. -1. Choose which documentation you want to generate (`qiskit`, `qiskit-ibm-runtime`, or `qiskit-ibm-transpiler`) and its version. +1. Choose which documentation you want to generate (e.g. `qiskit` or `qiskit-ibm-runtime`) and its version. 2. Determine the full version, such as by looking at https://github.com/Qiskit/qiskit/releases 3. Download a CI artifact with the project's documentation. To find this: 1. Pull up the CI runs for the stable commit that you want to build docs from. This should not be from a Pull Request @@ -389,22 +389,25 @@ This is useful when new docs content is published, usually corresponding to new 8. Under `Link Expiration` select `Disable Shared Link on` and set an expiration date of ~10 years into the future. 9. Copy the direct link at the end of the `Shared Link Settings` tab. 10. Modify the `scripts/config/api-html-artifacts.json` file, adding the new versions with the direct link from step 9. -11. Run `npm run gen-api -- -p -v `, - e.g. `npm run gen-api -- -p qiskit -v 0.45.0` +11. Run `npm run gen-api -- -p -v `, e.g. `npm run gen-api -- -p qiskit -v 0.45.0`. If it is not the latest minor version, set `--historical`. + +For dev docs, add `--dev` and either use a version like `-v 1.0.0-dev` or `-v 1.0.0rc1`. + +### Setting up a new minor version -If you are regenerating a dev version, then you can add `--dev` as an argument and the documentation will be built at `/docs/api//dev`. For dev versions, end the `--version` in `-dev`, e.g. `-v 1.0.0-dev`. If a release candidate has already been released, use `-v 1.0.0rc1`, for example. +For example, the latest unversioned docs were `0.2.0` but `0.3.0` was just released. -In case you want to save the current version and convert it into a historical one, you can run `npm run make-historical -- -p ` beforehand. +You must first save the latest unversioned docs as historical docs by running `npm run gen-api` with the `--historical` arg. For example, first run `npm run gen-api -- -p qiskit -v 0.2.0 --historical`. + +Once the historical docs are set up, you can now generate the newest docs by following the normal process, such as `npm run gen-api -- -p qiskit -v 0.3.0`. ### Generate patch releases For example, if the current docs are for 0.45.2 but you want to generate 0.45.3. -Follow the same process above for new API docs, other than: - -- When uploading the artifact, overwrite the existing file with the new one. Be careful to follow the above steps to change "Link Expiration"! +When uploading the artifact to Box, overwrite the existing file with the new one. No need to update the file metadata. -If the version is not for the latest stable minor release series, then add `--historical` to the arguments. For example, use `--historical` if the latest stable release is 0.45.\* but you're generating docs for the patch release 0.44.3. +If the version is not for the latest stable minor release series, remember to add `--historical` to the arguments. For example, use `--historical` if the latest stable release is 0.3.\* but you're generating docs for the patch release 0.2.1. ### View diff for `objects.inv` @@ -422,7 +425,7 @@ The add the following to your `.gitconfig` (usually found at `~/.gitconfig`). textconv = sh -c 'sphobjinv convert plain "$0" -' ``` -### Dependabot - upgrade notebook testing version +## Dependabot - upgrade notebook testing version When a new version of an API is released, we should also update `nb-tester/requirements.txt` to ensure that our notebooks still work with the latest version of the API. You can do this upgrade either manually or wait for Dependabot's automated PR. diff --git a/package.json b/package.json index 4b50b3a0859..f67d649c9f7 100644 --- a/package.json +++ b/package.json @@ -28,7 +28,6 @@ "check:stale-images": "tsx scripts/js/commands/checkStaleImages.ts", "regen-apis": "tsx scripts/js/commands/api/regenerateApiDocs.ts", "gen-api": "tsx scripts/js/commands/api/updateApiDocs.ts", - "make-historical": "tsx scripts/js/commands/api/convertApiDocsToHistorical.ts", "generate-historical-redirects": "tsx scripts/js/commands/api/generateHistoricalRedirects.ts", "save-internal-links": "tsx scripts/js/commands/saveInternalLinks.ts" }, diff --git a/scripts/js/commands/api/convertApiDocsToHistorical.ts b/scripts/js/commands/api/convertApiDocsToHistorical.ts deleted file mode 100644 index c546b190d16..00000000000 --- a/scripts/js/commands/api/convertApiDocsToHistorical.ts +++ /dev/null @@ -1,192 +0,0 @@ -// This code is a Qiskit project. -// -// (C) Copyright IBM 2023. -// -// This code is licensed under the Apache License, Version 2.0. You may -// obtain a copy of this license in the LICENSE file in the root directory -// of this source tree or at http://www.apache.org/licenses/LICENSE-2.0. -// -// Any modifications or derivative works of this code must retain this -// copyright notice, and modified files need to carry a notice indicating -// that they have been altered from the originals. - -import { $ } from "zx"; -import { globby } from "globby"; -import { readFile, writeFile } from "fs/promises"; -import { mkdirp } from "mkdirp"; -import yargs from "yargs/yargs"; -import { hideBin } from "yargs/helpers"; -import transformLinks from "transform-markdown-links"; - -import { - readApiFullVersion, - readApiMinorVersion, -} from "../../lib/apiVersions.js"; -import { pathExists } from "../../lib/fs.js"; -import { zxMain } from "../../lib/zx.js"; -import { Pkg } from "../../lib/api/Pkg.js"; -import { generateHistoricalRedirects } from "./generateHistoricalRedirects.js"; - -interface Arguments { - [x: string]: unknown; - package: string; -} - -const readArgs = (): Arguments => { - return yargs(hideBin(process.argv)) - .version(false) - .option("package", { - alias: "p", - type: "string", - choices: Pkg.VALID_NAMES, - demandOption: true, - description: "Which package to convert", - }) - .parseSync(); -}; - -zxMain(async () => { - const args = readArgs(); - - const pkg = await Pkg.fromArgs(args.package, "ignored", "ignored", "latest"); - - const version = await readApiFullVersion(`docs/api/${pkg.name}`); - const versionWithoutPatch = await readApiMinorVersion(`docs/api/${pkg.name}`); - - const projectNewHistoricalFolder = `docs/api/${pkg.name}/${versionWithoutPatch}`; - if (await pathExists(projectNewHistoricalFolder)) { - console.error( - `${pkg.name} has already a historical version ${versionWithoutPatch}.`, - `Manually delete the existing folder if you intend to overwrite it.`, - ); - process.exit(1); - } - - await mkdirp(projectNewHistoricalFolder); - - await copyApiDocsAndUpdateLinks(pkg.name, versionWithoutPatch); - await generateJsonFiles( - pkg.name, - version, - versionWithoutPatch, - projectNewHistoricalFolder, - ); - await copyImages( - pkg.name, - pkg.hasSeparateReleaseNotes(), - versionWithoutPatch, - ); - await copyObjectsInv(pkg.name, versionWithoutPatch); - await generateHistoricalRedirects(); -}); - -async function copyApiDocsAndUpdateLinks( - pkgName: string, - versionWithoutPatch: string, -) { - console.log("Generating API docs"); - const filePaths = await globby(`docs/api/${pkgName}/*.mdx`); - for (let filePath of filePaths) { - if (filePath.endsWith("release-notes.mdx")) { - continue; - } - updateLinksFile( - pkgName, - versionWithoutPatch, - filePath, - filePath.replace( - `/api/${pkgName}/`, - `/api/${pkgName}/${versionWithoutPatch}/`, - ), - ); - } - - const releaseNotePath = `docs/api/${pkgName}/release-notes/${versionWithoutPatch}.mdx`; - if (await pathExists(releaseNotePath)) { - updateLinksFile( - pkgName, - versionWithoutPatch, - releaseNotePath, - releaseNotePath, - ); - } -} - -async function generateJsonFiles( - pkgName: string, - version: string, - versionWithoutPatch: string, - projectNewHistoricalFolder: string, -) { - console.log("Generating version file"); - const pkgName_json = { name: pkgName, version: version }; - await writeFile( - `${projectNewHistoricalFolder}/_package.json`, - JSON.stringify(pkgName_json, null, 2) + "\n", - ); - - console.log("Generating toc"); - let tocFile = await readFile(`docs/api/${pkgName}/_toc.json`, { - encoding: "utf8", - }); - - // Regex to capture the links starting by /api/projectName and not followed - // by any subfolder starting with a number (historical version folders) - // or a release note file - const linksToUptade = new RegExp( - '"url": "/api/' + pkgName + "(?!/release-notes)(?!/[0-9])", - "g", - ); - tocFile = tocFile.replace( - linksToUptade, - `"url": "/api/${pkgName}/${versionWithoutPatch}`, - ); - await writeFile(`${projectNewHistoricalFolder}/_toc.json`, tocFile + "\n"); -} - -async function copyImages( - pkgName: string, - hasSeparateReleaseNotes: boolean, - versionWithoutPatch: string, -) { - console.log("Copying images"); - const imageDirSource = `public/images/api/${pkgName}/`; - const imageDirDest = `public/images/api/${pkgName}/${versionWithoutPatch}`; - await mkdirp(imageDirDest); - - // If the project only has a single release notes file, we should not copy the release notes images. - if (hasSeparateReleaseNotes) { - await $`find ${imageDirSource}/* -maxdepth 0 -type f | xargs -I {} cp -a {} ${imageDirDest}`; - } else { - await $`find ${imageDirSource}/* -maxdepth 0 -type f | grep -v "release_notes" | xargs -I {} cp -a {} ${imageDirDest}`; - } -} - -async function copyObjectsInv(pkgName: string, versionWithoutPatch: string) { - console.log("Copying objects.inv"); - const sourceDir = `public/api/${pkgName}`; - const destDir = `public/api/${pkgName}/${versionWithoutPatch}`; - await mkdirp(destDir); - await $`cp -a ${sourceDir}/objects.inv ${destDir}`; -} - -async function updateLinksFile( - pkgName: string, - versionWithoutPatch: string, - source: string, - dest: string, -) { - let markdown = await readFile(source, { encoding: "utf8" }); - - // Regex to capture the links containing /api/projectName and not followed - // by any subfolder starting with a number (historical version folders) - // or a release note file - const regexAbsolutePath = new RegExp( - "/api/" + pkgName + "/(?!release-notes)(?![0-9])", - ); - markdown = transformLinks(markdown, (link, _) => - link.replace(regexAbsolutePath, `/api/${pkgName}/${versionWithoutPatch}/`), - ); - - await writeFile(dest, markdown); -}