From eb62fb54f664c38d5dc3d99aedf7a1f6697ea13c Mon Sep 17 00:00:00 2001 From: Frank Harkins Date: Fri, 5 Dec 2025 14:57:46 +0000 Subject: [PATCH 1/7] Tidy up workflow --- .github/workflows/main.yml | 89 +++++++++++++++++++++----------------- 1 file changed, 50 insertions(+), 39 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 571c772453f..49959e6c5c3 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -26,10 +26,10 @@ jobs: id: decide env: GH_TOKEN: ${{ github.token }} - run: | - # If changing this regex, test it on https://regex101.com/ with the + # If changing these regexes, test them on https://regex101.com/ with the # following paths (you can paste the block in and uncomment it): - # + # Add new tests if necessary + NOTEBOOK_TEST_REGEX: (\.github\/workflows\/notebook-test\.yml|(docs|learning)(?!\/api\/)\/.*\.ipynb|scripts\/nb-tester\/.*) # -- Should match: # .github/workflows/notebook-test.yml # scripts/nb-tester/requirements.txt @@ -41,13 +41,8 @@ jobs: # docs/api/thing.mdx # docs/api/thing.ipynb # scripts/js/lib/thing.ts - # - # Add new tests if necessary - NOTEBOOK_TEST_REGEX='(\.github\/workflows\/notebook-test\.yml|(docs|learning)(?!\/api\/)\/.*\.ipynb|scripts\/nb-tester\/.*)' - # If changing this regex, test it on https://regex101.com/ with the - # following paths (you can paste the block in and uncomment it): - # + API_CHECKS_REGEX: (\.github\/workflows\/notebook-test\.yml|(docs|learning)(?!\/api\/)\/.*\.ipynb|scripts\/nb-tester\/.*) # -- Should match: # docs/api/qiskit/index.mdx # public/api/qiskit-ibm-runtime/objects.inv @@ -60,16 +55,12 @@ jobs: # docs/guides/thing.ipynb # public/learning/image.svg # .github/workflows/notebook-test-cron.yml - # - # Add new tests if necessary - API_CHECKS_REGEX='(\.github\/workflows\/notebook-test\.yml|(docs|learning)(?!\/api\/)\/.*\.ipynb|scripts\/nb-tester\/.*)' - + run: | CHANGED_FILES=$(gh pr diff -R Qiskit/documentation ${{ github.event.number }} --name-only) if [ "$(echo "${CHANGED_FILES[@]}" | grep -P $NOTEBOOK_TEST_REGEX)" != '' ] then echo "RUN_NOTEBOOK_TESTER=true" >> "$GITHUB_OUTPUT" fi - if [ "$(echo "${CHANGED_FILES[@]}" | grep -P $API_CHECKS_REGEX)" != '' ] then echo "RUN_API_CHECKS=true" >> "$GITHUB_OUTPUT" @@ -117,32 +108,49 @@ jobs: - name: Infrastructure tests run: npm test - - name: Get all changed docs files - id: all-changed-files - uses: tj-actions/changed-files@af2816c65436325c50621100d67f6e853cd1b0f1 - with: - files: "{docs,learning}/**/*.{md,mdx,ipynb}" - separator: "\n" - write_output_files: true - + - name: Get all changed content files + env: + GH_TOKEN: ${{ github.token }} + # If changing these regexes, test them on https://regex101.com/ with the + # following paths (you can paste the block in and uncomment it): + # Add new tests if necessary + CONTENT_FILE_REGEX: (docs|learning)\/.*\.(mdx|ipynb)$ + # -- Should match: + # docs/guides/thing.ipynb + # docs/guides/thing.mdx + # docs/api/qiskit/index.mdx + # learning/courses/my-course/introduction.ipynb + # + # -- Should not match: + # docs/guides/_toc.json + # scripts/nb-tester/example-notebook.ipynb + id: changed-content-files + run: | + CHANGED_FILES=$(gh pr diff -R Qiskit/documentation ${{ github.event.number }} --name-only) + CHANGED_CONTENT_FILES=$(echo $CHANGED_FILES | grep -P $CONTENT_FILE_REGEX) + if [ "$CHANGED_CONTENT_FILES" != '' ] + then + echo "ANY_CHANGED=true" >> "$GITHUB_OUTPUT" + fi + echo $CHANGED_CONTENT_FILES >> .github/outputs/changed-content-files.txt - name: Pull preview image - if: steps.all-changed-files.outputs.any_changed == 'true' + if: steps.changed-docs-files.outputs.ANY_CHANGED == 'true' run: ./start --pull-only - name: Start local Docker preview (cloud app) - if: steps.all-changed-files.outputs.any_changed == 'true' + if: steps.changed-docs-files.outputs.ANY_CHANGED == 'true' run: | ./start --apis & sleep 1 - name: Check that pages render - if: steps.all-changed-files.outputs.any_changed == 'true' + if: steps.changed-docs-files.outputs.ANY_CHANGED == 'true' run: | - npm run check:pages-render -- --from-file .github/outputs/all_changed_files.txt + npm run check:pages-render -- --from-file .github/outputs/changed-content-files.txt - name: Check that Katex expressions render - if: steps.all-changed-files.outputs.any_changed == 'true' + if: steps.changed-docs-files.outputs.ANY_CHANGED == 'true' run: | - npm run check:katex-render -- --from-file .github/outputs/all_changed_files.txt + npm run check:katex-render -- --from-file .github/outputs/changed-content-files.txt - name: Stop Docker preview - if: steps.all-changed-files.outputs.any_changed == 'true' + if: steps.changed-docs-files.outputs.ANY_CHANGED == 'true' run: docker ps -q | xargs docker stop - name: Setup Python environment @@ -155,6 +163,7 @@ jobs: run: python scripts/ci/check-all-notebooks-are-tested.py - name: Lint notebooks + if: steps.changed-docs-files.outputs.ANY_CHANGED == 'true' shell: python run: | import subprocess, sys @@ -185,23 +194,25 @@ jobs: - name: Check if extra linux deps needed id: check-deps shell: python - run: | + env: # Add your notebook to this list if it needs latex or graphviz to run - EXTRA_DEPS_NOTEBOOKS = """\ - docs/guides/visualize-circuits.ipynb - docs/guides/custom-backend.ipynb - docs/guides/transpiler-stages.ipynb - docs/guides/represent-quantum-computers.ipynb - docs/guides/common-parameters.ipynb - docs/guides/DAG-representation.ipynb - """.strip().split("\n") + EXTRA_DEPS_NOTEBOOKS: | + docs/guides/visualize-circuits.ipynb + docs/guides/custom-backend.ipynb + docs/guides/transpiler-stages.ipynb + docs/guides/represent-quantum-computers.ipynb + docs/guides/common-parameters.ipynb + docs/guides/DAG-representation.ipynb + run: | import os from pathlib import Path + + extra_deps_notebooks = """${{ env.EXTRA_DEPS_NOTEBOOKS }}""".strip().split("\n") github_output = os.getenv("GITHUB_OUTPUT") all_files = Path(".github/outputs/changed-files.txt").read_text().split("\n") config_changed = any(path.startswith("scripts/") or path.startswith(".github") for path in all_files) - extra_deps = config_changed or any(path in EXTRA_DEPS_NOTEBOOKS for path in all_files) + extra_deps = config_changed or any(path in extra_deps_notebooks for path in all_files) with open(github_output, "a") as output: output.write(f"NEEDS_EXTRA_DEPS={str(extra_deps).lower()}") From 47a571d915d8ee7009a0893a74af1180732a9710 Mon Sep 17 00:00:00 2001 From: Frank Harkins Date: Fri, 5 Dec 2025 15:00:04 +0000 Subject: [PATCH 2/7] Simplify extended checks --- .github/workflows/notebook-test-extended.yml | 10 +--------- scripts/ci/extended-execute-notebooks.py | 14 +------------- 2 files changed, 2 insertions(+), 22 deletions(-) diff --git a/.github/workflows/notebook-test-extended.yml b/.github/workflows/notebook-test-extended.yml index e09a1d09c8f..477c49dfab6 100644 --- a/.github/workflows/notebook-test-extended.yml +++ b/.github/workflows/notebook-test-extended.yml @@ -20,14 +20,6 @@ jobs: steps: - uses: actions/checkout@v4 - - name: Get relevant changed files - id: all-changed - uses: tj-actions/changed-files@af2816c65436325c50621100d67f6e853cd1b0f1 - with: - files: "{{docs,learning}/**/*.ipynb,scripts/nb-tester/**/*}" - separator: "\n" - write_output_files: true - - name: Setup environment uses: ./.github/actions/set-up-notebook-testing with: @@ -36,4 +28,4 @@ jobs: install-linux-deps: true - name: Execute notebooks - run: python scripts/ci/extended-execute-notebooks.py + run: tox -- --test-strategy extended diff --git a/scripts/ci/extended-execute-notebooks.py b/scripts/ci/extended-execute-notebooks.py index bde3e800ef5..49c7baa8889 100644 --- a/scripts/ci/extended-execute-notebooks.py +++ b/scripts/ci/extended-execute-notebooks.py @@ -11,24 +11,12 @@ # that they have been altered from the originals. """ -Run the notebook tester on changed notebooks (between branch and main) using -test-eagle. +Run the notebook tester on all notebooks using test-eagle. """ -import os import subprocess from pathlib import Path -all_changed_files = ( - Path(".github/outputs/all_changed_files.txt").read_text().split("\n") -) - -changed_notebooks = [ - path for path in all_changed_files - if path.endswith(".ipynb") -] -config_changed = any(path.startswith("scripts/") for path in all_changed_files) - args = ["tox", "--", "--test-strategy", "extended"] if changed_notebooks and not config_changed: args.extend(changed_notebooks) From 90594329da57fe1b5dadba2660940a9239f4483e Mon Sep 17 00:00:00 2001 From: Frank Harkins Date: Fri, 5 Dec 2025 15:28:20 +0000 Subject: [PATCH 3/7] Fix regexes --- .github/workflows/main.yml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 49959e6c5c3..4b1167ce07e 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -29,9 +29,9 @@ jobs: # If changing these regexes, test them on https://regex101.com/ with the # following paths (you can paste the block in and uncomment it): # Add new tests if necessary - NOTEBOOK_TEST_REGEX: (\.github\/workflows\/notebook-test\.yml|(docs|learning)(?!\/api\/)\/.*\.ipynb|scripts\/nb-tester\/.*) + NOTEBOOK_TEST_REGEX: (\.github\/workflows\/main\.yml|(docs|learning)(?!\/api\/)\/.*\.ipynb|scripts\/nb-tester\/.*) # -- Should match: - # .github/workflows/notebook-test.yml + # .github/workflows/main.yml # scripts/nb-tester/requirements.txt # docs/guides/thing.ipynb # learning/courses/my-course/notebook.ipynb @@ -42,13 +42,13 @@ jobs: # docs/api/thing.ipynb # scripts/js/lib/thing.ts - API_CHECKS_REGEX: (\.github\/workflows\/notebook-test\.yml|(docs|learning)(?!\/api\/)\/.*\.ipynb|scripts\/nb-tester\/.*) + API_CHECKS_REGEX: (\.github\/workflows\/main\.yml|(docs\/api|public\/docs\/api|scripts\/js)\/.*) # -- Should match: # docs/api/qiskit/index.mdx - # public/api/qiskit-ibm-runtime/objects.inv - # public/images/thing.avif + # public/docs/api/qiskit-ibm-runtime/objects.inv + # public/docs/api/qiskit/thing.avif # scripts/js/lib/links/thing.ts - # .github/workflows/api-checks.yml + # .github/workflows/main.yml # # -- Should not match: # scripts/nb-tester/file.py From ee2cd8af570880501d4d25aa56140eb5d4a2456e Mon Sep 17 00:00:00 2001 From: Frank Harkins Date: Fri, 5 Dec 2025 15:39:40 +0000 Subject: [PATCH 4/7] Stop grep exiting with code 1 on no matches --- .github/workflows/main.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 4b1167ce07e..4936cfd63a1 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -57,11 +57,11 @@ jobs: # .github/workflows/notebook-test-cron.yml run: | CHANGED_FILES=$(gh pr diff -R Qiskit/documentation ${{ github.event.number }} --name-only) - if [ "$(echo "${CHANGED_FILES[@]}" | grep -P $NOTEBOOK_TEST_REGEX)" != '' ] + if [ "$(echo "${CHANGED_FILES[@]}" | grep -P $NOTEBOOK_TEST_REGEX || true)" != '' ] then echo "RUN_NOTEBOOK_TESTER=true" >> "$GITHUB_OUTPUT" fi - if [ "$(echo "${CHANGED_FILES[@]}" | grep -P $API_CHECKS_REGEX)" != '' ] + if [ "$(echo "${CHANGED_FILES[@]}" | grep -P $API_CHECKS_REGEX || true)" != '' ] then echo "RUN_API_CHECKS=true" >> "$GITHUB_OUTPUT" fi @@ -127,7 +127,7 @@ jobs: id: changed-content-files run: | CHANGED_FILES=$(gh pr diff -R Qiskit/documentation ${{ github.event.number }} --name-only) - CHANGED_CONTENT_FILES=$(echo $CHANGED_FILES | grep -P $CONTENT_FILE_REGEX) + CHANGED_CONTENT_FILES=$(echo $CHANGED_FILES | grep -P $CONTENT_FILE_REGEX || true) if [ "$CHANGED_CONTENT_FILES" != '' ] then echo "ANY_CHANGED=true" >> "$GITHUB_OUTPUT" From 5f7e70d4a13aa7d3f2bbd960b663cbafe9b28afc Mon Sep 17 00:00:00 2001 From: Frank Harkins Date: Mon, 8 Dec 2025 13:20:09 +0000 Subject: [PATCH 5/7] Make sure directory exists --- .github/workflows/main.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 4936cfd63a1..20be8d340a0 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -132,6 +132,7 @@ jobs: then echo "ANY_CHANGED=true" >> "$GITHUB_OUTPUT" fi + mkdir -p .github/outputs echo $CHANGED_CONTENT_FILES >> .github/outputs/changed-content-files.txt - name: Pull preview image if: steps.changed-docs-files.outputs.ANY_CHANGED == 'true' From 1f76a56c3c48fe737af0f0239e7dc2c2604ad5e1 Mon Sep 17 00:00:00 2001 From: Frank Harkins Date: Tue, 9 Dec 2025 11:30:53 +0000 Subject: [PATCH 6/7] Get PR number in merge queue --- .github/workflows/main.yml | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 20be8d340a0..ec80f3cd86d 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -126,7 +126,17 @@ jobs: # scripts/nb-tester/example-notebook.ipynb id: changed-content-files run: | - CHANGED_FILES=$(gh pr diff -R Qiskit/documentation ${{ github.event.number }} --name-only) + # GitHub API doesn't give PR information in the merge_group event, but + # we can get the PR number from the branch name + if [ "${{ github.event_name }}" == 'merge_group' ] + then + BRANCH_NAME="$(git rev-parse --abbrev-ref HEAD)" + PR_NUMBER="$(echo $BRANCH_NAME | grep -oP '(?<=gh-readonly-queue/main/pr-)\d+')" + else + PR_NUMBER="${{ github.event.number }}" + fi + + CHANGED_FILES=$(gh pr diff -R Qiskit/documentation $PR_NUMBER --name-only) CHANGED_CONTENT_FILES=$(echo $CHANGED_FILES | grep -P $CONTENT_FILE_REGEX || true) if [ "$CHANGED_CONTENT_FILES" != '' ] then From 37d4c31b8c4fd43941202db2b9ae784b987a4836 Mon Sep 17 00:00:00 2001 From: Frank Harkins Date: Tue, 9 Dec 2025 11:32:03 +0000 Subject: [PATCH 7/7] Delete unused file --- scripts/ci/extended-execute-notebooks.py | 24 ------------------------ 1 file changed, 24 deletions(-) delete mode 100644 scripts/ci/extended-execute-notebooks.py diff --git a/scripts/ci/extended-execute-notebooks.py b/scripts/ci/extended-execute-notebooks.py deleted file mode 100644 index 49c7baa8889..00000000000 --- a/scripts/ci/extended-execute-notebooks.py +++ /dev/null @@ -1,24 +0,0 @@ -# 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. - -""" -Run the notebook tester on all notebooks using test-eagle. -""" - -import subprocess -from pathlib import Path - -args = ["tox", "--", "--test-strategy", "extended"] -if changed_notebooks and not config_changed: - args.extend(changed_notebooks) - -subprocess.run(args, check=True)