From 2476ee4c336a5e8fd9b2589e6113a30442f4162f Mon Sep 17 00:00:00 2001 From: Wei Xiao <11197323+wxiao0421@users.noreply.github.com> Date: Tue, 18 Aug 2026 16:47:25 -0700 Subject: [PATCH 1/2] Publish the API docs from main, not only on a v* tag The Sphinx site has never been published. The job that deploys it lives in publish.yml, which triggers only on a v* tag, and the repository has no tags and no releases, so that workflow has never run and roblox.github.io/Sentinel returns 404 - while docs.yml sits on pages: write, id-token: write and a "pages" concurrency group it never uses. Moves that job into docs.yml on pushes to main, so the site tracks the code rather than waiting on a release that may never be cut. publish.yml keeps the package path only, with publish-pypi depending on build directly. The job as written would have published an empty site. autodoc imports the package to read its docstrings, sentinel_local_index imports sentence_transformers at module level, and that is an optional extra, so poetry install --with docs left all ten modules unimportable: sentinel.html built to 18 KB of bare headings rather than the 270 KB it produces once the package imports. Both jobs now install --extras sbert. sphinx-build exits 0 when autodoc cannot import a module, which is how an empty site would have shipped unnoticed, so both build steps now fail if the log contains "failed to import". The pull request job builds the HTML as well as the RST, since nothing checked that the site builds at all. Deployments take the "pages" group with cancel-in-progress false so a docs check on another branch cannot cancel a deployment in flight, and the workflow-level group becomes per branch. Also ignores docs/build/, the output directory docs/README.md tells you to open. Co-authored-by: Cursor --- .github/workflows/docs.yml | 87 +++++++++++++++++++++++++++++++++-- .github/workflows/publish.yml | 55 +--------------------- .gitignore | 3 ++ 3 files changed, 88 insertions(+), 57 deletions(-) diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index 3ae388d..bb889b6 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -17,9 +17,10 @@ permissions: id-token: write pull-requests: write -# Allow only one concurrent deployment +# One run per branch. The deploy job below takes the shared "pages" group, so a +# docs check on another branch cannot cancel a deployment in flight. concurrency: - group: "pages" + group: docs-${{ github.ref }} cancel-in-progress: true jobs: @@ -44,8 +45,10 @@ jobs: echo "$HOME/.local/bin" >> $GITHUB_PATH - name: Install dependencies + # sentinel_local_index imports sentence_transformers at module level, so + # without the sbert extra autodoc cannot import the package at all. run: | - poetry install --with docs + poetry install --with docs --extras sbert - name: Check documentation sync run: | @@ -73,3 +76,81 @@ jobs: body: '⚠️ **Documentation is out of sync with the code!**\n\nPlease run `python docs/generate_docs.py` and commit the updated documentation files.' }) + # Runs last so a build failure cannot trigger the out-of-sync comment above. + - name: Build documentation + shell: bash + run: | + cd ${{ github.workspace }}/docs + poetry run sphinx-build -b html source build/html | tee "$RUNNER_TEMP/sphinx.log" + + # autodoc reports an unimportable module as a warning and sphinx-build + # still exits 0, which publishes pages of headings with no API content. + if grep -q "failed to import" "$RUNNER_TEMP/sphinx.log"; then + echo "::error::autodoc could not import a module, so the API pages would be empty" + exit 1 + fi + + publish-docs: + runs-on: ubuntu-latest + if: github.event_name != 'pull_request' + + # Serialize deployments, and let one finish rather than cancelling it. + concurrency: + group: "pages" + cancel-in-progress: false + + environment: + name: github-pages + url: ${{ steps.deployment.outputs.page_url }} + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Set up Python + uses: actions/setup-python@v5 + with: + python-version: '3.11' + cache: 'pip' + + - name: Install Poetry + run: | + curl -sSL https://install.python-poetry.org | python3 - + echo "$HOME/.local/bin" >> $GITHUB_PATH + + - name: Install dependencies + # sentinel_local_index imports sentence_transformers at module level, so + # without the sbert extra autodoc cannot import the package at all. + run: | + poetry install --with docs --extras sbert + + - name: Generate RST files + run: | + cd ${{ github.workspace }} + poetry run python docs/generate_docs.py + + - name: Build documentation + shell: bash + run: | + cd ${{ github.workspace }}/docs + poetry run sphinx-build -b html source build/html | tee "$RUNNER_TEMP/sphinx.log" + + # autodoc reports an unimportable module as a warning and sphinx-build + # still exits 0, which publishes pages of headings with no API content. + if grep -q "failed to import" "$RUNNER_TEMP/sphinx.log"; then + echo "::error::autodoc could not import a module, so the API pages would be empty" + exit 1 + fi + + - name: Setup Pages + uses: actions/configure-pages@v4 + + - name: Upload artifact + uses: actions/upload-pages-artifact@v3 + with: + path: ${{ github.workspace }}/docs/build/html + + - name: Deploy to GitHub Pages + id: deployment + uses: actions/deploy-pages@v4 + diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 6f8b241..83ef039 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -81,61 +81,8 @@ jobs: path: dist/ retention-days: 7 - publish-docs: - needs: build - runs-on: ubuntu-latest - permissions: - contents: read - pages: write - id-token: write - - environment: - name: github-pages - url: ${{ steps.deployment.outputs.page_url }} - - steps: - - name: Checkout repository - uses: actions/checkout@v4 - - - name: Set up Python - uses: actions/setup-python@v5 - with: - python-version: '3.11' - cache: 'pip' - - - name: Install Poetry - run: | - curl -sSL https://install.python-poetry.org | python3 - - echo "$HOME/.local/bin" >> $GITHUB_PATH - - - name: Install dependencies - run: | - poetry install --with docs - - - name: Generate RST files - run: | - cd ${{ github.workspace }} - poetry run python docs/generate_docs.py - - - name: Build documentation - run: | - cd ${{ github.workspace }}/docs - poetry run sphinx-build -b html source build/html - - - name: Setup Pages - uses: actions/configure-pages@v4 - - - name: Upload artifact - uses: actions/upload-pages-artifact@v3 - with: - path: ${{ github.workspace }}/docs/build/html - - - name: Deploy to GitHub Pages - id: deployment - uses: actions/deploy-pages@v4 - publish-pypi: - needs: publish-docs + needs: build runs-on: ubuntu-latest environment: name: pypi diff --git a/.gitignore b/.gitignore index afb687f..2d35bc6 100644 --- a/.gitignore +++ b/.gitignore @@ -3,6 +3,9 @@ __pycache__/ *.py[cod] *$py.class +# Generated documentation +docs/build/ + # Vim and emacs files *~ *.swp From 8503720e2318dbc6cae677df6a3b1c6705b66296 Mon Sep 17 00:00:00 2001 From: Wei Xiao <11197323+wxiao0421@users.noreply.github.com> Date: Tue, 18 Aug 2026 16:49:44 -0700 Subject: [PATCH 2/2] Run the docs workflow when the docs workflow changes The pull request trigger watched src/**/*.py and docs/**, so a change to docs.yml itself did not run it: the previous commit opened a pull request that rewrote this file and only Run Tests reported back, leaving the build and deploy steps unexercised until they reached main. Co-authored-by: Cursor --- .github/workflows/docs.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index bb889b6..b552faa 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -9,6 +9,7 @@ on: paths: - 'src/**/*.py' - 'docs/**' + - '.github/workflows/docs.yml' workflow_dispatch: permissions: