Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
131 commits
Select commit Hold shift + click to select a range
0036086
fix addon links
eharvey328 Apr 27, 2026
702a9bf
Merge branch 'main' into emh/addons-content
eharvey328 Apr 27, 2026
20bb262
fix links to addon api docs
eharvey328 Apr 29, 2026
eb9eea0
rem updateLinks mapping
eharvey328 Apr 29, 2026
c5b8f90
Merge branch 'main' into emh/addons-content
eharvey328 Apr 30, 2026
92cd49f
run ./fix for new content
eharvey328 Apr 30, 2026
6081772
add addon-mpf
eharvey328 Apr 30, 2026
881b975
fix addon-mfp includes
eharvey328 Apr 30, 2026
4846ee0
add all addons content
eharvey328 Apr 30, 2026
a51e7c4
fix addon utils includes
eharvey328 Apr 30, 2026
48c4b91
move to single pipeline
eharvey328 May 5, 2026
8921465
Merge branch 'main' into emh/addons-content
eharvey328 May 5, 2026
e002534
keep api and addon seperation
eharvey328 May 5, 2026
02e198d
cleanup old addon pipeline
eharvey328 May 6, 2026
6d8755c
sync conversion pipelines
eharvey328 May 6, 2026
3c74554
structure notebook processing
eharvey328 May 7, 2026
33985b9
gen toc
eharvey328 May 7, 2026
50126ae
run fix
eharvey328 May 7, 2026
a8dc85f
fix toc kebab case
eharvey328 May 7, 2026
087aed6
use manual toc
eharvey328 May 7, 2026
bb49c9d
update toc
eharvey328 May 7, 2026
4dcc050
update toc
eharvey328 May 7, 2026
ad80ebe
update adds parent to api toc
eharvey328 May 7, 2026
c81f885
update toc
eharvey328 May 7, 2026
e3048e9
add frontmatter to notebooks
eharvey328 May 8, 2026
4a6dbd8
fix frontmatter
eharvey328 May 9, 2026
612e9bb
fix changing id
eharvey328 May 9, 2026
e6f0633
create shared gen-docs command
eharvey328 May 9, 2026
fb02c41
revert change
eharvey328 May 11, 2026
46a0455
Merge branch 'main' into emh/addons-content
eharvey328 May 11, 2026
c403c44
revert changes
eharvey328 May 12, 2026
83dfdf4
Refactor docs generation pipeline
eharvey328 May 12, 2026
c7a0902
update import
eharvey328 May 12, 2026
00772dd
Remove conversionPipeline.ts in favor of apiDocsPipeline.ts
eharvey328 May 12, 2026
e4164d1
update script
eharvey328 May 12, 2026
2810efc
move file
eharvey328 May 12, 2026
976970c
Rename conversionPipeline.test.ts -> apiDocsPipeline.test.ts
eharvey328 May 12, 2026
6a3dcb5
revert api/images changes
eharvey328 May 13, 2026
cb9e5d1
revert public changes
eharvey328 May 13, 2026
9cc6b54
remove object.inv writing in addons
eharvey328 May 13, 2026
0e31f8e
simplify frontmatter
eharvey328 May 13, 2026
930b3db
add shared script commands
eharvey328 May 13, 2026
4ddf7a7
add ignores and handle release-notes
eharvey328 May 13, 2026
9733919
adds qiskit-addon-utils
eharvey328 May 13, 2026
3e6fbac
fix api github.io links
eharvey328 May 13, 2026
3e5ae4e
add descriptions
eharvey328 May 13, 2026
f5cd467
fix descriptions
eharvey328 May 13, 2026
dbcf1c8
fix spelling
eharvey328 May 13, 2026
e60dc51
fix owners
eharvey328 May 14, 2026
77a90f3
fix prettier
eharvey328 May 14, 2026
767cc0b
fix test
eharvey328 May 14, 2026
03b2274
remove magick dep from test
eharvey328 May 14, 2026
40df3f9
fix check notebooks
eharvey328 May 14, 2026
670972f
adds toc
eharvey328 May 14, 2026
34154ec
adds links to addons
eharvey328 May 14, 2026
8766cc2
adds mpf addon
eharvey328 May 14, 2026
9e1d338
fix link
eharvey328 May 14, 2026
120a98f
adds sqd
eharvey328 May 15, 2026
501f636
adds cutting
eharvey328 May 15, 2026
09aa489
addon link
eharvey328 May 15, 2026
3e31390
use sqd v 0.12.1
eharvey328 May 15, 2026
864f37f
fix spelling
eharvey328 May 15, 2026
4f800db
handle github stars badge
eharvey328 May 15, 2026
300aad5
fix images
eharvey328 May 15, 2026
59b17a9
Merge branch 'main' into emh/addons-content
eharvey328 May 18, 2026
8e3212b
add aqc tensor
eharvey328 May 18, 2026
0c4a0c3
add aqc toc
eharvey328 May 18, 2026
24a98f4
fix link
eharvey328 May 18, 2026
eec2940
adds gen addon toc
eharvey328 May 18, 2026
c456157
map explanations to how-tos
eharvey328 May 18, 2026
29d467c
undo file mapping and do toc mapping instead
eharvey328 May 18, 2026
08761f4
remove double backticks in title
eharvey328 May 18, 2026
a340484
removes tutorials
eharvey328 May 19, 2026
7e9c9b3
cleanup ignores
eharvey328 May 19, 2026
4a17ef5
rename toc titles
eharvey328 May 19, 2026
08c5b31
update toc
eharvey328 May 19, 2026
d63ed4f
link addon tutorials
eharvey328 May 21, 2026
c3ec500
handle link ignores
eharvey328 May 21, 2026
e075ba1
update to latest
eharvey328 May 21, 2026
e0008b5
adds sqd-hpc addon
eharvey328 May 21, 2026
34420ee
move index first in addon toc
eharvey328 May 21, 2026
63b19e2
stub all addons
eharvey328 May 22, 2026
ac2c598
adds pna
eharvey328 May 22, 2026
6ee9287
adds slc
eharvey328 May 22, 2026
5e32c51
adds opt-mapper
eharvey328 May 22, 2026
cbd0801
fix opt-mapper
eharvey328 May 22, 2026
fa5a206
fix opt-mapper
eharvey328 May 22, 2026
723c7bf
fix opt-mapper
eharvey328 May 22, 2026
e7ee451
adds pauli props and fixes non api links in objects.inv
eharvey328 May 22, 2026
68450c1
removes release notes from pauli props
eharvey328 May 22, 2026
ca41554
add docs
eharvey328 May 26, 2026
8d6a845
fix: link addon tutorials directly to /docs/tutorials/{slug}
eharvey328 May 27, 2026
6b9e151
chore: remove _tutorials.json generation from addon pipeline
eharvey328 May 27, 2026
b35be7f
remove _tutorials.json
eharvey328 May 27, 2026
1819731
adds mthree
eharvey328 May 27, 2026
5f3b572
updates guides for mthree
eharvey328 May 27, 2026
0ace261
remove release notes from mthree
eharvey328 May 27, 2026
fb51da8
rename main to index
eharvey328 May 27, 2026
afaeadf
rename main to index
eharvey328 May 27, 2026
8a7b663
simplify addon toc
eharvey328 May 28, 2026
c7c4201
fix aqc toc
eharvey328 May 28, 2026
3ae95e9
don't map how-tos or explainations
eharvey328 May 28, 2026
cc60239
fix toc links
eharvey328 May 28, 2026
a6ba2ca
removes check:addon-tutorials and fix frontmatter spelling
eharvey328 May 28, 2026
237f375
updates READEME.md
eharvey328 May 28, 2026
113a6ac
add qiskit-paulice
eharvey328 May 29, 2026
3e13cc4
rem release notes
eharvey328 May 29, 2026
8ed77e9
rem fermions
eharvey328 May 29, 2026
9f2212d
rem sqd-hpc
eharvey328 May 29, 2026
158ff50
Merge branch 'main' into emh/addons-content
eharvey328 Jun 8, 2026
a43969a
ignore md errors
eharvey328 Jun 8, 2026
361697b
fix prettier
eharvey328 Jun 8, 2026
725864a
fix test
eharvey328 Jun 8, 2026
af8b11b
fix prettier
eharvey328 Jun 8, 2026
21a52da
fix cutting table
eharvey328 Jun 8, 2026
32be949
fix cutting table
eharvey328 Jun 8, 2026
30bab15
fix cutting table
eharvey328 Jun 8, 2026
8a1d5c7
consume source fixes
eharvey328 Jun 10, 2026
e8b9b15
fix prettier
eharvey328 Jun 10, 2026
e8b91a8
Merge branch 'main' into emh/addons-content
eharvey328 Jun 11, 2026
2192feb
rem addons content
eharvey328 Jun 11, 2026
e3387bd
rem content changes
eharvey328 Jun 11, 2026
c9144c9
rem content additions
eharvey328 Jun 11, 2026
ce86833
undo package additions
eharvey328 Jun 11, 2026
7a79424
update readme
eharvey328 Jun 11, 2026
af7d35c
update readme
eharvey328 Jun 11, 2026
3edc37f
add image allowlist
eharvey328 Jun 11, 2026
293250b
fix formatting
eharvey328 Jun 11, 2026
6265f07
update gen addon toc
eharvey328 Jun 11, 2026
164899f
fix prettier
eharvey328 Jun 11, 2026
49bebe3
fix test
eharvey328 Jun 12, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 49 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,13 @@ API docs authors can preview their changes to one of the APIs by using the `-a`
1. Run `npm run gen-api -- -p <pkg-name> -v <version> -a <path/to/docs/_build/html>`.
2. Execute `./start` and open up `http://localhost:3000`, as explained in the prior section.

