From 140ee799beef98e5a3ead26cd8606b007ee24ae0 Mon Sep 17 00:00:00 2001 From: JosepSampe Date: Thu, 24 Sep 2026 22:20:59 +0200 Subject: [PATCH 1/5] Update docs --- docs/source/compute_config/ibm_cf.md | 4 +++ docs/source/compute_config/kubernetes.md | 8 +++++- docs/source/metrics.rst | 4 +-- docs/source/storage_backends.rst | 6 +---- lithops/concurrent/futures.py | 31 ++++++++++++++++++++++++ lithops/version.py | 2 +- pyproject.toml | 6 +++-- 7 files changed, 50 insertions(+), 11 deletions(-) diff --git a/docs/source/compute_config/ibm_cf.md b/docs/source/compute_config/ibm_cf.md index 98bd4130f..b448f57e6 100644 --- a/docs/source/compute_config/ibm_cf.md +++ b/docs/source/compute_config/ibm_cf.md @@ -1,3 +1,7 @@ +--- +orphan: true +--- + # IBM Cloud Functions Lithops with *IBM Cloud Functions* as compute backend. diff --git a/docs/source/compute_config/kubernetes.md b/docs/source/compute_config/kubernetes.md index 081a082b8..9c8d0f970 100644 --- a/docs/source/compute_config/kubernetes.md +++ b/docs/source/compute_config/kubernetes.md @@ -118,4 +118,10 @@ You can view the function executions logs in your local machine using the *litho ```bash lithops logs poll -``` \ No newline at end of file +``` + +```{toctree} +:hidden: + +kubernetes_rabbitmq +``` diff --git a/docs/source/metrics.rst b/docs/source/metrics.rst index c84c8e2c5..f9773d6e2 100644 --- a/docs/source/metrics.rst +++ b/docs/source/metrics.rst @@ -92,7 +92,7 @@ that. Lithops keeps a registry of cumulative metrics and replaces its Pushgateway group with it on every push. Installing Prometheus and the Pushgateway -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ The quickest way to get all three services up, including Grafana: @@ -194,7 +194,7 @@ OpenTelemetry endpoint: http://localhost:4318 Straight into Prometheus, without a collector -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Prometheus can receive OTLP itself, which means the ``otlp`` backend reaches it with no collector and no Pushgateway in between. Start Prometheus with diff --git a/docs/source/storage_backends.rst b/docs/source/storage_backends.rst index 008412d56..fe0a37729 100644 --- a/docs/source/storage_backends.rst +++ b/docs/source/storage_backends.rst @@ -1,11 +1,7 @@ Storage Backends ================ -.. toctree:: - :glob: - :maxdepth: 1 - - compute_config/localhost.md +* :doc:`compute_config/localhost` **Object Storage:** diff --git a/lithops/concurrent/futures.py b/lithops/concurrent/futures.py index 2d139af79..679d68d98 100644 --- a/lithops/concurrent/futures.py +++ b/lithops/concurrent/futures.py @@ -287,10 +287,30 @@ def done(self): return super().done() def result(self, timeout=None): + """ + Returns the result of the call, waiting for it to finish. + + :param timeout: Seconds to wait if the call is not done yet. ``None`` + waits without limit + :return: The value returned by the call + :raises concurrent.futures.CancelledError: If the future was cancelled + :raises TimeoutError: If the call did not finish within ``timeout`` + :raises Exception: The exception raised by the call, if it raised one + """ self._sync() return super().result(timeout) def exception(self, timeout=None): + """ + Returns the exception raised by the call, waiting for it to finish. + + :param timeout: Seconds to wait if the call is not done yet. ``None`` + waits without limit + :return: The exception raised by the call, or ``None`` if it returned + normally + :raises concurrent.futures.CancelledError: If the future was cancelled + :raises TimeoutError: If the call did not finish within ``timeout`` + """ self._sync() return super().exception(timeout) @@ -635,6 +655,17 @@ def _check_running(self): # -- concurrent.futures.Executor ---------------------------------------- def submit(self, fn, /, *args, **kwargs): + """ + Schedules ``fn(*args, **kwargs)`` to run on a Lithops worker. + + :param fn: The callable to run + :param args: Positional arguments for ``fn`` + :param kwargs: Keyword arguments for ``fn`` + :return: A :class:`Future` representing the call + :raises RuntimeError: If the executor has been shut down + :raises concurrent.futures.BrokenExecutor: If the executor stopped + working and can no longer run calls + """ # Shutdown must see every accepted submission in _pending before it # can release the native executor, including while submission blocks. with self._submission_lock: diff --git a/lithops/version.py b/lithops/version.py index 93c676f7c..71f85940a 100644 --- a/lithops/version.py +++ b/lithops/version.py @@ -1,5 +1,5 @@ -__version__ = "3.8.1.dev0" +__version__ = "3.8.0" if __name__ == "__main__": print(__version__) diff --git a/pyproject.toml b/pyproject.toml index 26254f584..d4a5ebe7b 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -19,8 +19,10 @@ keywords = [ "map-reduce", ] authors = [ - { name = "Gil Vernik", email = "gilv@ibm.com" }, - { name = "Josep Sampe", email = "josep.sampe@gmail.com" }, + { name = "Gil Vernik" }, + { name = "Josep Sampe" }, + { email = "gilv@ibm.com" }, + { email = "josep.sampe@gmail.com" }, ] license = "Apache-2.0" license-files = ["LICENSE"] From 1b447a197e0f582208e7ba26626b5fd0ffe6d6ce Mon Sep 17 00:00:00 2001 From: JosepSampe Date: Thu, 24 Sep 2026 22:32:43 +0200 Subject: [PATCH 2/5] Update release CI --- .github/workflows/release.yml | 83 ++++++++++++++++++++++++++++++++++- CONTRIBUTING.md | 5 ++- docs/README.md | 4 ++ docs/source/contributing.rst | 5 ++- lithops/version.py | 2 +- 5 files changed, 93 insertions(+), 6 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index a9cd202d5..55cdd6307 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -7,8 +7,12 @@ name: Release # 2. builds the sdist and wheel and publishes them (trusted publishing, no token) # 3. creates the GitHub release "Lithops-X" with the changelog section as notes # 4. bumps the branch to the next development version (X.Y.Z+1.dev0) +# 5. builds the Sphinx docs of the release and commits them to the docs/ folder of the +# GitHub Pages repository (/lithops-cloud.github.io) as "Update docs to X". +# Pushing there needs a deploy key with write access: its private key goes in the +# DOCS_DEPLOY_KEY secret of this repository; without it the docs are not published # Commits go to the branch the workflow runs on, authored by whoever runs it. -# With "dry run" checked it only does the edits and the build, and pushes or publishes nothing. +# With "dry run" checked it only does the edits and the builds, and pushes or publishes nothing. # # In lithops-cloud/lithops it releases from master to PyPI. In a fork it publishes to # TestPyPI instead, so the whole release can be tried out from a throwaway branch. @@ -172,6 +176,83 @@ jobs: with: repository-url: ${{ github.repository == 'lithops-cloud/lithops' && 'https://upload.pypi.org/legacy/' || 'https://test.pypi.org/legacy/' }} + docs: + needs: [prepare, publish] + # after the upload, or in a dry run just to check that the docs build + if: ${{ !cancelled() && needs.prepare.result == 'success' && (inputs.dry_run || needs.publish.result == 'success') }} + runs-on: ubuntu-latest + timeout-minutes: 20 + permissions: + contents: read + env: + # the GitHub Pages repository of the same owner, e.g. lithops-cloud/lithops-cloud.github.io + DOCS_REPOSITORY: ${{ github.repository_owner }}/lithops-cloud.github.io + + steps: + - name: Check the deploy key of the docs repository + id: key + env: + DEPLOY_KEY: ${{ secrets.DOCS_DEPLOY_KEY }} + DRY_RUN: ${{ inputs.dry_run }} + run: | + if [ "$DRY_RUN" = "true" ]; then + echo "publish=false" >> "$GITHUB_OUTPUT" + elif [ -z "$DEPLOY_KEY" ]; then + echo "::warning::The DOCS_DEPLOY_KEY secret is not set, the docs are built but not published to $DOCS_REPOSITORY" + echo "publish=false" >> "$GITHUB_OUTPUT" + else + echo "publish=true" >> "$GITHUB_OUTPUT" + fi + + - name: Clone Lithops repository + uses: actions/checkout@v5 + with: + # the release tag; a dry run pushed no tag, so its branch + ref: ${{ inputs.dry_run && github.sha || inputs.version }} + + - name: Install Python + uses: actions/setup-python@v6 + with: + python-version: '3.12' + + - name: Install the docs dependencies + run: | + sudo apt-get update && sudo apt-get install --no-install-recommends -y pandoc + pip3 install . sphinx myst-parser sphinx_copybutton nbsphinx ipykernel sphinx_book_theme sphinxcontrib-mermaid + + - name: Build the docs + run: make -C docs html + + - name: Clone the docs repository + if: ${{ steps.key.outputs.publish == 'true' }} + uses: actions/checkout@v5 + with: + repository: ${{ env.DOCS_REPOSITORY }} + ssh-key: ${{ secrets.DOCS_DEPLOY_KEY }} + path: site + + - name: Commit and push the docs + if: ${{ steps.key.outputs.publish == 'true' }} + env: + VERSION: ${{ inputs.version }} + AUTHOR_NAME: ${{ needs.prepare.outputs.author_name }} + AUTHOR_EMAIL: ${{ needs.prepare.outputs.author_email }} + run: | + # replace everything under docs/ with the new build (dotfiles are kept, as the + # manual "rm -R docs/*; cp -R _build/html/* docs/" did) + rm -rf site/docs/* + cp -R docs/_build/html/* site/docs/ + cd site + git add -A docs + if git diff --cached --quiet; then + echo "The docs did not change" + exit 0 + fi + git config user.name "$AUTHOR_NAME" + git config user.email "$AUTHOR_EMAIL" + git commit -m "Update docs to $VERSION" + git push + github-release: needs: publish runs-on: ubuntu-latest diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 60b4b36a6..11e9fb169 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -116,8 +116,9 @@ Releases are made by the [Release workflow](.github/workflows/release.yml): *Act *Release* -> *Run workflow*, with the version to release (e.g. `3.7.1`). Before running it, review the development section at the top of `CHANGELOG.md`, which becomes the release notes. The workflow sets the version, tags it, publishes the sdist and wheel to PyPI, creates the -GitHub release and bumps `master` to the next development version. Check *dry run* to build -and check a release without pushing or publishing anything. +GitHub release, publishes the docs to the website repository and bumps `master` to the next +development version. Check *dry run* to build and check a release without pushing or +publishing anything. ## AI coding agents diff --git a/docs/README.md b/docs/README.md index af6f68776..e44645d5e 100644 --- a/docs/README.md +++ b/docs/README.md @@ -1,5 +1,9 @@ # Build Lithops documentation +The [Release workflow](../.github/workflows/release.yml) builds these docs and publishes them to +the website repository on every release. The steps below are for building them locally, or +publishing them by hand. + 1. Install [Sphinx](https://www.sphinx-doc.org/en/master/usage/installation.html) and all plugins: ```bash diff --git a/docs/source/contributing.rst b/docs/source/contributing.rst index f51c3d0d9..e414ba85f 100644 --- a/docs/source/contributing.rst +++ b/docs/source/contributing.rst @@ -136,8 +136,9 @@ Releases are made by the `Release workflow *Release* -> *Run workflow*, with the version to release (e.g. ``3.7.1``). Before running it, review the development section at the top of ``CHANGELOG.md``, which becomes the release notes. The workflow sets the version, tags it, publishes the sdist and wheel to PyPI, -creates the GitHub release and bumps ``master`` to the next development version. Check -*dry run* to build and check a release without pushing or publishing anything. +creates the GitHub release, publishes the docs to the website repository and bumps ``master`` +to the next development version. Check *dry run* to build and check a release without pushing +or publishing anything. AI coding agents diff --git a/lithops/version.py b/lithops/version.py index 71f85940a..93c676f7c 100644 --- a/lithops/version.py +++ b/lithops/version.py @@ -1,5 +1,5 @@ -__version__ = "3.8.0" +__version__ = "3.8.1.dev0" if __name__ == "__main__": print(__version__) From 3323a87c33919508d0967e152da788a1a4d1e2da Mon Sep 17 00:00:00 2001 From: JosepSampe Date: Thu, 24 Sep 2026 22:35:52 +0200 Subject: [PATCH 3/5] Add a Publish docs workflow --- .github/workflows/docs.yml | 132 ++++++++++++++++++++++++++++++++++ .github/workflows/release.yml | 83 +++------------------ CONTRIBUTING.md | 3 +- docs/README.md | 5 +- docs/source/contributing.rst | 3 +- 5 files changed, 148 insertions(+), 78 deletions(-) create mode 100644 .github/workflows/docs.yml diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml new file mode 100644 index 000000000..eba4988c6 --- /dev/null +++ b/.github/workflows/docs.yml @@ -0,0 +1,132 @@ +name: Publish docs + +# Builds the Sphinx docs and commits them to the docs/ folder of the GitHub Pages +# repository (/lithops-cloud.github.io), authored by whoever runs the workflow. +# +# The Release workflow calls it for every release ("Update docs to X"). Run it by hand from +# the Actions tab (Publish docs -> Run workflow -> branch) to republish the docs of that +# branch without a release, e.g. after fixing them ("Update docs"). +# +# Pushing to the docs repository needs a deploy key with write access: its private key goes +# in the DOCS_DEPLOY_KEY secret of this repository; without it the docs are only built. + +on: + workflow_dispatch: + inputs: + dry_run: + description: "Dry run: build the docs only, do not publish them" + type: boolean + default: false + workflow_call: + inputs: + ref: + description: "Branch, tag or commit to build the docs from (default: the one that triggered the run)" + type: string + default: '' + version: + description: "Release the docs belong to, for the commit message" + type: string + default: '' + dry_run: + type: boolean + default: false + secrets: + DOCS_DEPLOY_KEY: + required: false + +jobs: + + docs: + runs-on: ubuntu-latest + timeout-minutes: 20 + # one push to the docs repository at a time + concurrency: + group: publish-docs + cancel-in-progress: false + permissions: + contents: read + env: + # the GitHub Pages repository of the same owner, e.g. lithops-cloud/lithops-cloud.github.io + DOCS_REPOSITORY: ${{ github.repository_owner }}/lithops-cloud.github.io + + steps: + - name: Check the deploy key of the docs repository + id: key + env: + DEPLOY_KEY: ${{ secrets.DOCS_DEPLOY_KEY }} + DRY_RUN: ${{ inputs.dry_run }} + run: | + if [ "$DRY_RUN" = "true" ]; then + echo "publish=false" >> "$GITHUB_OUTPUT" + elif [ -z "$DEPLOY_KEY" ]; then + echo "::warning::The DOCS_DEPLOY_KEY secret is not set, the docs are built but not published to $DOCS_REPOSITORY" + echo "publish=false" >> "$GITHUB_OUTPUT" + else + echo "publish=true" >> "$GITHUB_OUTPUT" + fi + + - name: Clone Lithops repository + uses: actions/checkout@v5 + with: + ref: ${{ inputs.ref }} + + - name: Install Python + uses: actions/setup-python@v6 + with: + python-version: '3.12' + + - name: Install the docs dependencies + run: | + sudo apt-get update && sudo apt-get install --no-install-recommends -y pandoc + pip3 install . sphinx myst-parser sphinx_copybutton nbsphinx ipykernel sphinx_book_theme sphinxcontrib-mermaid + + - name: Build the docs + run: make -C docs html + + - name: Get the git identity of who runs the workflow + if: ${{ steps.key.outputs.publish == 'true' }} + id: author + env: + GH_TOKEN: ${{ github.token }} + LOGIN: ${{ github.actor }} + LOGIN_ID: ${{ github.actor_id }} + run: | + # Their GitHub username, and the email of their latest commit in this repository, + # which is the one their own commits use. Someone who never committed here gets + # their GitHub noreply address + email=$(gh api "repos/$GITHUB_REPOSITORY/commits?author=$LOGIN&per_page=1" \ + --jq '.[0].commit.author.email // empty' 2>/dev/null || true) + [ -n "$email" ] || email="$LOGIN_ID+$LOGIN@users.noreply.github.com" + echo "Committing as $LOGIN <$email>" + echo "name=$LOGIN" >> "$GITHUB_OUTPUT" + echo "email=$email" >> "$GITHUB_OUTPUT" + + - name: Clone the docs repository + if: ${{ steps.key.outputs.publish == 'true' }} + uses: actions/checkout@v5 + with: + repository: ${{ env.DOCS_REPOSITORY }} + ssh-key: ${{ secrets.DOCS_DEPLOY_KEY }} + path: site + + - name: Commit and push the docs + if: ${{ steps.key.outputs.publish == 'true' }} + env: + VERSION: ${{ inputs.version }} + AUTHOR_NAME: ${{ steps.author.outputs.name }} + AUTHOR_EMAIL: ${{ steps.author.outputs.email }} + run: | + # replace everything under docs/ with the new build (dotfiles are kept, as the + # manual "rm -R docs/*; cp -R _build/html/* docs/" did) + rm -rf site/docs/* + cp -R docs/_build/html/* site/docs/ + cd site + git add -A docs + if git diff --cached --quiet; then + echo "The docs did not change" + exit 0 + fi + git config user.name "$AUTHOR_NAME" + git config user.email "$AUTHOR_EMAIL" + git commit -m "Update docs${VERSION:+ to $VERSION}" + git push diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 55cdd6307..b2c294356 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -7,10 +7,8 @@ name: Release # 2. builds the sdist and wheel and publishes them (trusted publishing, no token) # 3. creates the GitHub release "Lithops-X" with the changelog section as notes # 4. bumps the branch to the next development version (X.Y.Z+1.dev0) -# 5. builds the Sphinx docs of the release and commits them to the docs/ folder of the -# GitHub Pages repository (/lithops-cloud.github.io) as "Update docs to X". -# Pushing there needs a deploy key with write access: its private key goes in the -# DOCS_DEPLOY_KEY secret of this repository; without it the docs are not published +# 5. publishes the docs of the release to the GitHub Pages repository as "Update docs to X" +# (the Publish docs workflow, docs.yml, which can also be run by hand to republish them) # Commits go to the branch the workflow runs on, authored by whoever runs it. # With "dry run" checked it only does the edits and the builds, and pushes or publishes nothing. # @@ -180,78 +178,15 @@ jobs: needs: [prepare, publish] # after the upload, or in a dry run just to check that the docs build if: ${{ !cancelled() && needs.prepare.result == 'success' && (inputs.dry_run || needs.publish.result == 'success') }} - runs-on: ubuntu-latest - timeout-minutes: 20 permissions: contents: read - env: - # the GitHub Pages repository of the same owner, e.g. lithops-cloud/lithops-cloud.github.io - DOCS_REPOSITORY: ${{ github.repository_owner }}/lithops-cloud.github.io - - steps: - - name: Check the deploy key of the docs repository - id: key - env: - DEPLOY_KEY: ${{ secrets.DOCS_DEPLOY_KEY }} - DRY_RUN: ${{ inputs.dry_run }} - run: | - if [ "$DRY_RUN" = "true" ]; then - echo "publish=false" >> "$GITHUB_OUTPUT" - elif [ -z "$DEPLOY_KEY" ]; then - echo "::warning::The DOCS_DEPLOY_KEY secret is not set, the docs are built but not published to $DOCS_REPOSITORY" - echo "publish=false" >> "$GITHUB_OUTPUT" - else - echo "publish=true" >> "$GITHUB_OUTPUT" - fi - - - name: Clone Lithops repository - uses: actions/checkout@v5 - with: - # the release tag; a dry run pushed no tag, so its branch - ref: ${{ inputs.dry_run && github.sha || inputs.version }} - - - name: Install Python - uses: actions/setup-python@v6 - with: - python-version: '3.12' - - - name: Install the docs dependencies - run: | - sudo apt-get update && sudo apt-get install --no-install-recommends -y pandoc - pip3 install . sphinx myst-parser sphinx_copybutton nbsphinx ipykernel sphinx_book_theme sphinxcontrib-mermaid - - - name: Build the docs - run: make -C docs html - - - name: Clone the docs repository - if: ${{ steps.key.outputs.publish == 'true' }} - uses: actions/checkout@v5 - with: - repository: ${{ env.DOCS_REPOSITORY }} - ssh-key: ${{ secrets.DOCS_DEPLOY_KEY }} - path: site - - - name: Commit and push the docs - if: ${{ steps.key.outputs.publish == 'true' }} - env: - VERSION: ${{ inputs.version }} - AUTHOR_NAME: ${{ needs.prepare.outputs.author_name }} - AUTHOR_EMAIL: ${{ needs.prepare.outputs.author_email }} - run: | - # replace everything under docs/ with the new build (dotfiles are kept, as the - # manual "rm -R docs/*; cp -R _build/html/* docs/" did) - rm -rf site/docs/* - cp -R docs/_build/html/* site/docs/ - cd site - git add -A docs - if git diff --cached --quiet; then - echo "The docs did not change" - exit 0 - fi - git config user.name "$AUTHOR_NAME" - git config user.email "$AUTHOR_EMAIL" - git commit -m "Update docs to $VERSION" - git push + uses: ./.github/workflows/docs.yml + with: + # the release tag; a dry run pushed no tag, so its branch + ref: ${{ inputs.dry_run && github.sha || inputs.version }} + version: ${{ inputs.version }} + dry_run: ${{ inputs.dry_run }} + secrets: inherit github-release: needs: publish diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 11e9fb169..abddb220e 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -118,7 +118,8 @@ review the development section at the top of `CHANGELOG.md`, which becomes the r The workflow sets the version, tags it, publishes the sdist and wheel to PyPI, creates the GitHub release, publishes the docs to the website repository and bumps `master` to the next development version. Check *dry run* to build and check a release without pushing or -publishing anything. +publishing anything. To republish the docs without a release, run the *Publish docs* workflow +on `master`. ## AI coding agents diff --git a/docs/README.md b/docs/README.md index e44645d5e..ff2b9e0c4 100644 --- a/docs/README.md +++ b/docs/README.md @@ -1,8 +1,9 @@ # Build Lithops documentation The [Release workflow](../.github/workflows/release.yml) builds these docs and publishes them to -the website repository on every release. The steps below are for building them locally, or -publishing them by hand. +the website repository on every release. To republish them without a release (e.g. after fixing +them), run the [Publish docs workflow](../.github/workflows/docs.yml) from the *Actions* tab on +`master`. The steps below are for building them locally. 1. Install [Sphinx](https://www.sphinx-doc.org/en/master/usage/installation.html) and all plugins: diff --git a/docs/source/contributing.rst b/docs/source/contributing.rst index e414ba85f..36d53fc03 100644 --- a/docs/source/contributing.rst +++ b/docs/source/contributing.rst @@ -138,7 +138,8 @@ running it, review the development section at the top of ``CHANGELOG.md``, which release notes. The workflow sets the version, tags it, publishes the sdist and wheel to PyPI, creates the GitHub release, publishes the docs to the website repository and bumps ``master`` to the next development version. Check *dry run* to build and check a release without pushing -or publishing anything. +or publishing anything. To republish the docs without a release, run the *Publish docs* +workflow on ``master``. AI coding agents From f6d8f6ad2224b158bc2fdd8f9a65399de7b7480a Mon Sep 17 00:00:00 2001 From: JosepSampe Date: Thu, 24 Sep 2026 23:08:39 +0200 Subject: [PATCH 4/5] Check the docs build on pull requests --- .github/workflows/docs-check.yml | 52 ++++++++++++++++++++++++++++++++ .github/workflows/docs.yml | 2 +- AGENTS.md | 7 +++-- docs/README.md | 4 +-- pyproject.toml | 12 +++++++- 5 files changed, 71 insertions(+), 6 deletions(-) create mode 100644 .github/workflows/docs-check.yml diff --git a/.github/workflows/docs-check.yml b/.github/workflows/docs-check.yml new file mode 100644 index 000000000..10e499d73 --- /dev/null +++ b/.github/workflows/docs-check.yml @@ -0,0 +1,52 @@ +name: Docs + +# Builds the Sphinx docs on pull requests that change them, and fails on any warning, so +# broken markup, missing pages or bad docstrings are caught before they are merged + +on: + pull_request: + branches: + - master + paths: + - 'docs/**' + # the modules whose docstrings are part of the docs (autodoc) + - 'lithops/executors.py' + - 'lithops/concurrent/futures.py' + - 'lithops/retries.py' + - 'lithops/storage/storage.py' + - 'lithops/utils.py' + - 'pyproject.toml' + - '.github/workflows/docs-check.yml' + + workflow_dispatch: + # this allows to run the workflow manually through the github dashboard + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +jobs: + + sphinx: + runs-on: ubuntu-latest + timeout-minutes: 15 + + steps: + - name: Clone Lithops repository + uses: actions/checkout@v5 + + - name: Install Python 3.12 + uses: actions/setup-python@v6 + with: + python-version: '3.12' + cache: 'pip' + cache-dependency-path: pyproject.toml + + - name: Install the docs dependencies + run: | + sudo apt-get update && sudo apt-get install --no-install-recommends -y pandoc + pip3 install '.[docs]' + + - name: Build the docs + # -W turns warnings into errors; --keep-going reports all of them, not just the first + run: make -C docs html SPHINXOPTS="-W --keep-going" diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index eba4988c6..d53479ba2 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -78,7 +78,7 @@ jobs: - name: Install the docs dependencies run: | sudo apt-get update && sudo apt-get install --no-install-recommends -y pandoc - pip3 install . sphinx myst-parser sphinx_copybutton nbsphinx ipykernel sphinx_book_theme sphinxcontrib-mermaid + pip3 install '.[docs]' - name: Build the docs run: make -C docs html diff --git a/AGENTS.md b/AGENTS.md index 02e451597..5ea68eb15 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -38,7 +38,9 @@ loads the developer's own configuration (`~/.lithops/config`, `.lithops_config`, `LITHOPS_CONFIG_FILE`) and runs against whatever cloud account it points to. Some tests need a Redis server on `localhost:6379` and skip themselves when none is reachable. -Documentation is built with Sphinx from `docs/` (`make html`, see [docs/README.md](docs/README.md)). +Documentation is built with Sphinx from `docs/` (`pip3 install -e '.[docs]'`, then +`make -C docs html SPHINXOPTS="-W --keep-going"`, see [docs/README.md](docs/README.md)). Pull +requests that touch the docs must build without warnings: CI runs that same command. ## Repository map @@ -91,7 +93,8 @@ Documentation is built with Sphinx from `docs/` (`make html`, see [docs/README.m `ruff check .` clean with line length 120. Do not run `ruff format`: the code base is not formatted with it and it would rewrite almost every file. - Package metadata, dependencies and extras live in `pyproject.toml`. When adding a - dependency to an extra, also add it to the `all` extra. + dependency to an extra, also add it to the `all` extra (except the `dev` and `docs` tooling + extras). - Every bug fix includes a regression test; every feature includes tests of its behaviour. Tests must run on the localhost backend and storage; backend-specific code that cannot be exercised locally is tested with fakes or mocks. diff --git a/docs/README.md b/docs/README.md index ff2b9e0c4..a78fc7a79 100644 --- a/docs/README.md +++ b/docs/README.md @@ -5,10 +5,10 @@ the website repository on every release. To republish them without a release (e. them), run the [Publish docs workflow](../.github/workflows/docs.yml) from the *Actions* tab on `master`. The steps below are for building them locally. -1. Install [Sphinx](https://www.sphinx-doc.org/en/master/usage/installation.html) and all plugins: +1. Install Lithops with [Sphinx](https://www.sphinx-doc.org/en/master/usage/installation.html) and all plugins, from the repository root: ```bash - python3 -m pip install sphinx myst-parser sphinx_copybutton jupyter ipykernel nbsphinx sphinx_book_theme + python3 -m pip install -e '.[docs]' ``` 2. Install [Pandoc](https://pandoc.org/installing.html). For debian/ubuntu: diff --git a/pyproject.toml b/pyproject.toml index d4a5ebe7b..04c541f46 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -146,7 +146,17 @@ dev = [ "ruff>=0.16,<0.17", "pre-commit", ] -# union of every extra above except dev; keep it in sync when adding a dependency +# to build the Sphinx docs (the notebooks also need the pandoc binary) +docs = [ + "sphinx", + "myst-parser", + "sphinx-copybutton", + "nbsphinx", + "ipykernel", + "sphinx-book-theme", + "sphinxcontrib-mermaid", +] +# union of every extra above except dev and docs; keep it in sync when adding a dependency all = [ "alibabacloud-fc20230330>=4.7.0", "azure-identity", From 7dea4a16182ae93493f2149f132c5f84c1f247b1 Mon Sep 17 00:00:00 2001 From: JosepSampe Date: Thu, 24 Sep 2026 23:16:09 +0200 Subject: [PATCH 5/5] Publish docs from master with the latest release version --- .github/workflows/docs.yml | 57 ++++++++++++++++++----------------- .github/workflows/release.yml | 31 +++++++++---------- CONTRIBUTING.md | 4 +-- docs/README.md | 4 +-- docs/source/contributing.rst | 2 +- 5 files changed, 49 insertions(+), 49 deletions(-) diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index d53479ba2..87ac92f5c 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -3,33 +3,17 @@ name: Publish docs # Builds the Sphinx docs and commits them to the docs/ folder of the GitHub Pages # repository (/lithops-cloud.github.io), authored by whoever runs the workflow. # -# The Release workflow calls it for every release ("Update docs to X"). Run it by hand from -# the Actions tab (Publish docs -> Run workflow -> branch) to republish the docs of that -# branch without a release, e.g. after fixing them ("Update docs"). +# It always builds master, and names the commit after the latest GitHub release +# ("Update docs to X"). The Release workflow calls it at the end of every release; run it by +# hand from the Actions tab (Publish docs -> Run workflow) to republish the docs without a +# release, e.g. after fixing them. # # Pushing to the docs repository needs a deploy key with write access: its private key goes # in the DOCS_DEPLOY_KEY secret of this repository; without it the docs are only built. on: workflow_dispatch: - inputs: - dry_run: - description: "Dry run: build the docs only, do not publish them" - type: boolean - default: false workflow_call: - inputs: - ref: - description: "Branch, tag or commit to build the docs from (default: the one that triggered the run)" - type: string - default: '' - version: - description: "Release the docs belong to, for the commit message" - type: string - default: '' - dry_run: - type: boolean - default: false secrets: DOCS_DEPLOY_KEY: required: false @@ -54,11 +38,8 @@ jobs: id: key env: DEPLOY_KEY: ${{ secrets.DOCS_DEPLOY_KEY }} - DRY_RUN: ${{ inputs.dry_run }} run: | - if [ "$DRY_RUN" = "true" ]; then - echo "publish=false" >> "$GITHUB_OUTPUT" - elif [ -z "$DEPLOY_KEY" ]; then + if [ -z "$DEPLOY_KEY" ]; then echo "::warning::The DOCS_DEPLOY_KEY secret is not set, the docs are built but not published to $DOCS_REPOSITORY" echo "publish=false" >> "$GITHUB_OUTPUT" else @@ -68,7 +49,28 @@ jobs: - name: Clone Lithops repository uses: actions/checkout@v5 with: - ref: ${{ inputs.ref }} + ref: master + + - name: Get the latest release + id: version + env: + GH_TOKEN: ${{ github.token }} + run: | + # a repository without releases answers 404, and gh prints its body on stdout + VERSION=$(gh api "repos/$GITHUB_REPOSITORY/releases/latest" --jq .tag_name 2>/dev/null) || VERSION="" + echo "Docs of release ${VERSION:-(none)}" + echo "version=$VERSION" >> "$GITHUB_OUTPUT" + + - name: Set the docs to the release version + # the docs show lithops.__version__ ("Lithops vX" in the logo), and master carries the + # next development version; set before installing, as conf.py imports the installed + # package. Without any release the version of master is kept + if: ${{ steps.version.outputs.version != '' }} + env: + VERSION: ${{ steps.version.outputs.version }} + run: | + sed -i -E "s/^__version__ = \".*\"/__version__ = \"$VERSION\"/" lithops/version.py + grep '^__version__' lithops/version.py - name: Install Python uses: actions/setup-python@v6 @@ -94,8 +96,9 @@ jobs: # Their GitHub username, and the email of their latest commit in this repository, # which is the one their own commits use. Someone who never committed here gets # their GitHub noreply address + # (gh prints the error body on stdout when the call fails, so drop it then) email=$(gh api "repos/$GITHUB_REPOSITORY/commits?author=$LOGIN&per_page=1" \ - --jq '.[0].commit.author.email // empty' 2>/dev/null || true) + --jq '.[0].commit.author.email // empty' 2>/dev/null) || email="" [ -n "$email" ] || email="$LOGIN_ID+$LOGIN@users.noreply.github.com" echo "Committing as $LOGIN <$email>" echo "name=$LOGIN" >> "$GITHUB_OUTPUT" @@ -112,7 +115,7 @@ jobs: - name: Commit and push the docs if: ${{ steps.key.outputs.publish == 'true' }} env: - VERSION: ${{ inputs.version }} + VERSION: ${{ steps.version.outputs.version }} AUTHOR_NAME: ${{ steps.author.outputs.name }} AUTHOR_EMAIL: ${{ steps.author.outputs.email }} run: | diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index b2c294356..a0dde8b03 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -7,10 +7,11 @@ name: Release # 2. builds the sdist and wheel and publishes them (trusted publishing, no token) # 3. creates the GitHub release "Lithops-X" with the changelog section as notes # 4. bumps the branch to the next development version (X.Y.Z+1.dev0) -# 5. publishes the docs of the release to the GitHub Pages repository as "Update docs to X" +# 5. at the end, publishes the docs to the GitHub Pages repository as "Update docs to X" # (the Publish docs workflow, docs.yml, which can also be run by hand to republish them) # Commits go to the branch the workflow runs on, authored by whoever runs it. -# With "dry run" checked it only does the edits and the builds, and pushes or publishes nothing. +# With "dry run" checked it only does the edits and the package build, and pushes or +# publishes nothing. # # In lithops-cloud/lithops it releases from master to PyPI. In a fork it publishes to # TestPyPI instead, so the whole release can be tried out from a throwaway branch. @@ -68,8 +69,9 @@ jobs: # Their GitHub username, and the email of their latest commit in this repository, # which is the one their own commits use. Someone who never committed here gets # their GitHub noreply address + # (gh prints the error body on stdout when the call fails, so drop it then) email=$(gh api "repos/$GITHUB_REPOSITORY/commits?author=$LOGIN&per_page=1" \ - --jq '.[0].commit.author.email // empty' 2>/dev/null || true) + --jq '.[0].commit.author.email // empty' 2>/dev/null) || email="" [ -n "$email" ] || email="$LOGIN_ID+$LOGIN@users.noreply.github.com" echo "Committing as $LOGIN <$email>" echo "name=$LOGIN" >> "$GITHUB_OUTPUT" @@ -174,20 +176,6 @@ jobs: with: repository-url: ${{ github.repository == 'lithops-cloud/lithops' && 'https://upload.pypi.org/legacy/' || 'https://test.pypi.org/legacy/' }} - docs: - needs: [prepare, publish] - # after the upload, or in a dry run just to check that the docs build - if: ${{ !cancelled() && needs.prepare.result == 'success' && (inputs.dry_run || needs.publish.result == 'success') }} - permissions: - contents: read - uses: ./.github/workflows/docs.yml - with: - # the release tag; a dry run pushed no tag, so its branch - ref: ${{ inputs.dry_run && github.sha || inputs.version }} - version: ${{ inputs.version }} - dry_run: ${{ inputs.dry_run }} - secrets: inherit - github-release: needs: publish runs-on: ubuntu-latest @@ -258,3 +246,12 @@ jobs: git config user.email "$AUTHOR_EMAIL" git commit -am "Bump version to $DEV_VERSION" git push origin "HEAD:$GITHUB_REF_NAME" + + docs: + # last, once the release is out and master bumped (so a dry run, which skips those, + # does not publish the docs either) + needs: [github-release, bump-dev] + permissions: + contents: read + uses: ./.github/workflows/docs.yml + secrets: inherit diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index abddb220e..ddfac9ef4 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -118,8 +118,8 @@ review the development section at the top of `CHANGELOG.md`, which becomes the r The workflow sets the version, tags it, publishes the sdist and wheel to PyPI, creates the GitHub release, publishes the docs to the website repository and bumps `master` to the next development version. Check *dry run* to build and check a release without pushing or -publishing anything. To republish the docs without a release, run the *Publish docs* workflow -on `master`. +publishing anything. To republish the docs without a release, run the *Publish docs* workflow: +it builds `master` and publishes it as the docs of the latest release. ## AI coding agents diff --git a/docs/README.md b/docs/README.md index a78fc7a79..f301d2dd3 100644 --- a/docs/README.md +++ b/docs/README.md @@ -2,8 +2,8 @@ The [Release workflow](../.github/workflows/release.yml) builds these docs and publishes them to the website repository on every release. To republish them without a release (e.g. after fixing -them), run the [Publish docs workflow](../.github/workflows/docs.yml) from the *Actions* tab on -`master`. The steps below are for building them locally. +them), run the [Publish docs workflow](../.github/workflows/docs.yml) from the *Actions* tab: it +builds `master` and publishes it as the docs of the latest release. The steps below are for building them locally. 1. Install Lithops with [Sphinx](https://www.sphinx-doc.org/en/master/usage/installation.html) and all plugins, from the repository root: diff --git a/docs/source/contributing.rst b/docs/source/contributing.rst index 36d53fc03..086faeb37 100644 --- a/docs/source/contributing.rst +++ b/docs/source/contributing.rst @@ -139,7 +139,7 @@ release notes. The workflow sets the version, tags it, publishes the sdist and w creates the GitHub release, publishes the docs to the website repository and bumps ``master`` to the next development version. Check *dry run* to build and check a release without pushing or publishing anything. To republish the docs without a release, run the *Publish docs* -workflow on ``master``. +workflow: it builds ``master`` and publishes it as the docs of the latest release. AI coding agents