⬆️(deps-dev): Bump the python-root group across 1 directory with 2 updates #357
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # Docs build + deploy for both mirrors of this repo. Target is chosen at runtime | |
| # from github.server_url: | |
| # * github.com -> versioned GitHub Pages (mike) | |
| # * otherwise -> an internal docs host (static upload) | |
| # Internal host details come from an owner-level variable (DOCS_HOST), | |
| # which are empty on github.com, so that path is skipped and nothing | |
| # environment-specific is committed. | |
| name: Docs | |
| on: | |
| push: | |
| branches: [main, master] | |
| paths: | |
| - "docs/**" | |
| - "mkdocs.yml" | |
| - "configs/**" | |
| - "apps/mewbo_api/**" | |
| - "packages/mewbo_graph/**" | |
| - "packages/mewbo_core/src/mewbo_core/config.py" | |
| - "scripts/ci/generate_openapi_spec.py" | |
| - "scripts/ci/generate_config_schema.py" | |
| # The docs theme is a pinned wheel, so a theme upgrade changes only these | |
| # two files. Without them a pin bump publishes nothing and the deployed | |
| # site keeps serving the previous theme with no failure anywhere. | |
| - "pyproject.toml" | |
| - "uv.lock" | |
| - ".github/workflows/docs.yml" | |
| pull_request: | |
| types: [opened, synchronize, reopened, closed] | |
| paths: | |
| - "docs/**" | |
| - "mkdocs.yml" | |
| - "configs/**" | |
| - "apps/mewbo_api/**" | |
| - "packages/mewbo_graph/**" | |
| - "packages/mewbo_core/src/mewbo_core/config.py" | |
| - "scripts/ci/generate_openapi_spec.py" | |
| - "scripts/ci/generate_config_schema.py" | |
| # The docs theme is a pinned wheel, so a theme upgrade changes only these | |
| # two files. Without them a pin bump publishes nothing and the deployed | |
| # site keeps serving the previous theme with no failure anywhere. | |
| - "pyproject.toml" | |
| - "uv.lock" | |
| - ".github/workflows/docs.yml" | |
| workflow_dispatch: | |
| permissions: | |
| contents: write # mike pushes the gh-pages branch | |
| concurrency: | |
| group: docs-${{ github.ref }} | |
| cancel-in-progress: true | |
| env: | |
| DOCS_HOST: ${{ vars.DOCS_HOST }} | |
| jobs: | |
| deploy: | |
| name: Build & deploy docs | |
| if: >- | |
| github.event.action != 'closed' && | |
| (github.event_name != 'pull_request' || | |
| github.event.pull_request.head.repo.full_name == github.repository) | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v4 | |
| with: | |
| fetch-depth: 0 | |
| - name: Set up Python | |
| uses: actions/setup-python@v5 | |
| with: | |
| python-version: '3.11' | |
| - name: Install dependencies | |
| run: | | |
| python -m pip install --upgrade pip uv | |
| # The wiki extra pulls mewbo-graph, so the spec published from here is | |
| # generated in the same shape as the committed one rather than | |
| # depending on every graph import in the api staying guarded. | |
| uv sync --group docs --extra ha --extra api --extra wiki | |
| - name: Prepare docs inputs | |
| run: | | |
| printf '{"commit":"%s"}\n' "$(git rev-parse --short HEAD)" > docs/build-info.json | |
| # Both generators exit 0 whether the artifact was rewritten or already | |
| # current, and non-zero only on a genuine failure, so neither call is | |
| # masked. While they were masked a broken export was indistinguishable | |
| # from a clean one and the site kept publishing the committed schema | |
| # and spec regardless, so an API change that was never regenerated | |
| # locally shipped stale docs with no signal anywhere. | |
| uv run python scripts/ci/generate_config_schema.py | |
| cp configs/app.schema.json docs/app.schema.json | |
| uv run python scripts/ci/generate_openapi_spec.py | |
| # --- github.com: versioned GitHub Pages via mike --- | |
| - name: Configure git (mike) | |
| if: github.server_url == 'https://github.com' | |
| run: | | |
| git config user.name "github-actions[bot]" | |
| git config user.email "github-actions[bot]@users.noreply.github.com" | |
| - name: Publish to GitHub Pages | |
| if: github.server_url == 'https://github.com' && github.ref_name == github.event.repository.default_branch | |
| run: | | |
| # Version label is derived from the branch that was pushed, so the | |
| # same workflow publishes "master" on the GitHub mirror and "main" | |
| # on the Gitea origin without hardcoding either name. | |
| uv run mike deploy --push --update-aliases "${{ github.ref_name }}" latest --alias-type copy | |
| uv run mike set-default --push latest | |
| - name: Publish PR preview to GitHub Pages | |
| if: >- | |
| github.server_url == 'https://github.com' && | |
| github.event_name == 'pull_request' && | |
| github.event.pull_request.head.repo.full_name == github.repository && | |
| contains(fromJSON('["OWNER", "MEMBER", "COLLABORATOR"]'), github.event.pull_request.author_association) && | |
| !contains(github.actor, '[bot]') | |
| run: uv run mike deploy --push "pr-${{ github.event.pull_request.number }}" | |
| # --- internal docs host: single version, static upload --- | |
| - name: Publish to internal docs host | |
| if: github.server_url != 'https://github.com' | |
| run: | | |
| slug="$(echo "${GITHUB_REPOSITORY##*/}" | tr '[:upper:]' '[:lower:]')" | |
| [ "${{ github.event_name }}" = "pull_request" ] && slug="${slug}-pr-${{ github.event.pull_request.number }}" | |
| sed -i "s|^site_url:.*|site_url: https://${DOCS_HOST}/${slug}/|" mkdocs.yml | |
| # The BUILD is the gate, and it stays fatal for every event: a page | |
| # that cannot render, or a link that does not resolve, is the change's | |
| # own fault and must fail review. | |
| uv run python -m mkdocs build -d site | |
| tar -C site -cf site.tar . | |
| # --max-time bounds ONE attempt, and the site is now ~86MB of images | |
| # and demo video. A runner that reaches the docs host over a tunnel | |
| # moves that at roughly 0.5MB/s, so the upload needs about three | |
| # minutes and the old 180s cap cut it mid-stream at the same byte | |
| # every run. The server then reports a TRUNCATED ARCHIVE | |
| # ("tar: <some asset>: unexpected EOF"), which reads as a corrupt | |
| # build rather than a timeout, and --retry re-sends the whole archive | |
| # into the identical cap. Keep this comfortably above the real | |
| # transfer time; it is a ceiling, not a delay. | |
| publish() { | |
| curl -fsS -k --retry 5 --retry-all-errors --retry-delay 4 --max-time 900 \ | |
| -X PUT -H 'Content-Type: application/x-tar' --data-binary @site.tar \ | |
| "https://${DOCS_HOST}/${slug}/" | |
| } | |
| # The UPLOAD is a deploy to a host this repo does not own, so the two | |
| # events are judged differently. A push is the real deploy and stays | |
| # fatal. A pull request only publishes a throwaway preview, and an | |
| # unreachable docs host says nothing about the change under review — | |
| # failing the check there teaches everyone to ignore a red docs job, | |
| # which is how the next REAL breakage goes unnoticed. It is announced | |
| # rather than swallowed: the warning names the host, so a reader can | |
| # tell "ops is down" from "nothing was published". | |
| if [ "${{ github.event_name }}" = "pull_request" ]; then | |
| publish || echo "::warning::docs preview upload to ${DOCS_HOST} failed — the site itself built, so this is the docs host, not this change" | |
| else | |
| publish | |
| fi | |
| cleanup: | |
| name: Remove internal-host PR preview | |
| # Remove a PR preview from the internal docs host when the PR closes. | |
| # (GitHub Pages / mike PR cleanup lives in docs-cleanup.yml.) | |
| if: >- | |
| github.server_url != 'https://github.com' && | |
| github.event_name == 'pull_request' && | |
| github.event.action == 'closed' | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Remove PR preview | |
| run: | | |
| slug="$(echo "${GITHUB_REPOSITORY##*/}" | tr '[:upper:]' '[:lower:]')-pr-${{ github.event.pull_request.number }}" | |
| curl -fsS -k --retry 3 --retry-all-errors --retry-delay 4 \ | |
| -X DELETE "https://${DOCS_HOST}/${slug}/" || true |