### Addon docs authors: How to preview your changes

Addon docs authors can preview guide and how-to changes by pointing the addon pipeline at a local Sphinx build:

1. Run `npm run gen-addon -- -p <pkg-name> --sphinx-artifact-folder <path/to/docs/_build/html>`.
2. Execute `./start` and navigate to `http://localhost:3000/docs/addons/<pkg-name>`.

## Run quality checks

We use multiple tools to ensure that documentation meets high standards. These tools will run automatically in your PR through CI, but it is much faster to run the checks locally.
Expand Down Expand Up @@ -321,6 +328,43 @@ Additionally, If you are regenerating a dev version, then you can add `--dev` as

In this case, no commit will be automatically created.

## Generate or update addon docs

Addon docs for packages like are generated by a separate pipeline from the API pipeline. Content is published to `docs/addons/{pkg}/` rather than `docs/api/{pkg}/`.

### Generate addon docs for a new release

3. Run:

```sh
npm run gen-addon -- -p <pkg-name>
```

To regenerate all addon packages at once:

```sh
npm run gen-addon -- --all
```

Or if you don't need to download but need to re-run the pipeline you can pass "--ship-download" to speed things up

```sh
npm run gen-addon -- --all --skip-download
```

4. Open a pull request with the generated changes.

### Add a new addon package

