From ff42963d3bf65ad4c9d26ea235b6f0acf528551c Mon Sep 17 00:00:00 2001 From: silviana amethyst <1388063+ofloveandhate@users.noreply.github.com> Date: Tue, 19 May 2026 09:54:19 +0200 Subject: [PATCH 01/16] ci: factor docs into its own workflow and add path filters Split documentation build/deploy out of publish.yml into a reusable build_docs.yml workflow that supports both workflow_call (from publish.yml on tagged releases) and workflow_dispatch (manual trigger, e.g. to redeploy docs for an existing tag without re-releasing). Also: - Drop the eigenpy==3.11.0 pip install in the docs job; that version is not on PyPI (only 3.10.x and 3.12.0 are) and the bertini2 wheel bundles the C++ eigenpy libraries it links against, so no Python eigenpy install is needed for sphinx autodoc. - Add paths-ignore filters to build_and_test.yml so docs-only commits (python/docs, doc_resources, Doxyfile, *.md, build_docs.yml itself) no longer trigger the full wheel build matrix. Co-Authored-By: Claude Opus 4.7 --- .github/workflows/build_and_test.yml | 12 +++ .github/workflows/build_docs.yml | 148 +++++++++++++++++++++++++++ .github/workflows/publish.yml | 107 +------------------ 3 files changed, 165 insertions(+), 102 deletions(-) create mode 100644 .github/workflows/build_docs.yml diff --git a/.github/workflows/build_and_test.yml b/.github/workflows/build_and_test.yml index 4579501b2..88253bd2a 100644 --- a/.github/workflows/build_and_test.yml +++ b/.github/workflows/build_and_test.yml @@ -4,7 +4,19 @@ on: push: branches: - '**' + paths-ignore: + - 'python/docs/**' + - 'doc_resources/**' + - 'Doxyfile' + - '**/*.md' + - '.github/workflows/build_docs.yml' pull_request: + paths-ignore: + - 'python/docs/**' + - 'doc_resources/**' + - 'Doxyfile' + - '**/*.md' + - '.github/workflows/build_docs.yml' workflow_call: workflow_dispatch: inputs: diff --git a/.github/workflows/build_docs.yml b/.github/workflows/build_docs.yml new file mode 100644 index 000000000..0e0d8a57f --- /dev/null +++ b/.github/workflows/build_docs.yml @@ -0,0 +1,148 @@ +name: Build and deploy documentation 📝 + +on: + workflow_call: + # When called from publish.yml, the caller's build_and_test job has + # already produced the wheel artifact this workflow needs. The internal + # build_and_test job below is skipped in that case. + inputs: + deploy: + description: 'Deploy to GitHub Pages after building' + required: false + type: boolean + default: true + workflow_dispatch: + inputs: + deploy: + description: 'Deploy to GitHub Pages after building' + required: false + type: boolean + default: true + +concurrency: + group: docs-${{ github.ref }} + cancel-in-progress: true + +jobs: + build_and_test: + name: Build wheel (for docs) + # Only run when triggered manually. workflow_call invocations assume the + # caller already ran build_and_test in the same workflow run, so the + # wheel artifact is already available. + if: github.event_name == 'workflow_dispatch' + uses: ./.github/workflows/build_and_test.yml + + build_docs: + name: Build docs + needs: [build_and_test] + # `build_and_test` is skipped when invoked via workflow_call; treat that + # as success so build_docs runs in both modes. + if: | + always() && + (needs.build_and_test.result == 'success' || needs.build_and_test.result == 'skipped') + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v5 + with: + # gitpython (used by python/docs/source/conf.py to derive version) + # needs the full history; the default depth=1 leaves it unable to + # resolve HEAD's commit object on some refs. + fetch-depth: 0 + + - name: Set up Python + uses: actions/setup-python@v5 + with: + python-version: '3.11' + + - name: Compute build metadata + id: meta + run: | + SHA=$(git rev-parse HEAD) + SHORT=$(git rev-parse --short HEAD) + DATE=$(date -u +'%Y-%m-%d %H:%M UTC') + echo "sha=$SHA" >> "$GITHUB_OUTPUT" + echo "short=$SHORT" >> "$GITHUB_OUTPUT" + echo "date=$DATE" >> "$GITHUB_OUTPUT" + echo "Build metadata: $SHORT ($SHA) at $DATE" + + - name: Install system dependencies (Doxygen) + run: | + sudo apt-get update + sudo apt-get install -y doxygen graphviz + + - name: Fetch doxygen-awesome-css + run: | + curl -sSL https://github.com/jothepro/doxygen-awesome-css/archive/refs/tags/v2.3.4.tar.gz | tar -xz + mv doxygen-awesome-css-2.3.4 doxygen-awesome-css + + - name: Build C++ docs (Doxygen) + env: + PROJECT_NUMBER: "${{ steps.meta.outputs.short }} (${{ steps.meta.outputs.date }})" + run: | + mkdir -p build/docs/cpp site + # Append PROJECT_NUMBER override via stdin; Doxygen reads stdin + # config when invoked with `-` and merges with the file. + (cat Doxyfile; echo "PROJECT_NUMBER = $PROJECT_NUMBER") | doxygen - + mv build/docs/cpp site/cpp + + - name: Install Python deps for Sphinx + # The bertini2 wheel bundles the eigenpy C++ libraries it links + # against; no Python `eigenpy` install is required to import bertini + # for sphinx autodoc. + run: | + python -m pip install --upgrade pip + pip install \ + sphinx sphinx-rtd-theme sphinxcontrib-bibtex gitpython \ + scikit-build-core build numpy + + - name: Download built wheel + uses: actions/download-artifact@v5 + with: + name: wheels-ubuntu-latest-3.11 + path: dist/ + + - name: Install bertini from built wheel + run: pip install --no-index --find-links dist/ bertini2 + + - name: Build Python docs (Sphinx) + working-directory: python/docs + env: + BERTINI_GIT_SHA: ${{ steps.meta.outputs.sha }} + BERTINI_BUILD_DATE: ${{ steps.meta.outputs.date }} + run: | + sphinx-build -b html -W --keep-going source ../../site/python + + - name: Add landing page + env: + COMMIT_SHA: ${{ steps.meta.outputs.sha }} + COMMIT_SHORT: ${{ steps.meta.outputs.short }} + BUILD_DATE: ${{ steps.meta.outputs.date }} + run: | + sed \ + -e "s|__COMMIT_SHA__|${COMMIT_SHA}|g" \ + -e "s|__COMMIT_SHORT__|${COMMIT_SHORT}|g" \ + -e "s|__BUILD_DATE__|${BUILD_DATE}|g" \ + doc_resources/landing/index.html > site/index.html + cp doc_resources/landing/style.css site/style.css + + - name: Upload Pages artifact + uses: actions/upload-pages-artifact@v3 + with: + path: site + + deploy_docs: + name: Deploy to GitHub Pages + needs: + - build_docs + if: needs.build_docs.result == 'success' && inputs.deploy + runs-on: ubuntu-latest + permissions: + pages: write + id-token: write + environment: + name: github-pages + url: ${{ steps.deployment.outputs.page_url }} + steps: + - name: Deploy + id: deployment + uses: actions/deploy-pages@v4 diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index e5fdde3a2..e4c602956 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -143,109 +143,12 @@ jobs: files: | dist/*.* - build_docs: - name: Build docs + build_and_deploy_docs: + name: Build and deploy docs if: needs.check_version.outputs.is_prerelease == 'false' needs: [check_version, build_and_test] - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v5 - with: - # gitpython (used by python/docs/source/conf.py to derive version) - # needs the full history; the default depth=1 leaves it unable to - # resolve HEAD's commit object on some refs. - fetch-depth: 0 - - - name: Set up Python - uses: actions/setup-python@v5 - with: - python-version: '3.11' - - - name: Compute build metadata - id: meta - run: | - SHA=$(git rev-parse HEAD) - SHORT=$(git rev-parse --short HEAD) - DATE=$(date -u +'%Y-%m-%d %H:%M UTC') - echo "sha=$SHA" >> "$GITHUB_OUTPUT" - echo "short=$SHORT" >> "$GITHUB_OUTPUT" - echo "date=$DATE" >> "$GITHUB_OUTPUT" - echo "Build metadata: $SHORT ($SHA) at $DATE" - - - name: Install system dependencies (Doxygen) - run: | - sudo apt-get update - sudo apt-get install -y doxygen graphviz - - - name: Fetch doxygen-awesome-css - run: | - curl -sSL https://github.com/jothepro/doxygen-awesome-css/archive/refs/tags/v2.3.4.tar.gz | tar -xz - mv doxygen-awesome-css-2.3.4 doxygen-awesome-css - - - name: Build C++ docs (Doxygen) - env: - PROJECT_NUMBER: "${{ steps.meta.outputs.short }} (${{ steps.meta.outputs.date }})" - run: | - mkdir -p build/docs/cpp site - # Append PROJECT_NUMBER override via stdin; Doxygen reads stdin - # config when invoked with `-` and merges with the file. - (cat Doxyfile; echo "PROJECT_NUMBER = $PROJECT_NUMBER") | doxygen - - mv build/docs/cpp site/cpp - - - name: Install Python deps for Sphinx - run: | - python -m pip install --upgrade pip - pip install \ - sphinx sphinx-rtd-theme sphinxcontrib-bibtex gitpython \ - scikit-build-core build numpy eigenpy==3.11.0 - - - name: Download built wheel - uses: actions/download-artifact@v5 - with: - name: wheels-ubuntu-latest-3.11 - path: dist/ - - - name: Install bertini from built wheel - run: pip install --no-index --find-links dist/ bertini2 - - - name: Build Python docs (Sphinx) - working-directory: python/docs - env: - BERTINI_GIT_SHA: ${{ steps.meta.outputs.sha }} - BERTINI_BUILD_DATE: ${{ steps.meta.outputs.date }} - run: | - sphinx-build -b html -W --keep-going source ../../site/python - - - name: Add landing page - env: - COMMIT_SHA: ${{ steps.meta.outputs.sha }} - COMMIT_SHORT: ${{ steps.meta.outputs.short }} - BUILD_DATE: ${{ steps.meta.outputs.date }} - run: | - sed \ - -e "s|__COMMIT_SHA__|${COMMIT_SHA}|g" \ - -e "s|__COMMIT_SHORT__|${COMMIT_SHORT}|g" \ - -e "s|__BUILD_DATE__|${BUILD_DATE}|g" \ - doc_resources/landing/index.html > site/index.html - cp doc_resources/landing/style.css site/style.css - - - name: Upload Pages artifact - uses: actions/upload-pages-artifact@v3 - with: - path: site - - deploy_docs: - name: Deploy to GitHub Pages - needs: - - build_docs - runs-on: ubuntu-latest + uses: ./.github/workflows/build_docs.yml permissions: + contents: read pages: write - id-token: write - environment: - name: github-pages - url: ${{ steps.deployment.outputs.page_url }} - steps: - - name: Deploy - id: deployment - uses: actions/deploy-pages@v4 \ No newline at end of file + id-token: write \ No newline at end of file From ebc4301f67fb20ee6d90539646d62acbe997a77c Mon Sep 17 00:00:00 2001 From: silviana amethyst <1388063+ofloveandhate@users.noreply.github.com> Date: Tue, 19 May 2026 09:57:50 +0200 Subject: [PATCH 02/16] ci: add `minimal` input to build_and_test for docs-only rebuilds When `minimal: true`, build_and_test produces just the ubuntu-latest / python-3.11 wheel and skips the C++ test jobs, Windows wheels, and wheel test jobs. build_docs.yml passes `minimal: true` when manually dispatched, so redeploying docs no longer triggers the full multi-OS / multi-Python matrix. Tagged releases (publish.yml) still run the full matrix. Co-Authored-By: Claude Opus 4.7 --- .github/workflows/build_and_test.yml | 23 +++++++++++++++++++++-- .github/workflows/build_docs.yml | 4 ++++ 2 files changed, 25 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build_and_test.yml b/.github/workflows/build_and_test.yml index 88253bd2a..fab8e28ed 100644 --- a/.github/workflows/build_and_test.yml +++ b/.github/workflows/build_and_test.yml @@ -18,6 +18,12 @@ on: - '**/*.md' - '.github/workflows/build_docs.yml' workflow_call: + inputs: + minimal: + description: 'Build only the ubuntu-latest / python-3.11 wheel; skip C++ tests, Windows, macOS, and wheel tests.' + required: false + type: boolean + default: false workflow_dispatch: inputs: full_matrix: @@ -25,6 +31,11 @@ on: required: false type: boolean default: false + minimal: + description: 'Build only the ubuntu-latest / python-3.11 wheel; skip C++ tests, Windows, macOS, and wheel tests.' + required: false + type: boolean + default: false concurrency: group: build-${{ github.ref }} @@ -46,7 +57,10 @@ jobs: # Mac available to the maintainer). Intel macOS support is paused # pending a reproducer or an upstream fix. Re-add "macos-15-intel" # below when ready to revisit. - if [[ "${{ github.ref }}" == "refs/heads/main" || "${{ github.ref }}" == "refs/heads/develop" || "${{ github.ref }}" == refs/tags/* || "${{ inputs.full_matrix }}" == "true" || "${{ github.event.pull_request.base.ref }}" == "develop" || "${{ github.event.pull_request.base.ref }}" == "main" ]]; then + if [[ "${{ inputs.minimal }}" == "true" ]]; then + echo 'os=["ubuntu-latest"]' >> $GITHUB_OUTPUT + echo 'python_versions=["3.11"]' >> $GITHUB_OUTPUT + elif [[ "${{ github.ref }}" == "refs/heads/main" || "${{ github.ref }}" == "refs/heads/develop" || "${{ github.ref }}" == refs/tags/* || "${{ inputs.full_matrix }}" == "true" || "${{ github.event.pull_request.base.ref }}" == "develop" || "${{ github.event.pull_request.base.ref }}" == "main" ]]; then echo 'os=["ubuntu-latest","macos-14"]' >> $GITHUB_OUTPUT echo 'python_versions=["3.9","3.10","3.11","3.12","3.13"]' >> $GITHUB_OUTPUT else @@ -56,6 +70,7 @@ jobs: test_cpp_unix: name: C++ tests on ${{ matrix.os }} + if: ${{ inputs.minimal != true }} needs: [set_matrix] runs-on: ${{ matrix.os }} strategy: @@ -119,6 +134,7 @@ jobs: test_cpp_windows: name: C++ tests on Windows + if: ${{ inputs.minimal != true }} runs-on: windows-latest env: CONDA_PKGS_DIRS: ${{ github.workspace }}\conda_pkgs @@ -287,7 +303,8 @@ jobs: if-no-files-found: error build_windows_wheels: - name: Windows Python-${{ matrix.python-version }} wheels + name: Windows Python-${{ matrix.python-version }} wheels + if: ${{ inputs.minimal != true }} runs-on: windows-latest env: CONDA_PKGS_DIRS: ${{ github.workspace }}\conda_pkgs @@ -350,6 +367,7 @@ jobs: test_wheels_linux_macos: name: Test wheels on ${{ matrix.os }} / py${{ matrix.python-version }} + if: ${{ inputs.minimal != true }} needs: [set_matrix, build_macos_ubuntu_wheels] runs-on: ${{ matrix.os }} strategy: @@ -383,6 +401,7 @@ jobs: test_wheels_windows: name: Test wheel on windows-${{ matrix.python-version }} + if: ${{ inputs.minimal != true }} needs: [build_windows_wheels] runs-on: windows-latest strategy: diff --git a/.github/workflows/build_docs.yml b/.github/workflows/build_docs.yml index 0e0d8a57f..74c4d9445 100644 --- a/.github/workflows/build_docs.yml +++ b/.github/workflows/build_docs.yml @@ -31,6 +31,10 @@ jobs: # wheel artifact is already available. if: github.event_name == 'workflow_dispatch' uses: ./.github/workflows/build_and_test.yml + with: + # Docs only need the ubuntu-latest / python-3.11 wheel; skip the full + # OS/Python matrix and the wheel/C++ test jobs. + minimal: true build_docs: name: Build docs From 3b763877ade9e8a9f0a00a5b5cf73dad8c234353 Mon Sep 17 00:00:00 2001 From: silviana amethyst <1388063+ofloveandhate@users.noreply.github.com> Date: Tue, 19 May 2026 10:45:54 +0200 Subject: [PATCH 03/16] ci: add `ref` input to docs workflow_dispatch for tag rebuilds MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit GitHub's workflow_dispatch resolves the workflow file from the chosen ref, so build_docs.yml — which only exists on develop — cannot be dispatched against pre-existing tags like v2.0.1. Adds a `ref` input on build_docs.yml and threads it through to the reusable build_and_test call so the wheel and the docs are both built from the requested ref. Co-Authored-By: Claude Opus 4.7 --- .github/workflows/build_and_test.yml | 7 +++++++ .github/workflows/build_docs.yml | 7 +++++++ 2 files changed, 14 insertions(+) diff --git a/.github/workflows/build_and_test.yml b/.github/workflows/build_and_test.yml index fab8e28ed..e15d85165 100644 --- a/.github/workflows/build_and_test.yml +++ b/.github/workflows/build_and_test.yml @@ -24,6 +24,11 @@ on: required: false type: boolean default: false + ref: + description: 'Branch, tag, or SHA to check out before building (defaults to the calling workflow''s ref).' + required: false + type: string + default: '' workflow_dispatch: inputs: full_matrix: @@ -196,6 +201,8 @@ jobs: steps: - uses: actions/checkout@v5 + with: + ref: ${{ inputs.ref || github.ref }} - name: Cache cibuildwheel + pip + Homebrew uses: actions/cache@v5 with: diff --git a/.github/workflows/build_docs.yml b/.github/workflows/build_docs.yml index 74c4d9445..059c0746e 100644 --- a/.github/workflows/build_docs.yml +++ b/.github/workflows/build_docs.yml @@ -18,6 +18,11 @@ on: required: false type: boolean default: true + ref: + description: 'Branch, tag, or SHA to build docs for (defaults to the dispatched ref).' + required: false + type: string + default: '' concurrency: group: docs-${{ github.ref }} @@ -35,6 +40,7 @@ jobs: # Docs only need the ubuntu-latest / python-3.11 wheel; skip the full # OS/Python matrix and the wheel/C++ test jobs. minimal: true + ref: ${{ inputs.ref }} build_docs: name: Build docs @@ -48,6 +54,7 @@ jobs: steps: - uses: actions/checkout@v5 with: + ref: ${{ inputs.ref || github.ref }} # gitpython (used by python/docs/source/conf.py to derive version) # needs the full history; the default depth=1 leaves it unable to # resolve HEAD's commit object on some refs. From cfce01ad9275a87389458c1c5f10bb2c8e4e9b0f Mon Sep 17 00:00:00 2001 From: silviana amethyst <1388063+ofloveandhate@users.noreply.github.com> Date: Tue, 19 May 2026 11:34:07 +0200 Subject: [PATCH 04/16] =?UTF-8?q?=F0=9F=93=9D=20fixed=20pypi=20url?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- doc_resources/landing/index.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc_resources/landing/index.html b/doc_resources/landing/index.html index 44e6f5b4d..d6d41793c 100644 --- a/doc_resources/landing/index.html +++ b/doc_resources/landing/index.html @@ -32,7 +32,7 @@

C++