1. Download the Sphinx HTML artifact from the package's GitHub Actions workflow (see the [CI artifact links](#initial-steps) in the API docs section).
2. Unzip the artifact and make sure there is no subfolder before the content. Name the zip to its minor version, e.g. `0.5.zip`, and upload it to the Box folder.
- Unzipping should produce a flat structure of the content: 0.5.zip -> index.html. NOT: 0.5.zip -> sphinx-output/index.html.
3. Add the package's Box artifact URL to `scripts/config/api-html-artifacts.json` (see how to get the shareable link [here](#Final-steps-for-the-rc1-release))
4. Add the package name to `Pkg.ADDON_NAMES` in `scripts/js/lib/api/Pkg.ts` and add a `new Pkg(...)` with the correct `title`, `githubSlug`, and `language` in that file as well.
5. Run the pipeline for the new addon (`gen-api`/`gen-addon`)
6. Verify content with `npm run check:internal-links -- --current-apis`, `npm run check:spelling`, and `npm run check:markdown -- --apis`
7. Verify rendering with `./start --apis`

## Generate new API docs

Use this process when we want to publish new API docs, such as when we release a new version of a package like Qiskit SDK.
Expand Down Expand Up @@ -354,21 +398,25 @@ All release types start with the following steps:
1. In Git, check out the main branch of `Qiskit/documentation` and pull any updates. Then, create a new Git branch.
2. Determine which documentation you want to generate (e.g., `qiskit` or `qiskit-ibm-runtime`) and its full version, e.g., `0.45.2` or `1.2.0rc1`.
3. Download a CI artifact with the project's documentation. To find this:

1. Find the relevant GitHub Actions workflow for the project:

- Qiskit SDK: https://github.com/Qiskit/qiskit/actions/workflows/docs_deploy.yml
- Runtime: https://github.com/Qiskit/qiskit-ibm-runtime/actions/workflows/docs.yml
- Transpiler Service: https://github.com/Qiskit/qiskit-ibm-transpiler/actions/workflows/upload-docs.yml
- qiskit-addon-acq-tensor: https://github.com/Qiskit/qiskit-addon-aqc-tensor/actions/workflows/docs.yml
- qiskit-addon-aqc-tensor: https://github.com/Qiskit/qiskit-addon-aqc-tensor/actions/workflows/docs.yml
- qiskit-addon-obp: https://github.com/Qiskit/qiskit-addon-obp/actions/workflows/docs.yml
- qiskit-addon-mpf: https://github.com/Qiskit/qiskit-addon-mpf/actions/workflows/docs.yml
- qiskit-addon-sqd: https://github.com/Qiskit/qiskit-addon-sqd/actions/workflows/docs.yml
- qiskit-addon-cutting: https://github.com/Qiskit/qiskit-addon-cutting/actions/workflows/docs.yml
- qiskit-addon-utils: https://github.com/Qiskit/qiskit-addon-utils/actions/workflows/docs.yml

2. Find the run for the release by looking at the middle column with the blue text; look for the version number, like `0.45.2`. For the `rc1` release, look for `main` in blue text and a run description like "Prepare 2.3.0rc1".
3. Click the CI run name. (Not the middle column with the blue link!)
4. In the left navbar, it should show as selected the "Summary" page with the house.
5. Scroll down to "Artifacts" and look for the artifact related to documentation, such as `html_docs`.
6. Download the artifact by clicking on its name.

4. On some operating systems, the downloaded zip file will be auto-expanded rather than staying a zip file. If this happens, compress it back to a zip file. On macOS, secondary-click on the folder in Finder and use the "Compress" option.
5. Rename the downloaded zip file with its minor-version number. For example, for the release `0.45.2`, rename `html_docs.zip` to `0.45.zip`. For release candidates (rc), use a value like `2.3-rc.zip`.
6. Upload the renamed zip file to https://ibm.ent.box.com/folder/246867452622. If this is a patch release, this step will overwrite the prior file; if it's the `rc1` release or a new minor version like `2.3.0`, it will be a new file.
Expand Down
2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@
"check:qiskit-versions": "tsx scripts/js/commands/checkQiskitApiVersions.ts",
"regen-apis": "tsx scripts/js/commands/api/regenerateApiDocs.ts",
"gen-api": "tsx scripts/js/commands/api/updateApiDocs.ts",
"gen-addon": "tsx scripts/js/commands/api/updateAddonDocs.ts",
"postgen-addon": "./fix",
"generate-historical-redirects": "tsx scripts/js/commands/api/generateHistoricalRedirects.ts",
"save-internal-links": "tsx scripts/js/commands/saveInternalLinks.ts"
},
Expand Down
13 changes: 10 additions & 3 deletions scripts/ci/check-all-notebooks-are-tested.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,22 +15,29 @@
they don't slip through our CI tests.
"""

import fnmatch
from pathlib import Path
import tomllib
import sys

config_path = Path("scripts/config/notebook-testing.toml")
config = tomllib.loads(config_path.read_text())

categorized_notebooks = set()
categorized_notebooks: set[Path] = set()
categorized_globs: list[str] = []
for group in config["groups"].values():
for path in group.get("notebooks", []):
categorized_notebooks.add(Path(path))
if "*" in path or "?" in path:
categorized_globs.append(path)
else:
categorized_notebooks.add(Path(path))

uncategorized = [
path
for path in Path(".").glob("[!.]*/**/*.ipynb")
if not path.match("**/.ipynb_checkpoints/**") and path not in categorized_notebooks
if not path.match("**/.ipynb_checkpoints/**")
and path not in categorized_notebooks
and not any(fnmatch.fnmatch(str(path), g) for g in categorized_globs)
]

if uncategorized:
Expand Down
2 changes: 2 additions & 0 deletions scripts/config/allowLists.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ export function ignoreTitleMismatch(filepath: string): boolean {
return IGNORE_TITLE_MISMATCHES.includes(filepath);
}

export const IMAGE_ALLOWLIST: Set<string> = new Set([]);

const IGNORE_TITLE_MISMATCHES: string[] = [
"docs/guides/directed-execution-model.mdx", // ok
"docs/guides/estimator-examples.ipynb", // ok
Expand Down
6 changes: 6 additions & 0 deletions scripts/config/notebook-testing.toml
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,12 @@ notebooks = [
# Don't ever test the following notebooks
[groups.exclude]
notebooks = [
# Addon notebooks require the addon packages and are not run in standard CI
"docs/addons/**/*.ipynb",

# Test fixture — not real content
"scripts/js/lib/api/testdata/**/*.ipynb",

# This notebook contains undefined variables so can't run at all.
"docs/guides/function-template-hamiltonian-simulation.ipynb",
"docs/guides/function-template-chemistry-workflow.ipynb",
Expand Down
106 changes: 106 additions & 0 deletions scripts/js/commands/api/updateAddonDocs.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
// This code is a Qiskit project.
//
// (C) Copyright IBM 2024.
//
// 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 { readdir } from "fs/promises";

import yargs from "yargs/yargs";
import { hideBin } from "yargs/helpers";

import { Pkg } from "../../lib/api/Pkg.js";
import { runAddonDocsPipeline } from "../../lib/api/addonDocsPipeline.js";
import { zxMain } from "../../lib/zx.js";
import { parseMinorVersion } from "../../lib/apiVersions.js";
import { deleteOutputDirs, prepareSphinxFolder } from "./updateDocsShared.js";

type Args = {
package?: string;
all: boolean;
skipDownload: boolean;
sphinxArtifactFolder?: string;
};

const readArgs = (): Args => {
return yargs(hideBin(process.argv))
.version(false)
.option("package", {
alias: "p",
type: "string",
choices: Pkg.ADDON_NAMES,
description: "Which addon package to update",
})
.option("all", {
type: "boolean",
default: false,
description: "Update all addon packages in parallel",
})
.option("skip-download", {
alias: "s",
type: "boolean",
default: false,
description: "Skip downloading the Sphinx artifact",
})
.option("sphinx-artifact-folder", {
type: "string",
description: "Use a local artifact folder instead of downloading",
})
.check((argv) => {
if (!argv.all && !argv.package) {
throw new Error("Either --package or --all is required");
}
return true;
})
.parseSync() as unknown as Args;
};

async function resolveVersion(pkgName: string): Promise<string> {
const entries = await readdir(`.sphinx-artifacts/${pkgName}`);
const versions = entries.filter((e) => /^\d/.test(e)).sort();
if (versions.length === 0) {
throw new Error(
`No artifact versions found for ${pkgName}. Run without --skip-download first.`,
);
}
return versions.at(-1)!;
}

async function generateVersion(pkg: Pkg, args: Args): Promise<void> {
const sphinxArtifactFolder = await prepareSphinxFolder(pkg, args);
await deleteOutputDirs(pkg, {
markdownDir: pkg.outputDir("docs/addons"),
imagesDir: pkg.outputDir("public/docs/images/addons"),
recursive: true,
});

console.log(`Run pipeline for ${pkg.name}:${pkg.versionWithoutPatch}`);
await runAddonDocsPipeline(
sphinxArtifactFolder,
"docs/addons",
"public/docs",
pkg,
);
}

async function generatePackage(pkgName: string, args: Args): Promise<void> {
const version = await resolveVersion(pkgName);
const minorVersion = parseMinorVersion(version);
if (minorVersion === null) {
throw new Error(`Could not parse version ${version} for ${pkgName}`);
}
const pkg = await Pkg.fromArgs(pkgName, version, minorVersion, "latest");
await generateVersion(pkg, args);
}

zxMain(async () => {
const args = readArgs();
const packages = args.all ? Pkg.ADDON_NAMES : [args.package!];
await Promise.all(packages.map((pkgName) => generatePackage(pkgName, args)));
});
52 changes: 9 additions & 43 deletions scripts/js/commands/api/updateApiDocs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,10 @@ import { hideBin } from "yargs/helpers";

import { Pkg } from "../../lib/api/Pkg.js";
import { zxMain } from "../../lib/zx.js";
import { parseMinorVersion, isValidVersion } from "../../lib/apiVersions.js";
import { pathExists, rmFilesInFolder } from "../../lib/fs.js";
import { downloadSphinxArtifact } from "../../lib/api/sphinxArtifacts.js";
import { runConversionPipeline } from "../../lib/api/conversionPipeline.js";
import { isValidVersion, parseMinorVersion } from "../../lib/apiVersions.js";
import { runApiDocsPipeline } from "../../lib/api/apiDocsPipeline.js";
import { generateHistoricalRedirects } from "./generateHistoricalRedirects.js";
import { deleteOutputDirs, prepareSphinxFolder } from "./updateDocsShared.js";

export interface Arguments {
[x: string]: unknown;
Expand Down Expand Up @@ -87,10 +86,14 @@ export async function generateVersion(
args: Arguments,
): Promise<void> {
const sphinxArtifactFolder = await prepareSphinxFolder(pkg, args);
await deleteExistingFiles(pkg);
await deleteOutputDirs(pkg, {
markdownDir: pkg.apiOutputDir("docs"),
imagesDir: pkg.apiOutputDir("public/docs/images"),
recursive: false,
});

console.log(`Run pipeline for ${pkg.name}:${pkg.versionWithoutPatch}`);
await runConversionPipeline(sphinxArtifactFolder, "docs", "public/docs", pkg);
await runApiDocsPipeline(sphinxArtifactFolder, "docs", "public/docs", pkg);
await generateHistoricalRedirects();
}

Expand All @@ -112,43 +115,6 @@ export function determineMinorVersion(args: Arguments): string {
return minorVersion;
}

async function prepareSphinxFolder(pkg: Pkg, args: Arguments): Promise<string> {
if (args.sphinxArtifactFolder) {
if (!(await pathExists(args.sphinxArtifactFolder))) {
throw new Error(
`Explicit artifact path '${args.sphinxArtifactFolder}' does not exist.`,
);
}
return args.sphinxArtifactFolder;
}
const sphinxArtifactFolder = pkg.sphinxArtifactFolder();
if (
args.skipDownload &&
(await pathExists(`${sphinxArtifactFolder}/artifact`))
) {
console.log(
`Skip downloading sources for ${pkg.name}:${pkg.versionWithoutPatch}`,
);
} else {
await downloadSphinxArtifact(pkg, sphinxArtifactFolder);
}
return `${sphinxArtifactFolder}/artifact`;
}

async function deleteExistingFiles(pkg: Pkg): Promise<void> {
const markdownDir = pkg.outputDir("docs");
if (await pathExists(markdownDir)) {
await rmFilesInFolder(markdownDir);
}
const imagesDir = pkg.outputDir("public/docs/images");
if (await pathExists(imagesDir)) {
await rmFilesInFolder(imagesDir);
}
console.log(
`Deleted existing markdown & images for ${pkg.name}:${pkg.versionWithoutPatch}`,
);
}

if (import.meta.url === `file://${process.argv[1]}`) {
zxMain(async () => {
const args = readArgs();
Expand Down
Loading
Loading